Files
rea/src/domain/javascript/javascriptSemanticAnalysis.invalid_templates.test.ts
T
Kaoru0822 4135c911d3 fix(javascript): keep recovered invalid templates dynamic in semantic effects (#3815)
dataEffectLiteralString asked the literal owner for an exact value, and
when a template recovered with an invalid escape had no cooked value it
fell back to the raw spelling. Child-process commands, request endpoints
and event names then became resolved values that are not JavaScript
strings.

Use only the owner's cooked value; a template without one stays dynamic.

Fixes #3361

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 20:22:16 -07:00

39 lines
1.2 KiB
TypeScript

import { expect, it } from "vitest";
import { analyzeJavaScriptSemantics } from "./javascriptSemanticAnalysis.js";
const effects = (call: (value: string) => string, value: string) => {
const ir = analyzeJavaScriptSemantics(`
const { spawn } = require("child_process");
const { EventEmitter } = require("events");
${call(value)}
`);
return {
commands: ir.childProcessSpawns.map(({ command }) => command),
endpoints: ir.requestOperations.map(({ endpoint }) => endpoint),
events: ir.eventOperations.map(({ eventName }) => eventName),
};
};
const calls = (value: string) =>
[
`spawn(${value});`,
`fetch(${value});`,
`new EventEmitter().on(${value}, () => 1);`,
].join("\n");
it("keeps recovered templates without a cooked value dynamic", () => {
// `\\unicode` is an invalid escape: Babel recovers it with `cooked: null`.
expect(effects(calls, "`\\unicode`")).toEqual({
commands: [null],
endpoints: [null],
events: [null],
});
// Valid templates keep their cooked value, including escapes.
expect(effects(calls, "`ready\\n`")).toEqual({
commands: ["ready\n"],
endpoints: ["ready\n"],
events: ["ready\n"],
});
});