From f7b5c33c44632fba1579cb44f9f175be1ec46087 Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Fri, 19 Feb 2021 21:39:33 +0100 Subject: [PATCH] fix: Don't assume mocked timers imply jest fake timers (#900) * fix: Don't assume mocked timers imply jest fake timers * Create dedicated jest timer functions The naming should indicate that they should only be called in a jest-like environment * No implicit return * I don't know how istanbul works and I don't care --- src/helpers.js | 32 +++++++++++++++++++++----------- src/wait-for.js | 6 +++--- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/helpers.js b/src/helpers.js index 7b8d95e5..176b606f 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -5,10 +5,16 @@ const TEXT_NODE = 3 // Currently this fn only supports jest timers, but it could support other test runners in the future. function runWithRealTimers(callback) { - return _runWithRealTimers(callback).callbackReturnValue + // istanbul ignore else + if (typeof jest !== 'undefined') { + return runWithJestRealTimers(callback).callbackReturnValue + } + + // istanbul ignore next + return callback() } -function _runWithRealTimers(callback) { +function runWithJestRealTimers(callback) { const timerAPI = { clearImmediate, clearInterval, @@ -18,29 +24,33 @@ function _runWithRealTimers(callback) { setTimeout, } - // istanbul ignore else - if (typeof jest !== 'undefined') { - jest.useRealTimers() - } + jest.useRealTimers() const callbackReturnValue = callback() - const usedJestFakeTimers = Object.entries(timerAPI).some( + const usedFakeTimers = Object.entries(timerAPI).some( ([name, func]) => func !== globalObj[name], ) - if (usedJestFakeTimers) { + if (usedFakeTimers) { jest.useFakeTimers(timerAPI.setTimeout?.clock ? 'modern' : 'legacy') } return { callbackReturnValue, - usedJestFakeTimers, + usedFakeTimers, } } -const jestFakeTimersAreEnabled = () => - Boolean(_runWithRealTimers(() => {}).usedJestFakeTimers) +function jestFakeTimersAreEnabled() { + // istanbul ignore else + if (typeof jest !== 'undefined') { + return runWithJestRealTimers(() => {}).usedFakeTimers + } + + // istanbul ignore next + return false +} // we only run our tests in node, and setImmediate is supported in node. // istanbul ignore next diff --git a/src/wait-for.js b/src/wait-for.js index 9eb44842..860b7a15 100644 --- a/src/wait-for.js +++ b/src/wait-for.js @@ -52,8 +52,8 @@ function waitFor( const overallTimeoutTimer = setTimeout(handleTimeout, timeout) - const usingFakeTimers = jestFakeTimersAreEnabled() - if (usingFakeTimers) { + const usingJestFakeTimers = jestFakeTimersAreEnabled() + if (usingJestFakeTimers) { checkCallback() // this is a dangerous rule to disable because it could lead to an // infinite loop. However, eslint isn't smart enough to know that we're @@ -107,7 +107,7 @@ function waitFor( finished = true clearTimeout(overallTimeoutTimer) - if (!usingFakeTimers) { + if (!usingJestFakeTimers) { clearInterval(intervalId) observer.disconnect() }