68 lines · 2.3 KB · TypeScript
RawDownload
import { describe, expect, it } from "@effect/vitest"; import { composedRefCallback } from "./compose-refs"; /** * The contract under test: both refs always see the same node, across the * three shapes an incoming ref can take (object, plain callback, React 19 * callback with cleanup). The cleanup case matters most — React never calls * the callback with `null` when a cleanup was returned, so clearing the local * ref has to happen inside the merged cleanup or it dangles forever. */describe("composedRefCallback", () => {  const node = { nodeName: "DIV" };   it("tracks attach and detach in both an object ref and the local ref", () => {    const outer: { current: typeof node | null } = { current: null };    const local: { current: typeof node | null } = { current: null };    const callback = composedRefCallback(outer, local);     expect(callback(node)).toBeUndefined();    expect(outer.current).toBe(node);    expect(local.current).toBe(node);     callback(null);    expect(outer.current).toBeNull();    expect(local.current).toBeNull();  });   it("forwards attach and detach to a plain callback ref", () => {    const seen: Array<typeof node | null> = [];    const local: { current: typeof node | null } = { current: null };    const callback = composedRefCallback((value: typeof node | null) => {      seen.push(value);    }, local);     expect(callback(node)).toBeUndefined();    callback(null);    expect(seen).toEqual([node, null]);    expect(local.current).toBeNull();  });   it("preserves a React 19 cleanup and clears the local ref inside it", () => {    let cleanedUp = false;    const local: { current: typeof node | null } = { current: null };    const callback = composedRefCallback(() => {      return () => {        cleanedUp = true;      };    }, local);     const cleanup = callback(node);    expect(local.current).toBe(node);    expect(typeof cleanup).toBe("function");     (cleanup as () => void)();    expect(cleanedUp).toBe(true);    expect(local.current).toBeNull();  });   it("still tracks the local ref when no outer ref is given", () => {    const local: { current: typeof node | null } = { current: null };    const callback = composedRefCallback(undefined, local);    callback(node);    expect(local.current).toBe(node);    callback(null);    expect(local.current).toBeNull();  });});