From 20783699ac6b7fe79c2ab1f0766e42a467a489e8 Mon Sep 17 00:00:00 2001 From: Ajay Ghanwat Date: Sat, 22 Aug 2026 07:38:40 +0530 Subject: [PATCH] test(compiler): prove page loop locals render, not just emit The existing tests assert the marker is emitted. This one executes the generated module and asserts the rendered HTML carries each item's real, decodable values -- generated text that reads correctly can still render wrong, and what matters is what the runtime finds in the DOM at click time. Co-Authored-By: Claude Opus 5 --- .../compiler/test/page-loop-locals.test.ts | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/packages/compiler/test/page-loop-locals.test.ts b/packages/compiler/test/page-loop-locals.test.ts index f4c28c84..56cde1fe 100644 --- a/packages/compiler/test/page-loop-locals.test.ts +++ b/packages/compiler/test/page-loop-locals.test.ts @@ -83,3 +83,38 @@ test("a page with no loop-local markers does not define the encoder", () => { ); expect(code).not.toContain("__wrnexusEncodeLoopLocals"); }); + +// The tests above assert the marker is EMITTED. This one executes the generated +// module and asserts it RENDERS with the loop's real values -- generated text +// that reads correctly can still render wrong, and the whole point of the +// marker is what the runtime finds in the DOM at click time. +test("a page loop handler's locals render as real, decodable values", async () => { + const code = generate( + parse(`page Packs { + state packs = [{ code: "small" }, { code: "large" }] + functions { client async function pick(c) { console.log(c) } } + view { + {#each packs as pack} + + {/each} + } +}`), + ).replace(/^import \{ buildApiRequest[^\n]*\n/m, ""); + + const js = new Bun.Transpiler({ loader: "ts" }).transformSync(code); + const mod = await import("data:text/javascript;base64," + Buffer.from(js).toString("base64")); + const html: string = await mod.default({ + req: new Request("http://x/"), + cookies: {}, + session: {}, + }); + + const markers = [...html.matchAll(/data-wrn-loop-locals="([^"]+)"/g)].map((m) => m[1]!); + expect(markers.length).toBe(2); + + const decoded = markers.map((m) => JSON.parse(Buffer.from(m, "base64").toString("utf8"))); + expect(decoded[0].pack).toEqual({ code: "small" }); + expect(decoded[1].pack).toEqual({ code: "large" }); + expect(decoded[0].__wi).toBe(0); + expect(decoded[1].__wi).toBe(1); +});