import { act, render } from "@testing-library/react"; import FramePulse from "./FramePulse"; const mockInvalidate = jest.fn(); jest.mock("@react-three/fiber", () => ({ useThree: (select: (state: { invalidate: () => void }) => unknown) => select({ invalidate: mockInvalidate }), })); beforeEach(() => { jest.useFakeTimers(); mockInvalidate.mockClear(); }); afterEach(() => { jest.useRealTimers(); }); describe("FramePulse", () => { it("asks for frames at about 30 per second while active, not 60", () => { render(); act(() => { jest.advanceTimersByTime(1000); }); expect(mockInvalidate.mock.calls.length).toBeGreaterThan(20); expect(mockInvalidate.mock.calls.length).toBeLessThanOrEqual(34); }); it("draws nothing at all when it is not active (off screen)", () => { const { rerender } = render(); act(() => { jest.advanceTimersByTime(1000); }); expect(mockInvalidate).not.toHaveBeenCalled(); rerender(); act(() => { jest.advanceTimersByTime(200); }); const running = mockInvalidate.mock.calls.length; expect(running).toBeGreaterThan(0); rerender(); act(() => { jest.advanceTimersByTime(1000); }); expect(mockInvalidate.mock.calls.length).toBe(running); }); });