Files
brain/tools/verdict-surface-store.test.mjs
T

67 lines
3.0 KiB
JavaScript

import { describe, it, expect } from 'vitest';
import { mkdtempSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { pushVerdict, drainVerdicts, markSurfaced, readPendingAck, clearPendingAck } from './verdict-surface-store.mjs';
const dir = () => mkdtempSync(join(tmpdir(), 'vsurf-'));
describe('verdict-surface-store', () => {
it('push → drain one-shot (drain чистит)', () => {
const d = dir();
pushVerdict('s1', { outcome: 'NO-GO', gate: 'judge' }, d);
expect(drainVerdicts('s1', d)).toHaveLength(1);
expect(drainVerdicts('s1', d)).toHaveLength(0);
});
it('пер-сессия: чужие не видны', () => {
const d = dir();
pushVerdict('s1', { outcome: 'GO' }, d);
expect(drainVerdicts('s2', d)).toHaveLength(0);
});
it('pending-ack: mark → read → clear', () => {
const d = dir();
markSurfaced('s1', ['NO-GO'], d);
expect(readPendingAck('s1', d)).toEqual(['NO-GO']);
clearPendingAck('s1', d);
expect(readPendingAck('s1', d)).toBeNull();
});
it('fail-quiet: битый baseDir не кидает', () => {
expect(() => drainVerdicts('s1', '\0bad')).not.toThrow();
expect(drainVerdicts('s1', '\0bad')).toEqual([]);
});
});
import { writeStage, readSnapshot } from './verdict-surface-store.mjs';
describe('verdict-surface-store снимок стадий (видимость «всё в лоб»)', () => {
it('writeStage pending → читается через readSnapshot по hash', () => {
const d = dir();
writeStage('s1', { stage: 'mentor:plan', hash: 'h1', status: 'pending', ts: 1 }, d);
expect(readSnapshot('s1', 'h1', d)['mentor:plan'].status).toBe('pending');
});
it('завершение перезаписывает pending на исход (та же стадия+hash)', () => {
const d = dir();
writeStage('s1', { stage: 'mentor:plan', hash: 'h1', status: 'pending', ts: 1 }, d);
writeStage('s1', { stage: 'mentor:plan', hash: 'h1', status: 'NO-GO', reason: 'переделай', ts: 2 }, d);
const snap = readSnapshot('s1', 'h1', d);
expect(snap['mentor:plan'].status).toBe('NO-GO');
expect(snap['mentor:plan'].reason).toBe('переделай');
});
it('разные стадии одного hash сосуществуют', () => {
const d = dir();
writeStage('s1', { stage: 'router', hash: 'h1', status: 'recommend', ts: 1 }, d);
writeStage('s1', { stage: 'judge:plan', hash: 'h1', status: 'GO', ts: 2 }, d);
const snap = readSnapshot('s1', 'h1', d);
expect(snap.router.status).toBe('recommend');
expect(snap['judge:plan'].status).toBe('GO');
});
it('неизвестный hash → пустой объект', () => {
const d = dir();
expect(readSnapshot('s1', 'nope', d)).toEqual({});
});
it('fail-quiet: битый baseDir не кидает (снимок)', () => {
expect(() => writeStage('s1', { stage: 'router', hash: 'h', status: 'GO' }, '\0bad')).not.toThrow();
expect(readSnapshot('s1', 'h', '\0bad')).toEqual({});
});
});