diff --git a/package.json b/package.json index 7101db24..3638a5dd 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,7 @@ "lint-staged": "9.2.3", "markdown-loader": "5.1.0", "prettier": "1.18.2", + "raf-stub": "^3.0.0", "react": "16.9.0", "react-dom": "16.9.0", "react-spring": "8.0.27", diff --git a/src/__tests__/useRafLoop.test.tsx b/src/__tests__/useRafLoop.test.tsx index ec1f086d..522814e8 100644 --- a/src/__tests__/useRafLoop.test.tsx +++ b/src/__tests__/useRafLoop.test.tsx @@ -1,23 +1,26 @@ import { act, renderHook } from '@testing-library/react-hooks'; +import { replaceRaf } from 'raf-stub'; import useRafLoop from '../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', () => { - it('should be defined', () => { - expect(useRafLoop).toBeDefined(); + beforeAll(() => { + replaceRaf(); }); - it('should call a callback constantly inside the raf loop', done => { - let calls = 0; - const spy = () => calls++; - renderHook(() => useRafLoop(spy), { initialProps: false }); + afterEach(() => { + requestAnimationFrame.reset(); + }); - expect(calls).toEqual(0); - - setTimeout(() => { - expect(calls).toBeGreaterThanOrEqual(2); - - done(); - }, 120); + it('should be defined', () => { + expect(useRafLoop).toBeDefined(); }); it('should return stop function, start function and loop state', () => { @@ -28,26 +31,31 @@ describe('useRafLoop', () => { expect(typeof hook.result.current[2]).toEqual('function'); }); - it('first element call should stop the loop', done => { - let calls = 0; - const spy = () => calls++; + 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 }); - // stop the loop + expect(spy).not.toBeCalled(); + act(() => { hook.result.current[0](); }); - - setTimeout(() => { - expect(calls).toEqual(0); - - done(); - }, 50); + requestAnimationFrame.step(); + expect(spy).not.toBeCalled(); }); - it('second element should represent loop state', done => { - let calls = 0; - const spy = () => calls++; + 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); @@ -56,56 +64,39 @@ describe('useRafLoop', () => { act(() => { hook.result.current[0](); }); - expect(hook.result.current[1]).toBe(false); - setTimeout(() => { - expect(calls).toEqual(0); - - done(); - }, 120); }); - it('third element call should restart loop', done => { - let calls = 0; - const spy = () => calls++; + it('third element call should restart loop', () => { + const spy = jest.fn(); const hook = renderHook(() => useRafLoop(spy), { initialProps: false }); - expect(hook.result.current[1]).toBe(true); - + expect(spy).not.toBeCalled(); // stop the loop act(() => { hook.result.current[0](); }); + requestAnimationFrame.step(); + expect(spy).not.toBeCalled(); - setTimeout(() => { - expect(hook.result.current[1]).toBe(false); - expect(calls).toEqual(0); + // start the loop + act(() => { + hook.result.current[2](); + }); - // start the loop - act(() => { - hook.result.current[2](); - }); - - setTimeout(() => { - expect(hook.result.current[1]).toBe(true); - expect(calls).toBeGreaterThanOrEqual(2); - - done(); - }, 120); - }, 50); + requestAnimationFrame.step(); + requestAnimationFrame.step(); + expect(spy).toBeCalledTimes(2); }); - it('loop should stop itself on unmount', done => { - let calls = 0; - const spy = () => calls++; + it('loop should stop itself on unmount', () => { + const spy = jest.fn(); const hook = renderHook(() => useRafLoop(spy), { initialProps: false }); hook.unmount(); - setTimeout(() => { - expect(calls).toEqual(0); + requestAnimationFrame.step(); - done(); - }, 50); + expect(spy).not.toBeCalled(); }); }); diff --git a/yarn.lock b/yarn.lock index 28210218..02a3f49e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9973,6 +9973,11 @@ raf-schd@^4.0.0: resolved "https://registry.yarnpkg.com/raf-schd/-/raf-schd-4.0.2.tgz#bd44c708188f2e84c810bf55fcea9231bcaed8a0" integrity sha512-VhlMZmGy6A6hrkJWHLNTGl5gtgMUm+xfGza6wbwnE914yeQ5Ybm18vgM734RZhMgfw4tacUrWseGZlpUrrakEQ== +raf-stub@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/raf-stub/-/raf-stub-3.0.0.tgz#40e53dc3ad3b241311f914bbd41dc11a2c9ee0a9" + integrity sha512-64wjDTI8NAkplC3WYF3DUBXmdx8AZF0ubxiicZi83BKW5hcdvMtbwDe6gpFBngTo6+XIJbfwmUP8lMa85UPK6A== + raf@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.0.tgz#a28876881b4bc2ca9117d4138163ddb80f781575"