Skip to content

Commit 6cb2832

Browse files
committed
Replace async act in cleanup to still flush microtasks without swallowing missing act warnings
1 parent 6207abf commit 6cb2832

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

src/cleanup.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { act } from 'react-test-renderer'
1+
import flushMicroTasks from './flush-microtasks'
22

33
let cleanupCallbacks = []
44

55
async function cleanup() {
6-
await act(async () => {})
6+
await flushMicroTasks()
77
cleanupCallbacks.forEach((cb) => cb())
88
cleanupCallbacks = []
99
}

src/flush-microtasks.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/* istanbul ignore file */
2+
// the part of this file that we need tested is definitely being run
3+
// and the part that is not cannot easily have useful tests written
4+
// anyway. So we're just going to ignore coverage for this file
5+
/**
6+
* copied from React's enqueueTask.js
7+
* copied again from React Testing Library's flush-microtasks.js
8+
*/
9+
10+
let didWarnAboutMessageChannel = false
11+
let enqueueTask
12+
try {
13+
// read require off the module object to get around the bundlers.
14+
// we don't want them to detect a require and bundle a Node polyfill.
15+
const requireString = `require${Math.random()}`.slice(0, 7)
16+
const nodeRequire = module && module[requireString]
17+
// assuming we're in node, let's try to get node's
18+
// version of setImmediate, bypassing fake timers if any.
19+
enqueueTask = nodeRequire('timers').setImmediate
20+
} catch (_err) {
21+
// we're in a browser
22+
// we can't use regular timers because they may still be faked
23+
// so we try MessageChannel+postMessage instead
24+
enqueueTask = (callback) => {
25+
if (didWarnAboutMessageChannel === false) {
26+
didWarnAboutMessageChannel = true
27+
// eslint-disable-next-line no-console
28+
console.error(
29+
typeof MessageChannel !== 'undefined',
30+
'This browser does not have a MessageChannel implementation, ' +
31+
'so enqueuing tasks via await act(async () => ...) will fail. ' +
32+
'Please file an issue at https://github.com/facebook/react/issues ' +
33+
'if you encounter this warning.'
34+
)
35+
}
36+
const channel = new MessageChannel()
37+
channel.port1.onmessage = callback
38+
channel.port2.postMessage(undefined)
39+
}
40+
}
41+
42+
export default function flushMicroTasks() {
43+
return {
44+
then(resolve) {
45+
enqueueTask(resolve)
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)