Skip to content

Commit a9a486f

Browse files
authoredJan 23, 2024
fix(vitest): allow useFakeTimers to fake requestIdleCallback on non browser (#5028)
1 parent 253df1c commit a9a486f

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed
 

‎packages/vitest/src/integrations/mock/timers.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { isChildProcess } from '../../utils/base'
1717
import { RealDate, mockDate, resetDate } from './date'
1818

1919
export class FakeTimers {
20+
private _global: typeof globalThis
2021
private _clock!: InstalledClock
2122
private _fakingTime: boolean
2223
private _fakingDate: boolean
@@ -37,6 +38,7 @@ export class FakeTimers {
3738

3839
this._fakingTime = false
3940
this._fakeTimers = withGlobal(global)
41+
this._global = global
4042
}
4143

4244
clearAllTimers(): void {
@@ -138,13 +140,17 @@ export class FakeTimers {
138140
if (this._userConfig?.toFake?.includes('nextTick') && isChildProcess())
139141
throw new Error('process.nextTick cannot be mocked inside child_process')
140142

143+
// setImmediate/clearImmediate is not possible to mock when it's not globally avaiable and it throws an internal error.
144+
// this might be @sinonjs/fake-timers's bug and inconsistent behavior, but for now, we silently filter out these two beforehand for browser testing.
145+
// https://github.com/sinonjs/fake-timers/issues/277
146+
// https://github.com/sinonjs/sinon/issues/2085
141147
const existingFakedMethods = (this._userConfig?.toFake || toFake).filter((method) => {
142148
switch (method) {
143-
case 'hrtime':
144-
case 'nextTick':
145-
return typeof process !== 'undefined' && method in process && process[method]
149+
case 'setImmediate':
150+
case 'clearImmediate':
151+
return method in this._global && this._global[method]
146152
default:
147-
return method in globalThis && globalThis[method]
153+
return true
148154
}
149155
})
150156

‎test/core/test/fixtures/timers.suite.ts

+15
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,21 @@ describe('FakeTimers', () => {
119119
timers.useFakeTimers()
120120
expect(global.clearImmediate).not.toBe(origClearImmediate)
121121
})
122+
123+
it('mocks requestIdleCallback even if not on global', () => {
124+
const global = { Date: FakeDate, clearTimeout, setTimeout };
125+
const timers = new FakeTimers({ global, config: { toFake: ["requestIdleCallback"] }})
126+
timers.useFakeTimers()
127+
expect(global.requestIdleCallback).toBeDefined();
128+
})
129+
130+
it('cannot mock setImmediate and clearImmediate if not on global', () => {
131+
const global = { Date: FakeDate, clearTimeout, setTimeout };
132+
const timers = new FakeTimers({ global, config: { toFake: ["setImmediate", "clearImmediate"] }})
133+
timers.useFakeTimers()
134+
expect(global.setImmediate).toBeUndefined();
135+
expect(global.clearImmediate).toBeUndefined();
136+
})
122137
})
123138

124139
describe('runAllTicks', () => {

0 commit comments

Comments
 (0)
Please sign in to comment.