import { afterAll, describe, expect, test } from "bun:test"; import { GlobalRegistrator } from "@happy-dom/global-registrator"; import { act, Suspense, useLayoutEffect } from "react"; import { createRoot } from "react-dom/client"; import { useLatestCallback } from "./app-context"; GlobalRegistrator.register(); (globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT: boolean }).IS_REACT_ACT_ENVIRONMENT = true; afterAll(() => { GlobalRegistrator.unregister(); }); describe("useLatestCallback", () => { test("keeps one identity while dispatching to the latest render", async () => { let current: (() => string) | null = null; function Harness({ value }: { value: string }) { current = useLatestCallback(() => value); return null; } const container = document.createElement("div"); const root = createRoot(container); await act(async () => root.render()); const initial = current as unknown as () => string; expect(initial()).toBe("first"); await act(async () => root.render()); expect(current as unknown as () => string).toBe(initial); expect(initial()).toBe("second"); await act(async () => root.unmount()); }); test("never exposes a callback from a suspended, uncommitted render", async () => { let current: (() => string) | null = null; let blocked = false; let release!: () => void; const gate = new Promise((resolve) => { release = resolve; }); function Harness({ value }: { value: string }) { current = useLatestCallback(() => value); return null; } function CommitGate() { if (blocked) throw gate; return null; } const view = (value: string) => ( ); const container = document.createElement("div"); const root = createRoot(container); await act(async () => root.render(view("committed"))); const committed = current as unknown as () => string; blocked = true; act(() => root.render(view("not-committed"))); expect(current as unknown as () => string).toBe(committed); expect(committed()).toBe("committed"); blocked = false; await act(async () => release()); expect(committed()).toBe("not-committed"); await act(async () => root.unmount()); }); test("publishes the committed body before descendant layout effects run", async () => { const observed: string[] = []; function Observer({ read }: { read: () => string }) { useLayoutEffect(() => { observed.push(read()); }); return null; } function Harness({ value }: { value: string }) { const read = useLatestCallback(() => value); return ; } const container = document.createElement("div"); const root = createRoot(container); await act(async () => root.render()); await act(async () => root.render()); expect(observed).toEqual(["first", "second"]); await act(async () => root.unmount()); }); });