From 8c2ed70e2d9b94f03ad8690d9259c647cdc0d0a8 Mon Sep 17 00:00:00 2001 From: Michael Hensler Date: Mon, 26 Jul 2021 16:19:14 -0700 Subject: [PATCH 1/2] Add `setDefaultWaitOptions` method --- .all-contributorsrc | 12 ++++++++++++ README.md | 1 + docs/api-reference.md | 24 ++++++++++++++++++++++++ src/__tests__/asyncHook.test.ts | 30 ++++++++++++++++++++++++++++++ src/core/asyncUtils.ts | 19 +++++++++++-------- src/core/index.ts | 11 +++++++++-- src/dom/pure.ts | 8 +++++++- src/native/pure.ts | 8 +++++++- src/pure.ts | 22 +++++++++++++++++++--- src/server/pure.ts | 8 +++++++- src/types/react.ts | 4 +++- 11 files changed, 130 insertions(+), 17 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9c318f40..6292aa7c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -566,6 +566,18 @@ "bug", "review" ] + }, + { + "login": "orokanasaru", + "name": "Michael Hensler", + "avatar_url": "https://avatars.githubusercontent.com/u/5751627?v=4", + "profile": "https://github.com/orokanasaru", + "contributions": [ + "code", + "doc", + "ideas", + "test" + ] } ], "skipCi": true, diff --git a/README.md b/README.md index e3bba708..e4d7ad62 100644 --- a/README.md +++ b/README.md @@ -246,6 +246,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Matan Borenkraout

🚧
andyrooger

💻
Bryan Wain

🐛 👀 +
Michael Hensler

💻 📖 🤔 ⚠️ diff --git a/docs/api-reference.md b/docs/api-reference.md index 7416d1f7..19b89a2d 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -271,6 +271,30 @@ _Default: 1000_ The maximum amount of time in milliseconds (ms) to wait. +### `setDefaultWaitOptions` + +```ts +function setDefaultWaitOptions({ + interval?: number | false + timeout?: number | false +}): void +``` + +Updates the default values for `interval` and `timeout` used by the `waitFor*` functions. + +#### `interval` + +_Default: 50_ + +The amount of time in milliseconds (ms) to wait between checks of the callback if no renders occur. +Interval checking is disabled if `interval` is not provided as a `falsy`. + +#### `timeout` + +_Default: 1000_ + +The maximum amount of time in milliseconds (ms) to wait. + --- ## `console.error` diff --git a/src/__tests__/asyncHook.test.ts b/src/__tests__/asyncHook.test.ts index 17979ae2..f8e2b39f 100644 --- a/src/__tests__/asyncHook.test.ts +++ b/src/__tests__/asyncHook.test.ts @@ -1,6 +1,11 @@ +import { setDefaultWaitOptions } from 'core' import { useState, useRef, useEffect } from 'react' describe('async hook tests', () => { + beforeEach(() => { + setDefaultWaitOptions({ interval: 50, timeout: 1000 }) + }) + const useSequence = (values: string[], intervalMs = 50) => { const [first, ...otherValues] = values const [value, setValue] = useState(() => first) @@ -59,6 +64,17 @@ describe('async hook tests', () => { ) }) + test('should reject if custom default timeout exceeded when waiting for next update', async () => { + setDefaultWaitOptions({ timeout: 10 }) + const { result, waitForNextUpdate } = renderHook(() => useSequence(['first', 'second'])) + + expect(result.current).toBe('first') + + await expect(waitForNextUpdate()).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)) @@ -185,6 +201,20 @@ describe('async hook tests', () => { expect(checks).toBe(3) }) + test('should check on custom default interval when waiting for expectation to pass', async () => { + setDefaultWaitOptions({ interval: 100 }) + const { result, waitFor } = renderHook(() => useSequence(['first', 'second', 'third'])) + + let checks = 0 + + await waitFor(() => { + checks++ + return result.current === 'third' + }) + + expect(checks).toBe(3) + }) + test('should wait for value to change', async () => { const { result, waitForValueToChange } = renderHook(() => useSequence(['first', 'second', 'third']) diff --git a/src/core/asyncUtils.ts b/src/core/asyncUtils.ts index fe44c715..6032edeb 100644 --- a/src/core/asyncUtils.ts +++ b/src/core/asyncUtils.ts @@ -10,8 +10,13 @@ import { import { resolveAfter, callAfter } from '../helpers/promises' import { TimeoutError } from '../helpers/error' -const DEFAULT_INTERVAL = 50 -const DEFAULT_TIMEOUT = 1000 +let defaultInterval: number | false = 50 +let defaultTimeout: number | false = 1000 + +function setDefaultWaitOptions({ interval, timeout }: WaitOptions) { + defaultInterval = interval ?? defaultInterval + defaultTimeout = timeout ?? defaultTimeout +} function asyncUtils(act: Act, addResolver: (callback: () => void) => void): AsyncUtils { const wait = async (callback: () => boolean | void, { interval, timeout }: WaitOptions) => { @@ -55,7 +60,7 @@ function asyncUtils(act: Act, addResolver: (callback: () => void) => void): Asyn const waitFor = async ( callback: () => boolean | void, - { interval = DEFAULT_INTERVAL, timeout = DEFAULT_TIMEOUT }: WaitForOptions = {} + { interval = defaultInterval, timeout = defaultTimeout }: WaitForOptions = {} ) => { const safeCallback = () => { try { @@ -73,7 +78,7 @@ function asyncUtils(act: Act, addResolver: (callback: () => void) => void): Asyn const waitForValueToChange = async ( selector: () => unknown, - { interval = DEFAULT_INTERVAL, timeout = DEFAULT_TIMEOUT }: WaitForValueToChangeOptions = {} + { interval = defaultInterval, timeout = defaultTimeout }: WaitForValueToChangeOptions = {} ) => { const initialValue = selector() @@ -83,9 +88,7 @@ function asyncUtils(act: Act, addResolver: (callback: () => void) => void): Asyn } } - const waitForNextUpdate = async ({ - timeout = DEFAULT_TIMEOUT - }: WaitForNextUpdateOptions = {}) => { + const waitForNextUpdate = async ({ timeout = defaultTimeout }: WaitForNextUpdateOptions = {}) => { let updated = false addResolver(() => { updated = true @@ -104,4 +107,4 @@ function asyncUtils(act: Act, addResolver: (callback: () => void) => void): Asyn } } -export { asyncUtils } +export { asyncUtils, setDefaultWaitOptions } diff --git a/src/core/index.ts b/src/core/index.ts index ccd81b94..24ede8ca 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -1,6 +1,6 @@ import { CreateRenderer, Renderer, RenderResult, RenderHookOptions } from '../types' -import { asyncUtils } from './asyncUtils' +import { asyncUtils, setDefaultWaitOptions } from './asyncUtils' import { cleanup, addCleanup, removeCleanup } from './cleanup' import { suppressErrorOutput } from './console' @@ -82,4 +82,11 @@ function createRenderHook< return renderHook } -export { createRenderHook, cleanup, addCleanup, removeCleanup, suppressErrorOutput } +export { + createRenderHook, + cleanup, + addCleanup, + removeCleanup, + suppressErrorOutput, + setDefaultWaitOptions +} diff --git a/src/dom/pure.ts b/src/dom/pure.ts index 42d66072..53509c85 100644 --- a/src/dom/pure.ts +++ b/src/dom/pure.ts @@ -37,6 +37,12 @@ const renderHook = createRenderHook(createDomRenderer) export { renderHook, act } -export { cleanup, addCleanup, removeCleanup, suppressErrorOutput } from '../core' +export { + cleanup, + addCleanup, + removeCleanup, + setDefaultWaitOptions, + suppressErrorOutput +} from '../core' export * from '../types/react' diff --git a/src/native/pure.ts b/src/native/pure.ts index d033a312..01234064 100644 --- a/src/native/pure.ts +++ b/src/native/pure.ts @@ -36,6 +36,12 @@ const renderHook = createRenderHook(createNativeRenderer) export { renderHook, act } -export { cleanup, addCleanup, removeCleanup, suppressErrorOutput } from '../core' +export { + cleanup, + addCleanup, + removeCleanup, + setDefaultWaitOptions, + suppressErrorOutput +} from '../core' export * from '../types/react' diff --git a/src/pure.ts b/src/pure.ts index ec72c6fe..0231505a 100644 --- a/src/pure.ts +++ b/src/pure.ts @@ -32,8 +32,24 @@ function getRenderer() { } } -const { renderHook, act, cleanup, addCleanup, removeCleanup, suppressErrorOutput } = getRenderer() - -export { renderHook, act, cleanup, addCleanup, removeCleanup, suppressErrorOutput } +const { + renderHook, + act, + cleanup, + addCleanup, + removeCleanup, + setDefaultWaitOptions, + suppressErrorOutput +} = getRenderer() + +export { + renderHook, + act, + cleanup, + addCleanup, + removeCleanup, + setDefaultWaitOptions, + suppressErrorOutput +} export * from './types/react' diff --git a/src/server/pure.ts b/src/server/pure.ts index 1978f2d0..fffe3fb8 100644 --- a/src/server/pure.ts +++ b/src/server/pure.ts @@ -61,6 +61,12 @@ const renderHook = createRenderHook(createServerRenderer) export { renderHook, act } -export { cleanup, addCleanup, removeCleanup, suppressErrorOutput } from '../core' +export { + cleanup, + addCleanup, + removeCleanup, + setDefaultWaitOptions, + suppressErrorOutput +} from '../core' export * from '../types/react' diff --git a/src/types/react.ts b/src/types/react.ts index c03ad33d..a6f34e7d 100644 --- a/src/types/react.ts +++ b/src/types/react.ts @@ -5,7 +5,8 @@ import { RenderHookResult, ServerRenderHookResult, Act, - CleanupCallback + CleanupCallback, + WaitOptions } from '.' export type WrapperComponent = ComponentType @@ -27,6 +28,7 @@ export type ReactHooksRenderer = { cleanup: () => Promise addCleanup: (callback: CleanupCallback) => () => void removeCleanup: (callback: CleanupCallback) => void + setDefaultWaitOptions: (options: WaitOptions) => void suppressErrorOutput: () => () => void } From 62fa16d6165de9ab3a2f38f0b01e0759f2486cee Mon Sep 17 00:00:00 2001 From: Michael Hensler Date: Fri, 30 Jul 2021 09:38:21 -0700 Subject: [PATCH 2/2] Update src/core/index.ts Co-authored-by: Michael Peyper --- src/core/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/index.ts b/src/core/index.ts index 24ede8ca..45f7a914 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -87,6 +87,6 @@ export { cleanup, addCleanup, removeCleanup, - suppressErrorOutput, - setDefaultWaitOptions + setDefaultWaitOptions, + suppressErrorOutput }