test: remove redundant cases and strengthen state-transition assertions (#33309)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
OrcaWin
2026-10-24 17:05:58 -07:00
committed by GitHub
co-authored by OrcaWin
parent 44f97fa958
commit ca3b0fdb02
18 changed files with 41 additions and 128 deletions
@@ -38,10 +38,8 @@ describe('mobile terminal records', () => {
})
try {
for (let comparison = 0; comparison < 1_000; comparison += 1) {
expect(mobileTerminalThemesEqual(darkTheme, equivalentTheme)).toBe(true)
expect(mobileTerminalThemesEqual(darkTheme, lightTheme)).toBe(false)
}
expect(mobileTerminalThemesEqual(darkTheme, equivalentTheme)).toBe(true)
expect(mobileTerminalThemesEqual(darkTheme, lightTheme)).toBe(false)
} finally {
stringify.mockRestore()
}
@@ -166,10 +166,6 @@ describe('getMobileSessionTabTitle', () => {
)
})
it('keeps generic status titles unstripped when no agent identity is known', () => {
expect(getMobileSessionTabTitle(terminalTab('✳ investigating'))).toBe('✳ investigating')
})
it('preserves browser title fallbacks after moving the helper out of the route', () => {
const blankBrowserTab: Extract<MobileSessionTab, { type: 'browser' }> = {
type: 'browser',
@@ -67,20 +67,6 @@ describe('resolveTerminalViewportResubscribe', () => {
}
})
it('keeps holding on absent dims across repeated frames without spending budget', () => {
for (let frame = 0; frame < 50; frame += 1) {
expect(
resolveTerminalViewportResubscribe({
hostCols: null,
hostRows: null,
viewportMeasured: true,
viewport: PHONE,
attempts: 0
}).kind
).toBe('hold')
}
})
it('converges when host dims match the measured viewport', () => {
expect(
resolveTerminalViewportResubscribe({
@@ -307,7 +293,10 @@ describe('runTerminalViewportFitPass', () => {
}
}
const settle = () => new Promise((resolve) => setTimeout(resolve, 0))
const settle = async () => {
await Promise.resolve()
await Promise.resolve()
}
it('holds without any teardown when host dims are absent (STA-3337 regression)', async () => {
const h = makeHarness({ viewportMeasured: true, viewport: PHONE })
+8 -7
View File
@@ -31,25 +31,26 @@ function makeEngine(mutations: Partial<PrActionMutations>) {
describe('PrActionsEngine — scoped busy clear (overlapping actions)', () => {
it('a late-resolving action does not clear a newer action busy state', async () => {
const slow = deferred<GitHubPrMutationOutcome>()
const newer = deferred<GitHubPrMutationOutcome>()
const engine = makeEngine({
// merge resolves slowly; state resolves immediately.
mergePR: () => slow.promise,
updatePRState: async () => ({ ok: true })
updatePRState: () => newer.promise
})
// Start merge (sets busy = merge) but don't let it resolve yet.
const mergePromise = engine.merge()
expect(engine.isBusy({ kind: 'merge' })).toBe(true)
// While merge is in-flight, run state to completion (sets then clears busy=state).
await engine.updateState('closed')
// State began after merge, so it overwrote busy to 'state', then cleared its own.
expect(engine.isBusy({ kind: 'state' })).toBe(false)
const statePromise = engine.updateState('closed')
expect(engine.isBusy({ kind: 'state' })).toBe(true)
// Now let the slow merge finish. Its finally must NOT clear a busy it no longer owns.
slow.resolve({ ok: true })
await mergePromise
// busy stays null (state already cleared); the key point is merge didn't clobber.
expect(engine.isBusy({ kind: 'state' })).toBe(true)
newer.resolve({ ok: true })
await statePromise
expect(engine.busy).toBeNull()
})
@@ -116,6 +116,8 @@ describe('isMutablePRConversationComment', () => {
it('requires a positive integer id', () => {
expect(isMutablePRConversationComment(comment({ id: 0 }))).toBe(false)
expect(isMutablePRConversationComment(comment({ id: -1 }))).toBe(false)
expect(isMutablePRConversationComment(comment({ id: 1.5 }))).toBe(false)
expect(isMutablePRConversationComment(comment({ id: Number.MAX_SAFE_INTEGER + 1 }))).toBe(false)
})
})
@@ -104,7 +104,7 @@ describe('shouldShowSessionHeaderChecksAction', () => {
shouldShowSessionHeaderChecksAction({
isFolderWorkspaceRoute: false,
repoContextLoaded: false,
hostedChecksSupported: false
hostedChecksSupported: true
})
).toBe(false)
})
+2 -2
View File
@@ -64,9 +64,9 @@ describe('resolveTabStripScrollOffset', () => {
tabWidth: 128,
viewportWidth: 0,
contentWidth: 0,
currentOffset: 0
currentOffset: 150
})
).toBe(0)
).toBe(150)
})
})
@@ -2,11 +2,7 @@ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync
import { tmpdir } from 'node:os'
import { dirname, join } from 'node:path'
import { afterEach, describe, expect, it, vi } from 'vitest'
import {
isProfileStateSqliteAvailable,
openProfileStateDatabase,
profileStateDatabaseFile
} from './profile-state-database'
import { openProfileStateDatabase, profileStateDatabaseFile } from './profile-state-database'
import {
createProfileStateStore as createProfileStateStoreImpl,
type ProfileStateStoreFactoryOptions
@@ -138,18 +134,6 @@ describe('profile state Store authority factory', () => {
expect(() => initial.value.takeParsedState?.()).toThrow('already been consumed')
})
it('uses a capability probe that remains false on a Node 18-style host', () => {
const original = process.getBuiltinModule
vi.spyOn(process, 'getBuiltinModule').mockImplementation((id) => {
if (id === 'node:sqlite') {
return undefined
}
return original(id)
})
expect(isProfileStateSqliteAvailable()).toBe(false)
})
it('imports legacy state by default and preserves its original bytes', () => {
const options = createOptions()
const source = JSON.stringify({ settings: { theme: 'dark' }, unknownDomain: { keep: true } })
@@ -195,21 +179,6 @@ describe('profile state Store authority factory', () => {
}
)
it('migrates JSON and constructs a SQLite Store', () => {
const options = createOptions()
const source = JSON.stringify({ settings: { theme: 'dark' }, unknownDomain: { keep: true } })
writeFileSync(options.dataFile, source)
const result = createProfileStateStore({ ...options })
expect(result.backend).toBe('sqlite')
expect(result.classification).toBe('json-only')
expect(result.migrated).toBe(true)
expect(result.store.getSettings().theme).toBe('dark')
expect(existsSync(options.databaseFile)).toBe(true)
expect(readFileSync(options.dataFile, 'utf8')).toBe(source)
})
it('reuses the candidate authority after the legacy export is removed', () => {
const options = createOptions()
writeFileSync(options.dataFile, JSON.stringify({ settings: { theme: 'dark' } }))
@@ -224,28 +193,6 @@ describe('profile state Store authority factory', () => {
expect(result.store.getSettings().theme).toBe('dark')
})
it('fails closed instead of falling back to a stale JSON mirror when SQLite is missing', () => {
const options = createOptions()
writeFileSync(options.dataFile, JSON.stringify({ settings: { theme: 'dark' } }))
const migrated = createProfileStateStore({ ...options })
const exportPath = profileStateJsonExportPath(options.dataFile, 1)
expect(existsSync(exportPath)).toBe(true)
migrated.store.freezeWrites()
rmSync(options.databaseFile)
expect(() => createProfileStateStore({ ...options })).toThrow(ProfileStateRecoveryRequiredError)
})
it('does not let candidate mode re-import JSON after SQLite was established', () => {
const options = createOptions()
writeFileSync(options.dataFile, JSON.stringify({ settings: { theme: 'dark' } }))
const migrated = createProfileStateStore({ ...options })
migrated.store.freezeWrites()
rmSync(options.databaseFile)
expect(() => createProfileStateStore({ ...options })).toThrow(ProfileStateRecoveryRequiredError)
})
it('reopens JSON after an explicit rollback removes the SQLite export marker', () => {
const options = createOptions()
writeFileSync(options.dataFile, JSON.stringify({ settings: { theme: 'dark' } }))
@@ -107,19 +107,6 @@ it('keeps an unacknowledged close pending, then holds abort until the terminated
expect(vi.getTimerCount()).toBe(0)
})
it('completes a clean close only after the acknowledged worker exits', async () => {
const { client, worker, onFailure } = await createClient()
let settled = false
const closing = client.close().then(() => (settled = true))
await waitForPoll()
expect(settled).toBe(false)
worker.emit('exit', 0)
await closing
expect(worker.terminate).not.toHaveBeenCalled()
expect(onFailure).not.toHaveBeenCalled()
expect(vi.getTimerCount()).toBe(0)
})
it('joins an aborted writer without reporting a close request that was never sent', async () => {
const { client, worker } = await createClient()
const aborting = client.abort()
@@ -88,28 +88,6 @@ describe('writer protocol refuses uncertain acknowledgements', () => {
})
})
it('keeps an unanswered request pending past the slow warning without faulting', async () => {
const notify = vi.fn()
const client = clientFor('', undefined, notify)
await client.ready
let settled = false
const write = client
.writeSerializedDomains([{ domain: 'settings', payload: '{}' }])
.finally(() => (settled = true))
await new Promise((resolve) => setTimeout(resolve, 200))
expect(settled).toBe(false)
expect(notify).not.toHaveBeenCalled()
expect(() => client.assertWritable()).toThrow(
expect.objectContaining({ code: 'profile-state-writer-busy' })
)
const rejected = expect(write).rejects.toMatchObject({
code: 'profile-state-writer-aborted',
outcome: 'indeterminate'
})
await client.abort()
await rejected
})
it('reports an idle writer exit even without a subsequent save', async () => {
const notify = vi.fn()
const client = clientFor('', undefined, notify, 'setTimeout(() => process.exit(1), 50)')
@@ -515,7 +515,15 @@ describe.each(([APPLY, MOVE, SAVE] as const).map((name) => [name, WRITERS[name]]
it.each(WORKSPACE_LAYOUT_PROFILES.map((profile) => [profile.name, profile] as const))(
'%s: the same session, key order aside, as its load normalizes nothing',
(_name, profile) => {
for (const call of write(profile).flat()) {
const calls = write(profile).flat()
const skipsPatch =
profile.name === 'empty profile'
? writer !== SAVE
: writer === MOVE
? profile.hostId !== LOCAL_EXECUTION_HOST_ID
: writer === SAVE && profile.hostId.startsWith('runtime:')
expect(calls.length === 0).toBe(skipsPatch)
for (const call of calls) {
expect(recordsDiffering(call.stored, call.before)).toEqual([])
expect(stableJson(call.patched)).toBe(stableJson(call.full))
}
@@ -48,6 +48,7 @@ describe('folder workspace sort stamps', () => {
operations.updateFolderWorkspace(id, { smartTier: undefined, smartAt: undefined })
expect(operations.getFolderWorkspace(id)?.smartTier).toBeUndefined()
expect(operations.getFolderWorkspace(id)?.smartAt).toBeUndefined()
// An update that does not name the tier leaves it alone.
operations.updateFolderWorkspace(id, { smartTier: 'working', smartAt: 10 })
operations.updateFolderWorkspace(id, { comment: 'x' })
@@ -71,6 +71,8 @@ describe('installMouseHideWhileTyping', () => {
const disposable = installMouseHideWhileTyping(terminal, container as unknown as HTMLElement)
disposable.dispose()
expect(terminal.onData.mock.results[0]?.value.dispose).toHaveBeenCalledTimes(1)
expect(container.style.cursor).toBe('')
// After dispose, mousemove should not crash and cursor stays restored.
container.dispatchEvent(new Event('mousemove'))
@@ -111,7 +111,7 @@ describe('useOsc52ClipboardDefaultOnNotice', () => {
expect(storeState.clearOsc52ClipboardDefaultOnNotice).toHaveBeenCalledTimes(1)
})
it('dedupes the StrictMode double-invoke with a stable toast id', async () => {
it('assigns a stable toast id for notice deduplication', async () => {
// Why pin the id: the effect re-runs against the same closure, so the early return
// cannot catch the second pass — sonner collapses it only because the id matches.
await mountProbe(true)
@@ -760,9 +760,12 @@ describe('createPaneForegroundAgentTracker', () => {
onCommandFinished: () => tracker.onCommandFinished()
})
lifecycle.handlePtyData("printf '\\033]133;A\\007\\033]777;agent=codex\\007\\033]133;D;0\\007'")
lifecycle.handlePtyData('\x1b]133;C\x07\x1b]777;agent=codex\x07')
await flushSettleRead(COMMAND_SETTLE_MS)
expect(remoteRead).toHaveBeenCalledExactlyOnceWith('ssh:conn-1@@pty-9', {
expectedIncarnationId: 'inc-remote'
})
expect(publish).not.toHaveBeenCalledWith(
expect.objectContaining({ agent: 'codex', shellForeground: false })
)
@@ -268,7 +268,7 @@ describe('startParkedTerminalByteWatcher', () => {
dispose()
})
it('suppresses the completion OS notification when only terminal attention is on', async () => {
it('forwards completion to notification policy when only terminal attention is on', async () => {
mockStoreState.settings = {
...mockStoreState.settings,
experimentalTerminalAttention: true,
@@ -10,7 +10,7 @@ describe('parseOsc7', () => {
expect(parseOsc7('file:///home/jin')).toBe('/home/jin')
})
it('percent-decodes spaces and unicode', () => {
it('percent-decodes spaces', () => {
expect(parseOsc7('file:///home/jin/my%20code')).toBe('/home/jin/my code')
})
@@ -24,12 +24,13 @@ describe('resolveAgentStartupPlanInputs with extra agent args', () => {
extraAgentArgs: '--model opus --add-dir "my docs"'
})
const plan = buildAgentStartupPlan({ ...inputs, prompt: 'go' })
expect(plan?.launchCommand).toContain("'--add-dir' 'my docs'")
expect(plan?.launchCommand).toContain('opus')
expect(plan?.launchCommand).not.toContain('sonnet')
expect(plan?.launchCommand).toContain('--dangerously-skip-permissions')
})
it('builds the same command the desktop path builds', () => {
it('matches explicitly composed launch defaults and extras', () => {
const headless = resolveAgentStartupPlanInputs({
agent: 'claude',
settings: SETTINGS,