Files
rea/tests/boundary/filesystem/javascriptArtifactBomRanges.test.ts
morluto 63bf91405c refactor!: enforce canonical evidence and provider boundaries
Deliver complete Evidence directly through MCP with required nullable analysis profiles and immutable per-server delivery settings. Bind selected environments at construction and require typed cleanup outcomes with retained retry ownership.

Remove test-only routing, duplicate session and snapshot metadata, producer-field repairs, and ambiguous provider arguments. Separate artifact byte identity from occurrence classification and retain typed source-map and partial native facts across CLI, MCP, and verifier consumers.

BREAKING CHANGE: obsolete Evidence envelopes, session aliases, incomplete snapshots, and missing normalized producer facts are no longer accepted.
2026-10-09 20:18:52 +08:00

108 lines
3.8 KiB
TypeScript

import { expect, it } from "vitest";
import { reconstructJavaScriptArtifact } from "../../../src/application/javascript/JavaScriptArtifactReconstruction.js";
import {
bomSourceCases,
createBomArtifact,
expectBomSourceRange,
} from "../../fixtures/javascriptArtifactBom.js";
for (const format of ["directory", "asar"] as const) {
for (const fixture of bomSourceCases) {
for (const prefix of ["", "\uFEFF"] as const) {
it(`${format} preserves ${fixture.kind} original ranges with ${prefix === "" ? "no BOM" : "a UTF-8 BOM"}`, async () => {
const source =
fixture.kind === "html"
? `${prefix}${fixture.source}`
: `${prefix}${fixture.source}\nglobalThis.__rea_bom_executed = true; throw new Error("must remain inert");`;
const bytes = Buffer.from(source);
const input = await createBomArtifact(format, {
[fixture.path]: bytes,
"dep.js": "export const dependency = true;",
});
const result = await reconstructJavaScriptArtifact({
input_path: input,
});
expect(result.statistics).toMatchObject({
parse_failures: 0,
invalid_utf8_files: 0,
});
expect(Reflect.get(globalThis, "__rea_bom_executed")).toBeUndefined();
expectBomSourceRange(result.graph, fixture, bytes);
});
}
}
it(`${format} preserves accepted BOM handling for package, JSON and source maps`, async () => {
const input = await createBomArtifact(format, {
"package.json": '\uFEFF{"name":"bom-package","main":"dep.js"}',
"data.json": '\uFEFF{"__proto__":"owned","control":true}',
"app.js.map":
'\uFEFF{"version":3,"sources":["original.js"],"sourcesContent":["export const original = true;"],"names":[],"mappings":"AAAA"}',
"dep.js": "export const dependency = true;",
});
const result = await reconstructJavaScriptArtifact({ input_path: input });
expect(result.statistics).toMatchObject({
parse_failures: 0,
invalid_utf8_files: 0,
});
const observations = result.graph.nodes.flatMap(
({ observations }) => observations,
);
expect(
observations.some(
({ properties }) =>
properties.name === "bom-package" &&
properties.parse_status === "included",
),
).toBe(true);
expect(
observations.some(
({ properties }) =>
properties.path === "data.json" &&
properties.json_parse_status === "included",
),
).toBe(true);
const original = result.graph.nodes.find(
({ kind }) => kind === "source-module",
);
expect(original?.identity).toMatchObject({
strategy: "source-map-original",
original_source: "original.js",
source_root: null,
});
expect(original?.observations).toContainEqual(
expect.objectContaining({
source_map_reference: {
source_name: "original.js",
source_root: null,
map_path: "app.js.map",
resolution: { kind: "artifact-relative", path: "original.js" },
},
properties: { content_available: true },
}),
);
});
it(`${format} retains invalid UTF-8 as unavailable rather than replacing bytes`, async () => {
const invalid = Buffer.from([0xef, 0xbb, 0xbf, 0xff]);
const input = await createBomArtifact(format, {
"invalid.js": invalid,
"invalid.html": invalid,
});
const result = await reconstructJavaScriptArtifact({ input_path: input });
expect(result.statistics.invalid_utf8_files).toBe(2);
const observations = result.graph.nodes.flatMap(
({ observations }) => observations,
);
for (const path of ["invalid.js", "invalid.html"])
expect(
observations.some(
({ properties }) =>
properties.path === path &&
properties.text_status === "invalid-utf8",
),
).toBe(true);
});
}