Files
NODEDC_MISSION_CORE/apps/control-station/test/applicationArchitecture.test.mjs
T

157 lines
6.3 KiB
JavaScript

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,
/<LaboratoryArchiveWorkspace[\s\S]*SpatialView=\{SpatialWorkspace\}/,
);
assert.match(laboratory, /export function LaboratoryArchiveWorkspace/);
assert.match(laboratory, /type LaboratoryWorkspaceProps = WorkspaceRendererProps/);
assert.doesNotMatch(workspaceCss, /\.(?:lab-|laboratory-|e30-)/);
assert.match(laboratoryCss, /\.laboratory-work-template/);
assert.match(laboratoryCss, /\.e30-review-workspace/);
assert.match(laboratoryReportingCss, /\.laboratory-summary__brief/);
assert.match(laboratoryReportingCss, /\.laboratory-result-conclusion/);
assert.doesNotMatch(laboratory, /E30HumanReviewPanel/);
assert.match(e30Review, /<E30HumanReviewPanel/);
assert.doesNotMatch(e30Review, /E30EngineeringAuditPanel/);
assert.match(e30HumanReview, /from "@nodedc\/ui-react"/);
assert.doesNotMatch(laboratoryCss, /\.e30-human-review/);
assert.match(e30HumanReviewCss, /\.e30-human-review/);
});
test("Observatory owns a bounded explicit-open lifecycle around the shared recorded viewer", async () => {
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]*<ObservatoryWorkspace definition=\{props\.definition\} \/>/,
);
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]*<CanonicalVegetationRerunReplay/);
assert.match(observatory, /closeReplay\(\);[\s\S]*setSelectedSessionId/);
assert.doesNotMatch(
observatory,
/replayObservationSession|deleteObservationSession|useObservationSessions|useAdvancedLaboratoryCatalog/,
);
assert.match(recordedRun, /fetchVegetationShadowResultMetadata/);
assert.doesNotMatch(
recordedRun,
/advanced-index|resolveObservationSessionReplay|resolveCanonicalLabReplay|RerunViewport/,
);
assert.equal(sharedReplay.match(/<RerunViewport\b/g)?.length, 1);
assert.match(sharedReplay, /recordedSessionRerunProfile/);
assert.match(sharedReplay, /useState<0 \| 1>\(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, /<CanonicalResultRerunReplay/);
assert.doesNotMatch(source, /<RerunViewport|<video|setInterval|Canvas|THREE\./);
}
assert.doesNotMatch(workspaceCss, /\.observatory-/);
assert.match(observatoryCss, /\.observatory-workspace/);
});