import { describe, expect, test } from "bun:test"; import { createSourceRange, diagnose, diagnosticSummary, sliceSource, supportsSyntaxFeature, } from "../src/index.ts"; describe("syntax contract and security diagnostics", () => { test("validates source ranges and summarizes diagnostic codes", () => { const range = createSourceRange(2, 6); expect(sliceSource("0123456789", range)).toBe("2345"); expect(() => createSourceRange(-1, 2)).toThrow(RangeError); expect(() => createSourceRange(4, 3)).toThrow(RangeError); expect(supportsSyntaxFeature("runtime-markers")).toBe(true); expect(supportsSyntaxFeature("dynamic-eval")).toBe(false); const summary = diagnosticSummary([ { code: "A", severity: "error", message: "a" }, { code: "A", severity: "warning", message: "b" }, { code: "B", severity: "info", message: "c" }, ]); expect(summary).toEqual({ errors: 1, warnings: 1, info: 1, codes: { A: 2, B: 1 } }); }); test("rejects browser secret reads, executable sinks, and sensitive persistence", () => { const diagnostics = diagnose(`page store Unsafe { client state { apiToken: string = process.env.API_TOKEN } persist { storage = "local" include = ["apiToken"] version = 1 } functions { client function render(raw: string): void { document.write(raw); setTimeout("run()", 1) } } }`); const codes = diagnostics.map((diagnostic) => diagnostic.code); expect(codes).toContain("WRN-SEC-SERVER-SECRET-SOURCE"); expect(codes).toContain("WRN-SEC-DOM-SINK"); expect(codes).toContain("WRN-SEC-STRING-TIMER"); expect(codes).toContain("WRN-PERSIST-SENSITIVE"); }); test.each([ [ "server output call", `component Bad { outputs { save() } functions { server function run(): void { output.save() } } view {
} }`, "WRN-OUTPUT-SERVER-CALL", ], [ "unknown output call", `component Bad { functions { client function run(): void { output.missing() } } view { } }`, "WRN-OUTPUT-UNKNOWN", ], [ "server API in client function", `component Bad { functions { client function run(): void { process.cwd() } } view { } }`, "WRN-CLIENT-SERVER-API", ], [ "browser API in server function", `component Bad { functions { server function run(): void { document.title = "bad" } } view { } }`, "WRN-SERVER-BROWSER-API", ], [ "non-serializable shared state", `global store Bad { state { values: unknown = new Map() } }`, "WRN-STATE-NON-SERIALIZABLE", ], [ "unknown persisted state", `global store Bad { state { value: string = "x" } persist { storage = "local" include = ["missing"] version = 1 } }`, "WRN-PERSIST-UNKNOWN-FIELD", ], ])("diagnoses %s", (_name, source, expectedCode) => { expect(diagnose(source).map((diagnostic) => diagnostic.code)).toContain(expectedCode); }); });