import assert from "node:assert/strict"; import { readdir, readFile } from "node:fs/promises"; import { extname, join } from "node:path"; import { test } from "node:test"; const sourceRoot = new URL("../src/", import.meta.url); async function sourceFiles(relativeDirectory) { const directory = new URL(`${relativeDirectory}/`, sourceRoot); const entries = await readdir(directory, { recursive: true, withFileTypes: true, }); return entries .filter((entry) => entry.isFile() && [".ts", ".tsx"].includes(extname(entry.name))) .map((entry) => join(entry.parentPath, entry.name)); } async function read(relativePath) { return readFile(new URL(relativePath, sourceRoot), "utf8"); } test("dependency direction keeps core and reusable components below workspaces", async () => { const coreFiles = await sourceFiles("core"); const componentFiles = await sourceFiles("components"); for (const file of coreFiles) { const source = await readFile(file, "utf8"); assert.doesNotMatch( source, /from\s+["'][^"']*(?:workspaces|\/App)["']/, `${file} imports an application composition layer`, ); assert.doesNotMatch( source, /@nodedc\/ui-(?:react|dom)/, `${file} imports a visual adapter from the domain layer`, ); } for (const file of componentFiles) { const source = await readFile(file, "utf8"); assert.doesNotMatch( source, /from\s+["'][^"']*(?:workspaces|\/App)["']/, `${file} imports a workspace composition layer`, ); } }); test("shared visual primitives come only from the Design Guideline packages", async () => { const packageJson = JSON.parse( await readFile(new URL("../package.json", import.meta.url), "utf8"), ); for (const packageName of [ "@nodedc/tokens", "@nodedc/ui-core", "@nodedc/ui-react", ]) { assert.equal(typeof packageJson.dependencies[packageName], "string"); } const files = await sourceFiles("."); for (const file of files) { const source = await readFile(file, "utf8"); assert.doesNotMatch(source, /lucide-react/); assert.doesNotMatch(source, /NODEDC_DESIGN_GUIDELINE\/(?:apps|src)\//); } }); test("laboratory UI is a bounded feature slice, not a central workspace branch", async () => { const workspaceHub = await read("workspaces/Workspaces.tsx"); const laboratory = await read( "workspaces/laboratory/LaboratoryArchiveWorkspace.tsx", ); const workspaceCss = await read("styles/workspaces.css"); const laboratoryCss = await read("styles/laboratory.css"); const laboratoryReportingCss = await read("styles/laboratory-reporting.css"); const e30Review = await read("workspaces/E30ReviewWorkspace.tsx"); const e30HumanReview = await read( "workspaces/E30HumanReviewPanel.tsx", ); const e30HumanReviewCss = await read("styles/e30-human-review.css"); assert.doesNotMatch( workspaceHub, /fetchE(?:29|30)|LaboratoryWorkTemplate|function\s+E(?:29|30)LaboratoryResult/, ); assert.match( workspaceHub, / { const workspaceHub = await read("workspaces/Workspaces.tsx"); const observatory = await read("workspaces/observatory/ObservatoryWorkspace.tsx"); const observatoryCore = await read("core/observatory/catalog.ts"); const recordedRun = await read("core/observatory/recordedRun.ts"); const sharedReplay = await read( "components/laboratory/CanonicalResultRerunReplay.tsx", ); const workspaceCss = await read("styles/workspaces.css"); const observatoryCss = await read("styles/observatory.css"); assert.match( workspaceHub, /case "observatory":[\s\S]*/, ); assert.match(observatory, /export function ObservatoryWorkspace/); assert.match(observatory, /useObservatoryCatalog/); assert.match(observatory, /data-observatory-authority="observation-only"/); assert.match( observatory, /data-observatory-viewer={replay\.kind === "ready" \|\| replay\.kind === "composition" \? "attached" : "detached"}/, ); assert.doesNotMatch( `${observatory}\n${observatoryCore}`, /(?:core|workspaces)\/laboratory|\/api\/v1\/laboratory|RerunViewport|ObservationSessionSelect/, ); assert.match(observatory, /replay\.kind === "ready"[\s\S]*\(hasTgs \? 1 : 0\)/); assert.match(sharedReplay, /hasTgs \? 0\.000001 : 0/); for (const adapter of ["CanonicalVegetationRerunReplay", "PortableResultReplay"]) { const source = await read(`components/laboratory/${adapter}.tsx`); assert.match(source, /