mirror of
https://github.com/morluto/rea.git
synced 2026-11-03 13:26:10 +00:00
refactor(javascript): consolidate semantic graph boundaries
Retire the unused graph serialization facade and use one typed query implementation after canonical request admission. Migrate tests to the owning schemas while preserving graph commitments, Unicode transport, provenance, uncertainty, traversal and reconstruction controls.
This commit is contained in:
1 parent
9df94a62cd
commit
6298c84eea
12 files changed
+368
-265
No files matched your search
@@ -1,3 +1,4 @@
|
||||
import { javaScriptSemanticQueryInputSchema } from "../../domain/javascript/javascriptSemanticQuerySchemas.js";
|
||||
import { expect, it } from "vitest";
|
||||
import { graphForJavaScript } from "../../../tests/fixtures/javascriptSemanticGraph.js";
|
||||
import { queryJavaScriptSemanticGraph } from "../../domain/javascript/javascriptSemanticQuery.js";
|
||||
@@ -17,11 +18,14 @@ it.each([
|
||||
const state = { speed: 6 };
|
||||
export function update() { ${body} }
|
||||
`);
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "literal", value: 0.001 },
|
||||
direction: "forward-influence",
|
||||
include_ambiguous_dynamic_edges: true,
|
||||
});
|
||||
const trace = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "literal", value: 0.001 },
|
||||
direction: "forward-influence",
|
||||
include_ambiguous_dynamic_edges: true,
|
||||
}),
|
||||
);
|
||||
expect(trace.nodes.map((node) => node.label)).toContain(reached);
|
||||
expect(trace.nodes.map((node) => node.label)).toContain("return");
|
||||
expect(
|
||||
@@ -37,11 +41,14 @@ it("does not attribute deferred callback reads to an enclosing assignment", () =
|
||||
let callback;
|
||||
callback = () => accel;
|
||||
`);
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "literal", value: 0.001 },
|
||||
direction: "forward-influence",
|
||||
include_ambiguous_dynamic_edges: true,
|
||||
});
|
||||
const trace = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "literal", value: 0.001 },
|
||||
direction: "forward-influence",
|
||||
include_ambiguous_dynamic_edges: true,
|
||||
}),
|
||||
);
|
||||
expect(
|
||||
graph.relations.filter(
|
||||
(edge) => edge.properties.assignment_operator !== undefined,
|
||||
@@ -88,10 +95,13 @@ it("reaches a property write by default and keeps uncertain later reads opt-in",
|
||||
const graph = graphForJavaScript(
|
||||
"const accel = 0.001; const state = {speed: 6}; function update() { state.speed += accel; return state.speed; }",
|
||||
);
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "literal", value: 0.001 },
|
||||
direction: "forward-influence",
|
||||
});
|
||||
const trace = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "literal", value: 0.001 },
|
||||
direction: "forward-influence",
|
||||
}),
|
||||
);
|
||||
expect(
|
||||
trace.nodes.some(
|
||||
(node) => node.kind === "property-slot" && node.label === "speed",
|
||||
@@ -128,11 +138,14 @@ it.each([
|
||||
nodes.get(edge.target_node_id)?.label === "speed",
|
||||
);
|
||||
expect(assignment).toBeDefined();
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "literal", value: 0.001 },
|
||||
direction: "forward-influence",
|
||||
include_ambiguous_dynamic_edges: true,
|
||||
});
|
||||
const trace = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "literal", value: 0.001 },
|
||||
direction: "forward-influence",
|
||||
include_ambiguous_dynamic_edges: true,
|
||||
}),
|
||||
);
|
||||
expect(trace.nodes.map((node) => node.label)).toContain("return");
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { javaScriptSemanticQueryInputSchema } from "../../domain/javascript/javascriptSemanticQuerySchemas.js";
|
||||
import {
|
||||
primitiveByteExpansionSource,
|
||||
primitiveCandidateExpansionExpression,
|
||||
@@ -83,11 +84,14 @@ it.each([
|
||||
);
|
||||
if (source.includes("export {")) expect(exportReference).toBeDefined();
|
||||
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "semantic-node", node_id: binding.node_id },
|
||||
direction: "backward-provenance",
|
||||
allowed_relations: ["writes"],
|
||||
});
|
||||
const trace = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "semantic-node", node_id: binding.node_id },
|
||||
direction: "backward-provenance",
|
||||
allowed_relations: ["writes"],
|
||||
}),
|
||||
);
|
||||
expect(trace.status).toBe("found");
|
||||
expect(trace.summary).toMatchObject({
|
||||
total_seed_matches: 1,
|
||||
@@ -122,11 +126,14 @@ it("projects closure and direct interprocedural flow without execution", () => {
|
||||
({ kind, label }) => kind === "parameter" && label === "value",
|
||||
);
|
||||
if (parameter === undefined) throw new Error("Expected parameter node");
|
||||
const provenance = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "semantic-node", node_id: parameter.node_id },
|
||||
direction: "backward-provenance",
|
||||
include_ambiguous_dynamic_edges: true,
|
||||
});
|
||||
const provenance = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "semantic-node", node_id: parameter.node_id },
|
||||
direction: "backward-provenance",
|
||||
include_ambiguous_dynamic_edges: true,
|
||||
}),
|
||||
);
|
||||
expect(provenance.relations.map(({ relation }) => relation)).toEqual(
|
||||
expect.arrayContaining([
|
||||
"aliases",
|
||||
@@ -208,11 +215,14 @@ it("keeps a directly returned or passed property in backward provenance", () =>
|
||||
(item) => item.kind === "binding" && item.label === binding,
|
||||
);
|
||||
if (node === undefined) throw new Error(`missing ${binding}`);
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "semantic-node", node_id: node.node_id },
|
||||
direction: "backward-provenance",
|
||||
include_ambiguous_dynamic_edges: candidates,
|
||||
});
|
||||
const trace = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "semantic-node", node_id: node.node_id },
|
||||
direction: "backward-provenance",
|
||||
include_ambiguous_dynamic_edges: candidates,
|
||||
}),
|
||||
);
|
||||
return trace.nodes.some(
|
||||
(item) => item.kind === "literal" && item.properties.value === "products",
|
||||
);
|
||||
@@ -239,16 +249,22 @@ it("keeps dynamic calls explicit and returns complete deterministic results", ()
|
||||
)?.source_node_id;
|
||||
if (seedNodeId === undefined) throw new Error("Expected a definition seed");
|
||||
|
||||
const first = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "semantic-node", node_id: seedNodeId },
|
||||
direction: "forward-influence",
|
||||
include_ambiguous_dynamic_edges: true,
|
||||
});
|
||||
const repeated = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "semantic-node", node_id: seedNodeId },
|
||||
direction: "forward-influence",
|
||||
include_ambiguous_dynamic_edges: true,
|
||||
});
|
||||
const first = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "semantic-node", node_id: seedNodeId },
|
||||
direction: "forward-influence",
|
||||
include_ambiguous_dynamic_edges: true,
|
||||
}),
|
||||
);
|
||||
const repeated = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "semantic-node", node_id: seedNodeId },
|
||||
direction: "forward-influence",
|
||||
include_ambiguous_dynamic_edges: true,
|
||||
}),
|
||||
);
|
||||
expect(repeated).toEqual(first);
|
||||
});
|
||||
|
||||
@@ -358,17 +374,23 @@ it("keeps ambiguous interprocedural flow out of the default traversal", () => {
|
||||
"argument-to-parameter" as const,
|
||||
],
|
||||
};
|
||||
const strict = queryJavaScriptSemanticGraph(graph, query);
|
||||
const strict = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse(query),
|
||||
);
|
||||
expect(
|
||||
strict.relations.some(
|
||||
({ relation }) => relation === "argument-to-parameter",
|
||||
),
|
||||
).toBe(false);
|
||||
expect(strict.status).toBe("ambiguous");
|
||||
const admitted = queryJavaScriptSemanticGraph(graph, {
|
||||
...query,
|
||||
include_ambiguous_dynamic_edges: true,
|
||||
});
|
||||
const admitted = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
...query,
|
||||
include_ambiguous_dynamic_edges: true,
|
||||
}),
|
||||
);
|
||||
expect(
|
||||
admitted.relations.filter(
|
||||
({ relation }) => relation === "argument-to-parameter",
|
||||
@@ -403,18 +425,24 @@ it("connects caller results, direct returns, parameters, and captures", () => {
|
||||
readOuter === undefined
|
||||
)
|
||||
throw new Error("Expected semantic flow nodes");
|
||||
const provenance = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "semantic-node", node_id: output.node_id },
|
||||
direction: "backward-provenance",
|
||||
});
|
||||
const provenance = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "semantic-node", node_id: output.node_id },
|
||||
direction: "backward-provenance",
|
||||
}),
|
||||
);
|
||||
expect(provenance.nodes.map(({ node_id }) => node_id)).toContain(
|
||||
input.node_id,
|
||||
);
|
||||
const influence = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "semantic-node", node_id: outer.node_id },
|
||||
direction: "forward-influence",
|
||||
allowed_relations: ["captures"],
|
||||
});
|
||||
const influence = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "semantic-node", node_id: outer.node_id },
|
||||
direction: "forward-influence",
|
||||
allowed_relations: ["captures"],
|
||||
}),
|
||||
);
|
||||
expect(influence.nodes.map(({ node_id }) => node_id)).toContain(
|
||||
readOuter.node_id,
|
||||
);
|
||||
@@ -500,10 +528,13 @@ it("keeps duplicate function fingerprints ambiguous", () => {
|
||||
expect(digest).toBeDefined();
|
||||
expect(graph.fingerprints[1]?.fingerprint_sha256).toBe(digest);
|
||||
if (digest === undefined) throw new Error("Expected fingerprint");
|
||||
const query = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "function", fingerprint_sha256: digest },
|
||||
direction: "forward-influence",
|
||||
});
|
||||
const query = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "function", fingerprint_sha256: digest },
|
||||
direction: "forward-influence",
|
||||
}),
|
||||
);
|
||||
expect(query.status).toBe("ambiguous");
|
||||
expect(query.summary.total_seed_matches).toBe(2);
|
||||
});
|
||||
@@ -519,19 +550,25 @@ it("selects analyzer-produced boundaries by their method field", () => {
|
||||
method: "Number",
|
||||
});
|
||||
expect(
|
||||
queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "boundary-field", field: "Number" },
|
||||
direction: "forward-influence",
|
||||
}),
|
||||
queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "boundary-field", field: "Number" },
|
||||
direction: "forward-influence",
|
||||
}),
|
||||
),
|
||||
).toMatchObject({
|
||||
seed_node_ids: [boundary.node_id],
|
||||
summary: { total_seed_matches: 1 },
|
||||
});
|
||||
expect(
|
||||
queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "boundary-field", field: "missing-field" },
|
||||
direction: "forward-influence",
|
||||
}).summary.total_seed_matches,
|
||||
queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "boundary-field", field: "missing-field" },
|
||||
direction: "forward-influence",
|
||||
}),
|
||||
).summary.total_seed_matches,
|
||||
).toBe(0);
|
||||
});
|
||||
|
||||
@@ -713,11 +750,14 @@ it.each([
|
||||
expect(returnNode?.kind).toBe("return-site");
|
||||
if (returnNode === undefined)
|
||||
throw new Error("Expected the linked return site");
|
||||
const query = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "semantic-node", node_id: returnNode.node_id },
|
||||
direction: "forward-influence",
|
||||
allowed_relations: ["returns-task"],
|
||||
});
|
||||
const query = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "semantic-node", node_id: returnNode.node_id },
|
||||
direction: "forward-influence",
|
||||
allowed_relations: ["returns-task"],
|
||||
}),
|
||||
);
|
||||
expect(query.relations).toContainEqual(relation);
|
||||
expect(query.nodes.map(({ node_id }) => node_id)).toContain(promise?.node_id);
|
||||
});
|
||||
@@ -954,11 +994,14 @@ it("keeps full static property identities distinct through backward provenance",
|
||||
expect(slot.properties.presence).toBe(
|
||||
literal === null ? "absent" : "present",
|
||||
);
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "semantic-node", node_id: slot.node_id },
|
||||
direction: "backward-provenance",
|
||||
allowed_relations: ["defines"],
|
||||
});
|
||||
const trace = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "semantic-node", node_id: slot.node_id },
|
||||
direction: "backward-provenance",
|
||||
allowed_relations: ["defines"],
|
||||
}),
|
||||
);
|
||||
expect(
|
||||
trace.nodes
|
||||
.filter(({ kind }) => kind === "literal")
|
||||
@@ -1039,11 +1082,14 @@ it("keeps dynamic intermediate receivers unresolved instead of selecting a stati
|
||||
({ kind, label }) => kind === "binding" && label === "selected",
|
||||
);
|
||||
if (selected === undefined) throw new Error("Missing selected binding");
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "semantic-node", node_id: selected.node_id },
|
||||
direction: "backward-provenance",
|
||||
allowed_relations: ["defines"],
|
||||
});
|
||||
const trace = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "semantic-node", node_id: selected.node_id },
|
||||
direction: "backward-provenance",
|
||||
allowed_relations: ["defines"],
|
||||
}),
|
||||
);
|
||||
expect(trace.nodes.filter(({ kind }) => kind === "literal")).toEqual([]);
|
||||
});
|
||||
|
||||
@@ -1087,11 +1133,14 @@ it.each([
|
||||
resolution: resolved ? "resolved" : "candidate",
|
||||
}),
|
||||
);
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "semantic-node", node_id: write.node_id },
|
||||
direction: "forward-influence",
|
||||
allowed_relations: ["writes-property"],
|
||||
});
|
||||
const trace = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "semantic-node", node_id: write.node_id },
|
||||
direction: "forward-influence",
|
||||
allowed_relations: ["writes-property"],
|
||||
}),
|
||||
);
|
||||
expect(trace.nodes.some(({ node_id }) => node_id === slot.node_id)).toBe(
|
||||
resolved,
|
||||
);
|
||||
@@ -1123,11 +1172,14 @@ it.each(["", "root.length = 0;", "root.length = query(); root[0] = 9;"])(
|
||||
presence: "present",
|
||||
value_status: "unknown",
|
||||
});
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "property", name: "length" },
|
||||
direction: "forward-influence",
|
||||
allowed_relations: ["reads-property"],
|
||||
});
|
||||
const trace = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "property", name: "length" },
|
||||
direction: "forward-influence",
|
||||
allowed_relations: ["reads-property"],
|
||||
}),
|
||||
);
|
||||
expect(trace.seed_node_ids).toEqual([slot?.node_id]);
|
||||
expect(trace.relations).toContainEqual(
|
||||
expect.objectContaining({
|
||||
@@ -1156,10 +1208,13 @@ it.each([
|
||||
({ kind, label }) => kind === "binding" && label === "root",
|
||||
);
|
||||
if (root === undefined) throw new Error("Expected root binding");
|
||||
const result = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "semantic-node", node_id: root.node_id },
|
||||
direction: "forward-influence",
|
||||
});
|
||||
const result = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "semantic-node", node_id: root.node_id },
|
||||
direction: "forward-influence",
|
||||
}),
|
||||
);
|
||||
|
||||
expect(result.coverage.status).toBe("partial");
|
||||
expect(result.unknowns).toContainEqual(
|
||||
@@ -1211,10 +1266,13 @@ it.each([
|
||||
identity.role_key.includes("binding:shared"),
|
||||
);
|
||||
if (sharedMode === undefined) throw new Error("Expected shared mode slot");
|
||||
const result = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "semantic-node", node_id: sharedMode.node_id },
|
||||
direction: "backward-provenance",
|
||||
});
|
||||
const result = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "semantic-node", node_id: sharedMode.node_id },
|
||||
direction: "backward-provenance",
|
||||
}),
|
||||
);
|
||||
|
||||
expect(sharedMode.properties.presence).toBe("unknown-coverage");
|
||||
expect(result.nodes).toContainEqual(
|
||||
@@ -1243,11 +1301,14 @@ it.each(["{}", "unknownRoot", "{ a: null }"])(
|
||||
value_status: "unknown",
|
||||
},
|
||||
});
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "property", name: "c" },
|
||||
direction: "backward-provenance",
|
||||
allowed_relations: ["defines"],
|
||||
});
|
||||
const trace = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "property", name: "c" },
|
||||
direction: "backward-provenance",
|
||||
allowed_relations: ["defines"],
|
||||
}),
|
||||
);
|
||||
expect(trace.seed_node_ids).toEqual([slot?.node_id]);
|
||||
expect(trace.nodes.filter(({ kind }) => kind === "literal")).toEqual([]);
|
||||
},
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { javaScriptSemanticQueryInputSchema } from "../../domain/javascript/javascriptSemanticQuerySchemas.js";
|
||||
import { expect, it } from "vitest";
|
||||
|
||||
import { graphForJavaScript as graphFor } from "../../../tests/fixtures/javascriptSemanticGraph.js";
|
||||
@@ -287,10 +288,13 @@ it("projects literal seeds and static object flow", () => {
|
||||
kind === "property-slot" && properties.name === "token",
|
||||
),
|
||||
).toBeDefined();
|
||||
const literal = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "literal", value: "TOKEN" },
|
||||
direction: "forward-influence",
|
||||
});
|
||||
const literal = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "literal", value: "TOKEN" },
|
||||
direction: "forward-influence",
|
||||
}),
|
||||
);
|
||||
expect(literal.status).toBe("ambiguous");
|
||||
const targetName = (targetId: string): string => {
|
||||
const target = graph.nodes.find(({ node_id }) => node_id === targetId);
|
||||
@@ -320,10 +324,13 @@ it("projects literal seeds and static object flow", () => {
|
||||
"token",
|
||||
]);
|
||||
expect(literal.summary.total_seed_matches).toBe(literalTargets.length);
|
||||
const property = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "property", name: "token" },
|
||||
direction: "forward-influence",
|
||||
});
|
||||
const property = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "property", name: "token" },
|
||||
direction: "forward-influence",
|
||||
}),
|
||||
);
|
||||
expect(property.status).toBe("ambiguous");
|
||||
expect(property.seed_node_ids.map(targetName).sort()).toEqual([
|
||||
"copy.token",
|
||||
@@ -366,10 +373,13 @@ it("does not promote transformed return expressions to resolved aliases", () =>
|
||||
);
|
||||
if (output === undefined || input === undefined)
|
||||
throw new Error("Expected caller bindings");
|
||||
const strict = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "semantic-node", node_id: output.node_id },
|
||||
direction: "backward-provenance",
|
||||
});
|
||||
const strict = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "semantic-node", node_id: output.node_id },
|
||||
direction: "backward-provenance",
|
||||
}),
|
||||
);
|
||||
expect(strict.nodes.map(({ node_id }) => node_id)).not.toContain(
|
||||
input.node_id,
|
||||
);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { javaScriptSemanticQueryInputSchema } from "../../domain/javascript/javascriptSemanticQuerySchemas.js";
|
||||
import { expect, it } from "vitest";
|
||||
|
||||
import { graphForJavaScript } from "../../../tests/fixtures/javascriptSemanticGraph.js";
|
||||
@@ -18,10 +19,13 @@ it.each([
|
||||
properties.property_path.at(-1) === "speed",
|
||||
);
|
||||
expect(accesses.length).toBeGreaterThan(0);
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "property", name: "speed" },
|
||||
direction: "forward-influence",
|
||||
});
|
||||
const trace = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "property", name: "speed" },
|
||||
direction: "forward-influence",
|
||||
}),
|
||||
);
|
||||
expect(trace.seed_node_ids).toEqual(
|
||||
accesses.map(({ node_id }) => node_id).sort(),
|
||||
);
|
||||
@@ -33,10 +37,13 @@ it.each([
|
||||
expect.arrayContaining(relevant.map(({ unknown_id }) => unknown_id)),
|
||||
);
|
||||
expect(
|
||||
queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "property", name: "absent" },
|
||||
direction: "forward-influence",
|
||||
}).seed_node_ids,
|
||||
queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "property", name: "absent" },
|
||||
direction: "forward-influence",
|
||||
}),
|
||||
).seed_node_ids,
|
||||
).toEqual([]);
|
||||
},
|
||||
);
|
||||
@@ -45,10 +52,13 @@ it("keeps resolved property seeds on their slot without duplicating access occur
|
||||
const graph = graphForJavaScript(
|
||||
"const state = { speed: 1 }; const result = state.speed;",
|
||||
);
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "property", name: "speed" },
|
||||
direction: "backward-provenance",
|
||||
});
|
||||
const trace = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "property", name: "speed" },
|
||||
direction: "backward-provenance",
|
||||
}),
|
||||
);
|
||||
expect(trace.seed_node_ids).toHaveLength(1);
|
||||
expect(
|
||||
graph.nodes.find(({ node_id }) => node_id === trace.seed_node_ids[0])?.kind,
|
||||
@@ -59,10 +69,13 @@ it("queries an empty event name as an exact retained event identity", () => {
|
||||
const graph = graphForJavaScript(
|
||||
'const { EventEmitter } = require("node:events"); const bus = new EventEmitter(); bus.on("", function emptyListener() {}); bus.on("data", function dataListener() {});',
|
||||
);
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "event", name: "" },
|
||||
direction: "forward-influence",
|
||||
});
|
||||
const trace = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "event", name: "" },
|
||||
direction: "forward-influence",
|
||||
}),
|
||||
);
|
||||
expect(trace.seed_node_ids.length).toBeGreaterThan(0);
|
||||
expect(
|
||||
trace.nodes
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
parseApplicationGraphEvidence,
|
||||
} from "./JavaScriptApplicationEvidenceGraph.js";
|
||||
import type { Evidence } from "../../domain/evidence.js";
|
||||
import { queryJavaScriptSemanticGraphValidated } from "../../domain/javascript/javascriptSemanticQuery.js";
|
||||
import { queryJavaScriptSemanticGraph } from "../../domain/javascript/javascriptSemanticQuery.js";
|
||||
import {
|
||||
traceJavaScriptSemanticsInputSchema,
|
||||
type JavaScriptSemanticTraceResult,
|
||||
@@ -40,10 +40,7 @@ export const traceJavaScriptSemanticsEvidenceValidated = (
|
||||
},
|
||||
]),
|
||||
);
|
||||
const query = queryJavaScriptSemanticGraphValidated(
|
||||
source.semanticGraph,
|
||||
input.query,
|
||||
);
|
||||
const query = queryJavaScriptSemanticGraph(source.semanticGraph, input.query);
|
||||
const result: JavaScriptSemanticTraceResult = {
|
||||
...query,
|
||||
source_evidence_id: source.evidence.evidence_id,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { javaScriptSemanticQueryInputSchema } from "../../domain/javascript/javascriptSemanticQuerySchemas.js";
|
||||
import { createHash } from "node:crypto";
|
||||
import { expect, it } from "vitest";
|
||||
import type { JavaScriptArtifactFile } from "../../domain/javascript/javascriptArtifactFiles.js";
|
||||
@@ -83,10 +84,13 @@ it("bounds unknowns independently of retained nodes and accounts for examined om
|
||||
);
|
||||
expect(javaScriptSemanticGraphSchema.parse(graph)).toEqual(graph);
|
||||
expect(
|
||||
queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "property", name: "missing" },
|
||||
direction: "backward-provenance",
|
||||
}),
|
||||
queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "property", name: "missing" },
|
||||
direction: "backward-provenance",
|
||||
}),
|
||||
),
|
||||
).toMatchObject({ status: "partial", coverage: { status: "partial" } });
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user