mirror of
https://github.com/vitest-dev/vitest.git
synced 2026-02-01 17:36:51 +00:00
feat: allow passing config to sinon/fake-timers (#1261)
* feat: allow passing config to sinon/fake-timers * chore: fix timers test
This commit is contained in:
parent
7459ff8a46
commit
d4e8060f68
@ -33,6 +33,20 @@ const coverageConfigDefaults = {
|
||||
extension: ['.js', '.cjs', '.mjs', '.ts', '.tsx', '.jsx', '.vue', '.svelte'],
|
||||
} as ResolvedC8Options
|
||||
|
||||
export const fakeTimersDefaults = {
|
||||
loopLimit: 10_000,
|
||||
shouldClearNativeTimers: true,
|
||||
toFake: [
|
||||
'setTimeout',
|
||||
'clearTimeout',
|
||||
'setInterval',
|
||||
'clearInterval',
|
||||
'setImmediate',
|
||||
'clearImmediate',
|
||||
'Date',
|
||||
],
|
||||
} as NonNullable<UserConfig['fakeTimers']>
|
||||
|
||||
const config = {
|
||||
allowOnly: !process.env.CI,
|
||||
watch: !process.env.CI,
|
||||
@ -56,6 +70,7 @@ const config = {
|
||||
uiBase: '/__vitest__/',
|
||||
open: true,
|
||||
coverage: coverageConfigDefaults,
|
||||
fakeTimers: fakeTimersDefaults,
|
||||
}
|
||||
|
||||
export const configDefaults: Required<Pick<UserConfig, keyof typeof config>> = Object.freeze(config)
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
import type {
|
||||
FakeTimerInstallOpts,
|
||||
FakeTimerWithContext,
|
||||
InstalledClock,
|
||||
} from '@sinonjs/fake-timers'
|
||||
@ -19,17 +20,17 @@ export class FakeTimers {
|
||||
private _fakingTime: boolean
|
||||
private _fakingDate: boolean
|
||||
private _fakeTimers: FakeTimerWithContext
|
||||
private _maxLoops: number
|
||||
private _userConfig?: FakeTimerInstallOpts
|
||||
private _now = RealDate.now
|
||||
|
||||
constructor({
|
||||
global,
|
||||
maxLoops = 10_000,
|
||||
config,
|
||||
}: {
|
||||
global: typeof globalThis
|
||||
maxLoops?: number
|
||||
config: FakeTimerInstallOpts
|
||||
}) {
|
||||
this._maxLoops = maxLoops
|
||||
this._userConfig = config
|
||||
|
||||
this._fakingDate = false
|
||||
|
||||
@ -104,10 +105,9 @@ export class FakeTimers {
|
||||
const toFake = Object.keys(this._fakeTimers.timers) as Array<keyof FakeTimerWithContext['timers']>
|
||||
|
||||
this._clock = this._fakeTimers.install({
|
||||
loopLimit: this._maxLoops,
|
||||
now: Date.now(),
|
||||
toFake,
|
||||
shouldClearNativeTimers: true,
|
||||
...this._userConfig,
|
||||
})
|
||||
|
||||
this._fakingTime = true
|
||||
@ -143,6 +143,10 @@ export class FakeTimers {
|
||||
return 0
|
||||
}
|
||||
|
||||
configure(config: FakeTimerInstallOpts): void {
|
||||
this._userConfig = config
|
||||
}
|
||||
|
||||
private _checkFakeTimers() {
|
||||
if (!this._fakingTime) {
|
||||
throw new Error(
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
|
||||
import type { FakeTimerInstallOpts } from '@sinonjs/fake-timers'
|
||||
import { parseStacktrace } from '../utils/source-map'
|
||||
import type { VitestMocker } from '../runtime/mocker'
|
||||
import { resetModules } from '../utils'
|
||||
import { getWorkerState, resetModules } from '../utils'
|
||||
import { FakeTimers } from './timers'
|
||||
import type { EnhancedSpy, MaybeMocked, MaybeMockedDeep } from './spy'
|
||||
import { fn, isMockFunction, spies, spyOn } from './spy'
|
||||
@ -13,10 +14,6 @@ class VitestUtils {
|
||||
private _mocker: VitestMocker
|
||||
|
||||
constructor() {
|
||||
this._timers = new FakeTimers({
|
||||
global: globalThis,
|
||||
maxLoops: 10_000,
|
||||
})
|
||||
// @ts-expect-error injected by vite-nide
|
||||
this._mocker = typeof __vitest_mocker__ !== 'undefined' ? __vitest_mocker__ : null
|
||||
this._mockedDate = null
|
||||
@ -30,11 +27,24 @@ class VitestUtils {
|
||||
+ '\n- Otherwise, it might be a Vitest bug. Please report it to https://github.com/vitest-dev/vitest/issues\n'
|
||||
throw new Error(errorMsg)
|
||||
}
|
||||
|
||||
const workerState = getWorkerState()
|
||||
this._timers = new FakeTimers({
|
||||
global: globalThis,
|
||||
config: workerState.config.fakeTimers,
|
||||
})
|
||||
}
|
||||
|
||||
// timers
|
||||
|
||||
public useFakeTimers() {
|
||||
public useFakeTimers(config?: FakeTimerInstallOpts) {
|
||||
if (config) {
|
||||
this._timers.configure(config)
|
||||
}
|
||||
else {
|
||||
const workerState = getWorkerState()
|
||||
this._timers.configure(workerState.config.fakeTimers)
|
||||
}
|
||||
this._timers.useFakeTimers()
|
||||
return this
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import type { CommonServerOptions } from 'vite'
|
||||
import type { PrettyFormatOptions } from 'pretty-format'
|
||||
import type { FakeTimerInstallOpts } from '@sinonjs/fake-timers'
|
||||
import type { BuiltinReporters } from '../node/reporters'
|
||||
import type { C8Options, ResolvedC8Options } from './coverage'
|
||||
import type { JSDOMOptions } from './jsdom-options'
|
||||
@ -312,6 +313,11 @@ export interface InlineConfig {
|
||||
* Show heap usage after each test. Usefull for debugging memory leaks.
|
||||
*/
|
||||
logHeapUsage?: boolean
|
||||
|
||||
/**
|
||||
* Options for @sinon/fake-timers
|
||||
*/
|
||||
fakeTimers?: FakeTimerInstallOpts
|
||||
}
|
||||
|
||||
export interface UserConfig extends InlineConfig {
|
||||
|
||||
@ -176,7 +176,7 @@ describe('FakeTimers', () => {
|
||||
setTimeout,
|
||||
}
|
||||
|
||||
const timers = new FakeTimers({ global, maxLoops: 100 })
|
||||
const timers = new FakeTimers({ global, config: { loopLimit: 100 } })
|
||||
|
||||
timers.useFakeTimers()
|
||||
|
||||
@ -306,7 +306,7 @@ describe('FakeTimers', () => {
|
||||
|
||||
it('throws before allowing infinite recursion', () => {
|
||||
const global = { Date: FakeDate, clearTimeout, process, setTimeout }
|
||||
const timers = new FakeTimers({ global, maxLoops: 100 })
|
||||
const timers = new FakeTimers({ global, config: { loopLimit: 100 } })
|
||||
timers.useFakeTimers()
|
||||
|
||||
global.setTimeout(function infinitelyRecursingCallback() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user