@testing-library/react-hooks
Advanced tools
Comparing version 8.0.0-alpha.1 to 8.0.0
@@ -25,13 +25,11 @@ "use strict"; | ||
const timeoutController = (0, _createTimeoutController.createTimeoutController)(timeout, { | ||
allowFakeTimers: true | ||
}); | ||
const timeoutSignal = (0, _createTimeoutController.createTimeoutController)(timeout); | ||
const waitForResult = async () => { | ||
while (true) { | ||
const intervalController = (0, _createTimeoutController.createTimeoutController)(interval); | ||
timeoutController.onTimeout(() => intervalController.cancel()); | ||
await intervalController.wrap(new Promise(addResolver)); | ||
const intervalSignal = (0, _createTimeoutController.createTimeoutController)(interval); | ||
timeoutSignal.onTimeout(() => intervalSignal.cancel()); | ||
await intervalSignal.wrap(new Promise(addResolver)); | ||
if (checkResult() || timeoutController.timedOut) { | ||
if (checkResult() || timeoutSignal.timedOut) { | ||
return; | ||
@@ -43,6 +41,6 @@ } | ||
if (!checkResult()) { | ||
await act(() => timeoutController.wrap(waitForResult())); | ||
await act(() => timeoutSignal.wrap(waitForResult())); | ||
} | ||
return !timeoutController.timedOut; | ||
return !timeoutSignal.timedOut; | ||
}; | ||
@@ -49,0 +47,0 @@ |
@@ -6,6 +6,6 @@ "use strict"; | ||
}); | ||
exports.addCleanup = addCleanup; | ||
exports.autoRegisterCleanup = autoRegisterCleanup; | ||
exports.cleanup = cleanup; | ||
exports.addCleanup = addCleanup; | ||
exports.removeCleanup = removeCleanup; | ||
exports.autoRegisterCleanup = autoRegisterCleanup; | ||
let cleanupCallbacks = []; | ||
@@ -12,0 +12,0 @@ |
@@ -6,15 +6,15 @@ "use strict"; | ||
}); | ||
exports.createRenderHook = createRenderHook; | ||
Object.defineProperty(exports, "cleanup", { | ||
Object.defineProperty(exports, "addCleanup", { | ||
enumerable: true, | ||
get: function () { | ||
return _cleanup.cleanup; | ||
return _cleanup.addCleanup; | ||
} | ||
}); | ||
Object.defineProperty(exports, "addCleanup", { | ||
Object.defineProperty(exports, "cleanup", { | ||
enumerable: true, | ||
get: function () { | ||
return _cleanup.addCleanup; | ||
return _cleanup.cleanup; | ||
} | ||
}); | ||
exports.createRenderHook = createRenderHook; | ||
Object.defineProperty(exports, "removeCleanup", { | ||
@@ -21,0 +21,0 @@ enumerable: true, |
@@ -20,12 +20,12 @@ "use strict"; | ||
}); | ||
Object.defineProperty(exports, "cleanup", { | ||
Object.defineProperty(exports, "addCleanup", { | ||
enumerable: true, | ||
get: function () { | ||
return _core.cleanup; | ||
return _core.addCleanup; | ||
} | ||
}); | ||
Object.defineProperty(exports, "addCleanup", { | ||
Object.defineProperty(exports, "cleanup", { | ||
enumerable: true, | ||
get: function () { | ||
return _core.addCleanup; | ||
return _core.cleanup; | ||
} | ||
@@ -39,2 +39,3 @@ }); | ||
}); | ||
exports.renderHook = void 0; | ||
Object.defineProperty(exports, "suppressErrorOutput", { | ||
@@ -46,3 +47,2 @@ enumerable: true, | ||
}); | ||
exports.renderHook = void 0; | ||
@@ -49,0 +49,0 @@ var ReactDOM = _interopRequireWildcard(require("react-dom")); |
@@ -1,4 +0,3 @@ | ||
declare function createTimeoutController(timeout: number | false, { allowFakeTimers }?: { | ||
allowFakeTimers?: boolean | undefined; | ||
}): { | ||
import { WaitOptions } from '../types'; | ||
declare function createTimeoutController(timeout: WaitOptions['timeout']): { | ||
onTimeout(callback: () => void): void; | ||
@@ -5,0 +4,0 @@ wrap(promise: Promise<void>): Promise<void>; |
@@ -8,10 +8,5 @@ "use strict"; | ||
var _fakeTimers = require("./fakeTimers"); | ||
function createTimeoutController(timeout, { | ||
allowFakeTimers = false | ||
} = {}) { | ||
function createTimeoutController(timeout) { | ||
let timeoutId; | ||
const timeoutCallbacks = []; | ||
let finished = false; | ||
const timeoutController = { | ||
@@ -29,3 +24,2 @@ onTimeout(callback) { | ||
timeoutId = setTimeout(() => { | ||
finished = true; | ||
timeoutController.timedOut = true; | ||
@@ -37,10 +31,3 @@ timeoutCallbacks.forEach(callback => callback()); | ||
if ((0, _fakeTimers.fakeTimersAreEnabled)() && allowFakeTimers) { | ||
(0, _fakeTimers.advanceTimers)(() => finished); | ||
} | ||
promise.then(resolve).catch(reject).finally(() => { | ||
finished = true; | ||
timeoutController.cancel(); | ||
}); | ||
promise.then(resolve).catch(reject).finally(() => timeoutController.cancel()); | ||
}); | ||
@@ -50,3 +37,2 @@ }, | ||
cancel() { | ||
finished = true; | ||
clearTimeout(timeoutId); | ||
@@ -53,0 +39,0 @@ }, |
@@ -20,12 +20,12 @@ "use strict"; | ||
}); | ||
Object.defineProperty(exports, "cleanup", { | ||
Object.defineProperty(exports, "addCleanup", { | ||
enumerable: true, | ||
get: function () { | ||
return _core.cleanup; | ||
return _core.addCleanup; | ||
} | ||
}); | ||
Object.defineProperty(exports, "addCleanup", { | ||
Object.defineProperty(exports, "cleanup", { | ||
enumerable: true, | ||
get: function () { | ||
return _core.addCleanup; | ||
return _core.cleanup; | ||
} | ||
@@ -39,2 +39,3 @@ }); | ||
}); | ||
exports.renderHook = void 0; | ||
Object.defineProperty(exports, "suppressErrorOutput", { | ||
@@ -46,3 +47,2 @@ enumerable: true, | ||
}); | ||
exports.renderHook = void 0; | ||
@@ -49,0 +49,0 @@ var _reactTestRenderer = require("react-test-renderer"); |
@@ -14,3 +14,3 @@ "use strict"; | ||
}; | ||
exports.suppressErrorOutput = exports.removeCleanup = exports.addCleanup = exports.cleanup = exports.act = exports.renderHook = void 0; | ||
exports.suppressErrorOutput = exports.renderHook = exports.removeCleanup = exports.cleanup = exports.addCleanup = exports.act = void 0; | ||
@@ -17,0 +17,0 @@ var _react = require("./types/react"); |
@@ -20,12 +20,12 @@ "use strict"; | ||
}); | ||
Object.defineProperty(exports, "cleanup", { | ||
Object.defineProperty(exports, "addCleanup", { | ||
enumerable: true, | ||
get: function () { | ||
return _core.cleanup; | ||
return _core.addCleanup; | ||
} | ||
}); | ||
Object.defineProperty(exports, "addCleanup", { | ||
Object.defineProperty(exports, "cleanup", { | ||
enumerable: true, | ||
get: function () { | ||
return _core.addCleanup; | ||
return _core.cleanup; | ||
} | ||
@@ -39,2 +39,3 @@ }); | ||
}); | ||
exports.renderHook = void 0; | ||
Object.defineProperty(exports, "suppressErrorOutput", { | ||
@@ -46,3 +47,2 @@ enumerable: true, | ||
}); | ||
exports.renderHook = void 0; | ||
@@ -49,0 +49,0 @@ var ReactDOMServer = _interopRequireWildcard(require("react-dom/server")); |
{ | ||
"name": "@testing-library/react-hooks", | ||
"version": "8.0.0-alpha.1", | ||
"version": "8.0.0", | ||
"description": "Simple and complete React hooks testing utilities that encourage good testing practices.", | ||
@@ -53,13 +53,13 @@ "main": "lib/index.js", | ||
"@babel/runtime": "^7.12.5", | ||
"@types/react": ">=16.9.0", | ||
"@types/react-dom": ">=16.9.0", | ||
"@types/react-test-renderer": ">=16.9.0", | ||
"react-error-boundary": "^3.1.0" | ||
}, | ||
"devDependencies": { | ||
"@typescript-eslint/eslint-plugin": "4.31.1", | ||
"@typescript-eslint/parser": "4.31.1", | ||
"@types/react": "17.0.44", | ||
"@types/react-dom": "17.0.15", | ||
"@types/react-test-renderer": "17.0.1", | ||
"@typescript-eslint/eslint-plugin": "5.11.0", | ||
"@typescript-eslint/parser": "5.11.0", | ||
"all-contributors-cli": "6.20.0", | ||
"codecov": "3.8.3", | ||
"cross-env": "^7.0.3", | ||
"cross-env": "7.0.3", | ||
"docz": "2.3.1", | ||
@@ -71,15 +71,19 @@ "docz-theme-default": "1.2.0", | ||
"kcd-scripts": "11.2.2", | ||
"prettier": "2.4.1", | ||
"prettier": "2.5.1", | ||
"react": "17.0.2", | ||
"react-dom": "17.0.2", | ||
"react-test-renderer": "17.0.2", | ||
"ts-node": "10.2.1", | ||
"typescript": "4.4.3" | ||
"ts-node": "10.5.0", | ||
"typescript": "4.5.5" | ||
}, | ||
"peerDependencies": { | ||
"react": ">=16.9.0", | ||
"react-dom": ">=16.9.0", | ||
"react-test-renderer": ">=16.9.0" | ||
"@types/react": "^16.9.0 || ^17.0.0", | ||
"react": "^16.9.0 || ^17.0.0", | ||
"react-dom": "^16.9.0 || ^17.0.0", | ||
"react-test-renderer": "^16.9.0 || ^17.0.0" | ||
}, | ||
"peerDependenciesMeta": { | ||
"@types/react": { | ||
"optional": true | ||
}, | ||
"react-dom": { | ||
@@ -86,0 +90,0 @@ "optional": true |
@@ -40,2 +40,13 @@ <div align="center"> | ||
## A Note about React 18 Support | ||
As part of the changes for React 18, it has been decided that the `renderHook` API provided by this | ||
library will instead be included as official additions to both `react-testing-library` | ||
([PR](https://github.com/testing-library/react-testing-library/pull/991)) and | ||
`react-native-testing-library` | ||
([PR](https://github.com/callstack/react-native-testing-library/pull/923)) with the intention being | ||
to provide a more cohesive and consistent implementation for our users. | ||
Please be patient as we finalise these changes in the respective testing libraries. | ||
## Table of Contents | ||
@@ -150,5 +161,5 @@ | ||
however, if you do have both installed, we will use `react-test-renderer` as the default. For more | ||
information see the [installation docs](https://react-hooks-testing-library.com/#installation). | ||
Generally, the installed versions for `react` and the selected renderer should have matching | ||
versions: | ||
information see the | ||
[installation docs](https://react-hooks-testing-library.com/installation#renderer). Generally, the | ||
installed versions for `react` and the selected renderer should have matching versions: | ||
@@ -252,4 +263,5 @@ ```sh | ||
<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="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://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://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> | ||
<td align="center"><a href="https://github.com/Laishuxin"><img src="https://avatars.githubusercontent.com/u/56504759?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Laishuxin</b></sub></a><br /><a href="https://github.com/testing-library/react-hooks-testing-library/commits?author=Laishuxin" title="Documentation">📖</a></td> | ||
</tr> | ||
@@ -256,0 +268,0 @@ </table> |
@@ -24,251 +24,236 @@ 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() | ||
}) | ||
afterEach(() => { | ||
jest.useRealTimers() | ||
}) | ||
runForRenderers(['default', 'dom', 'native', 'server/hydrated'], ({ renderHook }) => { | ||
test('should wait for next update', async () => { | ||
const { result, waitForNextUpdate } = renderHook(() => useSequence(['first', 'second'])) | ||
runForRenderers(['default', 'dom', 'native', 'server/hydrated'], ({ renderHook }) => { | ||
test('should wait for next update', async () => { | ||
const { result, waitForNextUpdate } = renderHook(() => useSequence(['first', 'second'])) | ||
expect(result.current).toBe('first') | ||
expect(result.current).toBe('first') | ||
await waitForNextUpdate() | ||
await waitForNextUpdate() | ||
expect(result.current).toBe('second') | ||
}) | ||
expect(result.current).toBe('second') | ||
}) | ||
test('should wait for multiple updates', async () => { | ||
const { result, waitForNextUpdate } = renderHook(() => | ||
useSequence(['first', 'second', 'third']) | ||
) | ||
test('should wait for multiple updates', async () => { | ||
const { result, waitForNextUpdate } = renderHook(() => | ||
useSequence(['first', 'second', 'third']) | ||
) | ||
expect(result.current).toBe('first') | ||
expect(result.current).toBe('first') | ||
await waitForNextUpdate() | ||
await waitForNextUpdate() | ||
expect(result.current).toBe('second') | ||
expect(result.current).toBe('second') | ||
await waitForNextUpdate() | ||
await waitForNextUpdate() | ||
expect(result.current).toBe('third') | ||
}) | ||
expect(result.current).toBe('third') | ||
}) | ||
test('should reject if timeout exceeded when waiting for next update', async () => { | ||
const { result, waitForNextUpdate } = renderHook(() => useSequence(['first', 'second'])) | ||
test('should reject if timeout exceeded when waiting for next update', async () => { | ||
const { result, waitForNextUpdate } = renderHook(() => useSequence(['first', 'second'])) | ||
expect(result.current).toBe('first') | ||
expect(result.current).toBe('first') | ||
await expect(waitForNextUpdate({ timeout: 10 })).rejects.toThrow( | ||
Error('Timed out in waitForNextUpdate after 10ms.') | ||
) | ||
}) | ||
await expect(waitForNextUpdate({ timeout: 10 })).rejects.toThrow( | ||
Error('Timed out in waitForNextUpdate after 10ms.') | ||
) | ||
}) | ||
test('should not reject when waiting for next update if timeout has been disabled', async () => { | ||
const { result, waitForNextUpdate } = renderHook(() => useSequence(['first', 'second'], 1100)) | ||
test('should not reject when waiting for next update if timeout has been disabled', async () => { | ||
const { result, waitForNextUpdate } = renderHook(() => | ||
useSequence(['first', 'second'], 1100) | ||
) | ||
expect(result.current).toBe('first') | ||
expect(result.current).toBe('first') | ||
await waitForNextUpdate({ timeout: false }) | ||
await waitForNextUpdate({ timeout: false }) | ||
expect(result.current).toBe('second') | ||
}) | ||
expect(result.current).toBe('second') | ||
}) | ||
test('should wait for expectation to pass', async () => { | ||
const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) | ||
test('should wait for expectation to pass', async () => { | ||
const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) | ||
expect(result.current).toBe('first') | ||
expect(result.current).toBe('first') | ||
let complete = false | ||
await waitFor(() => { | ||
expect(result.current).toBe('third') | ||
complete = true | ||
}) | ||
expect(complete).toBe(true) | ||
let complete = false | ||
await waitFor(() => { | ||
expect(result.current).toBe('third') | ||
complete = 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 | ||
}) | ||
expect(complete).toBe(true) | ||
let complete = false | ||
await waitFor(() => { | ||
expect(actual).toBe(expected) | ||
complete = true | ||
}) | ||
test('should not hang if expectation is already passing', async () => { | ||
const { result, waitFor } = renderHook(() => useSequence(['first', 'second'])) | ||
expect(complete).toBe(true) | ||
}) | ||
expect(result.current).toBe('first') | ||
test('should not hang if expectation is already passing', async () => { | ||
const { result, waitFor } = renderHook(() => useSequence(['first', 'second'])) | ||
let complete = false | ||
await waitFor(() => { | ||
expect(result.current).toBe('first') | ||
complete = true | ||
}) | ||
expect(complete).toBe(true) | ||
}) | ||
expect(result.current).toBe('first') | ||
test('should wait for truthy value', async () => { | ||
const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) | ||
let complete = false | ||
await waitFor(() => { | ||
expect(result.current).toBe('first') | ||
complete = true | ||
}) | ||
expect(complete).toBe(true) | ||
}) | ||
await waitFor(() => result.current === 'third') | ||
test('should wait for truthy value', async () => { | ||
const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) | ||
expect(result.current).toBe('third') | ||
}) | ||
expect(result.current).toBe('first') | ||
test('should wait for arbitrary truthy value', async () => { | ||
const { waitFor } = renderHook(() => null) | ||
await waitFor(() => result.current === 'third') | ||
let actual = 0 | ||
const expected = 1 | ||
expect(result.current).toBe('third') | ||
}) | ||
setTimeout(() => { | ||
actual = expected | ||
}, 200) | ||
test('should wait for arbitrary truthy value', async () => { | ||
const { waitFor } = renderHook(() => null) | ||
await waitFor(() => actual === 1) | ||
let actual = 0 | ||
const expected = 1 | ||
expect(actual).toBe(expected) | ||
}) | ||
setTimeout(() => { | ||
actual = expected | ||
}, 200) | ||
test('should reject if timeout exceeded when waiting for expectation to pass', async () => { | ||
const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) | ||
await waitFor(() => actual === 1) | ||
expect(result.current).toBe('first') | ||
expect(actual).toBe(expected) | ||
}) | ||
await expect( | ||
waitFor( | ||
() => { | ||
expect(result.current).toBe('third') | ||
}, | ||
{ timeout: 75 } | ||
) | ||
).rejects.toThrow(Error('Timed out in waitFor after 75ms.')) | ||
}) | ||
test('should reject if timeout exceeded when waiting for expectation to pass', async () => { | ||
const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) | ||
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('first') | ||
expect(result.current).toBe('first') | ||
await waitFor( | ||
await expect( | ||
waitFor( | ||
() => { | ||
expect(result.current).toBe('third') | ||
}, | ||
{ timeout: false } | ||
{ timeout: 75 } | ||
) | ||
).rejects.toThrow(Error('Timed out in waitFor after 75ms.')) | ||
}) | ||
expect(result.current).toBe('third') | ||
}) | ||
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 check on interval when waiting for expectation to pass', async () => { | ||
const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) | ||
expect(result.current).toBe('first') | ||
let checks = 0 | ||
await waitFor( | ||
() => { | ||
expect(result.current).toBe('third') | ||
}, | ||
{ timeout: false } | ||
) | ||
await waitFor( | ||
() => { | ||
checks++ | ||
return result.current === 'third' | ||
}, | ||
{ interval: 100 } | ||
) | ||
expect(result.current).toBe('third') | ||
}) | ||
expect(checks).toBe(3) | ||
}) | ||
test('should check on interval when waiting for expectation to pass', async () => { | ||
const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) | ||
test('should wait for value to change', async () => { | ||
const { result, waitForValueToChange } = renderHook(() => | ||
useSequence(['first', 'second', 'third']) | ||
) | ||
let checks = 0 | ||
expect(result.current).toBe('first') | ||
await waitFor( | ||
() => { | ||
checks++ | ||
return result.current === 'third' | ||
}, | ||
{ interval: 100 } | ||
) | ||
await waitForValueToChange(() => result.current === 'third') | ||
expect(checks).toBe(3) | ||
}) | ||
expect(result.current).toBe('third') | ||
}) | ||
test('should wait for value to change', async () => { | ||
const { result, waitForValueToChange } = renderHook(() => | ||
useSequence(['first', 'second', 'third']) | ||
) | ||
test('should wait for arbitrary value to change', async () => { | ||
const { waitForValueToChange } = renderHook(() => null) | ||
expect(result.current).toBe('first') | ||
let actual = 0 | ||
const expected = 1 | ||
await waitForValueToChange(() => result.current === 'third') | ||
setTimeout(() => { | ||
actual = expected | ||
}, 200) | ||
expect(result.current).toBe('third') | ||
}) | ||
await waitForValueToChange(() => actual) | ||
test('should wait for arbitrary value to change', async () => { | ||
const { waitForValueToChange } = renderHook(() => null) | ||
expect(actual).toBe(expected) | ||
}) | ||
let actual = 0 | ||
const expected = 1 | ||
test('should reject if timeout exceeded when waiting for value to change', async () => { | ||
const { result, waitForValueToChange } = renderHook(() => | ||
useSequence(['first', 'second', 'third']) | ||
) | ||
setTimeout(() => { | ||
actual = expected | ||
}, 200) | ||
expect(result.current).toBe('first') | ||
await waitForValueToChange(() => actual) | ||
await expect( | ||
waitForValueToChange(() => result.current === 'third', { | ||
timeout: 75 | ||
}) | ||
).rejects.toThrow(Error('Timed out in waitForValueToChange after 75ms.')) | ||
}) | ||
expect(actual).toBe(expected) | ||
}) | ||
test('should not reject when waiting for value to change if timeout is disabled', async () => { | ||
const { result, waitForValueToChange } = renderHook(() => | ||
useSequence(['first', 'second', 'third'], 550) | ||
) | ||
test('should reject if timeout exceeded when waiting for value to change', async () => { | ||
const { result, waitForValueToChange } = renderHook(() => | ||
useSequence(['first', 'second', 'third']) | ||
) | ||
expect(result.current).toBe('first') | ||
expect(result.current).toBe('first') | ||
await waitForValueToChange(() => result.current === 'third', { | ||
timeout: false | ||
await expect( | ||
waitForValueToChange(() => result.current === 'third', { | ||
timeout: 75 | ||
}) | ||
).rejects.toThrow(Error('Timed out in waitForValueToChange after 75ms.')) | ||
}) | ||
expect(result.current).toBe('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') | ||
await waitForValueToChange(() => result.current === 'third', { | ||
timeout: false | ||
}) | ||
test('should reject if selector throws error', async () => { | ||
const { result, waitForValueToChange } = renderHook(() => useSequence(['first', 'second'])) | ||
expect(result.current).toBe('third') | ||
}) | ||
expect(result.current).toBe('first') | ||
test('should reject if selector throws error', async () => { | ||
const { result, waitForValueToChange } = renderHook(() => useSequence(['first', 'second'])) | ||
await expect( | ||
waitForValueToChange(() => { | ||
if (result.current === 'second') { | ||
throw new Error('Something Unexpected') | ||
} | ||
return result.current | ||
}) | ||
).rejects.toThrow(Error('Something Unexpected')) | ||
}) | ||
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')) | ||
}) | ||
}) | ||
}) |
@@ -17,6 +17,3 @@ import { | ||
function asyncUtils(act: Act, addResolver: (callback: () => void) => void): AsyncUtils { | ||
const wait = async ( | ||
callback: () => boolean | void, | ||
{ interval, timeout }: Required<WaitOptions> | ||
) => { | ||
const wait = async (callback: () => boolean | void, { interval, timeout }: WaitOptions) => { | ||
const checkResult = () => { | ||
@@ -27,12 +24,12 @@ const callbackResult = callback() | ||
const timeoutController = createTimeoutController(timeout, { allowFakeTimers: true }) | ||
const timeoutSignal = createTimeoutController(timeout) | ||
const waitForResult = async () => { | ||
while (true) { | ||
const intervalController = createTimeoutController(interval) | ||
timeoutController.onTimeout(() => intervalController.cancel()) | ||
const intervalSignal = createTimeoutController(interval) | ||
timeoutSignal.onTimeout(() => intervalSignal.cancel()) | ||
await intervalController.wrap(new Promise<void>(addResolver)) | ||
await intervalSignal.wrap(new Promise<void>(addResolver)) | ||
if (checkResult() || timeoutController.timedOut) { | ||
if (checkResult() || timeoutSignal.timedOut) { | ||
return | ||
@@ -44,6 +41,6 @@ } | ||
if (!checkResult()) { | ||
await act(() => timeoutController.wrap(waitForResult())) | ||
await act(() => timeoutSignal.wrap(waitForResult())) | ||
} | ||
return !timeoutController.timedOut | ||
return !timeoutSignal.timedOut | ||
} | ||
@@ -50,0 +47,0 @@ |
@@ -1,7 +0,6 @@ | ||
import { fakeTimersAreEnabled, advanceTimers } from './fakeTimers' | ||
import { WaitOptions } from '../types' | ||
function createTimeoutController(timeout: number | false, { allowFakeTimers = false } = {}) { | ||
function createTimeoutController(timeout: WaitOptions['timeout']) { | ||
let timeoutId: NodeJS.Timeout | ||
const timeoutCallbacks: Array<() => void> = [] | ||
let finished = false | ||
@@ -16,5 +15,5 @@ const timeoutController = { | ||
timeoutController.onTimeout(resolve) | ||
if (timeout) { | ||
timeoutId = setTimeout(() => { | ||
finished = true | ||
timeoutController.timedOut = true | ||
@@ -26,17 +25,9 @@ timeoutCallbacks.forEach((callback) => callback()) | ||
if (fakeTimersAreEnabled() && allowFakeTimers) { | ||
advanceTimers(() => finished) | ||
} | ||
promise | ||
.then(resolve) | ||
.catch(reject) | ||
.finally(() => { | ||
finished = true | ||
timeoutController.cancel() | ||
}) | ||
.finally(() => timeoutController.cancel()) | ||
}) | ||
}, | ||
cancel() { | ||
finished = true | ||
clearTimeout(timeoutId) | ||
@@ -43,0 +34,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance 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
6
1
306
137689
20
98
2843
+ Added@types/react@17.0.83(transitive)
+ Added@types/scheduler@0.16.8(transitive)
+ Addedreact@17.0.2(transitive)
+ Addedreact-dom@17.0.2(transitive)
+ Addedreact-is@17.0.2(transitive)
+ Addedreact-test-renderer@17.0.2(transitive)
+ Addedscheduler@0.20.2(transitive)
- Removed@types/react@>=16.9.0
- Removed@types/react-dom@>=16.9.0
- Removed@types/react-test-renderer@>=16.9.0
- Removed@types/react@18.3.11(transitive)
- Removed@types/react-dom@18.3.0(transitive)
- Removed@types/react-test-renderer@18.3.0(transitive)
- Removedreact@18.3.1(transitive)
- Removedreact-dom@18.3.1(transitive)
- Removedreact-is@18.3.1(transitive)
- Removedreact-test-renderer@18.3.1(transitive)
- Removedscheduler@0.23.2(transitive)