mirror of
https://github.com/stablyai/orca.git
synced 2026-11-02 10:08:13 +00:00
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:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user