Files
ycode/scripts/input-composition-regression.ts
T

87 lines
4.6 KiB
TypeScript

import assert from 'node:assert/strict'
import { composeComposer, isActiveComposerInteraction, type ComposerCompositionInput } from '../src/renderer/src/workbuddy/composer/input-composition'
const idle: ComposerCompositionInput = {}
let result = composeComposer(idle)
assert.equal(result.input.mounted, true)
assert.equal(result.input.destination, 'send')
assert.equal(result.queue.visible, false)
assert.equal(result.queue.hiddenBy, 'empty')
assert.equal(result.toolbar.permissionPlacement, 'after-add')
assert.equal(result.toolbar.primaryAction, 'send')
assert.equal(result.escapeStopsGeneration, false)
result = composeComposer({ running: true, queueCount: 2, queueRevision: 4 })
assert.equal(result.input.destination, 'queue', 'running messages are queued instead of interrupting the turn')
assert.equal(result.queue.visible, true)
assert.equal(result.toolbar.primaryAction, 'stop', 'stop remains reachable while the queue is visible')
for (const kind of ['question', 'approval', 'plan', 'mcp'] as const) {
result = composeComposer({
interaction: { id: `${kind}-1`, kind, status: 'pending' },
notice: { kind: 'error', id: 'global-error' },
task: { id: 'task-1', active: true },
queueCount: 3,
queueRevision: 8,
running: true
})
assert.equal(result.interaction?.kind, kind)
assert.equal(result.input.visible, kind !== 'approval' && kind !== 'question', 'active question and approval replace normal input')
assert.equal(result.input.blockedByInteraction, true)
assert.equal(result.input.destination, 'blocked')
assert.equal(result.input.preservesDraft, true, 'takeover never clears the draft')
assert.equal(result.queue.visible, false, 'takeover hides the queue')
assert.equal(result.queue.hiddenBy, 'interaction')
assert.equal(result.queue.count, 3, 'queue data remains available while hidden')
assert.equal(result.queue.preservesItems, true)
assert.equal(result.task?.id, 'task-1', 'task data remains available while hidden')
assert.equal(result.notice, null, 'interaction-local errors must not duplicate a global notice')
assert.equal(result.toolbar.primaryAction, 'stop', 'stop is not stolen by takeover')
assert.deepEqual(result.stack.beforeInput.map(panel => panel.kind), [kind])
assert.equal(result.stack.queue, null)
}
result = composeComposer({
interaction: { id: 'answered', kind: 'approval', status: 'answered' },
task: { active: true },
queueCount: 2
})
assert.equal(result.interaction, null, 'settled interactions no longer take over')
assert.equal(result.input.visible, true)
assert.equal(result.queue.visible, true)
assert.deepEqual(result.stack.beforeQueue.map(panel => panel.kind), ['task'])
assert.equal(result.stack.queue?.kind, 'queue')
result = composeComposer({ notice: { kind: 'quota', id: 'quota-1' }, task: { active: true } })
assert.deepEqual(result.stack.beforeInput.map(panel => panel.kind), ['quota'])
result = composeComposer({ notice: { kind: 'error', id: 'error-1' }, task: { id: 'task-2', active: true }, queueCount: 1 })
assert.deepEqual(result.stack.beforeInput.map(panel => panel.kind), ['error'])
assert.equal(result.stack.beforeQueue.length, 0)
assert.equal(result.task?.id, 'task-2', 'notice keeps task data while suppressing its placement')
assert.equal(result.queue.visible, false, 'notice suppresses accessory queue rendering')
assert.equal(result.queue.hiddenBy, 'notice')
assert.equal(result.stack.queue, null)
assert.equal(isActiveComposerInteraction({ id: 'q', kind: 'question', status: 'responding' }), true)
assert.equal(isActiveComposerInteraction({ id: 'q', kind: 'question', status: 'cancelled' }), false)
const clamped = composeComposer({ queueCount: Number.NaN, queueRevision: -3 })
assert.equal(clamped.queue.count, 0)
assert.equal(clamped.queue.revision, 0)
const firstLayout = composeComposer({ queueCount: 1, queueRevision: 1 }).layoutKey
const secondLayout = composeComposer({ queueCount: 1, queueRevision: 2 }).layoutKey
assert.notEqual(firstLayout, secondLayout, 'layout key changes when queue height may change')
console.log('input-composition-regression: precedence, takeover, queue preservation, task placement, toolbar and escape rules passed')
for (const kind of ['question', 'approval'] as const) {
for (const status of ['pending', 'responding', 'error', 'answered', 'rejected', 'cancelled'] as const) {
const active = ['pending', 'responding', 'error'].includes(status)
const state = composeComposer({ interaction: { id: kind, kind, status } })
assert.equal(state.input.visible, !active, `${kind}/${status} input exclusivity`)
assert.equal(state.input.mounted, true, 'draft editor always remains mounted')
}
}