test: consolidate refusal cases and repair boundary coverage (#33098)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
OrcaWin
2026-10-24 01:52:04 -07:00
committed by GitHub
co-authored by OrcaWin
parent b33ad1bb2c
commit 2a20d2de94
14 changed files with 173 additions and 32 deletions
@@ -97,6 +97,8 @@ describe('trim pipeline', () => {
const image = solidSquareWithInset(100, 60)
const cropped = cropImage(image, findOpaqueBounds(image))
expect(cropped.width).toBe(60)
expect(cropped.height).toBe(60)
expect(cropped.data).toEqual(solidSquareWithInset(60, 60).data)
const squared = squareWithMargin(cropped, 0.04)
// Glyph (60) plus ~4% margin per side keeps it near-full-bleed.
expect(glyphFillFraction(squared)).toBeGreaterThanOrEqual(0.9)
@@ -108,6 +110,12 @@ describe('trim pipeline', () => {
const filled = squareWithMargin(cropImage(image, findOpaqueBounds(image)))
const small = resizeImage(filled, 32, 32)
expect(small.width).toBe(32)
const edge = {
width: 2,
height: 1,
data: Buffer.from([200, 100, 50, 255, 0, 0, 0, 0])
}
expect(resizeImage(edge, 1, 1).data).toEqual(Buffer.from([200, 100, 50, 128]))
expect(glyphFillFraction(small)).toBeGreaterThanOrEqual(0.9)
})
})
+14 -2
View File
@@ -9,15 +9,23 @@ import {
} from 'node:fs'
import { tmpdir } from 'node:os'
import path from 'node:path'
import { describe, expect, it } from 'vitest'
import { afterEach, describe, expect, it } from 'vitest'
import { verifyPackageCliBin } from './verify-cli-bin.mjs'
const roots = []
afterEach(() => {
for (const root of roots.splice(0)) {
rmSync(root, { recursive: true, force: true })
}
})
/** Builds a temporary Orca-style project fixture with a compiled CLI entrypoint. */
function makeProjectWithCli(
content,
{ mode = 0o755, rootPackageType, writeOutPackageJson = true } = {}
) {
const projectDir = mkdtempSync(path.join(tmpdir(), 'orca-cli-bin-'))
roots.push(projectDir)
const cliPath = path.join(projectDir, 'out', 'cli', 'index.js')
const outPackageJsonPath = path.join(projectDir, 'out', 'package.json')
mkdirSync(path.dirname(cliPath), { recursive: true })
@@ -39,12 +47,16 @@ function makeProjectWithCli(
describe('verifyPackageCliBin', () => {
it('accepts a non-empty Node entrypoint and can run help through Node', () => {
const { projectDir, cliPath } = makeProjectWithCli(
'#!/usr/bin/env node\nif (process.argv.includes("--help")) process.exit(0)\n'
'#!/usr/bin/env node\nrequire("node:fs").writeFileSync("help-receipt.json", JSON.stringify({ args: process.argv.slice(2), cwd: process.cwd() }))\nif (!process.argv.includes("--help")) process.exit(9)\n'
)
expect(verifyPackageCliBin({ projectDir, runHelp: true })).toMatchObject({
binPath: cliPath
})
expect(JSON.parse(readFileSync(path.join(projectDir, 'help-receipt.json'), 'utf8'))).toEqual({
args: ['--help'],
cwd: projectDir
})
})
it('rejects an empty package bin target', () => {
@@ -60,6 +60,10 @@ describe.skipIf(process.platform === 'win32')('static ELF and remote musl payloa
it.each([
['missing program headers', 'Dynamic Section:\n'],
[
'version references without a dynamic segment',
`${STATIC_HEADERS}Version References:\n required from libc.so.6:\n 0x0 0x00 02 GLIBC_2.17\n`
],
['dynamic segment', `${STATIC_HEADERS} DYNAMIC off 0x0000000000001000\n`],
['interpreter segment', `${STATIC_HEADERS} INTERP off 0x0000000000001000\n`],
['dependency without a dynamic segment', `${STATIC_HEADERS} NEEDED libc.so.6\n`]
@@ -126,6 +126,51 @@ describe.skipIf(process.platform === 'win32')('terminal host round trip', () =>
}
}
it('accepts a valid peer round trip and cleans up after observing the boot request', async () => {
const messagesPath = join(root, 'messages.jsonl')
const entry = fakeDaemon(`(socket) => {
let buffer = ''
socket.on('data', (chunk) => {
buffer += chunk
let newline
while ((newline = buffer.indexOf('\\n')) !== -1) {
const message = JSON.parse(buffer.slice(0, newline))
buffer = buffer.slice(newline + 1)
fs.appendFileSync(${JSON.stringify(messagesPath)}, JSON.stringify(message) + '\\n')
if (message.type === 'hello') {
if (message.role === 'stream') globalThis.stream = socket
socket.write(JSON.stringify({ ok: true }) + '\\n')
} else if (message.type === 'createOrAttach') {
globalThis.stream.write(JSON.stringify({ payload: { data: 'OK 42' } }) + '\\n')
}
}
})
}`)
const result = await roundTrip(entry, 1_500)
expect(result.error).toBe(null)
expect(result.daemonAlive).toBe(false)
expect(result.scratchDirs).toEqual([])
const messages = readFileSync(messagesPath, 'utf8').trim().split('\n').map(JSON.parse)
expect(messages.slice(0, 2).map(({ type, role, token }) => ({ type, role, token }))).toEqual([
{ type: 'hello', role: 'control', token: 'tok' },
{ type: 'hello', role: 'stream', token: 'tok' }
])
expect(messages[0].clientId).toBe(messages[1].clientId)
expect(messages[0].clientId).toMatch(/^[0-9a-f-]{36}$/)
expect(messages).toHaveLength(3)
expect(messages[2]).toMatchObject({
id: 'boot-1',
type: 'createOrAttach',
payload: {
sessionId: 'terminal-host-boot',
cols: 80,
rows: 24,
command: 'echo "OK $((6*7))" && exit'
}
})
expect(messages[2].payload.cwd.startsWith(join(root, 'oth-'))).toBe(true)
})
it('rejects by the deadline and cleans up when the daemon never answers the hello', async () => {
const result = await roundTrip(fakeDaemon('() => {}'), 1_500)
expect(result.error?.message).toMatch(/timed out waiting for the control hello reply/)
@@ -21,7 +21,7 @@ describe('scheduleMobileClaudeAnswer', () => {
it('writes each question body then its Enter, paced per step, one Enter per line', () => {
const events: string[] = []
const timers = scheduleMobileClaudeAnswer(
['', 'b', 'c'], // blank middle answer must still get its own body + Enter
['', 'b', 'c'], // A blank answer still gets its own body + Enter.
(line) => events.push(`body:${line}`),
() => events.push('enter')
)
@@ -29,7 +29,9 @@ describe('scheduleMobileClaudeAnswer', () => {
vi.advanceTimersByTime(0)
expect(events).toEqual(['body:'])
vi.advanceTimersByTime(MOBILE_NATIVE_CHAT_SUBMIT_DELAY_MS)
vi.advanceTimersByTime(MOBILE_NATIVE_CHAT_SUBMIT_DELAY_MS - 1)
expect(events).toEqual(['body:'])
vi.advanceTimersByTime(1)
expect(events).toEqual(['body:', 'enter'])
vi.advanceTimersByTime(MOBILE_NATIVE_CHAT_ADVANCE_BUFFER_MS)
expect(events).toEqual(['body:', 'enter', 'body:b'])
@@ -42,13 +42,21 @@ describe('isNoiseMessage', () => {
expect(isNoiseMessage(msg('user', '<bash-brothers> is my band'))).toBe(false)
})
it('keeps assistant and tool turns', () => {
it('keeps assistant, tool, and ordinary system turns', () => {
expect(isNoiseMessage(msg('assistant', '<system-reminder> in prose'))).toBe(false)
expect(isNoiseMessage(msg('tool', '<system-reminder> in prose'))).toBe(false)
expect(isNoiseMessage(msg('system', 'Conversation interrupted'))).toBe(false)
})
it('keeps a user turn that carries tool results', () => {
expect(isNoiseMessage(msg('user', '', [{ type: 'tool-result', output: 'ok' }]))).toBe(false)
it('keeps tool-bearing user turns even when their text looks like harness noise', () => {
for (const block of [
{ type: 'tool-result', output: 'ok' },
{ type: 'tool-call', name: 'Bash', input: { command: 'ls' } }
] satisfies NativeChatMessage['blocks']) {
expect(
isNoiseMessage(msg('user', '', [{ type: 'text', text: '<task-notification>done' }, block]))
).toBe(false)
}
})
it('stripNoiseMessages removes only the noise', () => {
@@ -34,6 +34,14 @@ describe('mobile complete-pair stream windows', () => {
})
expect(result).toEqual({ kind: 'messages', messages: [...base, row('latest')] })
expect(merger.indexById.get('opencode:oldest:reasoning')).toBe(0)
const updated = { ...row('latest'), blocks: [{ type: 'text' as const, text: 'updated' }] }
applyMobileNativeChatStreamFrame({
merger,
frame: { type: 'appended', messages: [updated] },
limit: 40,
replaceSnapshot: false
})
expect(merger.list).toEqual([...base, updated])
}
)
@@ -47,7 +47,7 @@ describe('appendMobileNativeChatPending ordinals for repeated sends', () => {
const MULTILINE = 'first line of the prompt\nsecond line of the prompt'
it('gives a repeated multi-line send the next ordinal', () => {
const baseline = [userTurn('m1', 'unrelated')]
const baseline = [userTurn('m1', MULTILINE)]
const first = appendMobileNativeChatPending(
{},
KEY,
@@ -63,7 +63,8 @@ describe('appendMobileNativeChatPending ordinals for repeated sends', () => {
MULTILINE
)
expect(both[KEY]?.map((item) => item.expectedOccurrence)).toEqual([1, 2])
expect(sendOrigin(MULTILINE, baseline).baselineOccurrences).toBe(1)
expect(both[KEY]?.map((item) => item.expectedOccurrence)).toEqual([2, 3])
})
it('retires only the first echo when the first of two identical rows lands', () => {
@@ -26,6 +26,14 @@ describe('agent sleep confirmation', () => {
confirmAgentHibernationCandidates(first.confirmationState, [firstCandidate]).candidates
).toEqual([firstCandidate])
const absent = confirmAgentHibernationCandidates(first.confirmationState, [])
expect(absent.confirmationState).toEqual({})
const reappeared = confirmAgentHibernationCandidates(absent.confirmationState, [firstCandidate])
expect(reappeared.candidates).toEqual([])
expect(
confirmAgentHibernationCandidates(reappeared.confirmationState, [firstCandidate]).candidates
).toEqual([firstCandidate])
const changed = candidate({ signature: 'changed-signature' })
expect(
confirmAgentHibernationCandidates(first.confirmationState, [changed]).candidates
@@ -77,6 +77,9 @@ describe('hibernation PTY binding age', () => {
it('expires an unseen binding once it is older than the idle window', () => {
observe('pty-1', 1_000)
recordHibernationBoundaryResolved(PANE, 1_000)
observe(null, 1_000 + IDLE_MS)
expect(getHibernationPtyBindingFirstSeenAtByPaneKey()[PANE]).toBe(1_000)
expect(getHibernationBoundaryResolvedAtByPaneKey()[PANE]).toBe(1_000)
observe(null, 1_000 + IDLE_MS + 1)
expect(getHibernationPtyBindingFirstSeenAtByPaneKey()[PANE]).toBeUndefined()
expect(getHibernationBoundaryResolvedAtByPaneKey()[PANE]).toBeUndefined()
@@ -1,7 +1,6 @@
// @vitest-environment happy-dom
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import {
resetAgentHibernationCoordinatorForTests,
startAgentHibernationCoordinator,
stopAgentHibernationCoordinator
} from './agent-hibernation-coordinator'
@@ -17,21 +16,50 @@ describe('agent hibernation coordinator visibility wiring', () => {
setVisibility('visible')
resetStaleDocumentVisibilityForTesting()
})
afterEach(() => {
resetAgentHibernationCoordinatorForTests()
afterEach(async () => {
const { resetAgentHibernationCoordinatorFixture } =
await import('./agent-hibernation-coordinator-test-fixture')
resetAgentHibernationCoordinatorFixture()
resetStaleDocumentVisibilityForTesting()
setVisibility('visible')
vi.unstubAllGlobals()
vi.restoreAllMocks()
})
it('subscribes to the becoming-visible pass on start and unsubscribes on stop', () => {
const add = vi.spyOn(document, 'addEventListener')
const remove = vi.spyOn(document, 'removeEventListener')
it('subscribes to the becoming-visible pass on start and unsubscribes on stop', async () => {
// Keep happy-dom's event target when the state fixture stubs window.
const browserWindow = window
const { installEligibleState, NOW, LEAF } =
await import('./agent-hibernation-coordinator-test-fixture')
vi.stubGlobal('window', browserWindow)
vi.useFakeTimers()
const shutdown = installEligibleState(vi.fn().mockResolvedValue(undefined))
startAgentHibernationCoordinator({ intervalMs: 60_000, now: () => 0 })
expect(add.mock.calls.some(([type]) => type === 'visibilitychange')).toBe(true)
startAgentHibernationCoordinator({ intervalMs: 1_000, now: () => NOW })
await vi.advanceTimersByTimeAsync(1_000)
expect(shutdown).not.toHaveBeenCalled()
setVisibility('hidden')
await vi.advanceTimersByTimeAsync(3_000)
expect(shutdown).not.toHaveBeenCalled()
setVisibility('visible')
await vi.advanceTimersByTimeAsync(0)
expect(shutdown).toHaveBeenCalledExactlyOnceWith('wt-bg', {
paneKey: `tab-1:${LEAF}`,
tabId: 'tab-1',
leafId: LEAF,
ptyId: 'pty-1'
})
shutdown.mockClear()
stopAgentHibernationCoordinator()
expect(remove.mock.calls.some(([type]) => type === 'visibilitychange')).toBe(true)
setVisibility('hidden')
setVisibility('visible')
await vi.advanceTimersByTimeAsync(0)
setVisibility('hidden')
setVisibility('visible')
await vi.advanceTimersByTimeAsync(3_000)
expect(shutdown).not.toHaveBeenCalled()
})
})
@@ -147,8 +147,9 @@ describe('completed context clear projections', () => {
it('includes new sends but excludes older unknown sends even at the current fence', () => {
const currentSend = { ...oldSend, clientMessageId: 'new-send', acceptedSequence: 6 }
const boundarySend = { ...oldSend, clientMessageId: 'boundary-send', acceptedSequence: 5 }
const rows = [user, clear, row(7, { kind: 'turn', turnId: 'new-turn', state: 'running' })]
expect(agentSessionCurrentContextRows(rows, [oldSend, currentSend])).toEqual({
expect(agentSessionCurrentContextRows(rows, [oldSend, boundarySend, currentSend])).toEqual({
items: [rows[2]],
submissions: [currentSend]
})
@@ -1,5 +1,9 @@
import { describe, expect, it } from 'vitest'
import { MAX_CONTEXT_CATEGORIES, MAX_CONTEXT_MODEL_ID_CHARS } from './agent-session-context-usage'
import {
MAX_CONTEXT_CATEGORIES,
MAX_CONTEXT_CATEGORY_NAME_CHARS,
MAX_CONTEXT_MODEL_ID_CHARS
} from './agent-session-context-usage'
import {
AgentSessionContextUsageSchema,
isAdmissibleAgentSessionContextUsage
@@ -32,8 +36,18 @@ describe('context usage admission', () => {
capturedAt: 1
}
},
{ used: report, future: { retained: true } }
])('accepts canonical facts and leaves additive fields untouched (%j)', (value) => {
{ used: report, future: { retained: true } },
{
used: {
...report,
model: 'x'.repeat(MAX_CONTEXT_MODEL_ID_CHARS),
categories: Array.from({ length: MAX_CONTEXT_CATEGORIES }, () => ({
name: 'x'.repeat(MAX_CONTEXT_CATEGORY_NAME_CHARS),
tokens: 0
}))
}
}
])('accepts canonical facts and leaves inputs untouched (%j)', (value) => {
const original = structuredClone(value)
expect(isAdmissibleAgentSessionContextUsage(value)).toBe(true)
expect(AgentSessionContextUsageSchema.safeParse(value).success).toBe(true)
@@ -51,6 +65,12 @@ describe('context usage admission', () => {
{
used: { ...report, categories: Array(MAX_CONTEXT_CATEGORIES + 1).fill(report.categories[0]) }
},
{
used: {
...report,
categories: [{ name: 'x'.repeat(MAX_CONTEXT_CATEGORY_NAME_CHARS + 1), tokens: 0 }]
}
},
{ used: { ...report, categories: [{ name: 'messages', tokens: null }] } }
])('rejects malformed facts and bounds just like parsing (%j)', (value) => {
expect(isAdmissibleAgentSessionContextUsage(value)).toBe(false)
@@ -9,16 +9,6 @@ describe('definitive agent-session create refusals', () => {
expect(isDefinitiveAgentSessionCreateRefusal('agent_session_ownership_unknown')).toBe(false)
})
it('leaves transport failures, timeouts and a missing code unknown', () => {
expect(isDefinitiveAgentSessionCreateRefusal('runtime_error')).toBe(false)
expect(isDefinitiveAgentSessionCreateRefusal('remote_runtime_unavailable')).toBe(false)
expect(isDefinitiveAgentSessionCreateRefusal('timeout')).toBe(false)
expect(isDefinitiveAgentSessionCreateRefusal('runtime_timeout')).toBe(false)
expect(isDefinitiveAgentSessionCreateRefusal(undefined)).toBe(false)
expect(isDefinitiveAgentSessionCreateRefusal(null)).toBe(false)
expect(isDefinitiveAgentSessionCreateRefusal('')).toBe(false)
})
it('counts a method an old host never registered as definitive', () => {
expect(isDefinitiveAgentSessionCreateRefusal('method_not_found')).toBe(true)
})
@@ -41,6 +31,9 @@ describe('definitive agent-session create refusals', () => {
// Pins the RPC half (round-2 S5): transport and client-minted codes never allow a fallback.
it.each([
'runtime_error',
'timeout',
'',
'runtime_unavailable',
'remote_runtime_unavailable',
'runtime_timeout',