From 3e77a621f5115d0f845101ba6777c1c72600f13c Mon Sep 17 00:00:00 2001 From: Ajay Ghanwat Date: Sun, 9 Aug 2026 13:18:32 +0530 Subject: [PATCH] test(dev-server): guard nested component slot rendering --- .../component-composition-runtime.test.ts | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 packages/dev-server/test/component-composition-runtime.test.ts diff --git a/packages/dev-server/test/component-composition-runtime.test.ts b/packages/dev-server/test/component-composition-runtime.test.ts new file mode 100644 index 00000000..204012a1 --- /dev/null +++ b/packages/dev-server/test/component-composition-runtime.test.ts @@ -0,0 +1,47 @@ +import { afterEach, expect, test } from "bun:test"; +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs"; +import { basename, join } from "node:path"; +import { tmpdir } from "node:os"; +import { buildRouter } from "@wrnexus/router"; +import { createHandlers, type RuntimeDeps } from "../src/runtime.ts"; + +const roots: string[] = []; +afterEach(() => roots.splice(0).forEach((root) => rmSync(root, { recursive: true, force: true }))); + +test("a component nested in another component's slot keeps its boundary", async () => { + const root = mkdtempSync(join(tmpdir(), "wrnexus-component-slot-")); + roots.push(root); + const app = join(root, "app"); + mkdirSync(join(app, "pages"), { recursive: true }); + mkdirSync(join(app, "components"), { recursive: true }); + writeFileSync(join(app, "pages/index.ts"), "export default () => '';\n"); + writeFileSync(join(app, "components/Card.wrn"), "component Card { view { } }\n"); + writeFileSync(join(app, "components/Badge.wrn"), "component Badge { view { } }\n"); + + const handlers = createHandlers({ + mode: "development", + hmr: false, + router: buildRouter(app), + loadModule: async (file) => { + if (basename(file) === "Card.wrn") { + return { render: () => '
' }; + } + if (basename(file) === "Badge.wrn") { + return { render: (props: Record) => `${props.label}` }; + } + return { + default: () => '
', + }; + }, + getMiddleware: async () => [], + assets: { serve: async () => null }, + } satisfies RuntimeDeps); + + const response = await handlers.fetch(new Request("https://example.test/"), { + upgrade: () => false, + }); + const html = await response!.text(); + expect(html).toContain('
'); + expect(html).toContain('x'); + expect(html).not.toContain('data-component="Badge"'); +});