/** * Conformance test: the runtime enum lists in `evidence-link.ts` must * match the lists in `wiki/SharedContracts.md` §2.4 and §2.5 exactly. * * If you intentionally change an enum, update both the doc and the * runtime list together — this test will tell you which one you forgot. */ import { readFileSync } from "node:fs"; import { resolve } from "node:path"; import { fileURLToPath } from "node:url"; import { describe, expect, it } from "vitest"; import { EVIDENCE_LINK_STATUS_VALUES, EVIDENCE_RELATION_VALUES, } from "./evidence-link"; const HERE = fileURLToPath(new URL(".", import.meta.url)); const CONTRACTS_PATH = resolve(HERE, "../../wiki/SharedContracts.md"); function extractFencedListAfterHeading(markdown: string, heading: string): string[] { const headingIndex = markdown.indexOf(heading); if (headingIndex === -1) { throw new Error(`Could not find heading "${heading}" in SharedContracts.md`); } const after = markdown.slice(headingIndex + heading.length); const fenceOpen = after.indexOf("```"); if (fenceOpen === -1) throw new Error(`No fenced block after "${heading}"`); const bodyStart = after.indexOf("\n", fenceOpen) + 1; const fenceClose = after.indexOf("```", bodyStart); if (fenceClose === -1) throw new Error(`Unterminated fenced block after "${heading}"`); const body = after.slice(bodyStart, fenceClose); return body .split("\n") .map((line) => line.trim()) .filter((line) => line.length > 0) // Strip trailing " — explanatory note" if present (none in §2.4/§2.5 today, // but §2.1/§2.2 use that style — being defensive keeps the helper reusable). .map((line) => line.split(/\s+[—-]\s+/)[0]!.trim()); } describe("EvidenceLink enum conformance with SharedContracts.md", () => { const markdown = readFileSync(CONTRACTS_PATH, "utf8"); it("§2.4 EvidenceLink.status matches EVIDENCE_LINK_STATUS_VALUES", () => { const docValues = extractFencedListAfterHeading( markdown, "### 2.4 `EvidenceLink.status` (per target)", ); expect(docValues).toEqual([...EVIDENCE_LINK_STATUS_VALUES]); }); it("§2.5 EvidenceLink.relation matches EVIDENCE_RELATION_VALUES", () => { const docValues = extractFencedListAfterHeading( markdown, "### 2.5 `EvidenceLink.relation`", ); expect(docValues).toEqual([...EVIDENCE_RELATION_VALUES]); }); });