mirror of
https://github.com/morluto/rea.git
synced 2026-11-06 06:46:10 +00:00
test(javascript): consolidate source analysis and export regressions
This commit is contained in:
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,
|
||||
});
|
||||
};
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user