import { describe, test } from 'node:test'; import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; // Lint-test for the fact-checker fasit fixture. // Mirrors the structure-only discipline of state-updater.test.mjs: this test // asserts the SHAPE of the fixture (exactly 3 cases, one of each verdict, a // non-empty fasit per case). The accuracy comparison β€” does the agent's live // output actually match the fasit verdicts β€” is [GATE]/[OPERATØR], never // self-certified here. const FIXTURE_PATH = fileURLToPath( new URL('../fixtures/fact-checker-cases.md', import.meta.url) ); const VERDICTS = ['🟒', 'πŸ”΄', '🟑']; const fixture = readFileSync(FIXTURE_PATH, 'utf8'); // Split on "## Case N" headings; drop the preamble before the first case. const blocks = fixture .split(/^##\s+Case\s+\d+\b.*$/m) .slice(1) .map((b) => b.trim()); describe('fact-checker fixture structure', () => { test('contains exactly 3 cases', () => { assert.equal(blocks.length, 3, `expected 3 cases, found ${blocks.length}`); }); test('each case carries exactly one verdict emoji', () => { for (const [i, block] of blocks.entries()) { const present = VERDICTS.filter((v) => block.includes(v)); assert.equal( present.length, 1, `case ${i + 1} must have exactly one of 🟒/πŸ”΄/🟑, found: [${present.join(', ')}]` ); } }); test('the three verdicts are one each of 🟒/πŸ”΄/🟑', () => { const seen = blocks.map((b) => VERDICTS.find((v) => b.includes(v))); assert.deepEqual( [...seen].sort(), [...VERDICTS].sort(), `fixture must cover one true (🟒), one false (πŸ”΄), one unverifiable (🟑); saw ${JSON.stringify(seen)}` ); }); test('each case has a non-empty Fasit field', () => { for (const [i, block] of blocks.entries()) { const m = block.match(/\*\*Fasit:\*\*\s*(.+)/); assert.ok(m, `case ${i + 1} is missing a **Fasit:** field`); assert.ok( m[1].trim().length > 0, `case ${i + 1} has an empty **Fasit:** field` ); } }); });