mirror of
https://github.com/morluto/rea.git
synced 2026-11-11 01:13:39 +00:00
77 lines
2.3 KiB
TypeScript
77 lines
2.3 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { analyzeJavaScriptSemantics } from "./javascriptSemanticAnalysis.js";
|
|
|
|
const observe = (source: string) => {
|
|
const ir = analyzeJavaScriptSemantics(source);
|
|
return {
|
|
binding: ir.bindings.find((item) => item.name === "x")?.value,
|
|
returned: ir.callables.find((item) => item.name === "read")?.returnSites[0]
|
|
?.value,
|
|
};
|
|
};
|
|
|
|
describe("JavaScript semantic analysis: logical assignment", () => {
|
|
it.each(["||=", "??=", "&&="])(
|
|
"keeps a parameter uncertain after %s",
|
|
(operator) => {
|
|
const { binding, returned } = observe(
|
|
`function read(x) { x ${operator} 2; return x; }`,
|
|
);
|
|
expect(binding?.status).toBe("unknown");
|
|
expect(returned?.status).toBe("unknown");
|
|
},
|
|
);
|
|
|
|
it.each(["||=", "??=", "&&="])(
|
|
"keeps a destructured parameter uncertain after %s",
|
|
(operator) => {
|
|
const { binding, returned } = observe(
|
|
`function read({ x }) { x ${operator} 2; return x; }`,
|
|
);
|
|
expect(binding?.status).toBe("unknown");
|
|
expect(returned?.status).toBe("unknown");
|
|
},
|
|
);
|
|
|
|
it.each(["||=", "??=", "&&="])(
|
|
"keeps a catch binding uncertain after %s",
|
|
(operator) => {
|
|
const { binding, returned } = observe(
|
|
`function read() { try { run(); } catch (x) { x ${operator} 2; return x; } }`,
|
|
);
|
|
expect(binding?.status).toBe("unknown");
|
|
expect(returned?.status).toBe("unknown");
|
|
},
|
|
);
|
|
|
|
it.each([
|
|
["let", "||="],
|
|
["let", "??="],
|
|
["var", "||="],
|
|
["var", "??="],
|
|
])(
|
|
"keeps an uninitialized %s local exact after %s",
|
|
(declaration, operator) => {
|
|
const { binding, returned } = observe(
|
|
`function read() { ${declaration} x; x ${operator} 2; return x; }`,
|
|
);
|
|
expect(binding).toEqual({ status: "literal", value: 2 });
|
|
expect(returned).toEqual({ status: "literal", value: 2 });
|
|
},
|
|
);
|
|
|
|
it("keeps an unconditional parameter assignment exact", () => {
|
|
const { binding, returned } = observe(
|
|
"function read(x) { x = 2; return x; }",
|
|
);
|
|
expect(binding).toEqual({ status: "literal", value: 2 });
|
|
expect(returned).toEqual({ status: "literal", value: 2 });
|
|
});
|
|
|
|
it("keeps an unchanged parameter unknown", () => {
|
|
expect(observe("function read(x) { return x; }").returned?.status).toBe(
|
|
"unknown",
|
|
);
|
|
});
|
|
});
|