mirror of
https://github.com/morluto/rea.git
synced 2026-10-26 17:35:11 +00:00
test(sourcemap): consolidate source map regressions (#2034)
fix(sourcemap): retain named originals beside unknown source names Co-authored-by: hhang <169027046+xu91102@users.noreply.github.com>
This commit is contained in:
1 parent
783fcb06a4
commit
83a4445f44
2 files changed
+90
-11
No files matched your search
@@ -2,6 +2,7 @@ import { createHash } from "node:crypto";
|
||||
import { readFile, writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
|
||||
import { TraceMap, originalPositionFor } from "@jridgewell/trace-mapping";
|
||||
import { expect } from "vitest";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
import { cliTest } from "../../support/cli/cliFixture.js";
|
||||
@@ -85,6 +86,13 @@ cliTest.for(["CLI", "stdio MCP"] as const)(
|
||||
names: [],
|
||||
mappings: "ACAA",
|
||||
}),
|
||||
"unnamed-empty.js.map": JSON.stringify({
|
||||
version: 3,
|
||||
sources: [null, "original.ts"],
|
||||
sourcesContent: [null, original],
|
||||
names: [],
|
||||
mappings: "ACAA",
|
||||
}),
|
||||
};
|
||||
await writeFixtureFiles(root, {
|
||||
...maps,
|
||||
@@ -92,13 +100,32 @@ cliTest.for(["CLI", "stdio MCP"] as const)(
|
||||
"export const absent = 1;\n//# sourceMappingURL=absent.js.map\n",
|
||||
"mixed.js":
|
||||
"export const answer = 42;\n//# sourceMappingURL=mixed.js.map\n",
|
||||
"unnamed-empty.js":
|
||||
"export const answer = 42;\n//# sourceMappingURL=unnamed-empty.js.map\n",
|
||||
});
|
||||
for (const [mapPath, expectedSource] of [
|
||||
["absent.js.map", "unembedded.ts"],
|
||||
["mixed.js.map", "original.ts"],
|
||||
["unnamed-empty.js.map", "original.ts"],
|
||||
] as const)
|
||||
expect(
|
||||
originalPositionFor(new TraceMap(maps[mapPath], `file:///${mapPath}`), {
|
||||
line: 1,
|
||||
column: 0,
|
||||
}).source,
|
||||
).toBe(`file:///${expectedSource}`);
|
||||
const { graph } = await analyzeJavaScriptDirectory(surface, cli, root);
|
||||
const digest = (text: string) =>
|
||||
createHash("sha256").update(text).digest("hex");
|
||||
for (const [name, mapPath, content] of [
|
||||
["unembedded.ts", "absent.js.map", null],
|
||||
["original.ts", "mixed.js.map", original],
|
||||
expect(
|
||||
graph.nodes.filter(
|
||||
(node) => node.identity.strategy === "source-map-original",
|
||||
),
|
||||
).toHaveLength(3);
|
||||
for (const [name, mapPath, content, sourceIndex] of [
|
||||
["unembedded.ts", "absent.js.map", null, 0],
|
||||
["original.ts", "mixed.js.map", original, 1],
|
||||
["original.ts", "unnamed-empty.js.map", original, 1],
|
||||
] as const) {
|
||||
const mapDigest = digest(maps[mapPath]);
|
||||
expect(graph.nodes).toContainEqual(
|
||||
@@ -117,6 +144,9 @@ cliTest.for(["CLI", "stdio MCP"] as const)(
|
||||
map_path: mapPath,
|
||||
}),
|
||||
properties: expect.objectContaining({
|
||||
source_index: sourceIndex,
|
||||
declaration_index: sourceIndex,
|
||||
source_name_available: true,
|
||||
content_available: content !== null,
|
||||
}),
|
||||
evidence: expect.objectContaining({
|
||||
@@ -127,27 +157,77 @@ cliTest.for(["CLI", "stdio MCP"] as const)(
|
||||
}),
|
||||
);
|
||||
}
|
||||
for (const [mapPath, content] of [
|
||||
["mixed.js.map", unnamed],
|
||||
["unnamed-empty.js.map", null],
|
||||
] as const)
|
||||
expect(graph.nodes).toContainEqual(
|
||||
expect.objectContaining({
|
||||
kind: "unknown",
|
||||
observations: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
source_map_reference: null,
|
||||
properties: expect.objectContaining({
|
||||
source_index: 0,
|
||||
declaration_index: 0,
|
||||
source_name_available: false,
|
||||
content_available: content !== null,
|
||||
content_sha256: content === null ? null : digest(content),
|
||||
}),
|
||||
evidence: expect.objectContaining({
|
||||
artifact: expect.objectContaining({
|
||||
sha256: digest(maps[mapPath]),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
);
|
||||
expect(graph.coverage.status).toBe("complete");
|
||||
for (const [path, text] of Object.entries(maps))
|
||||
expect(await readFile(join(root, path), "utf8")).toBe(text);
|
||||
},
|
||||
);
|
||||
|
||||
cliTest.for(["CLI", "stdio MCP"] as const)(
|
||||
"rejects non-string source-map names without inventing originals through %s",
|
||||
async (surface, { cli }) => {
|
||||
const root = await createTestTempDirectory("rea-invalid-map-source-");
|
||||
const mapText = JSON.stringify({
|
||||
version: 3,
|
||||
sources: [42, "discarded.ts"],
|
||||
sourcesContent: [null, "export const answer: number = 42;"],
|
||||
names: [],
|
||||
mappings: "ACAA",
|
||||
});
|
||||
await writeFixtureFiles(root, { "invalid.js.map": mapText });
|
||||
const { graph } = await analyzeJavaScriptDirectory(surface, cli, root);
|
||||
expect(graph.coverage.status).toBe("partial");
|
||||
expect(
|
||||
graph.nodes.some(
|
||||
(node) => node.identity.strategy === "source-map-original",
|
||||
),
|
||||
).toBe(false);
|
||||
expect(graph.nodes).toContainEqual(
|
||||
expect.objectContaining({
|
||||
kind: "unknown",
|
||||
observations: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
properties: expect.objectContaining({
|
||||
source_name_available: false,
|
||||
content_available: true,
|
||||
content_sha256: digest(unnamed),
|
||||
operation: "parse-local-source-map",
|
||||
}),
|
||||
evidence: expect.objectContaining({
|
||||
artifact: expect.objectContaining({
|
||||
sha256: digest(maps["mixed.js.map"]),
|
||||
sha256: createHash("sha256").update(mapText).digest("hex"),
|
||||
}),
|
||||
limitations: expect.arrayContaining([
|
||||
"Source map contains a non-string source name.",
|
||||
]),
|
||||
}),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
);
|
||||
expect(graph.coverage.status).toBe("complete");
|
||||
for (const [path, text] of Object.entries(maps))
|
||||
expect(await readFile(join(root, path), "utf8")).toBe(text);
|
||||
expect(await readFile(join(root, "invalid.js.map"), "utf8")).toBe(mapText);
|
||||
},
|
||||
);
|
||||
@@ -136,7 +136,6 @@ it.each([
|
||||
["a non-array sourcesContent value", { sourcesContent: "source" }],
|
||||
["a non-string, non-null source entry", { sourcesContent: [42] }],
|
||||
["a source-content array with the wrong length", { sourcesContent: [] }],
|
||||
["a non-string source name", { sources: [42] }],
|
||||
])(
|
||||
"reports %s as an invalid local source map",
|
||||
async (_description, content) => {
|
||||
|
||||
Reference in new issue
Block a user