Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@testing-library/react-hooks

Package Overview
Dependencies
Maintainers
16
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@testing-library/react-hooks - npm Package Compare versions

Comparing version 7.0.2 to 8.0.0-alpha.1

lib/helpers/fakeTimers.d.ts

16

lib/core/asyncUtils.js

@@ -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 @@ },

{
"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": {

@@ -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>

@@ -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 @@ },

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc