fix(javascript): preserve semantic query identity and source coverage
This commit is contained in:
1 parent
34552ff0df
commit
cf5e4f6fa3
16 files changed
+362
-51
No files matched your search
@@ -0,0 +1,72 @@
|
||||
import { expect, it } from "vitest";
|
||||
|
||||
import { graphForJavaScript } from "../../../tests/fixtures/javascriptSemanticGraph.js";
|
||||
import { queryJavaScriptSemanticGraph } from "../../domain/javascript/javascriptSemanticQuery.js";
|
||||
|
||||
it.each([
|
||||
"function read() { return this.speed; }",
|
||||
"class Game { read() { return this.config.speed; } }",
|
||||
])(
|
||||
"matches retained slotless property accesses and their unknowns: %s",
|
||||
(source) => {
|
||||
const graph = graphForJavaScript(source);
|
||||
const accesses = graph.nodes.filter(
|
||||
({ kind, properties }) =>
|
||||
kind === "expression" &&
|
||||
properties.property_slot_resolution === "unresolved" &&
|
||||
Array.isArray(properties.property_path) &&
|
||||
properties.property_path.at(-1) === "speed",
|
||||
);
|
||||
expect(accesses.length).toBeGreaterThan(0);
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "property", name: "speed" },
|
||||
direction: "forward-influence",
|
||||
});
|
||||
expect(trace.seed_node_ids).toEqual(
|
||||
accesses.map(({ node_id }) => node_id).sort(),
|
||||
);
|
||||
const relevant = graph.unknowns.filter(({ node_id }) =>
|
||||
accesses.some((node) => node.node_id === node_id),
|
||||
);
|
||||
expect(relevant.length).toBeGreaterThan(0);
|
||||
expect(trace.unknowns.map(({ unknown_id }) => unknown_id)).toEqual(
|
||||
expect.arrayContaining(relevant.map(({ unknown_id }) => unknown_id)),
|
||||
);
|
||||
expect(
|
||||
queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "property", name: "absent" },
|
||||
direction: "forward-influence",
|
||||
}).seed_node_ids,
|
||||
).toEqual([]);
|
||||
},
|
||||
);
|
||||
|
||||
it("keeps resolved property seeds on their slot without duplicating access occurrences", () => {
|
||||
const graph = graphForJavaScript(
|
||||
"const state = { speed: 1 }; const result = state.speed;",
|
||||
);
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
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,
|
||||
).toBe("property-slot");
|
||||
});
|
||||
|
||||
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",
|
||||
});
|
||||
expect(trace.seed_node_ids.length).toBeGreaterThan(0);
|
||||
expect(
|
||||
trace.nodes
|
||||
.filter(({ node_id }) => trace.seed_node_ids.includes(node_id))
|
||||
.every(({ properties }) => properties.event_name === ""),
|
||||
).toBe(true);
|
||||
});
|
||||
Reference in new issue
Block a user