Skip to content

Commit 918be8c

Browse files
refactor: flush microtask queue implementation (#1374)
* refactor: flush microtask queue implementation * refactor: code review changes * refactor: restore original flush function as legacy version * chore: rename file
1 parent ce75f66 commit 918be8c

File tree

4 files changed

+35
-19
lines changed

4 files changed

+35
-19
lines changed

src/flush-micro-tasks.ts

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { setImmediate } from './helpers/timers';
2+
3+
export function flushMicroTasks() {
4+
return new Promise((resolve) => setImmediate(resolve));
5+
}
6+
7+
/**
8+
* @deprecated To be removed in the next major release.
9+
*/
10+
type Thenable<T> = { then: (callback: () => T) => unknown };
11+
12+
/**
13+
* This legacy implementation of `flushMicroTasks` is used for compatibility with
14+
* older versions of React Native (pre 0.71) which uses Promise polyfil.
15+
*
16+
* For users with older version of React Native there is a workaround of using our own
17+
* Jest preset instead the `react-native` one, but requiring such change would be a
18+
* breaking change for existing users.
19+
*
20+
* @deprecated To be removed in the next major release.
21+
*/
22+
export function flushMicroTasksLegacy(): Thenable<void> {
23+
return {
24+
// using "thenable" instead of a Promise, because otherwise it breaks when
25+
// using "modern" fake timers
26+
then(resolve) {
27+
setImmediate(resolve);
28+
},
29+
};
30+
}

src/flushMicroTasks.ts

-13
This file was deleted.

src/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { cleanup } from './pure';
2-
import { flushMicroTasks } from './flushMicroTasks';
2+
import { flushMicroTasksLegacy } from './flush-micro-tasks';
33
import { getIsReactActEnvironment, setReactActEnvironment } from './act';
44

55
if (typeof process === 'undefined' || !process.env?.RNTL_SKIP_AUTO_CLEANUP) {
@@ -11,7 +11,7 @@ if (typeof process === 'undefined' || !process.env?.RNTL_SKIP_AUTO_CLEANUP) {
1111
if (typeof afterEach === 'function') {
1212
// eslint-disable-next-line no-undef
1313
afterEach(async () => {
14-
await flushMicroTasks();
14+
await flushMicroTasksLegacy();
1515
cleanup();
1616
});
1717
}

src/waitFor.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
/* globals jest */
22
import act, { setReactActEnvironment, getIsReactActEnvironment } from './act';
33
import { getConfig } from './config';
4-
import { flushMicroTasks } from './flushMicroTasks';
4+
import { flushMicroTasks, flushMicroTasksLegacy } from './flush-micro-tasks';
55
import { ErrorWithStack, copyStackTrace } from './helpers/errors';
66
import {
77
setTimeout,
88
clearTimeout,
9-
setImmediate,
109
jestFakeTimersAreEnabled,
1110
} from './helpers/timers';
1211
import { checkReactVersionAtLeast } from './react-versions';
@@ -89,7 +88,7 @@ function waitForInternal<T>(
8988
// of parallelization so we're fine.
9089
// https://stackoverflow.com/a/59243586/971592
9190
// eslint-disable-next-line no-await-in-loop
92-
await new Promise((resolve) => setImmediate(resolve));
91+
await flushMicroTasks();
9392
}
9493
} else {
9594
overallTimeoutTimer = setTimeout(handleTimeout, timeout);
@@ -207,7 +206,7 @@ export default async function waitFor<T>(
207206
try {
208207
const result = await waitForInternal(expectation, optionsWithStackTrace);
209208
// Flush the microtask queue before restoring the `act` environment
210-
await flushMicroTasks();
209+
await flushMicroTasksLegacy();
211210
return result;
212211
} finally {
213212
setReactActEnvironment(previousActEnvironment);

0 commit comments

Comments
 (0)