test(javascript): consolidate source analysis and export regressions

This commit is contained in:
morluto committed 2026-10-08 04:03:23 +08:00
1 parent c93422a898
commit f517a5a1d7
18 files changed
+354 -853

No files matched your search

@@ -2,156 +2,46 @@ import { describe, expect, it } from "vitest";
import { analyzeJavaScriptStaticSource } from "./javascriptStaticAnalysis.js";
describe.each(["webPreferences", "serviceName"] as const)(
"Electron %s option lookup",
(name) => {
const value =
name === "webPreferences"
? '{ preload: "./kept.js", sandbox: true }'
: '"kept"';
const explicit = `${name}: ${value}`;
const method = `${name}() { return ${value}; }`;
const getter = `get ${name}() { return ${value}; }`;
const setter = `set ${name}(value) {}`;
describe("Electron option evidence", () => {
it("keeps the final explicit preload and service name with unrelated keys", () => {
const analysis = analyzeJavaScriptStaticSource(`
new BrowserWindow({ webPreferences: { preload: "./kept.js", sandbox: true }, title: "App" });
utilityProcess.fork("./worker.js", [], { serviceName: "kept", cwd: "/app" });
`);
const explicitCases = [
["plain key", explicit],
["quoted key", `"${name}": ${value}`],
["computed string key", `["${name}"]: ${value}`],
["duplicate key", `${name}: null, ${explicit}`],
["computed duplicate key", `${name}: null, ["${name}"]: ${value}`],
["earlier spread", `...options, ${explicit}`],
["earlier computed identifier", `[key]: null, ${explicit}`],
["earlier computed expression", `[getKey()]: null, ${explicit}`],
["earlier getter", `${getter}, ${explicit}`],
["earlier method", `${method}, ${explicit}`],
["unrelated later key", `${explicit}, title: "title"`],
["unrelated computed literal", `${explicit}, ["title"]: null`],
["unrelated numeric key", `${explicit}, [1]: null`],
["unrelated empty key", `${explicit}, [""]: null`],
["unrelated getter", `${explicit}, get title() { return "title"; }`],
];
it.each(explicitCases)(
"retains the explicit value with %s",
(_, members) => {
const analysis = analyzeOption(name, `{ ${members} }`);
expect(analysis.parse_status).toBe("complete");
if (name === "webPreferences") {
expect(analysis.electron.browser_windows).toEqual([
expect.objectContaining({
options_status: "object-literal",
web_preferences_status: "object-literal",
preload_path: "./kept.js",
preload_resolution_context: "module-specifier",
web_preferences: [
{ name: "preload", value: literal("./kept.js") },
{ name: "sandbox", value: literal(true) },
],
}),
]);
} else {
expect(analysis.electron.utility_processes).toEqual([
expect.objectContaining({ service_name: "kept" }),
]);
}
},
);
const dynamicCases = [
["same-spelled computed binding", `[${name}]: ${value}`],
["different computed binding", `[key]: ${value}`],
["computed expression", `[getKey()]: ${value}`],
["unevaluated template key", `[\`${name}\`]: ${value}`],
["spread only", "...options"],
["later spread", `${explicit}, ...options`],
["later computed binding", `${explicit}, [key]: null`],
["later computed expression", `${explicit}, [getKey()]: null`],
["exact getter", getter],
["exact setter", setter],
["exact method", method],
["computed string method", `["${name}"]() { return ${value}; }`],
["overriding getter", `${explicit}, ${getter}`],
["overriding setter", `${explicit}, ${setter}`],
["overriding method", `${explicit}, ${method}`],
["dynamic explicit value", `${name}: dynamicValue`],
["null explicit value", `${name}: null`],
["duplicate null value", `${explicit}, ${name}: null`],
];
it.each(dynamicCases)("preserves uncertainty for %s", (_, members) => {
expectUnknownOption(name, `{ ${members} }`, "object-literal");
});
it.each(["null", "options"])(
"preserves nonliteral options %s",
(options) => {
expectUnknownOption(name, options, "dynamic");
},
);
it.each(["", "{}", '{ title: "title", ["other"]: null }'])(
"reports an omitted option in %s without inventing a default",
(options) => {
const analysis = analyzeOption(name, options);
expect(analysis.parse_status).toBe("complete");
if (name === "webPreferences")
expect(analysis.electron.browser_windows[0]).toMatchObject({
options_status: options === "" ? "missing" : "object-literal",
web_preferences_status: "missing",
web_preferences: [],
preload_path: null,
preload_resolution_context: null,
});
else
expect(
analysis.electron.utility_processes[0]?.service_name,
).toBeNull();
},
);
},
);
type OptionName = "webPreferences" | "serviceName";
const analyzeOption = (name: OptionName, options: string) =>
analyzeJavaScriptStaticSource(`
const webPreferences = "title";
const serviceName = "env";
${
name === "webPreferences"
? `new BrowserWindow(${options});`
: `utilityProcess.fork("./worker.js", []${options === "" ? "" : `, ${options}`});`
}
`);
const literal = (value: string | boolean) => ({
status: "literal",
value,
expression: null,
});
const expectUnknownOption = (
name: OptionName,
options: string,
optionsStatus: "object-literal" | "dynamic",
): void => {
const analysis = analyzeOption(name, options);
expect(analysis.parse_status).toBe("partial");
expect(analysis.parse_error_count).toBe(0);
expect(analysis.limitations.join(" ")).toContain("remain unknown");
if (name === "webPreferences")
expect(analysis.parse_status).toBe("complete");
expect(analysis.electron.browser_windows[0]).toMatchObject({
options_status: optionsStatus,
web_preferences_status: "dynamic",
web_preferences: [],
preload_path: null,
preload_resolution_context: null,
preload_path: "./kept.js",
preload_resolution_context: "module-specifier",
web_preferences: [
{ name: "preload", value: { status: "literal", value: "./kept.js" } },
{ name: "sandbox", value: { status: "literal", value: true } },
],
});
expect(analysis.electron.utility_processes[0]).toMatchObject({
module_path: "./worker.js",
service_name: "kept",
});
});
it("keeps values unknown when a later computed key can override them", () => {
const analysis = analyzeJavaScriptStaticSource(`
new BrowserWindow({ webPreferences: { preload: "./maybe.js" }, [key]: null });
utilityProcess.fork("./worker.js", [], { serviceName: "maybe", [key]: null });
`);
expect(analysis.parse_status).toBe("partial");
expect(analysis.parse_error_count).toBe(0);
expect(analysis.limitations.join(" ")).toContain("remain unknown");
expect(analysis.electron.browser_windows[0]).toMatchObject({
preload_path: null,
preload_resolution_context: null,
web_preferences_status: "dynamic",
web_preferences: [],
});
else
expect(analysis.electron.utility_processes[0]).toMatchObject({
module_path: "./worker.js",
module_expression: null,
service_name: null,
});
};
});
});
@@ -1,9 +1,6 @@
import { expect, it } from "vitest";
import {
javaScriptExportShapeComparisonResultSchema,
projectedExportReturnShapesSchema,
} from "./javascriptExportShapeComparisonSchemas.js";
import { projectedExportReturnShapesSchema } from "./javascriptExportShapeComparisonSchemas.js";
const projectionWithField = (field: unknown) => ({
semantic_role: "export-return-shapes",
@@ -54,104 +51,3 @@ it("parses projected fields into literal, union, or unknown values", () => {
).success,
).toBe(true);
});
it("accepts every projected return site and field without presentation caps", () => {
const fields = Array.from({ length: 65 }, (_, index) => ({
path: `/field-${String(index)}`,
state: "literal",
value: index,
reason: null,
}));
const propertyCoverage = fields.map(({ path }) => ({
path,
status: "complete",
omitted: 0,
}));
const shapes = Array.from({ length: 33 }, () => ({
source_range: {
start: { line: 1, column: 0 },
end: { line: 1, column: 10 },
},
value_status: "object",
fields,
property_coverage: propertyCoverage,
}));
expect(
projectedExportReturnShapesSchema.parse({
...projectionWithField(fields[0]),
static_return_shapes: shapes,
return_shape_coverage: {
status: "complete",
retained_return_sites: shapes.length,
omitted_return_sites: 0,
omitted_fields: 0,
omitted_property_coverage: 0,
projection_complete: true,
},
}).static_return_shapes,
).toHaveLength(33);
});
it("accepts complete candidate and change inventories without page ceilings", () => {
const evidenceId = `ev_${"a".repeat(64)}`;
const graphId = `jag_${"b".repeat(64)}`;
const selector = {
evidence_id: evidenceId,
graph_id: graphId,
requested_module_path: "index.js",
requested_export_name: "render",
candidates: Array.from({ length: 1_001 }, (_, index) => ({
node_id: `jag_node_${index.toString(16).padStart(64, "0")}`,
module_path: "index.js",
export_name: "render",
matches_requested_module: true,
matches_requested_export: true,
})),
omitted_candidates: 0,
status: "missing",
selected_node_id: null,
};
const changes = Array.from({ length: 10_001 }, (_, index) => ({
change_id: `jesc_change_${index.toString(16).padStart(64, "0")}`,
status: "unknown",
path: `/field-${String(index)}`,
discriminant: null,
left: { availability: "absent" },
right: { availability: "absent" },
left_source_range: null,
right_source_range: null,
evidence_links: [evidenceId, `ev_${"c".repeat(64)}`],
limitations: [],
}));
expect(
javaScriptExportShapeComparisonResultSchema.parse({
comparison_id: `jesc_${"d".repeat(64)}`,
left: selector,
right: { ...selector, graph_id: `jag_${"e".repeat(64)}` },
summary: { added: 0, removed: 0, changed: 0, unknown: changes.length },
changes,
coverage: {
status: "complete-within-inputs",
left_graph_status: "complete",
right_graph_status: "complete",
paired_variants: 0,
unpaired_left_variants: 0,
unpaired_right_variants: 0,
omitted_left_variants: 0,
omitted_right_variants: 0,
left_source_omitted_variants: 0,
right_source_omitted_variants: 0,
left_omitted_fields: 0,
right_omitted_fields: 0,
left_omitted_property_coverage: 0,
right_omitted_property_coverage: 0,
omitted_candidates: 0,
omitted_changes: 0,
},
evidence_links: [evidenceId, `ev_${"c".repeat(64)}`],
limitations: [],
}).changes,
).toHaveLength(10_001);
});
@@ -253,56 +253,58 @@ describe("feature seed selection controls", () => {
});
describe("public feature trace from contextBridge source members", () => {
it.each(matchingModes)(
"traces $match / $value / case-sensitive $case_sensitive",
(mode) => {
const graph = contextBridgeGraph();
const before = structuredClone(graph);
const input = {
sourceEvidenceId,
graph,
nativeEvidence: [],
direction: "both" as const,
};
const generic = traceApplicationFeature({
...input,
seed: { kind: "string", ...mode },
});
const typed = traceApplicationFeature({
...input,
seed: { kind: "api", ...mode },
});
it("traces one exact member seed through the public feature workflow", () => {
const mode = {
value: "openProject",
match: "exact" as const,
case_sensitive: true,
};
const graph = contextBridgeGraph();
const before = structuredClone(graph);
const input = {
sourceEvidenceId,
graph,
nativeEvidence: [],
direction: "both" as const,
};
const generic = traceApplicationFeature({
...input,
seed: { kind: "string", ...mode },
});
const typed = traceApplicationFeature({
...input,
seed: { kind: "api", ...mode },
});
expect(typed.coverage).toEqual({
status: "complete-within-source",
source_graph_status: "complete",
total_seed_matches: 1,
});
expect(typed.seed_matches).toEqual(generic.seed_matches);
expect(typed.seed_matches).toEqual([
{
node_id: graph.nodes[0]?.node_id,
kind: "context-bridge-api",
basis: "property",
field: "observations[0].properties.members[1]",
},
]);
expect(typed.graph?.nodes).toEqual(graph.nodes);
expect(typed.graph?.edges).toEqual([]);
expect(typed.evidence_links).toEqual([sourceEvidenceId]);
expect(typed.summary).toMatchObject({
matched_seeds: 1,
traced_nodes: 1,
traced_edges: 0,
observed_facts: 1,
inferred_facts: 0,
unknown_facts: 0,
unavailable_facts: 0,
});
expect(typed.native_handoffs).toEqual([]);
expect(graph).toEqual(before);
},
);
expect(typed.coverage).toEqual({
status: "complete-within-source",
source_graph_status: "complete",
total_seed_matches: 1,
});
expect(typed.seed_matches).toEqual(generic.seed_matches);
expect(typed.seed_matches).toEqual([
{
node_id: graph.nodes[0]?.node_id,
kind: "context-bridge-api",
basis: "property",
field: "observations[0].properties.members[1]",
},
]);
expect(typed.graph?.nodes).toEqual(graph.nodes);
expect(typed.graph?.edges).toEqual([]);
expect(typed.evidence_links).toEqual([sourceEvidenceId]);
expect(typed.summary).toMatchObject({
matched_seeds: 1,
traced_nodes: 1,
traced_edges: 0,
observed_facts: 1,
inferred_facts: 0,
unknown_facts: 0,
unavailable_facts: 0,
});
expect(typed.native_handoffs).toEqual([]);
expect(graph).toEqual(before);
});
it("keeps a missing member explicit without changing source coverage", () => {
const graph = contextBridgeGraph();
@@ -2,19 +2,6 @@ import { describe, expect, it } from "vitest";
import { javascriptRecoveryInputSchema } from "./javascriptRecovery.js";
describe("JavaScript recovery requests", () => {
it("defaults omitted transform metadata without requiring engine confirmations", () => {
expect(
javascriptRecoveryInputSchema.parse({
path: "/tmp/bundle.js",
output_directory: "/tmp/recovered",
}),
).toEqual({
path: "/tmp/bundle.js",
output_directory: "/tmp/recovered",
extraction_mode: "structural",
rewrite_level: "standard",
});
});
it.each([
{ path: "", output_directory: "/tmp/recovered" },
{ path: "/tmp/bundle.js" },
@@ -1,39 +1,15 @@
import { expect, it } from "vitest";
import { analyzeJavaScriptSemantics } from "./javascriptSemanticAnalysis.js";
it.each(["namespace", "default", "named-default"])(
"retains Node built-in effects from %s imports",
(mode) => {
const imports = ["fs", "child_process", "timers", "http"]
.map((name, index) => {
const declaration =
mode === "namespace"
? `* as m${String(index)}`
: mode === "default"
? `m${String(index)}`
: `{default as m${String(index)}}`;
return `import ${declaration} from 'node:${name}';`;
})
.join("\n");
const ir = analyzeJavaScriptSemantics(`${imports}
const text = m0.readFileSync('config.json','utf8');
const stream = m0.createReadStream('config.json'); stream.destroy();
const child = m1.spawn('/usr/bin/tool', ['--version']);
const timer = m2.setTimeout(work,1000); m2.clearTimeout(timer);
const request = m3.get('http://localhost/');
it("does not assign built-in APIs to unrelated or shadowed bindings", () => {
const ir = analyzeJavaScriptSemantics(`
import fs from "./fs.js";
import { constants as constantsFs } from "node:fs";
fs.createReadStream("config.json");
constantsFs.createReadStream("config.json");
function run(fs) { fs.createReadStream("config.json"); }
`);
expect(ir.configurationOperations).toHaveLength(1);
expect(ir.resourceOperations).toHaveLength(2);
expect(ir.childProcessSpawns).toHaveLength(1);
expect(ir.timerOperations).toHaveLength(2);
expect(ir.requestOperations).toHaveLength(1);
},
);
it.each([
"import fs from './fs.js'; fs.createReadStream('config.json');",
"import {constants as fs} from 'node:fs'; fs.createReadStream('config.json');",
"function run(fs) { fs.createReadStream('config.json'); }",
])("does not invent a built-in namespace for %s", (source) => {
expect(analyzeJavaScriptSemantics(source).resourceOperations).toEqual([]);
expect(ir.resourceOperations).toEqual([]);
});
@@ -155,19 +155,6 @@ describe("JavaScript semantic analysis: calls 2", () => {
]);
});
it("retains every promise operation found in the finite source", () => {
const ir = analyzeJavaScriptSemantics(
`
Promise.resolve(1);
Promise.resolve(2);
Promise.resolve(3);
`,
);
expect(ir.promiseOperations).toHaveLength(3);
expect(ir.coverage.status).toBe("complete");
});
it("fingerprints formatting and local-name changes identically", () => {
const left = analyzeJavaScriptSemantics(`
function calculate(value) {
@@ -1,67 +1,43 @@
import * as t from "@babel/types";
import { expect, it } from "vitest";
import { analyzeJavaScriptSemantics } from "./javascriptSemanticAnalysis.js";
import {
analyzeJavaScriptSemantics,
analyzeParsedJavaScriptSemantics,
} from "./javascriptSemanticAnalysis.js";
import { onlyBinding, origin } from "./javascriptSemanticAnalysis.fixture.js";
import { parseJavaScriptSource } from "./javascriptSourceParser.js";
import { calleeName } from "./javascriptStaticAnalysisHelpers.js";
import { analyzeJavaScriptStaticSource } from "./javascriptStaticAnalysis.js";
import { analyzeParsedJavaScriptStaticSource } from "./javascriptStaticAnalysis.js";
const memberChain = ".next".repeat(12_000);
const ordinaryMemberChain = ".next".repeat(64);
it("retains native addon observations through a deep member initializer", () => {
const analysis = analyzeJavaScriptStaticSource(
`const value = require("./addon.node")${memberChain}.last[""];`,
it("preserves a 12,000-member native import through both analyzers", () => {
const parsed = parseJavaScriptSource(
`const value = require("./addon.node")${memberChain}.last; const ordinary = root.next.last;`,
);
expect(analysis.electron.native_addon_bindings).toEqual([
if (parsed === null) throw new Error("Expected valid JavaScript");
const staticAnalysis = analyzeParsedJavaScriptStaticSource("", parsed);
const ir = analyzeParsedJavaScriptSemantics(parsed);
expect(staticAnalysis.parse_status).toBe("complete");
expect(staticAnalysis.electron.native_addon_bindings).toEqual([
expect.objectContaining({ specifier: "./addon.node", members: ["last"] }),
]);
expect(analysis.parse_error_count).toBe(0);
});
it("keeps a deep non-native initializer outside native addon observations", () => {
const analysis = analyzeJavaScriptStaticSource(
`const value = root${memberChain}.last;`,
);
expect(analysis.electron.native_addon_bindings).toEqual([]);
expect(analysis.parse_status).toBe("complete");
});
it("retains unknown value diagnostics and references after a deep member initializer", () => {
const ir = analyzeJavaScriptSemantics(
`const value = root${memberChain}.last;`,
);
expect(ir.coverage).toEqual({ status: "complete", omittedCount: 0 });
expect(onlyBinding(ir, "value")).toMatchObject({
value: { status: "unknown", reason: "Cannot project last from unknown." },
provenance: { status: "unknown", reason: "Unbound identifier root." },
});
expect(ir.references.map(({ name, role }) => ({ name, role }))).toEqual([
{ name: "root", role: "read" },
]);
});
it.each([
`const value = require("./dependency.js")${memberChain}[""].last;`,
`const dependency = require("./dependency.js"); const value = dependency${memberChain}[""].last;`,
`const value = require("./dependency.js")?.next${memberChain}[""].last;`,
])("preserves the full literal module path (case %#)", (source) => {
const ir = analyzeJavaScriptSemantics(source);
const path = origin(onlyBinding(ir, "value"));
expect(path.specifier).toBe("./dependency.js");
expect(path.specifier).toBe("./addon.node");
expect(path.importedPath).toEqual([
...(source.includes("?.next") ? ["next"] : []),
...Array.from({ length: 12_000 }, () => "next"),
"",
"last",
]);
expect(ir.coverage.status).toBe("complete");
});
it("retains a deep CommonJS re-export path without inventing dynamic module links", () => {
const ir = analyzeJavaScriptSemantics(`
module.exports.result = require("./dependency.js")${memberChain}.last;
const dynamic = require("./other.js")${memberChain}[key].last;
module.exports.result = require("./dependency.js")${ordinaryMemberChain}.last;
const dynamic = require("./other.js")${ordinaryMemberChain}[key].last;
`);
expect(ir.moduleLinks).toEqual([
expect.objectContaining({
@@ -80,7 +56,7 @@ it("retains a deep CommonJS re-export path without inventing dynamic module link
it("invalidates a deep mutation while retaining unrelated literal properties", () => {
const ir = analyzeJavaScriptSemantics(`
const root = { untouched: "retained" };
root${memberChain}.last = 1;
root${ordinaryMemberChain}.last = 1;
const value = root.untouched;
`);
expect(onlyBinding(ir, "root").value).toEqual({
@@ -98,7 +74,7 @@ it("invalidates a deep mutation while retaining unrelated literal properties", (
});
it("retains the complete location and unresolved target of a deep call", () => {
const callee = `root${memberChain}.last`;
const callee = `root${ordinaryMemberChain}.last`;
const ir = analyzeJavaScriptSemantics(`${callee}();`);
expect(ir.callSites).toEqual([
expect.objectContaining({
@@ -115,7 +91,7 @@ it("retains the complete location and unresolved target of a deep call", () => {
it("retains deep default values without confusing their reads with parameter bindings", () => {
const ir = analyzeJavaScriptSemantics(
`export function inspect(value = root${memberChain}.last) { return value; }`,
`export function inspect(value = root${ordinaryMemberChain}.last) { return value; }`,
);
expect(ir.references.map(({ name, role }) => ({ name, role }))).toEqual([
{ name: "root", role: "read" },
@@ -126,7 +102,7 @@ it("retains deep default values without confusing their reads with parameter bin
it("keeps a shadowed require local through a deep member initializer", () => {
const ir = analyzeJavaScriptSemantics(
`function inspect(require) { const value = require("./dependency.js")${memberChain}.last; return value; }`,
`function inspect(require) { const value = require("./dependency.js")${ordinaryMemberChain}.last; return value; }`,
);
expect(ir.moduleLinks).toEqual([]);
expect(onlyBinding(ir, "value").provenance.origins).toEqual([]);
@@ -140,7 +116,7 @@ it.each([
["root[0].last()", "root.0.last"],
["root[key].last()", "root.[computed@5].last"],
["root?.first.last()", "root.first.last"],
[`root${memberChain}.last()`, `root${memberChain}.last`],
[`root${ordinaryMemberChain}.last()`, `root${ordinaryMemberChain}.last`],
])("preserves exact callee syntax (case %#)", (source, expected) => {
const file = parseJavaScriptSource(source);
const statement = file?.program.body[0];
@@ -18,6 +18,19 @@ const valueOf = (expression: string) =>
analyzeJavaScriptSemantics(`const answer = ${expression};`),
"answer",
).value;
const valuesOf = (expressions: readonly string[]) => {
const ir = analyzeJavaScriptSemantics(
expressions
.map(
(expression, index) =>
`const candidate${String(index)} = ${expression};`,
)
.join("\n"),
);
return expressions.map(
(_, index) => topLevelBinding(ir, `candidate${String(index)}`).value,
);
};
describe("conditional primitive unions", () => {
const cases = conditionalCandidates.flatMap((known) =>
@@ -35,11 +48,11 @@ describe("conditional primitive unions", () => {
]),
);
it.each(cases)("preserves incompatible alternatives in %s", (expression) => {
expect(valueOf(expression)).toEqual(incompatibleValue);
it("preserves incompatible alternatives across conditional expressions", () => {
expect(valuesOf(cases)).toEqual(cases.map(() => incompatibleValue));
});
it.each([
const exactCases = [
[
'condition ? (choice ? "two" : "one") : "three"',
{ status: "union", values: ["one", "three", "two"] },
@@ -69,8 +82,12 @@ describe("conditional primitive unions", () => {
{ status: "union", values: [null, "one", "two"] },
],
["condition ? null : null", { status: "literal", value: null }],
])("retains exact primitive candidates in %s", (expression, expected) => {
expect(valueOf(expression)).toEqual(expected);
] as const;
it("retains exact primitive candidates across conditional expressions", () => {
expect(valuesOf(exactCases.map(([expression]) => expression))).toEqual(
exactCases.map(([, expected]) => expected),
);
});
it("propagates an incompatible nested branch through an outer union", () => {
@@ -119,11 +136,11 @@ describe("logical primitive unions", () => {
),
);
it.each(cases)("preserves unresolved alternatives in %s", (expression) => {
expect(valueOf(expression)).toEqual(incompatibleValue);
it("preserves unresolved alternatives across logical expressions", () => {
expect(valuesOf(cases)).toEqual(cases.map(() => incompatibleValue));
});
it.each([
const exactCases = [
[
'(choice ? "" : "one") || "two"',
{ status: "union", values: ["", "one", "two"] },
@@ -138,19 +155,24 @@ describe("logical primitive unions", () => {
],
['"one" || "one"', { status: "literal", value: "one" }],
["null ?? null", { status: "literal", value: null }],
])(
"retains the conservative primitive union in %s",
(expression, expected) => {
expect(valueOf(expression)).toEqual(expected);
},
);
] as const;
it.each([
it("retains conservative primitive unions across logical expressions", () => {
expect(valuesOf(exactCases.map(([expression]) => expression))).toEqual(
exactCases.map(([, expected]) => expected),
);
});
const unevaluatedCases = [
'true ? "one" : missing',
'"one" || missing',
"false && missing",
'"one" ?? missing',
])("does not introduce short-circuit evaluation for %s", (expression) => {
expect(valueOf(expression)).toEqual(incompatibleValue);
];
it("does not introduce short-circuit evaluation", () => {
expect(valuesOf(unevaluatedCases)).toEqual(
unevaluatedCases.map(() => incompatibleValue),
);
});
});
@@ -1,28 +1,8 @@
import { expect, it } from "vitest";
import {
javaScriptSemanticQueryInputSchema,
javaScriptSemanticQueryResultSchema,
} from "./javascriptSemanticQuerySchemas.js";
import { javaScriptSemanticQueryInputSchema } from "./javascriptSemanticQuerySchemas.js";
it("accepts long selectors and complete relation and class selections", () => {
const longText = "x".repeat(16_385);
const result = javaScriptSemanticQueryInputSchema.parse({
seed: { kind: "endpoint", value: longText },
direction: "forward-influence",
allowed_relations: Array(2).fill("calls"),
expected: {
role: "sink",
classes: Array(25).fill("module"),
},
});
expect(result.seed).toEqual({ kind: "endpoint", value: longText });
expect(result.allowed_relations).toHaveLength(2);
expect(result.expected?.classes).toHaveLength(25);
});
it("rejects the inert source-map authority setting", () => {
it("rejects a source-map authority setting that the query does not consume", () => {
expect(
javaScriptSemanticQueryInputSchema.safeParse({
seed: { kind: "endpoint", value: "/api" },
@@ -31,36 +11,3 @@ it("rejects the inert source-map authority setting", () => {
}).success,
).toBe(false);
});
it("accepts every reported limitation without a count ceiling", () => {
const limitations = Array.from(
{ length: 1_001 },
(_, index) => `gap-${index}`,
);
const id = "a".repeat(64);
const result = javaScriptSemanticQueryResultSchema.parse({
query_id: `jsrq_${id}`,
source_graph_id: `jsrg_${id}`,
seed: { kind: "literal", value: null },
direction: "forward-influence",
status: "no-match",
seed_node_ids: [],
nodes: [],
relations: [],
unknowns: [],
expected_match_node_ids: [],
summary: {
total_seed_matches: 0,
traversed_nodes: 0,
traversed_relations: 0,
traversed_functions: 0,
traversed_modules: 0,
relevant_unknowns: 0,
},
coverage: { status: "complete" },
limitations,
});
expect(result.limitations).toHaveLength(1_001);
});
@@ -1,66 +0,0 @@
import * as t from "@babel/types";
import { expect, it } from "vitest";
import { parseJavaScriptSource } from "./javascriptSourceParser.js";
import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js";
it("preserves source-tree enter/exit order and detached ancestor snapshots", () => {
const parsed = parseJavaScriptSource("const answer = first + second;");
if (parsed === null)
throw new TypeError("Expected a parsed JavaScript fixture");
const visits: string[] = [];
const snapshots: (readonly t.Node[])[] = [];
traverseJavaScriptAst(parsed.program, {
enter: (node, parent, readAncestors) => {
visits.push(`enter:${node.type}`);
const ancestors = readAncestors();
expect(ancestors.at(-1) ?? null).toBe(parent);
if (t.isIdentifier(node)) snapshots.push(ancestors);
},
exit: (node) => visits.push(`exit:${node.type}`),
});
expect(visits).toEqual([
"enter:Program",
"enter:VariableDeclaration",
"enter:VariableDeclarator",
"enter:Identifier",
"exit:Identifier",
"enter:BinaryExpression",
"enter:Identifier",
"exit:Identifier",
"enter:Identifier",
"exit:Identifier",
"exit:BinaryExpression",
"exit:VariableDeclarator",
"exit:VariableDeclaration",
"exit:Program",
]);
expect(snapshots.map((nodes) => nodes.map(({ type }) => type))).toEqual([
["Program", "VariableDeclaration", "VariableDeclarator"],
[
"Program",
"VariableDeclaration",
"VariableDeclarator",
"BinaryExpression",
],
[
"Program",
"VariableDeclaration",
"VariableDeclarator",
"BinaryExpression",
],
]);
});
it("skips sparse child slots without disturbing sibling visit order", () => {
const parsed = parseJavaScriptSource("const values = [first, , second];");
if (parsed === null)
throw new TypeError("Expected a parsed JavaScript fixture");
const identifiers: string[] = [];
traverseJavaScriptAst(parsed.program, {
enter: (node) => {
if (t.isIdentifier(node)) identifiers.push(node.name);
},
});
expect(identifiers).toEqual(["values", "first", "second"]);
});
@@ -5,6 +5,7 @@ import { analyzeJavaScriptStaticSource } from "./javascriptStaticAnalysis.js";
import { parseJavaScriptSource } from "./javascriptSourceParser.js";
const memberChain = ".next".repeat(12_000);
const ordinaryMemberChain = ".next".repeat(64);
it("collects a 12,000-member CommonJS export path without recursion", () => {
const file = parseJavaScriptSource(`exports${memberChain}.last = 1;`);
@@ -48,8 +49,8 @@ it("keeps left-first and outer-member-first bundler runtime matches", () => {
).toBe("webpackChunkInner");
});
it("analyzes a 12,000-member bundler runtime chain without recursion", () => {
const source = `globalThis.webpackChunkApp${memberChain}.push([[1], { 1: function(module) { module.exports.ok = 42; } }]);`;
it("recognizes a bundler runtime through nested member names", () => {
const source = `globalThis.webpackChunkApp${ordinaryMemberChain}.push([[1], { 1: function(module) { module.exports.ok = 42; } }]);`;
const analysis = analyzeJavaScriptStaticSource(source);
expect(analysis.parse_status).toBe("complete");
expect(analysis.parse_error_count).toBe(0);
@@ -22,12 +22,6 @@ describe("source map directives", () => {
expect(sourceMapUrls(source)).toEqual([expected]);
});
it("keeps the comment terminator out of the declared url", () => {
expect(sourceMapUrls("/*# sourceMappingURL=app.js.map */")).toEqual([
"app.js.map",
]);
});
it("retains every directive in a source", () => {
expect(
sourceMapUrls(
@@ -84,30 +78,6 @@ describe("source map comment boundaries", () => {
});
describe("source map comment locations and recovery", () => {
it("keeps exact locations and the first occurrence of duplicate URLs", () => {
const line = "//# sourceMappingURL=first.map";
const block = "/*# sourceMappingURL=second.map";
const result = analyzeJavaScriptStaticSource(
['const marker = "😀";', line, `${block} */`, line].join("\r\n"),
);
expect(result.source_map_urls).toEqual([
{
declared_url: "first.map",
location: {
start: { line: 2, column: 0 },
end: { line: 2, column: line.length },
},
},
{
declared_url: "second.map",
location: {
start: { line: 3, column: 0 },
end: { line: 3, column: block.length },
},
},
]);
});
it("keeps real comments when the parser recovers and reports partial syntax", () => {
const result = analyzeJavaScriptStaticSource(
"let value; let value;\n//# sourceMappingURL=recovered.map",