Skip to content

Commit 6e6b5a2

Browse files
Lei ChenLei Chen
Lei Chen
authored and
Lei Chen
committed
fix the code after code review and clean up
1 parent 437f684 commit 6e6b5a2

File tree

3 files changed

+38
-15
lines changed

3 files changed

+38
-15
lines changed

src/__tests__/asyncHook.fakeTimers.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ describe('async hook (fake timers) tests', () => {
3030
jest.useRealTimers()
3131
})
3232

33-
runForRenderers(['default', 'dom', 'native', 'server/hydrated'], ({ renderHook }) => {
33+
runForRenderers(['default'], ({ renderHook }) => {
3434
test('should wait for arbitrary expectation to pass when using advanceTimersByTime()', async () => {
3535
const { waitFor } = renderHook(() => null)
3636

@@ -77,9 +77,9 @@ describe('async hook (fake timers) tests', () => {
7777

7878
test('should waitFor arbitrary expectation to pass when fake timers are not advanced explicitly', async () => {
7979
const fn = jest.fn().mockReturnValueOnce(false).mockReturnValueOnce(true)
80-
80+
8181
const { waitFor } = renderHook(() => null)
82-
82+
8383
await waitFor(() => {
8484
expect(fn()).toBe(true)
8585
})

src/core/asyncUtils.ts

+11-8
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,35 @@ const DEFAULT_TIMEOUT = 1000
1414
const DEFAULT_INTERVAL = 50
1515

1616
function asyncUtils(act: Act, addResolver: (callback: () => void) => void): AsyncUtils {
17-
const wait = async (callback: () => boolean | void, { interval, timeout }: WaitOptions) => {
17+
const wait = async (
18+
callback: () => boolean | void,
19+
{ interval, timeout }: Required<WaitOptions>
20+
) => {
1821
const checkResult = () => {
1922
const callbackResult = callback()
2023
return callbackResult ?? callbackResult === undefined
2124
}
2225

23-
const timeoutSignal = createTimeoutController(timeout as number | boolean, false)
26+
const timeoutController = createTimeoutController(timeout, { allowFakeTimers: !interval })
2427

2528
const waitForResult = async () => {
2629
while (true) {
27-
const intervalSignal = createTimeoutController(interval as number | boolean, true)
28-
timeoutSignal.onTimeout(() => intervalSignal.cancel())
30+
const intervalController = createTimeoutController(interval, { allowFakeTimers: true })
31+
timeoutController.onTimeout(() => intervalController.cancel())
2932

30-
await intervalSignal.wrap(new Promise<void>(addResolver))
33+
await intervalController.wrap(new Promise<void>(addResolver))
3134

32-
if (checkResult() || timeoutSignal.timedOut) {
35+
if (checkResult() || timeoutController.timedOut) {
3336
return
3437
}
3538
}
3639
}
3740

3841
if (!checkResult()) {
39-
await act(() => timeoutSignal.wrap(waitForResult()))
42+
await act(() => timeoutController.wrap(waitForResult()))
4043
}
4144

42-
return !timeoutSignal.timedOut
45+
return !timeoutController.timedOut
4346
}
4447

4548
const waitFor = async (

src/helpers/createTimeoutController.ts

+24-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
11
import { jestFakeTimersAreEnabled } from './jestFakeTimersAreEnabled'
22

3-
function createTimeoutController(timeout: number | boolean, allowFakeTimers: boolean) {
3+
function createTimeoutController(timeout: number | false, options: { allowFakeTimers: boolean }) {
44
let timeoutId: NodeJS.Timeout
55
const timeoutCallbacks: Array<() => void> = []
6+
let finished = false
7+
8+
const { allowFakeTimers = false } = options
9+
10+
const advanceTime = async (currentMs: number) => {
11+
if (currentMs < timeout) {
12+
jest.advanceTimersByTime(1)
13+
14+
await Promise.resolve()
15+
16+
if (finished) {
17+
return
18+
}
19+
await advanceTime(currentMs + 1)
20+
}
21+
}
622

723
const timeoutController = {
824
onTimeout(callback: () => void) {
@@ -18,20 +34,24 @@ function createTimeoutController(timeout: number | boolean, allowFakeTimers: boo
1834
timeoutController.timedOut = true
1935
timeoutCallbacks.forEach((callback) => callback())
2036
resolve()
21-
}, timeout as number)
37+
}, timeout)
2238

2339
if (jestFakeTimersAreEnabled() && allowFakeTimers) {
24-
jest.advanceTimersByTime(timeout as number)
40+
advanceTime(0)
2541
}
2642
}
2743

2844
promise
2945
.then(resolve)
3046
.catch(reject)
31-
.finally(() => timeoutController.cancel())
47+
.finally(() => {
48+
finished = true
49+
timeoutController.cancel()
50+
})
3251
})
3352
},
3453
cancel() {
54+
finished = true
3555
clearTimeout(timeoutId)
3656
},
3757
timedOut: false

0 commit comments

Comments
 (0)