import { expect, test } from "bun:test"; import { compile } from "../src/index.ts"; test("component conditional templates retain enclosing loop locals for reactive reevaluation", async () => { const source = `component FormFields { props { pages = [{id:'page',fields:[{id:'name',hidden:false}]}] } state answers = {} view { {#each pages as page}
{#each page.fields as field}{#if !field.hidden}{/if}{/each}
{/each} } }`; const code = new Bun.Transpiler({ loader: "ts" }).transformSync( compile(source, "FormFields.wrn").code, ); const mod = await import("data:text/javascript;base64," + Buffer.from(code).toString("base64")); const html = mod.render({}); const markers = [...html.matchAll(/]+)>/g)].map((match) => match[1]!); const conditional = markers.find((marker) => marker.includes("data-wrn-if="))!; const locals = /data-wrn-loop-locals="([^"]+)"/.exec(conditional); expect(conditional?.trim().startsWith("data-wrn-if=")).toBe(true); expect(locals).not.toBeNull(); const decoded = JSON.parse(Buffer.from(locals![1]!, "base64").toString()); expect(decoded.field.id).toBe("name"); expect(decoded.page.id).toBe("page"); const nestedEach = markers.filter((marker) => marker.includes("data-wrn-each="))[1]!; const eachLocals = /data-wrn-loop-locals="([^"]+)"/.exec(nestedEach); expect(eachLocals).not.toBeNull(); expect(JSON.parse(Buffer.from(eachLocals![1]!, "base64").toString()).page.id).toBe("page"); const child = /
]+)>/.exec(html)!; const childLocals = /data-wrn-loop-locals="([^"]+)"/.exec(child[1]!); expect(childLocals).not.toBeNull(); expect(JSON.parse(Buffer.from(childLocals![1]!, "base64").toString()).field.id).toBe("name"); const childCode = new Bun.Transpiler({ loader: "ts" }).transformSync( compile("component Child { view { } }", "Child.wrn").code, ); const childModule = await import( "data:text/javascript;base64," + Buffer.from(childCode).toString("base64") ); const renderedChild = childModule.render({ "data-wrn-loop-locals": childLocals![1]!, "data-wrn-if": "forbidden", }); expect(renderedChild).toContain('data-wrn-loop-locals="' + childLocals![1] + '"'); expect(renderedChild).not.toContain('data-wrn-if="forbidden"'); });