Skip to content

Commit

Permalink
fix: Don't assume mocked timers imply jest fake timers (#900)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
eps1lon committed Feb 19, 2021
1 parent a25149d commit f7b5c33
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 14 deletions.
32 changes: 21 additions & 11 deletions src/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
6 changes: 3 additions & 3 deletions src/wait-for.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -107,7 +107,7 @@ function waitFor(
finished = true
clearTimeout(overallTimeoutTimer)

if (!usingFakeTimers) {
if (!usingJestFakeTimers) {
clearInterval(intervalId)
observer.disconnect()
}
Expand Down

0 comments on commit f7b5c33

Please sign in to comment.