@testing-library/react-hooks
Advanced tools
| export declare const fakeTimersAreEnabled: () => boolean; | ||
| export declare function advanceTimers(checkComplete: () => boolean): Promise<void>; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { | ||
| value: true | ||
| }); | ||
| exports.advanceTimers = advanceTimers; | ||
| exports.fakeTimersAreEnabled = void 0; | ||
| const fakeTimersAreEnabled = () => { | ||
| /* istanbul ignore else */ | ||
| if (typeof jest !== 'undefined' && jest !== null) { | ||
| return (// legacy timers | ||
| jest.isMockFunction(setTimeout) || // modern timers | ||
| Object.prototype.hasOwnProperty.call(setTimeout, 'clock') | ||
| ); | ||
| } // istanbul ignore next | ||
| return false; | ||
| }; | ||
| exports.fakeTimersAreEnabled = fakeTimersAreEnabled; | ||
| function advanceTimers(checkComplete) { | ||
| const advanceTime = async () => { | ||
| if (!checkComplete()) { | ||
| jest.advanceTimersByTime(1); | ||
| await Promise.resolve(); | ||
| await advanceTime(); | ||
| } | ||
| }; | ||
| return advanceTime(); | ||
| } |
| export const fakeTimersAreEnabled = () => { | ||
| /* istanbul ignore else */ | ||
| if (typeof jest !== 'undefined' && jest !== null) { | ||
| return ( | ||
| // legacy timers | ||
| jest.isMockFunction(setTimeout) || | ||
| // modern timers | ||
| Object.prototype.hasOwnProperty.call(setTimeout, 'clock') | ||
| ) | ||
| } | ||
| // istanbul ignore next | ||
| return false | ||
| } | ||
| export function advanceTimers(checkComplete: () => boolean) { | ||
| const advanceTime = async () => { | ||
| if (!checkComplete()) { | ||
| jest.advanceTimersByTime(1) | ||
| await Promise.resolve() | ||
| await advanceTime() | ||
| } | ||
| } | ||
| return advanceTime() | ||
| } |
@@ -25,11 +25,13 @@ "use strict"; | ||
| const timeoutSignal = (0, _createTimeoutController.createTimeoutController)(timeout); | ||
| const timeoutController = (0, _createTimeoutController.createTimeoutController)(timeout, { | ||
| allowFakeTimers: true | ||
| }); | ||
| const waitForResult = async () => { | ||
| while (true) { | ||
| const intervalSignal = (0, _createTimeoutController.createTimeoutController)(interval); | ||
| timeoutSignal.onTimeout(() => intervalSignal.cancel()); | ||
| await intervalSignal.wrap(new Promise(addResolver)); | ||
| const intervalController = (0, _createTimeoutController.createTimeoutController)(interval); | ||
| timeoutController.onTimeout(() => intervalController.cancel()); | ||
| await intervalController.wrap(new Promise(addResolver)); | ||
| if (checkResult() || timeoutSignal.timedOut) { | ||
| if (checkResult() || timeoutController.timedOut) { | ||
| return; | ||
@@ -41,6 +43,6 @@ } | ||
| if (!checkResult()) { | ||
| await act(() => timeoutSignal.wrap(waitForResult())); | ||
| await act(() => timeoutController.wrap(waitForResult())); | ||
| } | ||
| return !timeoutSignal.timedOut; | ||
| return !timeoutController.timedOut; | ||
| }; | ||
@@ -47,0 +49,0 @@ |
@@ -1,3 +0,4 @@ | ||
| import { WaitOptions } from '../types'; | ||
| declare function createTimeoutController(timeout: WaitOptions['timeout']): { | ||
| declare function createTimeoutController(timeout: number | false, { allowFakeTimers }?: { | ||
| allowFakeTimers?: boolean | undefined; | ||
| }): { | ||
| onTimeout(callback: () => void): void; | ||
@@ -4,0 +5,0 @@ wrap(promise: Promise<void>): Promise<void>; |
@@ -8,5 +8,10 @@ "use strict"; | ||
| function createTimeoutController(timeout) { | ||
| var _fakeTimers = require("./fakeTimers"); | ||
| function createTimeoutController(timeout, { | ||
| allowFakeTimers = false | ||
| } = {}) { | ||
| let timeoutId; | ||
| const timeoutCallbacks = []; | ||
| let finished = false; | ||
| const timeoutController = { | ||
@@ -24,2 +29,3 @@ onTimeout(callback) { | ||
| timeoutId = setTimeout(() => { | ||
| finished = true; | ||
| timeoutController.timedOut = true; | ||
@@ -31,3 +37,10 @@ timeoutCallbacks.forEach(callback => callback()); | ||
| promise.then(resolve).catch(reject).finally(() => timeoutController.cancel()); | ||
| if ((0, _fakeTimers.fakeTimersAreEnabled)() && allowFakeTimers) { | ||
| (0, _fakeTimers.advanceTimers)(() => finished); | ||
| } | ||
| promise.then(resolve).catch(reject).finally(() => { | ||
| finished = true; | ||
| timeoutController.cancel(); | ||
| }); | ||
| }); | ||
@@ -37,2 +50,3 @@ }, | ||
| cancel() { | ||
| finished = true; | ||
| clearTimeout(timeoutId); | ||
@@ -39,0 +53,0 @@ }, |
+6
-6
| { | ||
| "name": "@testing-library/react-hooks", | ||
| "version": "7.0.2", | ||
| "version": "8.0.0-alpha.1", | ||
| "description": "Simple and complete React hooks testing utilities that encourage good testing practices.", | ||
@@ -59,4 +59,4 @@ "main": "lib/index.js", | ||
| "devDependencies": { | ||
| "@typescript-eslint/eslint-plugin": "4.30.0", | ||
| "@typescript-eslint/parser": "4.30.0", | ||
| "@typescript-eslint/eslint-plugin": "4.31.1", | ||
| "@typescript-eslint/parser": "4.31.1", | ||
| "all-contributors-cli": "6.20.0", | ||
@@ -70,4 +70,4 @@ "codecov": "3.8.3", | ||
| "get-pkg-repo": "4.1.1", | ||
| "kcd-scripts": "11.2.0", | ||
| "prettier": "2.3.2", | ||
| "kcd-scripts": "11.2.2", | ||
| "prettier": "2.4.1", | ||
| "react": "17.0.2", | ||
@@ -77,3 +77,3 @@ "react-dom": "17.0.2", | ||
| "ts-node": "10.2.1", | ||
| "typescript": "4.4.2" | ||
| "typescript": "4.4.3" | ||
| }, | ||
@@ -80,0 +80,0 @@ "peerDependencies": { |
+1
-1
@@ -250,3 +250,3 @@ <div align="center"> | ||
| <td align="center"><a href="https://github.com/snowystinger"><img src="https://avatars.githubusercontent.com/u/698229?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Robert Snow</b></sub></a><br /><a href="https://github.com/testing-library/react-hooks-testing-library/commits?author=snowystinger" title="Tests">⚠️</a></td> | ||
| <td align="center"><a href="https://github.com/chris110408"><img src="https://avatars.githubusercontent.com/u/10645051?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Chris Chen</b></sub></a><br /><a href="https://github.com/testing-library/react-hooks-testing-library/commits?author=chris110408" title="Tests">⚠️</a></td> | ||
| <td align="center"><a href="https://github.com/chris110408"><img src="https://avatars.githubusercontent.com/u/10645051?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Chris Chen</b></sub></a><br /><a href="https://github.com/testing-library/react-hooks-testing-library/commits?author=chris110408" title="Code">💻</a> <a href="https://github.com/testing-library/react-hooks-testing-library/commits?author=chris110408" title="Tests">⚠️</a></td> | ||
| <td align="center"><a href="https://www.facebook.com/masoud.bonabi"><img src="https://avatars.githubusercontent.com/u/6429009?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Masious</b></sub></a><br /><a href="https://github.com/testing-library/react-hooks-testing-library/commits?author=masious" title="Documentation">📖</a></td> | ||
@@ -253,0 +253,0 @@ </tr> |
+174
-159
@@ -24,236 +24,251 @@ import { useState, useRef, useEffect } from 'react' | ||
| } | ||
| describe.each([ | ||
| { timerType: 'real timer', setTimer: () => jest.useRealTimers() }, | ||
| { timerType: 'fake timer (legacy)', setTimer: () => jest.useFakeTimers('legacy') }, | ||
| { timerType: 'fake timer (modern)', setTimer: () => jest.useFakeTimers('modern') } | ||
| ])('$timerType', ({ setTimer }) => { | ||
| beforeEach(() => { | ||
| setTimer() | ||
| }) | ||
| runForRenderers(['default', 'dom', 'native', 'server/hydrated'], ({ renderHook }) => { | ||
| test('should wait for next update', async () => { | ||
| const { result, waitForNextUpdate } = renderHook(() => useSequence(['first', 'second'])) | ||
| afterEach(() => { | ||
| jest.useRealTimers() | ||
| }) | ||
| expect(result.current).toBe('first') | ||
| runForRenderers(['default', 'dom', 'native', 'server/hydrated'], ({ renderHook }) => { | ||
| test('should wait for next update', async () => { | ||
| const { result, waitForNextUpdate } = renderHook(() => useSequence(['first', 'second'])) | ||
| await waitForNextUpdate() | ||
| expect(result.current).toBe('first') | ||
| expect(result.current).toBe('second') | ||
| }) | ||
| await waitForNextUpdate() | ||
| test('should wait for multiple updates', async () => { | ||
| const { result, waitForNextUpdate } = renderHook(() => | ||
| useSequence(['first', 'second', 'third']) | ||
| ) | ||
| expect(result.current).toBe('second') | ||
| }) | ||
| expect(result.current).toBe('first') | ||
| test('should wait for multiple updates', async () => { | ||
| const { result, waitForNextUpdate } = renderHook(() => | ||
| useSequence(['first', 'second', 'third']) | ||
| ) | ||
| await waitForNextUpdate() | ||
| expect(result.current).toBe('first') | ||
| expect(result.current).toBe('second') | ||
| await waitForNextUpdate() | ||
| await waitForNextUpdate() | ||
| expect(result.current).toBe('second') | ||
| expect(result.current).toBe('third') | ||
| }) | ||
| await waitForNextUpdate() | ||
| test('should reject if timeout exceeded when waiting for next update', async () => { | ||
| const { result, waitForNextUpdate } = renderHook(() => useSequence(['first', 'second'])) | ||
| expect(result.current).toBe('third') | ||
| }) | ||
| expect(result.current).toBe('first') | ||
| test('should reject if timeout exceeded when waiting for next update', async () => { | ||
| const { result, waitForNextUpdate } = renderHook(() => useSequence(['first', 'second'])) | ||
| await expect(waitForNextUpdate({ timeout: 10 })).rejects.toThrow( | ||
| Error('Timed out in waitForNextUpdate after 10ms.') | ||
| ) | ||
| }) | ||
| expect(result.current).toBe('first') | ||
| test('should not reject when waiting for next update if timeout has been disabled', async () => { | ||
| const { result, waitForNextUpdate } = renderHook(() => useSequence(['first', 'second'], 1100)) | ||
| await expect(waitForNextUpdate({ timeout: 10 })).rejects.toThrow( | ||
| Error('Timed out in waitForNextUpdate after 10ms.') | ||
| ) | ||
| }) | ||
| expect(result.current).toBe('first') | ||
| test('should not reject when waiting for next update if timeout has been disabled', async () => { | ||
| const { result, waitForNextUpdate } = renderHook(() => | ||
| useSequence(['first', 'second'], 1100) | ||
| ) | ||
| await waitForNextUpdate({ timeout: false }) | ||
| expect(result.current).toBe('first') | ||
| expect(result.current).toBe('second') | ||
| }) | ||
| await waitForNextUpdate({ timeout: false }) | ||
| test('should wait for expectation to pass', async () => { | ||
| const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) | ||
| expect(result.current).toBe('second') | ||
| }) | ||
| expect(result.current).toBe('first') | ||
| test('should wait for expectation to pass', async () => { | ||
| const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) | ||
| let complete = false | ||
| await waitFor(() => { | ||
| expect(result.current).toBe('third') | ||
| complete = true | ||
| expect(result.current).toBe('first') | ||
| let complete = false | ||
| await waitFor(() => { | ||
| expect(result.current).toBe('third') | ||
| complete = true | ||
| }) | ||
| expect(complete).toBe(true) | ||
| }) | ||
| expect(complete).toBe(true) | ||
| }) | ||
| test('should wait for arbitrary expectation to pass', async () => { | ||
| const { waitFor } = renderHook(() => null) | ||
| test('should wait for arbitrary expectation to pass', async () => { | ||
| const { waitFor } = renderHook(() => null) | ||
| let actual = 0 | ||
| const expected = 1 | ||
| let actual = 0 | ||
| const expected = 1 | ||
| setTimeout(() => { | ||
| actual = expected | ||
| }, 200) | ||
| setTimeout(() => { | ||
| actual = expected | ||
| }, 200) | ||
| let complete = false | ||
| await waitFor(() => { | ||
| expect(actual).toBe(expected) | ||
| complete = true | ||
| let complete = false | ||
| await waitFor(() => { | ||
| expect(actual).toBe(expected) | ||
| complete = true | ||
| }) | ||
| expect(complete).toBe(true) | ||
| }) | ||
| expect(complete).toBe(true) | ||
| }) | ||
| test('should not hang if expectation is already passing', async () => { | ||
| const { result, waitFor } = renderHook(() => useSequence(['first', 'second'])) | ||
| test('should not hang if expectation is already passing', async () => { | ||
| const { result, waitFor } = renderHook(() => useSequence(['first', 'second'])) | ||
| expect(result.current).toBe('first') | ||
| expect(result.current).toBe('first') | ||
| let complete = false | ||
| await waitFor(() => { | ||
| expect(result.current).toBe('first') | ||
| complete = true | ||
| }) | ||
| expect(complete).toBe(true) | ||
| }) | ||
| let complete = false | ||
| await waitFor(() => { | ||
| test('should wait for truthy value', async () => { | ||
| const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) | ||
| expect(result.current).toBe('first') | ||
| complete = true | ||
| await waitFor(() => result.current === 'third') | ||
| expect(result.current).toBe('third') | ||
| }) | ||
| expect(complete).toBe(true) | ||
| }) | ||
| test('should wait for truthy value', async () => { | ||
| const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) | ||
| test('should wait for arbitrary truthy value', async () => { | ||
| const { waitFor } = renderHook(() => null) | ||
| expect(result.current).toBe('first') | ||
| let actual = 0 | ||
| const expected = 1 | ||
| await waitFor(() => result.current === 'third') | ||
| setTimeout(() => { | ||
| actual = expected | ||
| }, 200) | ||
| expect(result.current).toBe('third') | ||
| }) | ||
| await waitFor(() => actual === 1) | ||
| test('should wait for arbitrary truthy value', async () => { | ||
| const { waitFor } = renderHook(() => null) | ||
| expect(actual).toBe(expected) | ||
| }) | ||
| let actual = 0 | ||
| const expected = 1 | ||
| test('should reject if timeout exceeded when waiting for expectation to pass', async () => { | ||
| const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) | ||
| setTimeout(() => { | ||
| actual = expected | ||
| }, 200) | ||
| expect(result.current).toBe('first') | ||
| await waitFor(() => actual === 1) | ||
| await expect( | ||
| waitFor( | ||
| () => { | ||
| expect(result.current).toBe('third') | ||
| }, | ||
| { timeout: 75 } | ||
| ) | ||
| ).rejects.toThrow(Error('Timed out in waitFor after 75ms.')) | ||
| }) | ||
| expect(actual).toBe(expected) | ||
| }) | ||
| test('should not reject when waiting for expectation to pass if timeout has been disabled', async () => { | ||
| const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'], 550)) | ||
| test('should reject if timeout exceeded when waiting for expectation to pass', async () => { | ||
| const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) | ||
| expect(result.current).toBe('first') | ||
| expect(result.current).toBe('first') | ||
| await expect( | ||
| waitFor( | ||
| await waitFor( | ||
| () => { | ||
| expect(result.current).toBe('third') | ||
| }, | ||
| { timeout: 75 } | ||
| { timeout: false } | ||
| ) | ||
| ).rejects.toThrow(Error('Timed out in waitFor after 75ms.')) | ||
| }) | ||
| test('should not reject when waiting for expectation to pass if timeout has been disabled', async () => { | ||
| const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'], 550)) | ||
| expect(result.current).toBe('third') | ||
| }) | ||
| expect(result.current).toBe('first') | ||
| test('should check on interval when waiting for expectation to pass', async () => { | ||
| const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) | ||
| await waitFor( | ||
| () => { | ||
| expect(result.current).toBe('third') | ||
| }, | ||
| { timeout: false } | ||
| ) | ||
| let checks = 0 | ||
| expect(result.current).toBe('third') | ||
| }) | ||
| await waitFor( | ||
| () => { | ||
| checks++ | ||
| return result.current === 'third' | ||
| }, | ||
| { interval: 100 } | ||
| ) | ||
| test('should check on interval when waiting for expectation to pass', async () => { | ||
| const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) | ||
| expect(checks).toBe(3) | ||
| }) | ||
| let checks = 0 | ||
| test('should wait for value to change', async () => { | ||
| const { result, waitForValueToChange } = renderHook(() => | ||
| useSequence(['first', 'second', 'third']) | ||
| ) | ||
| await waitFor( | ||
| () => { | ||
| checks++ | ||
| return result.current === 'third' | ||
| }, | ||
| { interval: 100 } | ||
| ) | ||
| expect(result.current).toBe('first') | ||
| expect(checks).toBe(3) | ||
| }) | ||
| await waitForValueToChange(() => result.current === 'third') | ||
| test('should wait for value to change', async () => { | ||
| const { result, waitForValueToChange } = renderHook(() => | ||
| useSequence(['first', 'second', 'third']) | ||
| ) | ||
| expect(result.current).toBe('third') | ||
| }) | ||
| expect(result.current).toBe('first') | ||
| test('should wait for arbitrary value to change', async () => { | ||
| const { waitForValueToChange } = renderHook(() => null) | ||
| await waitForValueToChange(() => result.current === 'third') | ||
| let actual = 0 | ||
| const expected = 1 | ||
| expect(result.current).toBe('third') | ||
| }) | ||
| setTimeout(() => { | ||
| actual = expected | ||
| }, 200) | ||
| test('should wait for arbitrary value to change', async () => { | ||
| const { waitForValueToChange } = renderHook(() => null) | ||
| await waitForValueToChange(() => actual) | ||
| let actual = 0 | ||
| const expected = 1 | ||
| expect(actual).toBe(expected) | ||
| }) | ||
| setTimeout(() => { | ||
| actual = expected | ||
| }, 200) | ||
| test('should reject if timeout exceeded when waiting for value to change', async () => { | ||
| const { result, waitForValueToChange } = renderHook(() => | ||
| useSequence(['first', 'second', 'third']) | ||
| ) | ||
| await waitForValueToChange(() => actual) | ||
| expect(result.current).toBe('first') | ||
| expect(actual).toBe(expected) | ||
| }) | ||
| await expect( | ||
| waitForValueToChange(() => result.current === 'third', { | ||
| timeout: 75 | ||
| }) | ||
| ).rejects.toThrow(Error('Timed out in waitForValueToChange after 75ms.')) | ||
| }) | ||
| test('should reject if timeout exceeded when waiting for value to change', async () => { | ||
| const { result, waitForValueToChange } = renderHook(() => | ||
| useSequence(['first', 'second', 'third']) | ||
| ) | ||
| test('should not reject when waiting for value to change if timeout is disabled', async () => { | ||
| const { result, waitForValueToChange } = renderHook(() => | ||
| useSequence(['first', 'second', 'third'], 550) | ||
| ) | ||
| expect(result.current).toBe('first') | ||
| expect(result.current).toBe('first') | ||
| await expect( | ||
| waitForValueToChange(() => result.current === 'third', { | ||
| timeout: 75 | ||
| await waitForValueToChange(() => result.current === 'third', { | ||
| timeout: false | ||
| }) | ||
| ).rejects.toThrow(Error('Timed out in waitForValueToChange after 75ms.')) | ||
| }) | ||
| test('should not reject when waiting for value to change if timeout is disabled', async () => { | ||
| const { result, waitForValueToChange } = renderHook(() => | ||
| useSequence(['first', 'second', 'third'], 550) | ||
| ) | ||
| expect(result.current).toBe('first') | ||
| await waitForValueToChange(() => result.current === 'third', { | ||
| timeout: false | ||
| expect(result.current).toBe('third') | ||
| }) | ||
| expect(result.current).toBe('third') | ||
| }) | ||
| test('should reject if selector throws error', async () => { | ||
| const { result, waitForValueToChange } = renderHook(() => useSequence(['first', 'second'])) | ||
| test('should reject if selector throws error', async () => { | ||
| const { result, waitForValueToChange } = renderHook(() => useSequence(['first', 'second'])) | ||
| expect(result.current).toBe('first') | ||
| expect(result.current).toBe('first') | ||
| await expect( | ||
| waitForValueToChange(() => { | ||
| if (result.current === 'second') { | ||
| throw new Error('Something Unexpected') | ||
| } | ||
| return result.current | ||
| }) | ||
| ).rejects.toThrow(Error('Something Unexpected')) | ||
| await expect( | ||
| waitForValueToChange(() => { | ||
| if (result.current === 'second') { | ||
| throw new Error('Something Unexpected') | ||
| } | ||
| return result.current | ||
| }) | ||
| ).rejects.toThrow(Error('Something Unexpected')) | ||
| }) | ||
| }) | ||
| }) | ||
| }) |
@@ -17,3 +17,6 @@ import { | ||
| function asyncUtils(act: Act, addResolver: (callback: () => void) => void): AsyncUtils { | ||
| const wait = async (callback: () => boolean | void, { interval, timeout }: WaitOptions) => { | ||
| const wait = async ( | ||
| callback: () => boolean | void, | ||
| { interval, timeout }: Required<WaitOptions> | ||
| ) => { | ||
| const checkResult = () => { | ||
@@ -24,12 +27,12 @@ const callbackResult = callback() | ||
| const timeoutSignal = createTimeoutController(timeout) | ||
| const timeoutController = createTimeoutController(timeout, { allowFakeTimers: true }) | ||
| const waitForResult = async () => { | ||
| while (true) { | ||
| const intervalSignal = createTimeoutController(interval) | ||
| timeoutSignal.onTimeout(() => intervalSignal.cancel()) | ||
| const intervalController = createTimeoutController(interval) | ||
| timeoutController.onTimeout(() => intervalController.cancel()) | ||
| await intervalSignal.wrap(new Promise<void>(addResolver)) | ||
| await intervalController.wrap(new Promise<void>(addResolver)) | ||
| if (checkResult() || timeoutSignal.timedOut) { | ||
| if (checkResult() || timeoutController.timedOut) { | ||
| return | ||
@@ -41,6 +44,6 @@ } | ||
| if (!checkResult()) { | ||
| await act(() => timeoutSignal.wrap(waitForResult())) | ||
| await act(() => timeoutController.wrap(waitForResult())) | ||
| } | ||
| return !timeoutSignal.timedOut | ||
| return !timeoutController.timedOut | ||
| } | ||
@@ -47,0 +50,0 @@ |
@@ -1,6 +0,7 @@ | ||
| import { WaitOptions } from '../types' | ||
| import { fakeTimersAreEnabled, advanceTimers } from './fakeTimers' | ||
| function createTimeoutController(timeout: WaitOptions['timeout']) { | ||
| function createTimeoutController(timeout: number | false, { allowFakeTimers = false } = {}) { | ||
| let timeoutId: NodeJS.Timeout | ||
| const timeoutCallbacks: Array<() => void> = [] | ||
| let finished = false | ||
@@ -15,5 +16,5 @@ const timeoutController = { | ||
| timeoutController.onTimeout(resolve) | ||
| if (timeout) { | ||
| timeoutId = setTimeout(() => { | ||
| finished = true | ||
| timeoutController.timedOut = true | ||
@@ -25,9 +26,17 @@ timeoutCallbacks.forEach((callback) => callback()) | ||
| if (fakeTimersAreEnabled() && allowFakeTimers) { | ||
| advanceTimers(() => finished) | ||
| } | ||
| promise | ||
| .then(resolve) | ||
| .catch(reject) | ||
| .finally(() => timeoutController.cancel()) | ||
| .finally(() => { | ||
| finished = true | ||
| timeoutController.cancel() | ||
| }) | ||
| }) | ||
| }, | ||
| cancel() { | ||
| finished = true | ||
| clearTimeout(timeoutId) | ||
@@ -34,0 +43,0 @@ }, |
| describe('async hook (fake timers) tests', () => { | ||
| beforeEach(() => { | ||
| jest.useFakeTimers() | ||
| }) | ||
| afterEach(() => { | ||
| jest.useRealTimers() | ||
| }) | ||
| runForRenderers(['default', 'dom', 'native', 'server/hydrated'], ({ renderHook }) => { | ||
| test('should wait for arbitrary expectation to pass when using advanceTimersByTime()', async () => { | ||
| const { waitFor } = renderHook(() => null) | ||
| let actual = 0 | ||
| const expected = 1 | ||
| setTimeout(() => { | ||
| actual = expected | ||
| }, 200) | ||
| let complete = false | ||
| jest.advanceTimersByTime(200) | ||
| await waitFor(() => { | ||
| expect(actual).toBe(expected) | ||
| complete = true | ||
| }) | ||
| expect(complete).toBe(true) | ||
| }) | ||
| test('should wait for arbitrary expectation to pass when using runOnlyPendingTimers()', async () => { | ||
| const { waitFor } = renderHook(() => null) | ||
| let actual = 0 | ||
| const expected = 1 | ||
| setTimeout(() => { | ||
| actual = expected | ||
| }, 200) | ||
| let complete = false | ||
| jest.runOnlyPendingTimers() | ||
| await waitFor(() => { | ||
| expect(actual).toBe(expected) | ||
| complete = true | ||
| }) | ||
| expect(complete).toBe(true) | ||
| }) | ||
| }) | ||
| }) | ||
| // eslint-disable-next-line jest/no-export | ||
| export {} |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
138606
1.44%100
2.04%2893
1.76%2
100%