26 lines
1.7 KiB
JavaScript
26 lines
1.7 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { readFile } from "node:fs/promises";
|
|
import { createHash } from "node:crypto";
|
|
import { classifyMissingResources, isOptionalSourceKey, LINUXCNC_SOURCE_SEMANTICS_SCHEMA } from "./linuxcnc-source-semantics.mjs";
|
|
|
|
const report = JSON.parse(await readFile(new URL("../../coverage/linuxcnc-source-semantics-contract.json", import.meta.url), "utf8"));
|
|
assert.equal(report.schema, "linuxcnc-source-semantics-contract.v1");
|
|
assert.equal(LINUXCNC_SOURCE_SEMANTICS_SCHEMA, "linuxcnc-source-semantics.v1");
|
|
assert.equal(isOptionalSourceKey("OPEN_FILE", "DISPLAY"), true);
|
|
assert.equal(isOptionalSourceKey("INTRO_GRAPHIC", "DISPLAY"), true);
|
|
assert.equal(isOptionalSourceKey("OPEN_FILE", "RS274NGC"), false);
|
|
assert.equal(classifyMissingResources(["linuxcnc/configs/sim/craftsman/custom.hal"]), "BLOCKED_HAL");
|
|
assert.equal(classifyMissingResources(["linuxcnc/configs/sim/qtplasmac/metric_parameters.txt"]), "BLOCKED_RESOURCE");
|
|
assert.equal(report.control_panel_contract.projection_only, true);
|
|
assert.ok(report.control_panel_contract.required_fields.includes("state_hash"));
|
|
const canonical = (value) => {
|
|
if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
|
|
if (value && typeof value === "object") return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`).join(",")}}`;
|
|
return JSON.stringify(value);
|
|
};
|
|
const copy = structuredClone(report);
|
|
const expected = copy.report_sha256;
|
|
delete copy.report_sha256;
|
|
assert.equal(expected, createHash("sha256").update(canonical(copy)).digest("hex"));
|
|
console.log(JSON.stringify({ schema: report.schema, status: "verified", optional_open_file: true, hal_missing: "BLOCKED_HAL", resource_missing: "BLOCKED_RESOURCE", projection_only: true }));
|