From 5aeb882a6fb59667ed07bb9459538af41d263aa2 Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Wed, 24 Jun 2020 12:41:09 -0600 Subject: [PATCH] fix(cleanup): microtask flushing now supports fake timers --- src/flush-microtasks.js | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/flush-microtasks.js b/src/flush-microtasks.js index e309fe6a..e653bd42 100644 --- a/src/flush-microtasks.js +++ b/src/flush-microtasks.js @@ -3,9 +3,23 @@ // 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 + * copied and modified from React's enqueueTask.js */ +// the jest fake timers bit is borrowed from DOM Testing Library +// and is copy/pasted rather than imported because I'm not sure +// we want to expose this functionality from DOM Testing Library +// just yet (or ever) +const globalObj = typeof window === 'undefined' ? global : window + +function getIsUsingFakeTimers() { + return ( + typeof jest !== 'undefined' && + (globalObj.setTimeout?.hasOwnProperty('_isMockFunction') || + globalObj.setTimeout?.hasOwnProperty('clock')) + ) +} + let didWarnAboutMessageChannel = false let enqueueTask try { @@ -43,7 +57,15 @@ try { export default function flushMicroTasks() { return { then(resolve) { - enqueueTask(resolve) + if (getIsUsingFakeTimers()) { + // without this, a test using fake timers would never get microtasks + // actually flushed. I spent several days on this... Really hard to + // reproduce the problem, so there's no test for it. But it works! + jest.advanceTimersByTime(0) + resolve() + } else { + enqueueTask(resolve) + } }, } }