@@ -20,9 +20,9 @@ export class FakeTimers {
2020 // | _fakingTime | _fakingDate |
2121 // +-------------+-------------+
2222 // | false | falsy | initial
23- // | false | truthy | vi.setSystemTime called first (for mocking only Date without fake timers)
23+ // | false | truthy | vi.setSystemTime called first (for mocking only Date without fake timers)
2424 // | true | falsy | vi.useFakeTimers called first
25- // | true | truthy | unreachable
25+ // | true | truthy | unreachable
2626 private _fakingTime : boolean
2727 private _fakingDate : Date | null
2828 private _fakeTimers : FakeTimerWithContext
@@ -145,34 +145,36 @@ export class FakeTimers {
145145 }
146146
147147 useFakeTimers ( ) : void {
148+ const fakeDate = this . _fakingDate || Date . now ( )
148149 if ( this . _fakingDate ) {
149- throw new Error (
150- '"setSystemTime" was called already and date was mocked. Reset timers using `vi.useRealTimers()` if you want to use fake timers again.' ,
151- )
150+ resetDate ( )
151+ this . _fakingDate = null
152152 }
153153
154- if ( ! this . _fakingTime ) {
155- const toFake = Object . keys ( this . _fakeTimers . timers )
156- // Do not mock timers internally used by node by default. It can still be mocked through userConfig.
157- . filter (
158- timer => timer !== 'nextTick' && timer !== 'queueMicrotask' ,
159- ) as ( keyof FakeTimerWithContext [ 'timers' ] ) [ ]
160-
161- if ( this . _userConfig ?. toFake ?. includes ( 'nextTick' ) && isChildProcess ( ) ) {
162- throw new Error (
163- 'process.nextTick cannot be mocked inside child_process' ,
164- )
165- }
154+ if ( this . _fakingTime ) {
155+ this . _clock . uninstall ( )
156+ }
166157
167- this . _clock = this . _fakeTimers . install ( {
168- now : Date . now ( ) ,
169- ...this . _userConfig ,
170- toFake : this . _userConfig ?. toFake || toFake ,
171- ignoreMissingTimers : true ,
172- } )
158+ const toFake = Object . keys ( this . _fakeTimers . timers )
159+ // Do not mock timers internally used by node by default. It can still be mocked through userConfig.
160+ . filter (
161+ timer => timer !== 'nextTick' && timer !== 'queueMicrotask' ,
162+ ) as ( keyof FakeTimerWithContext [ 'timers' ] ) [ ]
173163
174- this . _fakingTime = true
164+ if ( this . _userConfig ?. toFake ?. includes ( 'nextTick' ) && isChildProcess ( ) ) {
165+ throw new Error (
166+ 'process.nextTick cannot be mocked inside child_process' ,
167+ )
175168 }
169+
170+ this . _clock = this . _fakeTimers . install ( {
171+ now : fakeDate ,
172+ ...this . _userConfig ,
173+ toFake : this . _userConfig ?. toFake || toFake ,
174+ ignoreMissingTimers : true ,
175+ } )
176+
177+ this . _fakingTime = true
176178 }
177179
178180 reset ( ) : void {
@@ -221,7 +223,8 @@ export class FakeTimers {
221223 private _checkFakeTimers ( ) {
222224 if ( ! this . _fakingTime ) {
223225 throw new Error (
224- 'Timers are not mocked. Try calling "vi.useFakeTimers()" first.' ,
226+ 'A function to advance timers was called but the timers APIs are not mocked. '
227+ + 'Call `vi.useFakeTimers()` in the test file first.' ,
225228 )
226229 }
227230
0 commit comments