import { expect, test } from "bun:test"; import { generate, generateTargets, parse } from "../src/index.ts"; test("page computed values derived from request state are declared during SSR", () => { const code = generate( parse(`import UserCard from "./UserCard.wrn" page Chat { state { currentUserId = ctx.url.searchParams.get("as") ?? "asha" users = [{ id: "asha", name: "Asha" }, { id: "rohan", name: "Rohan" }] } computed { currentUser = users.find((user) => user.id === currentUserId) ?? users[0] } view {

{currentUser.name}

{#each users as user}
{/each} } }`), ); expect(code).toContain("const currentUser ="); expect(code).toContain("__wrnexusEscapeHtml(currentUser.name)"); expect(code).toContain("__wrnexusPropAttr(user)"); expect(code).toContain("__wrnexusEscapeHtml(user.id)"); expect(code).not.toContain("__wrnexusPropAttr(user.id)"); expect(code).toContain('encoded = value === undefined ? "undefined" : JSON.stringify(value)'); expect(code).not.toContain("String((__state as any)[key])"); }); test("computed values that reference ctx directly stay dynamic during SSR", () => { const code = generate( parse(`page DirectRequestComputed { computed { identity = ctx.url.searchParams.get("as") ?? "asha" } view {

{identity}

} }`), ); expect(code).toContain("const identity ="); expect(code).toContain("__wrnexusEscapeHtml(identity)"); }); test("computed values derived from server loads stay dynamic during SSR", () => { const code = generate( parse(`page LoadedComputed { load server overview { return { count: 4 } } computed { total = overview.count + 1 } view {

{total}

} }`), ); expect(code).toContain('const overview = ctx["overview"]'); expect(code).toContain("__wrnexusEscapeHtml(total)"); }); test("request-derived state dependencies stay dynamic during SSR", async () => { const code = generate( parse(`page Identity { state { userId = ctx.url.searchParams.get("as") ?? "asha" label = "User: " + userId } view {

{label}

} }`), ); expect(code).toContain("__wrnexusEscapeHtml(label)"); expect(code).not.toContain(''); const javascript = new Bun.Transpiler({ loader: "ts" }).transformSync(code); const moduleUrl = `data:text/javascript;base64,${Buffer.from(javascript).toString("base64")}`; const rendered = await ( await import(moduleUrl) ).default({ url: new URL("http://localhost/?as=rohan"), }); expect(rendered).toContain("User: rohan"); }); test("Async aliases and invalidation tags are scoped in generated templates", () => { const code = generate( parse(`page Uploads { load client uploads { return { name: "report.pdf" } } view { Loading {file.name}

{problem.message}

} }`), ); expect(code).toContain('data-wrn-async-tags="uploads,files"'); expect(code).toContain('data-wrn-async-alias="file"'); expect(code).toContain('data-wrn-async-alias="problem"'); expect(code).toContain("const file ="); expect(code).toContain("const problem ="); }); test("browser codegen prunes SSR-only UI imports and keeps client dependencies", () => { const browser = generateTargets( parse(`import { Button } from "@wrnexus/ui" import { save } from "./helper.ts" component Settings { state { enabled = true } functions { client function persist(): void { save(enabled) } } view { } }`), ).browser; expect(browser).not.toContain("@wrnexus/ui"); expect(browser).toContain('import { save } from "./helper.ts"'); expect(browser).toContain('"persist": function'); }); test("reactive view imports trigger a browser module without hydrating static SSR helpers", () => { const reactiveAst = parse(`import { formatName } from "./format.ts" page Profile { state { name = "Asha" } view {

{formatName(name)}

} }`); const staticAst = parse(`import { readFileSync } from "node:fs" page StaticProfile { runtime = "server" view {

{readFileSync("profile.txt", "utf8")}

} }`); expect(generate(reactiveAst)).toContain('data-wrn-client-module="__WRNEXUS_CLIENT_MODULE__"'); expect(generateTargets(reactiveAst).browser).toContain( 'import { formatName } from "./format.ts"', ); expect(generate(staticAst)).not.toContain("data-wrn-client-module"); }); test("state dependency cycles fail code generation", () => { expect(() => generate( parse(`page CyclicState { state { first = second + 1 second = first + 1 } view {

{first}

} }`), ), ).toThrow("WRN-STATE-CYCLE"); }); test("computed dependency cycles fail code generation", () => { expect(() => generate( parse(`page Cyclic { computed { first = second + 1 second = first + 1 } view {

{first}

} }`), ), ).toThrow("WRN-COMPUTED-CYCLE"); });