tools/ci/test-map.json maps every automated case of the Test and Acceptance Standard's registry to the cell that runs it (the seven crate suites of the release matrix, the pre-push gate, the freeze check, the fast-time harness, the finality simulator, the P01 vectors and parser-malformed harnesses as they land), each cell with its command, box class and fixtures (F0 onward), each case with what the cell proves and what remains; 31 of 109 automated cases map tonight, 78 read NOT RUN with the reason. tools/ci/test-map-doc.mjs writes docs/plans/igneum-2.0-test-harness-map.md from the JSON (--check in the gate refuses a stale page). tools/ci/test-record.mjs --check refuses an unmapped automated case without a reason or an unknown id; --record <batch> writes run_status, run_id, evidence_path, updated and the evidence record (cell, manifest sha, coverage) to the mapped cases only, leaves every accept text byte-identical (the self-test diffs them), gives an unmapped automated case NOT RUN with its reason and a manual case nothing. Rule: a mapped cell's green writes RUNNING; PASS only when coverage is full and the evidence file exists; never PASS by inference. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
20 lines
2.1 KiB
JavaScript
20 lines
2.1 KiB
JavaScript
#!/usr/bin/env node
|
|
// docs/plans/igneum-2.0-test-harness-map.md is generated from tools/ci/test-map.json (the single source); --check refuses a stale page.
|
|
import fs from 'node:fs'; import path from 'node:path';
|
|
const ROOT = path.resolve(path.dirname(new URL(import.meta.url).pathname), '..', '..');
|
|
const map = JSON.parse(fs.readFileSync(path.join(ROOT, 'tools/ci/test-map.json'), 'utf8'));
|
|
const reg = JSON.parse(fs.readFileSync(path.join(ROOT, map.registry), 'utf8'));
|
|
const cases = (reg.suites || []).flatMap((s) => s.tests || []); const byId = new Map(cases.map((c) => [c.id, c]));
|
|
let md = `# ${map.title}\n\nGenerated from tools/ci/test-map.json by tools/ci/test-map-doc.mjs; edit the JSON, never this page. Registry: ${map.registry} (${cases.length} cases).\n\nRule: ${map.rule}.\n\n## Cells (the harness or suite, what it runs, where, the fixtures it needs)\n\n`;
|
|
for (const [cell, m] of Object.entries(map.cells)) {
|
|
md += `### ${cell}\n\n- Command: \`${m.command}\`\n- Box class: ${m.box_class}\n- Fixtures: ${m.fixtures.join(', ') || 'none'}\n- Cases:\n`;
|
|
for (const id of m.cases) md += ` - ${id} ${byId.get(id)?.title ?? ''}: ${m.coverage?.[id] ?? 'full'}\n`;
|
|
md += '\n';
|
|
}
|
|
md += `## Automated cases with no harness in the matrix (NOT RUN, the reason)\n\n`;
|
|
for (const [id, why] of Object.entries(map.not_run)) md += `- ${id} ${byId.get(id)?.title ?? ''}: ${why}\n`;
|
|
const auto = cases.filter((c) => /automated/i.test(String(c.method))).length; const mapped = new Set(Object.values(map.cells).flatMap((m) => m.cases)).size;
|
|
md += `\n## Count\n\n${auto} automated cases: ${mapped} mapped to a cell, ${Object.keys(map.not_run).length} NOT RUN with a reason.\n`;
|
|
const out = path.join(ROOT, 'docs/plans/igneum-2.0-test-harness-map.md');
|
|
if (process.argv.includes('--check')) { const cur = fs.existsSync(out) ? fs.readFileSync(out, 'utf8') : ''; if (cur !== md) { console.error('test-map-doc: the harness map page is stale; run node tools/ci/test-map-doc.mjs and commit it'); process.exit(1); } console.log('test-map-doc: the harness map page matches the JSON'); process.exit(0); }
|
|
fs.writeFileSync(out, md); console.log(`test-map-doc: wrote ${out}`);
|