76 lines
3.9 KiB
TypeScript
76 lines
3.9 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.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.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')
|