import { afterAll, expect, test } from "bun:test"; import { mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { assertReactAvailable, buildIslands, generateIslandEntry } from "../src/island-bundle.ts"; const created: string[] = []; afterAll(() => { for (const dir of created) rmSync(dir, { recursive: true, force: true }); }); test("generates an entry that re-exports the island component", () => { const entry = generateIslandEntry({ name: "Chart", sourcePath: "/app/Chart.tsx" }); expect(entry).toContain("/app/Chart.tsx"); expect(entry).toContain("Chart"); expect(entry).not.toContain("react-dom/server"); }); test("island .tsx compiles against React's JSX runtime, not WRNexus's", async () => { // The root tsconfig points jsxImportSource at @wrnexus/core, so an island // would otherwise compile to WRNexus's HTML-string renderer and never mount. // A pragma applies only to the file carrying it, so this asserts the built // output rather than the generated entry text. // The fixture must live inside the repo: Bun resolves `react` from the // importing file's location, exactly as a real island resolves it from the // app that installed react. const root = mkdtempSync(join(process.cwd(), ".island-jsx-test-")); created.push(root); const source = join(root, "Chart.tsx"); writeFileSync( source, `export default function Chart({ title }: { title: string }) { return
{title}
; }`, ); const outDir = join(root, "out"); await buildIslands({ islands: [{ name: "Chart", sourcePath: source }], outDir }); const built = readdirSync(outDir) .filter((file) => file.endsWith(".js")) .map((file) => readFileSync(join(outDir, file), "utf8")) .join("\n"); expect(built).not.toContain("wrnexus"); expect(built).toMatch(/react\/jsx|jsxDEV|jsx_runtime/); }); test("reports WRN-ISLAND-REACT-MISSING when react is not installed", () => { const root = mkdtempSync(join(tmpdir(), "wrnexus-noreact-")); writeFileSync(join(root, "package.json"), JSON.stringify({ name: "app" })); const diagnostic = assertReactAvailable(root); expect(diagnostic?.code).toBe("WRN-ISLAND-REACT-MISSING"); expect(diagnostic?.message).toContain("bun add react react-dom"); }); test("returns null when react resolves", () => { expect(assertReactAvailable(process.cwd())).toBeNull(); });