UNPKG

2.21 kBJavaScriptView Raw
1import { act } from 'react-test-renderer'
2
3function createTimeoutError(utilName, { timeout }) {
4 const timeoutError = new Error(`Timed out in ${utilName} after ${timeout}ms.`)
5 timeoutError.timeout = true
6 return timeoutError
7}
8
9function asyncUtils(addResolver) {
10 let nextUpdatePromise = null
11
12 const waitForNextUpdate = async (options = {}) => {
13 if (!nextUpdatePromise) {
14 nextUpdatePromise = new Promise((resolve, reject) => {
15 let timeoutId
16 if (options.timeout > 0) {
17 timeoutId = setTimeout(
18 () => reject(createTimeoutError('waitForNextUpdate', options)),
19 options.timeout
20 )
21 }
22 addResolver(() => {
23 clearTimeout(timeoutId)
24 nextUpdatePromise = null
25 resolve()
26 })
27 })
28 await act(() => nextUpdatePromise)
29 }
30 await nextUpdatePromise
31 }
32
33 const wait = async (callback, { timeout, suppressErrors = true } = {}) => {
34 const checkResult = () => {
35 try {
36 const callbackResult = callback()
37 return callbackResult || callbackResult === undefined
38 } catch (e) {
39 if (!suppressErrors) {
40 throw e
41 }
42 }
43 }
44
45 const waitForResult = async () => {
46 const initialTimeout = timeout
47 while (true) {
48 const startTime = Date.now()
49 try {
50 await waitForNextUpdate({ timeout })
51 if (checkResult()) {
52 return
53 }
54 } catch (e) {
55 if (e.timeout) {
56 throw createTimeoutError('wait', { timeout: initialTimeout })
57 }
58 throw e
59 }
60 timeout -= Date.now() - startTime
61 }
62 }
63
64 if (!checkResult()) {
65 await waitForResult()
66 }
67 }
68
69 const waitForValueToChange = async (selector, options = {}) => {
70 const initialValue = selector()
71 try {
72 await wait(() => selector() !== initialValue, {
73 suppressErrors: false,
74 ...options
75 })
76 } catch (e) {
77 if (e.timeout) {
78 throw createTimeoutError('waitForValueToChange', options)
79 }
80 throw e
81 }
82 }
83
84 return {
85 wait,
86 waitForNextUpdate,
87 waitForValueToChange
88 }
89}
90
91export default asyncUtils