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

112 lines
5.4 KiB
JavaScript

import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import { test } from "node:test";
const component = (name) => new URL(`../src/components/laboratory/${name}`, import.meta.url);
test("semantic evidence mask is GPU-colored, bounded, cancelled and object-contained client-side", async () => {
const source = await readFile(component("RecordedEvidenceSemanticMaskOverlay.tsx"), "utf8");
assert.match(source, /decodedMaskCache/);
assert.match(source, /pendingMaskCache/);
assert.match(source, /MASK_CACHE_LIMIT = 20/);
assert.match(source, /MASK_PREFETCH_LIMIT = 12/);
assert.match(source, /prefetchSrcs\?: readonly string\[\]/);
assert.match(source, /\.slice\(0, MASK_PREFETCH_LIMIT\)/);
assert.match(source, /AbortController/);
assert.match(source, /createSemanticMaskRenderer/);
assert.match(source, /getContext\("webgl"/);
assert.match(source, /preserveDrawingBuffer: true/);
assert.match(source, /vec2\(v_uv\.x, 1\.0 - v_uv\.y\)/);
assert.match(source, /UNPACK_FLIP_Y_WEBGL, 0/);
assert.match(source, /gl\.isContextLost\(\)/);
assert.match(source, /webglcontextlost/);
assert.match(source, /setRendererMode\("2d"\)/);
assert.match(source, /gl\.texImage2D/);
assert.match(source, /u_palette/);
assert.match(source, /getImageData/);
assert.match(source, /ResizeObserver/);
assert.match(source, /Math\.min\(width \/ mask\.width, height \/ mask\.height\)/);
assert.match(source, /decoded\.key !== expectedKey/);
assert.match(source, /mask\?\.key === expectedKey/);
assert.match(source, /lastReadyMaskRef/);
assert.match(source, /data-state=\{failure \? "error" : exactMask \? "ready" : renderMask \? "stale" : "loading"\}/);
assert.match(source, /recorded-evidence-semantic-mask-overlay__error/);
assert.match(source, /role="alert"/);
});
test("shared recorded scenes place optional semantic masks beneath boxes", async () => {
const [imageScene, videoScene] = await Promise.all([
readFile(component("RecordedEvidenceImageScene.tsx"), "utf8"),
readFile(component("RecordedEvidenceVideoScene.tsx"), "utf8"),
]);
for (const source of [imageScene, videoScene]) {
assert.match(source, /semanticOverlay\?: RecordedEvidenceSemanticOverlay/);
assert.ok(
source.indexOf("<RecordedEvidenceSemanticMaskOverlay")
< source.indexOf("<RecordedEvidenceBoxOverlay"),
);
}
});
test("metric evidence keeps missing semantic assignments as context and exposes a taxonomy legend", async () => {
const source = await readFile(component("LaboratoryMetricEvidenceScene.tsx"), "utf8");
assert.match(source, /pointSemanticClassIds\?: readonly \(number \| null\)\[\]/);
assert.match(source, /pointSemanticClassIds\.length === pointCloudBodyXyzM\.length/);
assert.match(source, /classId === null \? undefined : colorsByClassId\.get\(classId\)/);
assert.match(source, /data-decision="semantic"/);
assert.match(source, /recordedEvidenceSemanticCssColor/);
assert.match(source, /DynamicDrawUsage/);
assert.match(source, /classifiedMeshesRef/);
assert.match(source, /classifiedPackedCells/);
assert.match(source, /updatePointPositions/);
assert.match(source, /renderer\.info\.render\.calls/);
assert.match(source, /data-decision="performance"/);
});
test("semantic point alignment follows the last qualified spatial increment", async () => {
const source = await readFile(
new URL("../src/workspaces/laboratory/M4ReplayThreatVisual.tsx", import.meta.url),
"utf8",
);
assert.match(source, /frame\?\.spatialAvailable && semanticFrame/);
assert.match(source, /lastSpatialSemanticFrameRef/);
assert.match(source, /\|\| !spatialFrame\s*\|\| !spatialSemanticFrame/);
assert.match(source, /spatialSemanticFrame\.sourcePointCount !== spatialFrame\.pointCloudSourceCount/);
});
test("M4 keeps independent semantic controls in media and spatial panes", async () => {
const [source, canonical] = await Promise.all([
readFile(
new URL("../src/workspaces/laboratory/M4ReplayThreatVisual.tsx", import.meta.url),
"utf8",
),
readFile(
new URL("../src/components/laboratory/CanonicalRecordedLabReplay.tsx", import.meta.url),
"utf8",
),
]);
assert.match(source, /showMediaSemantic/);
assert.match(source, /showSpatialSemantic/);
assert.match(source, /activeSpatialSemantic = spatialSemantic \?\? activeSemantic/);
assert.match(source, /spatialSemanticClasses/);
assert.match(source, /spatialSemanticPalette/);
assert.match(source, /activeSemantic && evidenceDemand\.selectedSemanticMask && frame/);
assert.match(source, /Array\.from\(\{ length: 12 \}, \(_, index\) => index \+ 1\)/);
assert.match(source, /\|\| !showSpatialSemantic/);
assert.match(source, /aria-label="Слои камеры и видео"/);
assert.match(source, /aria-label="Слои 3D и плана"/);
assert.match(canonical, /data-pane-mode="media"/);
assert.match(canonical, /data-pane-mode="spatial"/);
assert.match(canonical, /modeControlsVisible=\{!splitView && !paneToolbarsAlwaysVisible\}/);
assert.match(source, /semanticOverlay=\{mediaMode === "video" \? semanticOverlay : undefined\}/);
});
test("laboratory fullscreen preserves the mounted evidence subtree", async () => {
const source = await readFile(component("LaboratoryEvidenceViewer.tsx"), "utf8");
assert.match(source, /useLayoutEffect/);
assert.match(source, /viewer\.showModal\(\)/);
assert.match(source, /viewer\.show\(\)/);
assert.match(source, /<dialog/);
assert.doesNotMatch(source, /createPortal/);
});