Files
rea/src/domain/javascript/javascriptSemanticTraversal.test.ts
T
morluto 62b37111e7 fix(javascript): handle deep AST traversal and addition without stack overflow (#915)
* fix(javascript): avoid recursion and eager ancestry copies in deep ASTs

* fix(javascript): traverse static analysis and bundler ASTs iteratively
2026-10-07 17:40:05 +08:00

54 lines
1.6 KiB
TypeScript

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",
],
]);
});