Files
dsh-recall/test/projection.test.js
2026-09-26 05:35:29 +01:00

117 lines
4.8 KiB
JavaScript

import { strict as assert } from 'node:assert'
import { test } from 'node:test'
import { usageProjection } from '../index.js'
import { deriveUsage, emptyUsage, foldUsage, usageSummary } from '../lib/usage.js'
/**
* The projection contract, tested against the framework's stated requirements
* rather than against the shape of my own code:
*
* - the state schema validates the persisted checkpoint before it seeds a fold,
* so a stale or corrupt row must be *rejected*, not coerced;
* - `apply` must return the same reference for an event it does not own, or the
* unit republishes on every step of every session;
* - the view is compared by `Object.is`, so one state must yield one object.
*/
/** A folded state, as a conversation with a couple of searches would produce. */
function foldedState() {
const value = {
action: 'search',
ok: true,
weak: false,
focus: { path: 'src/auth' },
results: [{ excerpt: 'x'.repeat(400) }, { excerpt: 'y'.repeat(200) }],
measure: { excerpts: 2, returnedBytes: 600, sourceBytes: 24_000, files: 2 },
}
const event = { type: 'tool/result', meta: deriveUsage({ action: 'search' }, value) }
return foldUsage(foldUsage(emptyUsage(), event), event)
}
test('the unit owns the key the client will read', () => {
assert.equal(usageProjection.key, 'recallUsage')
assert.equal(usageProjection.stateVersion, 1)
assert.ok(Number.isInteger(usageProjection.stateVersion) && usageProjection.stateVersion >= 0)
})
test('init produces the empty state, and it survives a round trip', () => {
const state = usageProjection.init()
assert.deepEqual(state, emptyUsage())
assert.deepEqual(usageProjection.stateSchema.parse(state), state)
})
test('the state schema accepts a folded state and preserves it', () => {
const state = foldedState()
assert.equal(state.searches, 2)
// Persisted as JSON and re-parsed on restore, so that round trip must hold.
const restored = usageProjection.stateSchema.parse(JSON.parse(JSON.stringify(state)))
assert.deepEqual(restored, state)
})
test('the state schema REJECTS a corrupt checkpoint rather than coercing it', () => {
// The service catches a parse failure and skips the row; coercing garbage
// would forward-apply nonsense into every later total instead.
for (const bad of [null, undefined, 42, 'state', {}, { searches: 'two' }, { ...emptyUsage(), searches: null }]) {
assert.equal(usageProjection.stateSchema.safeParse(bad).success, false, `accepted ${JSON.stringify(bad)}`)
}
})
test('apply returns the SAME reference for events the unit does not own', () => {
const state = foldedState()
assert.equal(usageProjection.apply(state, { type: 'user/message' }), state)
assert.equal(usageProjection.apply(state, { type: 'tool/result', meta: { other: 1 } }), state)
assert.equal(usageProjection.apply(state, { type: 'assistant/message' }), state)
})
test('apply folds an event the unit does own', () => {
const state = usageProjection.init()
const value = {
action: 'search',
ok: true,
results: [{ excerpt: 'abc' }],
measure: { excerpts: 1, returnedBytes: 3, sourceBytes: 900, files: 1 },
}
const event = { type: 'tool/result', meta: deriveUsage({ action: 'search' }, value) }
const next = usageProjection.apply(state, event)
assert.notEqual(next, state, 'a real event must produce a new state')
assert.equal(next.searches, 1)
assert.equal(next.sourceBytes, 900)
})
test('the view validates against its own schema', () => {
const state = foldedState()
const view = usageProjection.wire.view(state)
assert.deepEqual(usageProjection.wire.viewSchema.parse(view), view)
})
test('one state yields ONE view object, by reference', () => {
// The live drive compares the two latest views with Object.is; returning a
// fresh object per call would republish on every event that touched the state
// even when the numbers a surface shows had not moved.
const state = foldedState()
const first = usageProjection.wire.view(state)
const second = usageProjection.wire.view(state)
assert.equal(first, second)
})
test('a different state yields a different view', () => {
const one = usageProjection.wire.view(foldedState())
const two = usageProjection.wire.view(emptyUsage())
assert.notEqual(one, two)
assert.equal(one.searches, 2)
assert.equal(two.searches, 0)
})
test('the view carries the comparison and the compounding figure', () => {
const view = usageProjection.wire.view(foldedState())
assert.equal(view.searches, 2)
assert.equal(view.sourceBytes, 48_000)
assert.equal(view.returnedBytes, 1200)
assert.equal(view.avoidedBytes, 46_800)
// bytes/4 is an approximation and is labelled as one where it is displayed.
assert.equal(view.avoidedTokens, Math.round(46_800 / 4))
assert.ok(view.compression > 1)
assert.equal(view.avoidedUsd, usageSummary(foldedState()).avoidedUsd)
})