import { act, cleanup, render, screen } from "@testing-library/react"; import { afterEach, beforeEach, expect, it, vi } from "vitest"; import { DeferredRender } from "./deferred-render"; let sequence = 0; const frames = new Map(); const tick = () => act(() => { const callbacks = [...frames.values()]; frames.clear(); callbacks.forEach((callback) => callback(0)); }); beforeEach(() => { vi.stubGlobal("IntersectionObserver", undefined); vi.stubGlobal("requestAnimationFrame", (callback: FrameRequestCallback) => { frames.set(++sequence, callback); return sequence; }); vi.stubGlobal("cancelAnimationFrame", (id: number) => frames.delete(id)); }); afterEach(() => { cleanup(); frames.clear(); vi.unstubAllGlobals(); }); it("paints loading placeholders before mounting visible drawings one at a time", () => { render(<>

甲图已就绪

乙图已就绪

); expect(screen.getByRole("status", { name: "正在加载甲图" })).toHaveAttribute("aria-busy", "true"); tick(); expect(screen.queryByText("甲图已就绪")).toBeNull(); tick(); expect(screen.getByText("甲图已就绪")).toBeInTheDocument(); expect(screen.queryByText("乙图已就绪")).toBeNull(); tick(); tick(); expect(screen.getByText("乙图已就绪")).toBeInTheDocument(); expect(screen.queryByRole("status")).toBeNull(); }); it("cancels queued drawings when the task is removed", () => { const Drawing = vi.fn(() =>

已过期图表

); const { unmount } = render(); tick(); unmount(); expect(frames.size).toBe(0); tick(); tick(); expect(Drawing).not.toHaveBeenCalled(); expect(frames.size).toBe(0); }); it("defers offscreen content until its own viewport intersection", () => { let intersect!: IntersectionObserverCallback; const disconnect = vi.fn(); vi.stubGlobal("IntersectionObserver", class { constructor(callback: IntersectionObserverCallback) { intersect = callback; } observe() {} disconnect = disconnect; }); render(

可见图表

); expect(frames.size).toBe(0); act(() => intersect([{ isIntersecting: false }] as IntersectionObserverEntry[], {} as IntersectionObserver)); expect(frames.size).toBe(0); act(() => intersect([{ isIntersecting: true }] as IntersectionObserverEntry[], {} as IntersectionObserver)); tick(); tick(); expect(screen.getByText("可见图表")).toBeInTheDocument(); expect(disconnect).toHaveBeenCalled(); });