Rocko-authored, Filbert-reviewed inspector (r6 manifest a4a44930...) with full review/build/verdict evidence under docs/plans/reviews. 43/0 selftests, oracle zero-disagreement, foundation checker PASS. Owner A9 acceptance recorded separately.
99 lines
5.3 KiB
JavaScript
99 lines
5.3 KiB
JavaScript
// Every fixture case runs through the real CLI in a fresh subprocess; the observed
|
|
// exit/result/reason/rule/proposalRule/byteOffset must equal index.json. The owner
|
|
// demo goldens are compared byte-for-byte.
|
|
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { spawnSync } from "node:child_process";
|
|
import { readFileSync, readdirSync, existsSync } from "node:fs";
|
|
import { join, dirname } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { renderText, run } from "../foundation-inspect.mjs";
|
|
import { exitFor } from "./resolve.mjs";
|
|
|
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
const FIXTURES = join(HERE, "fixtures");
|
|
const CLI = join(HERE, "..", "foundation-inspect.mjs");
|
|
const INDEX = JSON.parse(readFileSync(join(FIXTURES, "index.json"), "utf8"));
|
|
const ENV = { PATH: "/nonexistent", HOME: "/nonexistent", LANG: "C" };
|
|
const RAW_RISKY_RE = /[\u0000-\u0008\u000b-\u001f\u007f-\u009f\u2028\u2029\ufeff\u200b]/;
|
|
|
|
function spawnJson(file) {
|
|
const r = spawnSync(process.execPath, [CLI, "--json", file], { cwd: FIXTURES, env: ENV, encoding: "utf8", timeout: 30000 });
|
|
assert.equal(r.error, undefined);
|
|
assert.equal(r.stderr, "", `${file}: stderr must be empty`);
|
|
const parsed = JSON.parse(r.stdout);
|
|
assert.ok(!("exit" in parsed), `${file}: exit is not a serialized field`);
|
|
assert.equal(r.status, exitFor(parsed), `${file}: exit code derived from the closed result`);
|
|
return { parsed, stdout: r.stdout, status: r.status };
|
|
}
|
|
|
|
test("index is complete and every listed file exists", () => {
|
|
assert.equal(INDEX.count, INDEX.cases.length);
|
|
assert.equal(INDEX.generator, "build-fixtures.mjs");
|
|
const names = INDEX.cases.map((c) => c.name);
|
|
assert.deepEqual(names, [...names].sort(), "index sorted by name");
|
|
assert.equal(new Set(names).size, names.length);
|
|
const listed = new Set(INDEX.cases.map((c) => c.file));
|
|
for (const dir of ["bundles", "raw"]) {
|
|
for (const f of readdirSync(join(FIXTURES, dir))) assert.ok(listed.has(`${dir}/${f}`), `${dir}/${f} not in index`);
|
|
}
|
|
for (const c of INDEX.cases) assert.ok(existsSync(join(FIXTURES, c.file)), c.file);
|
|
});
|
|
|
|
test("every fixture case matches its expected verdict through the CLI", () => {
|
|
const failures = [];
|
|
for (const c of INDEX.cases) {
|
|
const { parsed, status } = spawnJson(c.file);
|
|
const got = {
|
|
exit: status, result: parsed.result, reason: parsed.reason, rule: parsed.rule,
|
|
proposalRule: parsed.proposal === null ? null : parsed.proposal.rule,
|
|
};
|
|
const want = { exit: c.expect.exit, result: c.expect.result, reason: c.expect.reason, rule: c.expect.rule, proposalRule: c.expect.proposalRule };
|
|
if ("byteOffset" in c.expect) {
|
|
got.byteOffset = parsed.diagnostic === null ? null : parsed.diagnostic.byteOffset;
|
|
want.byteOffset = c.expect.byteOffset;
|
|
if (parsed.diagnostic !== null) assert.equal(parsed.diagnostic.inputPath, null, `${c.name}: path never echoed on parse failure`);
|
|
} else {
|
|
assert.equal(parsed.diagnostic, null, `${c.name}: diagnostic only on I/O or parse failure`);
|
|
}
|
|
if (JSON.stringify(got) !== JSON.stringify(want)) failures.push(`${c.name}: got ${JSON.stringify(got)} want ${JSON.stringify(want)}`);
|
|
if (status === 0) assert.equal(parsed.rule, null, c.name);
|
|
if (parsed.proposal !== null) assert.equal(parsed.result, parsed.proposal.result, c.name);
|
|
}
|
|
assert.deepEqual(failures, []);
|
|
});
|
|
|
|
test("in-process text rendering agrees with the JSON result for every case", () => {
|
|
for (const c of INDEX.cases) {
|
|
const file = join(FIXTURES, c.file);
|
|
const text = run([file]);
|
|
const json = run(["--json", file]);
|
|
assert.equal(text.json, false);
|
|
assert.deepEqual(text.result, json.result, c.name);
|
|
assert.equal(text.exit, c.expect.exit, c.name);
|
|
assert.equal(json.exit, c.expect.exit, c.name);
|
|
const rendered = renderText(text.result);
|
|
assert.ok(rendered.startsWith("SYNTHETIC PREVIEW — NO LIVE EFFECTS\n"), c.name);
|
|
assert.ok(/\ndiagnostic: [^\n]*\n$/.test(rendered), `${c.name}: text ends with the diagnostic line, no exit line`);
|
|
assert.ok(!/^exit/m.test(rendered), c.name);
|
|
assert.ok(!RAW_RISKY_RE.test(rendered), `${c.name}: raw control in text output`);
|
|
}
|
|
});
|
|
|
|
test("owner demo goldens match byte-for-byte", () => {
|
|
const names = readdirSync(join(FIXTURES, "demo")).filter((f) => f.endsWith(".json") && !f.includes(".expected."));
|
|
assert.equal(names.length, 5);
|
|
for (const name of names) {
|
|
const base = name.slice(0, -5);
|
|
const file = join(FIXTURES, "demo", name);
|
|
const text = spawnSync(process.execPath, [CLI, file], { cwd: FIXTURES, env: ENV, encoding: "utf8" });
|
|
const json = spawnSync(process.execPath, [CLI, "--json", file], { cwd: FIXTURES, env: ENV, encoding: "utf8" });
|
|
assert.equal(text.stdout, readFileSync(join(FIXTURES, "demo", `${base}.expected.txt`), "utf8"), `${base}.expected.txt`);
|
|
assert.equal(json.stdout, readFileSync(join(FIXTURES, "demo", `${base}.expected.json`), "utf8"), `${base}.expected.json`);
|
|
assert.equal(text.status, json.status);
|
|
assert.equal(String(text.status), readFileSync(join(FIXTURES, "demo", `${base}.expected.exit`), "utf8").trim());
|
|
// the demo copy equals the indexed bundle it was copied from
|
|
assert.equal(readFileSync(file, "utf8"), readFileSync(join(FIXTURES, "bundles", name), "utf8"), `${base}: demo copy drifted`);
|
|
}
|
|
});
|