diff --git a/src/flush-microtasks.js b/src/flush-microtasks.js new file mode 100644 index 00000000..a34b5e85 --- /dev/null +++ b/src/flush-microtasks.js @@ -0,0 +1,47 @@ +/* istanbul ignore file */ +// the part of this file that we need tested is definitely being run +// and the part that is not cannot easily have useful tests written +// anyway. So we're just going to ignore coverage for this file +/** + * copied from React's enqueueTask.js + */ + +let didWarnAboutMessageChannel = false +let enqueueTask +try { + // read require off the module object to get around the bundlers. + // we don't want them to detect a require and bundle a Node polyfill. + const requireString = `require${Math.random()}`.slice(0, 7) + const nodeRequire = module && module[requireString] + // assuming we're in node, let's try to get node's + // version of setImmediate, bypassing fake timers if any. + enqueueTask = nodeRequire('timers').setImmediate +} catch (_err) { + // we're in a browser + // we can't use regular timers because they may still be faked + // so we try MessageChannel+postMessage instead + enqueueTask = callback => { + if (didWarnAboutMessageChannel === false) { + didWarnAboutMessageChannel = true + // eslint-disable-next-line no-console + console.error( + typeof MessageChannel !== 'undefined', + 'This browser does not have a MessageChannel implementation, ' + + 'so enqueuing tasks via await act(async () => ...) will fail. ' + + 'Please file an issue at https://github.com/facebook/react/issues ' + + 'if you encounter this warning.', + ) + } + const channel = new MessageChannel() + channel.port1.onmessage = callback + channel.port2.postMessage(undefined) + } +} + +export default function flushMicroTasks() { + return { + then(resolve) { + enqueueTask(resolve) + }, + } +} diff --git a/src/index.js b/src/index.js index 5e05b725..5e942670 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -import {asyncAct} from './act-compat' +import flush from './flush-microtasks' import {cleanup} from './pure' // if we're running in a test runner that supports afterEach @@ -8,7 +8,7 @@ import {cleanup} from './pure' // or set the RTL_SKIP_AUTO_CLEANUP env variable to 'true'. if (typeof afterEach === 'function' && !process.env.RTL_SKIP_AUTO_CLEANUP) { afterEach(async () => { - await asyncAct(async () => {}) + await flush() cleanup() }) }