test: close per-file coverage gaps opened by the message-machine refactor

Downstream packages lost the tests that exercised their agent-loop-facing
edges when the loop was rewritten. Restore 100% per-file coverage with
behavior tests through public seams: llm-retry config validation and
cancellation races, goal replay drift/staleness/teardown edges, plan-mode
disposed-flush, workspace-context empty-change commits, api-proxy
synchronous send failures, acp-snapshot spill-path extraction and refresh
write-back, ACP injection-triggered turns, cli-demo and tui inbox
lifecycle edges, and agent-loop retry/settlement/lifecycle branches.
The only source changes are narrowly-justified v8 ignore annotations on
invariant guards and one redundant-guard removal (workspace-context).
This commit is contained in:
_Kerman
2026-07-26 11:49:19 +08:00
parent 8432c68b6a
commit af3311e1f6
16 changed files with 940 additions and 5 deletions

View File

@@ -1,6 +1,7 @@
import { describe, expect, it } from 'vitest'
import {
type NormalizeContext,
extractSnapshotSpillPaths,
normalizeSessionLog,
normalizeStdout,
scrubRequestHeaders,
@@ -319,6 +320,24 @@ describe('normalizeSessionLog', () => {
})
})
describe('extractSnapshotSpillPaths', () => {
it('maps each spill filename to its full matched path, last match wins per name', () => {
const log = [
'Full formatted result stored at: /tmp/dsh-acp-snapshot-spill/session-c22bc3f1d2af/8a7b6c5d4e3f-bash.txt. Use read with offset/limit, or grep this path to search within it.',
'stale copy at /tmp/dsh-acp-snap-012345678/session-aaaaaaaaaaaa/bbbbbbbbbbbb-grep.txt then',
'fresh copy at /tmp/dsh-acp-snap-012345678/session-cccccccccccc/dddddddddddd-grep.txt then',
].join('\n')
expect(extractSnapshotSpillPaths(log)).toEqual(new Map([
['bash.txt', '/tmp/dsh-acp-snapshot-spill/session-c22bc3f1d2af/8a7b6c5d4e3f-bash.txt'],
['grep.txt', '/tmp/dsh-acp-snap-012345678/session-cccccccccccc/dddddddddddd-grep.txt'],
]))
})
it('returns an empty map when the log carries no snapshot spill paths', () => {
expect(extractSnapshotSpillPaths('no spill paths here, only /tmp/other.txt\n')).toEqual(new Map())
})
})
describe('scrubRequestHeaders', () => {
const headerLine = JSON.stringify({ type: 'session', version: 0, id: 's', createdAt: 1, cwd: '/w' })
const headerEvent = (header: object) =>

View File

@@ -455,6 +455,29 @@ describe('refreshFixtureReplacements', () => {
{ from: '/new', to: '/old' },
])
})
it('stabilizes moved snapshot spill paths by filename while skipping unchanged or unmatched names', () => {
const spill = (session: string, hash: string, name: string): string =>
`/tmp/dsh-acp-snapshot-spill/session-${session}/${hash}-${name}`
const record = (text: string): string =>
`${JSON.stringify({ type: 'session', id: 'same', cwd: '/same' })}\n`
+ `${JSON.stringify({ type: 'tool/result', data: { content: [{ type: 'text', text: `stored at: ${text} ` }] } })}\n`
const freshBash = spill('aaaaaaaaaaaa', 'bbbbbbbbbbbb', 'bash.txt')
const oldBash = spill('cccccccccccc', 'dddddddddddd', 'bash.txt')
const shared = spill('eeeeeeeeeeee', 'ffffffffffff', 'grep.txt')
const orphan = spill('111111111111', '222222222222', 'orphan.txt')
const logs: HarvestedLog[] = [{
id: 'diagnostic',
createdAt: 1,
content: record(`${freshBash} and ${shared}`),
}]
const fixtures = [record(`${oldBash} and ${shared} and ${orphan}`)]
// bash.txt moved → replaced; grep.txt is identical and orphan.txt has no
// fresh counterpart → both skipped.
expect(refreshFixtureReplacements(logs, fixtures)).toEqual([
{ from: freshBash, to: oldBash },
])
})
})
describe('stabilizeRefreshLog', () => {