/** @jsxImportSource react */ import { afterEach, expect, test } from "bun:test"; import { Window } from "happy-dom"; import { act } from "react"; import { createRoot } from "react-dom/client"; import { IslandErrorBoundary } from "../src/error-boundary.tsx"; // React error boundaries only engage during client rendering — the server // renderers rethrow. Islands are client-only, so this is also how they run. (globalThis as any).IS_REACT_ACT_ENVIRONMENT = true; function Boom(): never { throw new Error("chart exploded"); } function mountHost() { const window = new Window(); (globalThis as any).window = window; (globalThis as any).document = window.document; const container = window.document.createElement("div"); window.document.body.appendChild(container); return { window, container: container as unknown as HTMLElement }; } const silenced: Array<() => void> = []; afterEach(() => { for (const restore of silenced.splice(0)) restore(); }); function silenceExpectedErrors() { const original = console.error; console.error = () => {}; silenced.push(() => { console.error = original; }); } test("renders children when nothing throws", async () => { const { container } = mountHost(); const root = createRoot(container); await act(async () => { root.render(

ok

, ); }); expect(container.innerHTML).toBe("

ok

"); }); test("contains a thrown error and shows details in development", async () => { silenceExpectedErrors(); const { container } = mountHost(); const root = createRoot(container); await act(async () => { root.render( , ); }); expect(container.innerHTML).toContain("Chart"); expect(container.innerHTML).toContain("chart exploded"); }); test("renders nothing in production when an island throws", async () => { silenceExpectedErrors(); const { container } = mountHost(); const root = createRoot(container); await act(async () => { root.render( , ); }); expect(container.innerHTML).toBe(""); }); test("a crashed island does not remove sibling server markup", async () => { silenceExpectedErrors(); const { window, container } = mountHost(); const sibling = window.document.createElement("p"); sibling.textContent = "server rendered"; window.document.body.appendChild(sibling); const root = createRoot(container); await act(async () => { root.render( , ); }); expect(window.document.body.textContent).toContain("server rendered"); });