Skip to content

Commit 75b76f6

Browse files
author
Sebastian Silbermann
committed
Unify advanceTimersByTime and flushPromises
Ports testing-library/dom-testing-library#1229
1 parent 69b474b commit 75b76f6

File tree

4 files changed

+13
-35
lines changed

4 files changed

+13
-35
lines changed

src/__tests__/waitFor.test.js

+1-7
Original file line numberDiff line numberDiff line change
@@ -176,15 +176,9 @@ test('does not work after it resolves', async () => {
176176

177177
/** @type {import('../').FakeClock} */
178178
const jestFakeClock = {
179-
advanceTimersByTime: timeoutMS => {
179+
advanceTimersByTime: async timeoutMS => {
180180
jest.advanceTimersByTime(timeoutMS)
181181
},
182-
flushPromises: () => {
183-
return new Promise(r => {
184-
setTimeout(r, 0)
185-
jest.advanceTimersByTime(0)
186-
})
187-
},
188182
}
189183
describe.each([
190184
['real timers', {useTimers: () => jest.useRealTimers(), clock: undefined}],

src/__tests__/waitForDOM.test.js

+6-9
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ function waitFor(
6565
return error
6666
}
6767

68+
/**
69+
* @template T
70+
* @param {() => T} cb
71+
* @returns T
72+
*/
6873
function advanceTimersWrapper(cb) {
6974
// /dom config. /react uses act() here
7075
return cb()
@@ -78,16 +83,8 @@ function waitFor(
7883
/** @type {import('../').FakeClock} */
7984
const jestFakeClock = {
8085
advanceTimersByTime: timeoutMS => {
81-
advanceTimersWrapper(() => {
82-
jest.advanceTimersByTime(timeoutMS)
83-
})
84-
},
85-
flushPromises: () => {
8686
return advanceTimersWrapper(async () => {
87-
await new Promise(r => {
88-
setTimeout(r, 0)
89-
jest.advanceTimersByTime(0)
90-
})
87+
jest.advanceTimersByTime(timeoutMS)
9188
})
9289
},
9390
}

src/__tests__/waitForNode.js renamed to src/__tests__/waitForNode.test.js

+4-10
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,9 @@ function jestFakeTimersAreEnabled() {
3737
function waitFor(callback, options) {
3838
/** @type {import('../').FakeClock} */
3939
const jestFakeClock = {
40-
advanceTimersByTime: timeoutMS => {
40+
advanceTimersByTime: async timeoutMS => {
4141
jest.advanceTimersByTime(timeoutMS)
4242
},
43-
flushPromises: () => {
44-
return new Promise(r => {
45-
setTimeout(r, 0)
46-
jest.advanceTimersByTime(0)
47-
})
48-
},
4943
}
5044
const clock = jestFakeTimersAreEnabled() ? jestFakeClock : undefined
5145

@@ -210,15 +204,15 @@ describe('using fake modern timers', () => {
210204
// An actual test would not have any frames pointing to this test.
211205
expect(waitForError.stack).toMatchInlineSnapshot(`
212206
Error: Timed out in waitFor.
213-
at handleTimeout (<PROJECT_ROOT>/src/waitFor.ts:146:17)
207+
at handleTimeout (<PROJECT_ROOT>/src/waitFor.ts:139:17)
214208
at callTimer (<PROJECT_ROOT>/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:729:24)
215209
at doTickInner (<PROJECT_ROOT>/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1289:29)
216210
at doTick (<PROJECT_ROOT>/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1370:20)
217211
at Object.tick (<PROJECT_ROOT>/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1378:20)
218212
at FakeTimers.advanceTimersByTime (<PROJECT_ROOT>/node_modules/@jest/fake-timers/build/modernFakeTimers.js:101:19)
219213
at Object.advanceTimersByTime (<PROJECT_ROOT>/node_modules/jest-runtime/build/index.js:2228:26)
220-
at Object.advanceTimersByTime (<PROJECT_ROOT>/src/__tests__/waitForNode.js:41:12)
221-
at <PROJECT_ROOT>/src/waitFor.ts:80:15
214+
at Object.advanceTimersByTime (<PROJECT_ROOT>/src/__tests__/waitForNode.test.js:41:12)
215+
at <PROJECT_ROOT>/src/waitFor.ts:85:21
222216
at new Promise (<anonymous>)
223217
`)
224218
})

src/waitFor.ts

+2-9
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ function copyStackTrace(target: Error, source: Error) {
77
}
88

99
export interface FakeClock {
10-
advanceTimersByTime: (timeoutMS: number) => void
10+
advanceTimersByTime: (timeoutMS: number) => Promise<void>
1111
flushPromises: () => Promise<void>
1212
}
1313

@@ -77,19 +77,12 @@ function waitForImpl<T>(
7777
// waiting or when we've timed out.
7878
// eslint-disable-next-line no-unmodified-loop-condition, @typescript-eslint/no-unnecessary-condition
7979
while (!finished && !signal?.aborted) {
80-
clock.advanceTimersByTime(interval)
81-
82-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- No it isn't
83-
if (finished) {
84-
break
85-
}
86-
8780
// In this rare case, we *need* to wait for in-flight promises
8881
// to resolve before continuing. We don't need to take advantage
8982
// of parallelization so we're fine.
9083
// https://stackoverflow.com/a/59243586/971592
9184
// eslint-disable-next-line no-await-in-loop
92-
await clock.flushPromises()
85+
await clock.advanceTimersByTime(interval)
9386
}
9487
}
9588

0 commit comments

Comments
 (0)