mirror of
https://github.com/morluto/rea.git
synced 2026-11-11 17:28:08 +00:00
fix(web): preserve exact module imports and capture coverage (#9940)
This commit is contained in:
1 parent
19f7eef513
commit
a2aea3f4c6
4 files changed
+60
-7
No files matched your search
@@ -2123,6 +2123,32 @@ it("keeps known capture omissions in compact route summaries and queryable gap f
|
||||
expect(row).toMatchObject({ source_id: null, provenance: null });
|
||||
});
|
||||
|
||||
it.each(
|
||||
(["scripts", "script_sources"] as const).flatMap((section) =>
|
||||
[0, 1, null].map((count) => ({ section, count })),
|
||||
),
|
||||
)(
|
||||
"preserves actual capture omission coverage for $section count $count",
|
||||
({ section, count }) => {
|
||||
const captured = inspection("export {};");
|
||||
captured.completeness.excluded.push({
|
||||
section,
|
||||
reason: "resource_budget_exhausted",
|
||||
count,
|
||||
});
|
||||
const result = analyzeWebBundleFixture(captured);
|
||||
expect(result.completeness.status).toBe(
|
||||
count === 0 ? "complete" : "partial",
|
||||
);
|
||||
expect(result.unknowns).toHaveLength(count === 0 ? 0 : 1);
|
||||
expect(
|
||||
result.route_inventory?.unknowns.filter(
|
||||
({ kind }) => kind === "capture-omission",
|
||||
),
|
||||
).toHaveLength(count === 0 ? 0 : 1);
|
||||
},
|
||||
);
|
||||
|
||||
it("retains captured Next script identity while deriving decoded route patterns", () => {
|
||||
const url = `${origin}/base/_next/static/chunks/app/%28shop%29/blog/%5Bid%5D/page-abc.js`;
|
||||
const captured = createWebPageInspection([
|
||||
|
||||
@@ -385,7 +385,8 @@ const captureBudgetOmission = (
|
||||
const exclusions = inspection.completeness.excluded.filter(
|
||||
(exclusion) =>
|
||||
exclusion.section === section &&
|
||||
exclusion.reason === "resource_budget_exhausted",
|
||||
exclusion.reason === "resource_budget_exhausted" &&
|
||||
exclusion.count !== 0,
|
||||
);
|
||||
if (exclusions.length === 0) return undefined;
|
||||
if (exclusions.some(({ count }) => count === null)) return null;
|
||||
|
||||
@@ -63,6 +63,34 @@ describe("native module syntax observations", () => {
|
||||
column: 7,
|
||||
});
|
||||
});
|
||||
it.each([
|
||||
['"./dep.js" as const', "./dep.js"],
|
||||
['"./dep.js" satisfies string', "./dep.js"],
|
||||
['"./dep.js"!', "./dep.js"],
|
||||
["`./dep.js` as const", "./dep.js"],
|
||||
["`./${name}.js` as const", null],
|
||||
] as const)(
|
||||
"retains exact import identity through erased syntax: %s",
|
||||
(expression, specifier) => {
|
||||
const source = `import(${expression});`;
|
||||
const result = collectWebModuleImports(source, "main.ts");
|
||||
expect(result.state).toBe("parsed");
|
||||
expect(result.diagnostics).toEqual([]);
|
||||
expect(result.imports).toEqual([
|
||||
{
|
||||
kind: "dynamic-import",
|
||||
specifier,
|
||||
expression,
|
||||
start: { offset: 7, line: 1, column: 7 },
|
||||
end: {
|
||||
offset: 7 + expression.length,
|
||||
line: 1,
|
||||
column: 7 + expression.length,
|
||||
},
|
||||
},
|
||||
]);
|
||||
},
|
||||
);
|
||||
it("reports unparseable input without asserting an empty complete graph", () => {
|
||||
const result = collectWebModuleImports(
|
||||
'import "./ok.js"; function {',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { isStringLiteral, isTemplateLiteral } from "@babel/types";
|
||||
import type { Node } from "@babel/types";
|
||||
import { readExactJavaScriptLiteral } from "./javascript/javascriptAstValues.js";
|
||||
import { traverseJavaScriptAst } from "./javascript/javascriptSemanticTraversal.js";
|
||||
import { parseJavaScriptSource } from "./javascript/javascriptSourceParser.js";
|
||||
import type { WebModuleImport } from "./webModuleTrace.js";
|
||||
@@ -36,11 +36,9 @@ export const collectWebModuleImports = (
|
||||
expression.loc === undefined
|
||||
)
|
||||
return;
|
||||
const specifier = isStringLiteral(expression)
|
||||
? expression.value
|
||||
: isTemplateLiteral(expression) && expression.expressions.length === 0
|
||||
? (expression.quasis[0]?.value.cooked ?? null)
|
||||
: null;
|
||||
const literal = readExactJavaScriptLiteral(expression);
|
||||
const specifier =
|
||||
literal.found && typeof literal.value === "string" ? literal.value : null;
|
||||
imports.push({
|
||||
kind,
|
||||
specifier,
|
||||
|
||||
Reference in new issue
Block a user