Skip to content

Commit

Permalink
Fix waitFor in jest 27
Browse files Browse the repository at this point in the history
  • Loading branch information
eps1lon committed Jun 1, 2021
1 parent 6cb426c commit f1a8a14
Show file tree
Hide file tree
Showing 8 changed files with 17 additions and 319 deletions.
30 changes: 0 additions & 30 deletions src/__tests__/deprecation-warnings.js

This file was deleted.

2 changes: 1 addition & 1 deletion src/__tests__/fake-timers.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ test('recursive timers do not cause issues', async () => {
}

startTimer()
await runWaitFor({time: 800}, {timeout: 100})
await runWaitFor({time: 800}, {timeout: 900})

recurse = false
})
71 changes: 1 addition & 70 deletions src/__tests__/helpers.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import {screen} from '../'
import {
getDocument,
getWindowFromNode,
checkContainerType,
runWithRealTimers,
} from '../helpers'
import {getDocument, getWindowFromNode, checkContainerType} from '../helpers'

test('returns global document if exists', () => {
expect(getDocument()).toBe(document)
Expand Down Expand Up @@ -61,67 +56,3 @@ describe('query container validation throws when validation fails', () => {
)
})
})

describe('run with real timers', () => {
const realSetTimeout = global.setTimeout

afterEach(() => {
// restore timers replaced by jest.useFakeTimers()
jest.useRealTimers()
// restore setTimeout replaced by assignment
global.setTimeout = realSetTimeout
})

test('use real timers when timers are faked with jest.useFakeTimers(legacy)', () => {
// legacy timers use mocks and do not rely on a clock instance
jest.useFakeTimers('legacy')
runWithRealTimers(() => {
expect(global.setTimeout).toBe(realSetTimeout)
})
expect(global.setTimeout._isMockFunction).toBe(true)
expect(global.setTimeout.clock).toBeUndefined()
})

test('use real timers when timers are faked with jest.useFakeTimers(modern)', () => {
// modern timers use a clock instance instead of a mock
jest.useFakeTimers('modern')
runWithRealTimers(() => {
expect(global.setTimeout).toBe(realSetTimeout)
})
expect(global.setTimeout._isMockFunction).toBeUndefined()
expect(global.setTimeout.clock).toBeDefined()
})

test('do not use real timers when timers are not faked with jest.useFakeTimers', () => {
// useFakeTimers is not used, timers are faked in some other way
const fakedSetTimeout = callback => {
callback()
}
fakedSetTimeout.clock = jest.fn()
global.setTimeout = fakedSetTimeout

runWithRealTimers(() => {
expect(global.setTimeout).toBe(fakedSetTimeout)
})
expect(global.setTimeout).toBe(fakedSetTimeout)
})

describe('run with setImmediate and clearImmediate deleted', () => {
const setImmediate = global.setImmediate
const clearImmediate = global.clearImmediate

beforeEach(() => {
delete global.setImmediate
delete global.clearImmediate
})

afterEach(() => {
global.setImmediate = setImmediate
global.clearImmediate = clearImmediate
})

test('safe check for setImmediate and clearImmediate', () => {
expect(() => runWithRealTimers(() => {})).not.toThrow()
})
})
})
54 changes: 0 additions & 54 deletions src/__tests__/wait-for-dom-change.js

This file was deleted.

88 changes: 10 additions & 78 deletions src/helpers.js
Original file line number Diff line number Diff line change
@@ -1,85 +1,21 @@
const globalObj = typeof window === 'undefined' ? global : window
// Constant node.nodeType for text nodes, see:
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType#Node_type_constants
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 hasJestTimers()
? runWithJestRealTimers(callback).callbackReturnValue
: // istanbul ignore next
callback()
}

function hasJestTimers() {
return (
typeof jest !== 'undefined' &&
jest !== null &&
typeof jest.useRealTimers === 'function'
)
}

function runWithJestRealTimers(callback) {
const timerAPI = {
clearInterval,
clearTimeout,
setInterval,
setTimeout,
}

// For more on why we have the check here,
// checkout https://github.com/testing-library/dom-testing-library/issues/914
if (typeof setImmediate === 'function') {
timerAPI.setImmediate = setImmediate
}
if (typeof clearImmediate === 'function') {
timerAPI.clearImmediate = clearImmediate
}

jest.useRealTimers()

const callbackReturnValue = callback()

const usedFakeTimers = Object.entries(timerAPI).some(
([name, func]) => func !== globalObj[name],
)

if (usedFakeTimers) {
jest.useFakeTimers(timerAPI.setTimeout?.clock ? 'modern' : 'legacy')
}

return {
callbackReturnValue,
usedFakeTimers,
}
}

function jestFakeTimersAreEnabled() {
return hasJestTimers()
? runWithJestRealTimers(() => {}).usedFakeTimers
: // istanbul ignore next
false
}

// we only run our tests in node, and setImmediate is supported in node.
// istanbul ignore next
function setImmediatePolyfill(fn) {
return globalObj.setTimeout(fn, 0)
}

function getTimeFunctions() {
// istanbul ignore next
return {
clearTimeoutFn: globalObj.clearTimeout,
setImmediateFn: globalObj.setImmediate || setImmediatePolyfill,
setTimeoutFn: globalObj.setTimeout,
/* istanbul ignore else */
if (typeof jest !== 'undefined' && jest !== null) {
return (
// legacy timers
setTimeout._isMockFunction === true ||
// modern timers
Object.prototype.hasOwnProperty.call(setTimeout, 'clock')
)
}
// istanbul ignore next
return false
}

const {clearTimeoutFn, setImmediateFn, setTimeoutFn} = runWithRealTimers(
getTimeFunctions,
)

function getDocument() {
/* istanbul ignore if */
if (typeof window === 'undefined') {
Expand Down Expand Up @@ -144,10 +80,6 @@ function checkContainerType(container) {
export {
getWindowFromNode,
getDocument,
clearTimeoutFn as clearTimeout,
setImmediateFn as setImmediate,
setTimeoutFn as setTimeout,
runWithRealTimers,
checkContainerType,
jestFakeTimersAreEnabled,
TEXT_NODE,
Expand Down
1 change: 0 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ export * from './queries'
export * from './wait-for'
export * from './wait-for-element'
export * from './wait-for-element-to-be-removed'
export * from './wait-for-dom-change'
export {getDefaultNormalizer} from './matches'
export * from './get-node-text'
export * from './events'
Expand Down
64 changes: 0 additions & 64 deletions src/wait-for-dom-change.js

This file was deleted.

Loading

0 comments on commit f1a8a14

Please sign in to comment.