import { act, renderHook } from '@testing-library/react-hooks'; import { replaceRaf } from 'raf-stub'; import useRafLoop from '../src/useRafLoop'; declare var requestAnimationFrame: { add: (cb: Function) => number; remove: (id: number) => void; flush: (duration?: number) => void; reset: () => void; step: (steps?: number, duration?: number) => void; }; describe('useRafLoop', () => { beforeAll(() => { replaceRaf(); }); afterEach(() => { requestAnimationFrame.reset(); }); it('should be defined', () => { expect(useRafLoop).toBeDefined(); }); it('should return stop function, start function and loop state', () => { const hook = renderHook(() => useRafLoop(() => false), { initialProps: false }); expect(typeof hook.result.current[0]).toEqual('function'); expect(typeof hook.result.current[1]).toEqual('boolean'); expect(typeof hook.result.current[2]).toEqual('function'); }); it('should call a callback constantly inside the raf loop', () => { const spy = jest.fn(); renderHook(() => useRafLoop(spy), { initialProps: false }); expect(spy).not.toBeCalled(); requestAnimationFrame.step(); requestAnimationFrame.step(); expect(spy).toBeCalledTimes(2); }); it('first element call should stop the loop', () => { const spy = jest.fn(); const hook = renderHook(() => useRafLoop(spy), { initialProps: false }); expect(spy).not.toBeCalled(); act(() => { hook.result.current[0](); }); requestAnimationFrame.step(); expect(spy).not.toBeCalled(); }); it('second element should represent loop state', () => { const spy = jest.fn(); const hook = renderHook(() => useRafLoop(spy), { initialProps: false }); expect(hook.result.current[1]).toBe(true); // stop the loop act(() => { hook.result.current[0](); }); expect(hook.result.current[1]).toBe(false); }); it('third element call should restart loop', () => { const spy = jest.fn(); const hook = renderHook(() => useRafLoop(spy), { initialProps: false }); expect(spy).not.toBeCalled(); // stop the loop act(() => { hook.result.current[0](); }); requestAnimationFrame.step(); expect(spy).not.toBeCalled(); // start the loop act(() => { hook.result.current[2](); }); requestAnimationFrame.step(); requestAnimationFrame.step(); expect(spy).toBeCalledTimes(2); }); it('loop should stop itself on unmount', () => { const spy = jest.fn(); const hook = renderHook(() => useRafLoop(spy), { initialProps: false }); hook.unmount(); requestAnimationFrame.step(); expect(spy).not.toBeCalled(); }); });