diff --git a/src/main/ai-vault/session-scan-cutoff.test.ts b/src/main/ai-vault/session-scan-cutoff.test.ts index 304078ed5f5..23669e09d7c 100644 --- a/src/main/ai-vault/session-scan-cutoff.test.ts +++ b/src/main/ai-vault/session-scan-cutoff.test.ts @@ -104,6 +104,21 @@ describe('canStopParsingSessions', () => { }) it('uses the same nullish modified-time fallback and numeric limit semantics', () => { + const modifiedOnly = session('', { + updatedAt: null, + modifiedAt: '1970-01-01T00:00:02+00:00' + }) + expect(canStopParsingSessions(collection([modifiedOnly]), 1, 1000)).toBe(true) + expect(canStopParsingSessions(collection([{ ...modifiedOnly, updatedAt: '' }]), 1, 1000)).toBe( + false + ) + + const boundaries = collection([session(10), session(20)]) + expect(canStopParsingSessions(boundaries, 0, 9)).toBe(true) + expect(canStopParsingSessions(boundaries, 0, 10)).toBe(false) + expect(canStopParsingSessions(boundaries, 0.5, 19)).toBe(true) + expect(canStopParsingSessions(boundaries, Number.NaN, 20)).toBe(false) + const rows = [ session('', { updatedAt: null, modifiedAt: '1970-01-01T00:00:02+00:00' }), session('-000001-01-01T00:00:00Z'), diff --git a/src/shared/agent-hook-listener/claude-session-continuation.test.ts b/src/shared/agent-hook-listener/claude-session-continuation.test.ts index 81f27cf75f5..3fe16c462f2 100644 --- a/src/shared/agent-hook-listener/claude-session-continuation.test.ts +++ b/src/shared/agent-hook-listener/claude-session-continuation.test.ts @@ -212,7 +212,7 @@ describe('ClaudeSessionContinuationTracker', () => { expect(tracker.resolve(session(OLD, oldPath))).toEqual(session(FORK, forkPath)) }) - it('reads only the tail of a transcript larger than the first scan', () => { + it('finds a continuation near the end of a large transcript', () => { const { projectDir } = makeProject() const filler = turn(OLD, 'filler').repeat(Math.ceil((3 * 1024 * 1024) / 90)) const oldPath = writeTranscript(projectDir, OLD, filler + pointer(OLD, FORK)) @@ -244,7 +244,7 @@ describe('ClaudeSessionContinuationTracker', () => { const oldPath = writeTranscript(projectDir, OLD, turn(OLD, 'u1') + pointer(OLD, FORK)) const elsewhere = join(configDir, 'projects', '-other-repo') mkdirSync(elsewhere, { recursive: true }) - const forkPath = writeTranscript(elsewhere, 'transcript-file-uuid', turn(FORK, 'u1')) + const forkPath = writeTranscript(elsewhere, FILE_ID, turn(FORK, 'u1')) const jobDir = join(configDir, 'jobs', FORK.slice(0, 8)) mkdirSync(jobDir, { recursive: true }) writeFileSync( diff --git a/src/shared/git-status-line-stats-cache.test.ts b/src/shared/git-status-line-stats-cache.test.ts index fcf33ff7c7c..80c5a46081d 100644 --- a/src/shared/git-status-line-stats-cache.test.ts +++ b/src/shared/git-status-line-stats-cache.test.ts @@ -24,7 +24,7 @@ describe('git status line stats cache', () => { clearGitStatusLineStatsCache() }) - it('reuses counts only for an exact head and status-entry identity', () => { + it('reuses counts for matching entries and rejects a changed head', () => { storeGitStatusLineStats({ cacheKey: 'native\0/repo', head: 'head-1', entries: cachedEntries }) const matchingEntries = [{ path: 'src/a.ts', status: 'modified', area: 'unstaged' }] diff --git a/src/shared/git-tracked-pathspecs.test.ts b/src/shared/git-tracked-pathspecs.test.ts index 5bd1611319d..870dde4ad86 100644 --- a/src/shared/git-tracked-pathspecs.test.ts +++ b/src/shared/git-tracked-pathspecs.test.ts @@ -1,21 +1,6 @@ import { describe, expect, it, vi } from 'vitest' import { isTrackedPathSpec, partitionTrackedPathSpecs } from './git-tracked-pathspecs' -function previousPartition(filePaths: readonly string[], trackedPaths: readonly string[]) { - const normalize = (value: string) => value.replace(/\\/g, '/').replace(/\/+$/, '') - const isTracked = (filePath: string) => { - const normalized = normalize(filePath) - return trackedPaths.some((trackedPath) => { - const normalizedTracked = normalize(trackedPath) - return normalizedTracked === normalized || normalizedTracked.startsWith(`${normalized}/`) - }) - } - return { - trackedPaths: filePaths.filter(isTracked), - untrackedPaths: filePaths.filter((filePath) => !isTracked(filePath)) - } -} - function countNormalizations(run: () => unknown): number { const replace = vi.spyOn(String.prototype, 'replace') try { @@ -53,7 +38,9 @@ describe('tracked pathspec partition', () => { ] as const)('keeps matching semantics for %j against %j', (request, tracked, expected) => { expect(isTrackedPathSpec(request, tracked)).toBe(expected) expect(partitionTrackedPathSpecs([request], tracked)).toEqual( - previousPartition([request], tracked) + expected + ? { trackedPaths: [request], untrackedPaths: [] } + : { trackedPaths: [], untrackedPaths: [request] } ) }) @@ -66,47 +53,14 @@ describe('tracked pathspec partition', () => { }) }) - it('matches the previous implementation across combinations of path edges', () => { - const paths = [ - '', - '/', - '.', - './a', - 'a', - 'a/', - 'a//', - 'a/b', - 'a\\b', - 'a//b', - 'ab', - 'A', - '../a', - 'a/../b', - '[a]', - '*', - 'a b', - 'é', - 'e\u0301', - '/a', - '//host/share', - 'C:\\a' - ] - for (const tracked of [[], paths, ...paths.map((entry) => [entry])]) { - expect(partitionTrackedPathSpecs(paths, tracked)).toEqual(previousPartition(paths, tracked)) - } - }) - it('normalizes each visited tracked entry once and each request once per operation', () => { const requests = Array.from({ length: 64 }, (_, index) => `missing/${index}`) const tracked = Array.from({ length: 256 }, (_, index) => `docs\\file-${index}///`) - expect(countNormalizations(() => previousPartition(requests, tracked))).toBe(32_896) - expect(countNormalizations(() => partitionTrackedPathSpecs(requests, tracked))).toBe(320) expect(countNormalizations(() => partitionTrackedPathSpecs(requests, tracked))).toBe(320) }) it('retains early exit for a selected directory with many tracked descendants', () => { - const tracked = Array.from({ length: 150_000 }, (_, index) => `docs/file-${index}`) - expect(countNormalizations(() => previousPartition(['docs'], tracked))).toBe(4) + const tracked = Array.from({ length: 64 }, (_, index) => `docs/file-${index}`) expect(countNormalizations(() => partitionTrackedPathSpecs(['docs'], tracked))).toBe(2) expect(countNormalizations(() => partitionTrackedPathSpecs([], tracked))).toBe(0) }) diff --git a/src/shared/git-uncommitted-line-stats.test.ts b/src/shared/git-uncommitted-line-stats.test.ts index 9fcc572adcf..a52b7faf36f 100644 --- a/src/shared/git-uncommitted-line-stats.test.ts +++ b/src/shared/git-uncommitted-line-stats.test.ts @@ -1,3 +1,4 @@ +import { basename } from 'node:path' import { beforeEach, describe, expect, it, vi } from 'vitest' const { lstatMock, readFileMock } = vi.hoisted(() => ({ @@ -85,11 +86,11 @@ describe('collectUntrackedAdditions', () => { it('counts file lines as additions, with or without a trailing newline', async () => { lstatMock.mockImplementation((target: string) => - Promise.resolve(mockFileStat(String(target).endsWith('trailing.ts') ? 6 : 5)) + Promise.resolve(mockFileStat(basename(target) === 'trailing.ts' ? 6 : 5)) ) readFileMock.mockImplementation((target: string) => Promise.resolve( - String(target).endsWith('trailing.ts') ? Buffer.from('a\nb\nc\n') : Buffer.from('a\nb\nc') + basename(target) === 'trailing.ts' ? Buffer.from('a\nb\nc\n') : Buffer.from('a\nb\nc') ) ) const stats = await collectUntrackedAdditions('/repo', ['trailing.ts', 'no-trailing.ts']) diff --git a/src/shared/github/account-binding.test.ts b/src/shared/github/account-binding.test.ts index 9a033de4fef..bacb1efc4b5 100644 --- a/src/shared/github/account-binding.test.ts +++ b/src/shared/github/account-binding.test.ts @@ -47,7 +47,7 @@ describe('ghTokenEnvVarForHost', () => { }) describe('ghAccountBindingsEqual', () => { - it('compares normalized host/user pairs', () => { + it('compares equal pairs and preserves user case sensitivity', () => { expect( ghAccountBindingsEqual( { host: 'github.com', user: 'Alice' }, diff --git a/src/shared/gitlab-job-log-excerpt.test.ts b/src/shared/gitlab-job-log-excerpt.test.ts index d477f9f094b..f54aad843c2 100644 --- a/src/shared/gitlab-job-log-excerpt.test.ts +++ b/src/shared/gitlab-job-log-excerpt.test.ts @@ -65,7 +65,7 @@ describe('gitLabJobTraceToLogExcerpt', () => { expect(excerpt).toContain('Uploading artifact 89') }) - it('bounds the raw trace before stripping so a huge log is not scanned in full', () => { + it('keeps the error tail and drops the head of a huge trace', () => { const filler = `${'x'.repeat(200)}\n`.repeat(6_000) // ~1.2 MB, above the raw cap const excerpt = gitLabJobTraceToLogExcerpt(`head marker\n${filler}ERROR: Job failed`)