import * as t from "@babel/types"; import { expect, it } from "vitest"; import { semanticStaticPropertyKey, staticObjectProperty, } from "./javascriptAstValues.js"; import { SEMANTIC_EXPRESSION_DEPTH_LIMIT } from "./javascriptSemanticResourceLimits.js"; it("copies ordinary members without proving requested methods or getter effects", () => { const method = (name: string, computed = false) => t.objectMethod( "method", t.identifier(name), [], t.blockStatement([]), computed, ); const getter = t.objectMethod( "get", t.identifier("helper"), [], t.blockStatement([]), ); const setter = t.objectMethod( "set", t.identifier("helper"), [t.identifier("value")], t.blockStatement([]), ); for (const [member, status] of [ [method("helper"), "explicit"], [setter, "explicit"], [method("stdio"), "dynamic"], [getter, "dynamic"], [method("key", true), "dynamic"], ] as const) { const object = t.objectExpression([ t.objectProperty(t.identifier("stdio"), t.stringLiteral("inherit")), t.spreadElement(t.objectExpression([member])), ]); expect(staticObjectProperty(object, "stdio").status).toBe(status); } }); it("limits unary-plus keys to transparent numeric literals", () => { const wrapped = t.tsAsExpression(t.numericLiteral(1), t.tsNumberKeyword()); expect(semanticStaticPropertyKey(t.unaryExpression("+", wrapped), true)).toBe( "1", ); for (const argument of [ t.stringLiteral("1"), t.bigIntLiteral(1n), t.identifier("input"), ]) expect( semanticStaticPropertyKey(t.unaryExpression("+", argument), true), ).toBeNull(); }); it("bounds nested inline object spreads without losing a shallow final property", () => { let object = t.objectExpression([ t.objectProperty(t.identifier("stdio"), t.stringLiteral("inherit")), ]); for (let depth = 0; depth < SEMANTIC_EXPRESSION_DEPTH_LIMIT; depth++) object = t.objectExpression([t.spreadElement(object)]); expect(staticObjectProperty(object, "stdio").status).toBe("explicit"); expect( staticObjectProperty(t.objectExpression([t.spreadElement(object)]), "stdio") .status, ).toBe("dynamic"); });