test: consolidate duplicates and strengthen behavioral boundaries (#33088)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
OrcaWin
2026-10-24 01:22:18 -07:00
committed by GitHub
co-authored by OrcaWin
parent 28258c0ba9
commit 0c06f1f082
16 changed files with 114 additions and 44 deletions
@@ -29,7 +29,19 @@ describe('findUncollectedTestFiles', () => {
it('counts a suite module as collected only while a collected entry runtime-imports it', () => {
const sources = new Map([
['src/page.test.ts', "import './page.case.spec'\nimport './twin.spec'\n"],
[
'src/page.test.ts',
[
"import './page.case.spec'",
"import './twin.spec'",
"import '@renderer/alias-one.spec'",
"import '@/alias-two.spec.js'",
"import './nested-suite'"
].join('\n')
],
['src/renderer/src/alias-one.spec.ts', SUITE],
['src/renderer/src/alias-two.spec.ts', SUITE],
['src/nested-suite/index.ts', SUITE],
['src/twin.spec.ts', SUITE],
['src/twin.spec.tsx', SUITE],
['src/page.case.spec.ts', `import './page-harness.spec'\n${SUITE}`],
@@ -33,6 +33,7 @@ describe('mobile diff comment editing', () => {
expect(result.comment).toMatchObject({ id: 'a', body: 'updated', updatedAt: 200 })
expect(result.comment?.sentAt).toBeUndefined()
expect(result.comments).toEqual([result.comment])
})
it('marks notes sent and excludes them from unsent counts', () => {
@@ -2,7 +2,6 @@ import { describe, expect, it } from 'vitest'
import type { DiffComment } from '../../../src/shared/diff-comment-types'
import {
addMobileDiffComment,
formatDiffComments,
formatMobileDiffReviewPrompt,
normalizeMobileDiffComments,
removeDeliveredMobileDiffComments,
@@ -117,18 +116,6 @@ describe('mobile diff comments', () => {
).toEqual([comment({ id: 'a', body: 'new note' }), comment({ id: 'b' })])
})
it('uses the desktop-compatible prompt format', () => {
expect(formatDiffComments([comment({ id: 'a', body: 'quote "this"' })])).toBe(
['File: src/app.ts', 'Line: 4', 'User comment: "quote \\"this\\""'].join('\n')
)
})
it('formats file-level notes with file scope', () => {
expect(formatDiffComments([comment({ id: 'a', lineNumber: 0 })])).toBe(
['File: src/app.ts', 'Scope: file', 'User comment: "check this"'].join('\n')
)
})
it('wraps sent review notes in the mobile agent prompt', () => {
expect(formatMobileDiffReviewPrompt([comment({ id: 'a' })])).toBe(
[
@@ -53,14 +53,14 @@ describe('mobile diff review positioning', () => {
})
it('matches renamed files by oldPath through the queue key', () => {
const queue = [item('new.ts', 'branch', 'old.ts'), item('other.ts', 'branch')]
const queue = [item('other.ts', 'branch'), item('new.ts', 'branch', 'old.ts')]
expect(
findMobileDiffReviewInitialIndex(queue, {
filePath: 'old.ts',
area: 'branch'
})
).toBe(0)
).toBe(1)
})
it('falls back to the first file when the target is missing', () => {
@@ -192,11 +192,18 @@ describe('mobile diff review queue', () => {
reviewState
})
expect(filterMobileDiffReviewQueue(queue, 'unreviewed').map((item) => item.filePath)).toEqual([
'a.ts',
'b.ts'
])
expect(filterMobileDiffReviewQueue(queue, 'notes').map((item) => item.filePath)).toEqual([
const reviewedItem: MobileDiffReviewQueueItem = {
...queue[0],
key: createMobileDiffReviewFileKey('unstaged', 'unstaged', 'c.ts'),
filePath: 'c.ts',
isReviewed: true
}
const filterQueue = [...queue, reviewedItem]
expect(
filterMobileDiffReviewQueue(filterQueue, 'unreviewed').map((item) => item.filePath)
).toEqual(['a.ts', 'b.ts'])
expect(filterMobileDiffReviewQueue(filterQueue, 'notes').map((item) => item.filePath)).toEqual([
'b.ts'
])
})
@@ -101,5 +101,6 @@ describe('mobile diff review state', () => {
it('builds stable content identities from ordered parts', () => {
expect(buildMobileDiffIdentity(['a', 'b'])).toBe(buildMobileDiffIdentity(['a', 'b']))
expect(buildMobileDiffIdentity(['a', 'b'])).not.toBe(buildMobileDiffIdentity(['ab']))
expect(buildMobileDiffIdentity(['a', 'b'])).not.toBe(buildMobileDiffIdentity(['b', 'a']))
})
})
@@ -46,12 +46,32 @@ import { useWorktreeAwarenessEnvironment } from './index-test-harness'
const STRUCTURED_HANDLE = 'structworker_a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d'
// Cover distinct handler shapes that share sender resolution and liveness checks.
const SENDER_VERBS: { argv: string[]; method: string }[] = [
{ argv: ['orchestration', 'run-current'], method: 'orchestration.runCurrent' },
{ argv: ['orchestration', 'run-create', '--objective', 'x'], method: 'orchestration.runCreate' },
{ argv: ['orchestration', 'task-list'], method: 'orchestration.taskList' },
{ argv: ['orchestration', 'gate-list'], method: 'orchestration.gateList' },
{ argv: ['orchestration', 'dispatch-show', '--task', 't1'], method: 'orchestration.dispatchShow' }
const SENDER_VERBS: {
argv: string[]
method: string
senderField: 'from' | 'callerTerminalHandle'
}[] = [
{
argv: ['orchestration', 'run-current'],
method: 'orchestration.runCurrent',
senderField: 'from'
},
{
argv: ['orchestration', 'run-create', '--objective', 'x'],
method: 'orchestration.runCreate',
senderField: 'from'
},
{
argv: ['orchestration', 'task-list'],
method: 'orchestration.taskList',
senderField: 'callerTerminalHandle'
},
{ argv: ['orchestration', 'gate-list'], method: 'orchestration.gateList', senderField: 'from' },
{
argv: ['orchestration', 'dispatch-show', '--task', 't1', '--preamble'],
method: 'orchestration.dispatchShow',
senderField: 'from'
}
]
describe('a structured worker running orchestration commands as itself', () => {
@@ -74,33 +94,42 @@ describe('a structured worker running orchestration commands as itself', () => {
_meta: { runtimeId: 'runtime-1' }
}
}
return { id: 'req', ok: true, result: {}, _meta: { runtimeId: 'runtime-1' } }
const result =
method === 'orchestration.runCreate'
? { run: { id: 'run-1', objective: 'x' } }
: method === 'orchestration.runCurrent'
? { run: null }
: method === 'orchestration.taskList'
? { tasks: [], count: 0 }
: method === 'orchestration.gateList'
? { gates: [], count: 0 }
: { dispatch: null, preamble: 'preview' }
return { id: 'req', ok: true, result, _meta: { runtimeId: 'runtime-1' } }
})
}
it.each(SENDER_VERBS)(
'resolves its own identity for $method with no --from',
async ({ argv, method }) => {
async ({ argv, method, senderField }) => {
process.env.ORCA_TERMINAL_HANDLE = STRUCTURED_HANDLE
answerCalls()
vi.spyOn(console, 'log').mockImplementation(() => {})
const priorExitCode = process.exitCode
await expect(main(argv)).resolves.not.toThrow()
expect(process.exitCode).toBe(priorExitCode)
const called = callMock.mock.calls.map((call) => call[0] as string)
expect(called).toContain(method)
expect(callMock).toHaveBeenCalledWith('terminal.resolveIdentity', {
terminal: STRUCTURED_HANDLE
})
expect(callMock).toHaveBeenCalledWith(
method,
expect.objectContaining({ [senderField]: STRUCTURED_HANDLE })
)
// Structured workers lack writable PTYs; terminal.show must not validate them.
expect(called).not.toContain('terminal.show')
}
)
it('sends the structured handle as the sender, not a guessed sibling', async () => {
process.env.ORCA_TERMINAL_HANDLE = STRUCTURED_HANDLE
answerCalls()
vi.spyOn(console, 'log').mockImplementation(() => {})
await main(['orchestration', 'run-create', '--objective', 'x'])
const create = callMock.mock.calls.find((call) => call[0] === 'orchestration.runCreate')
expect((create?.[1] as { from?: string } | undefined)?.from).toBe(STRUCTURED_HANDLE)
})
it('still refuses a handle the runtime reports dead, with no pane key to remint from', async () => {
process.env.ORCA_TERMINAL_HANDLE = 'term_stale'
callMock.mockImplementation(async (method: string) => {
@@ -81,5 +81,9 @@ describe('a structured chat session with no orchestration identity', () => {
callMock.mockResolvedValue({ result: { messages: [], count: 0 } })
await invoke('orchestration check')
expect(getTerminalHandleMock).toHaveBeenCalled()
expect(callMock).toHaveBeenCalledWith(
'orchestration.check',
expect.objectContaining({ terminal: 'term_sibling' })
)
})
})
@@ -239,6 +239,7 @@ describe('OSC 7501 status beside hooks', () => {
programStatus({ state: 'done', agentType: 'pi' })
vi.advanceTimersByTime(1_000)
programStatus({ state: 'working', agentType: 'pi' })
expect(paneRow()?.state).toBe('waiting')
vi.advanceTimersByTime(HOOK_SILENCE_BEFORE_PROGRAM_STATUS_FALLBACK_MS)
expect(paneRow()?.state).toBe('working')
})
@@ -61,6 +61,7 @@ describe('programStatusHookYieldEndsAt', () => {
const block = report({ state: 'waiting', agentType: 'antigravity' })
expect(programStatusHookYieldEndsAt(hook, block)).toBe(Infinity)
expect(programStatusHookYieldEndsAt(hook, block, NOW - 1)).toBe(Infinity)
expect(programStatusHookYieldEndsAt(hook, block, NOW)).toBe(Infinity)
expect(programStatusHookYieldEndsAt(hook, block, NOW + 1)).toBeUndefined()
for (const state of ['working', 'blocked'] as const) {
expect(programStatusHookYieldEndsAt(hook, report({ state, agentType: 'antigravity' }))).toBe(
@@ -74,6 +75,7 @@ describe('programStatusHookYieldEndsAt', () => {
const hook = row({ state, agentType: 'pi' })
const working = report({ state: 'working', agentType: 'pi' })
expect(programStatusHookYieldEndsAt(hook, working, NOW - 1)).toBe(Infinity)
expect(programStatusHookYieldEndsAt(hook, working, NOW)).toBe(Infinity)
expect(programStatusHookYieldEndsAt(hook, working, NOW + 1)).toBe(NOW + SILENCE)
expect(programStatusHookYieldEndsAt(hook, working)).toBe(NOW + SILENCE)
expect(programStatusHookYieldEndsAt(hook, report({ state: 'done', agentType: 'pi' }))).toBe(
@@ -7,10 +7,10 @@ import {
} from './filesystem-watcher-event-batch'
describe('queueWatcherEvents', () => {
function events(count: number): WatcherEvent[] {
function events(count: number, start = 0): WatcherEvent[] {
return Array.from({ length: count }, (_, index): WatcherEvent => ({
type: 'update',
path: `/repo/file-${index}.ts`
path: `/repo/file-${start + index}.ts`
}))
}
@@ -21,6 +21,14 @@ describe('queueWatcherEvents', () => {
expect(batch.overflowed).toBe(false)
expect(batch.events.map((event) => event.path)).toEqual(['/repo/file-0.ts', '/repo/file-1.ts'])
const retained = [...batch.events]
const remaining = events(MAX_BATCHED_WATCHER_EVENTS - retained.length, retained.length)
queueWatcherEvents(batch, remaining)
expect(batch.overflowed).toBe(false)
expect(batch.events).toEqual([...retained, ...remaining])
expect(batch.events).toHaveLength(MAX_BATCHED_WATCHER_EVENTS)
})
it('marks overflow without retaining oversized event lists', () => {
@@ -78,12 +78,18 @@ describe('watcher event queue flush', () => {
it('settles all flush callers when closed while delivery is blocked', async () => {
const blocked = Promise.withResolvers<void>()
const queue = createWatcherProcessEventDeliveryQueue({}, () => blocked.promise, vi.fn())
const deliver = vi.fn(() => blocked.promise)
const queue = createWatcherProcessEventDeliveryQueue({}, deliver, vi.fn())
queue.enqueue([{ type: 'update', path: '/repo/file' }])
await vi.waitFor(() => expect(deliver).toHaveBeenCalledTimes(1))
const first = queue.flush()
const second = queue.flush()
expect(second).toBe(first)
const settled = vi.fn()
void first.then(settled)
queue.close()
await Promise.resolve()
expect(settled).toHaveBeenCalledTimes(1)
await expect(first).resolves.toBeUndefined()
await expect(queue.flush()).resolves.toBeUndefined()
blocked.resolve()
@@ -65,6 +65,7 @@ describe('createFileWatchEventBatcher', () => {
vi.advanceTimersByTime(10)
}
expect(emit.mock.calls.length).toBeGreaterThanOrEqual(1_000 / WATCH_BATCH_INTERVAL_MS)
expect(emit.mock.calls.length).toBeLessThanOrEqual(1 + 1_000 / WATCH_BATCH_INTERVAL_MS)
} finally {
vi.useRealTimers()
}
@@ -68,8 +68,16 @@ describe('files.watch batch cadence negotiation', () => {
it('treats an unknown cadence from a newer client as legacy instead of rejecting', async () => {
vi.useFakeTimers()
try {
const { replies } = await startWatch({ worktree: 'id:wt-1', batchCadence: 'future' })
const { replies, emitChange } = await startWatch({
worktree: 'id:wt-1',
batchCadence: 'future'
})
expect(replies[1]?.result?.type).toBe('ready')
emitChange([{ kind: 'update', absolutePath: '/repo/a.ts' }])
await vi.advanceTimersByTimeAsync(149)
expect(changedCount(replies)).toBe(0)
await vi.advanceTimersByTimeAsync(1)
expect(changedCount(replies)).toBe(1)
} finally {
vi.useRealTimers()
}
@@ -69,7 +69,9 @@ describe('markdown document templates', () => {
const nonBreakingSpace = String.fromCharCode(160)
const fileName = ` launch___plan\t${nonBreakingSpace}${' pasted '.repeat(300)}.md`
expect(getMarkdownTemplateTitleForFileName(fileName)).toContain('Launch plan pasted pasted')
expect(getMarkdownTemplateTitleForFileName(fileName)).toBe(
`Launch plan ${'pasted '.repeat(299)}pasted`
)
expect(
replace.mock.calls.filter(
([pattern]) => pattern instanceof RegExp && pattern.source === '\\s+'
@@ -34,6 +34,7 @@ describe('pr-comment-action-state', () => {
expect(getPRCommentGroupActionState(groups[0]!)).toBe('open')
expect(getPRCommentGroupActionState(groups[1]!)).toBe('resolved')
expect(getPRCommentGroupActionState(groups[2]!)).toBe('conversation')
expect(groups.map(isPRCommentGroupQueueableForAI)).toEqual([true, false, true])
})
it('partitions groups for triage sections', () => {