Skip to content

Commit 03912b4

Browse files
authoredFeb 4, 2025··
fix: fix getMockedSystemTime for useFakeTimer (#7405)
1 parent d3acbd8 commit 03912b4

File tree

4 files changed

+70
-13
lines changed

4 files changed

+70
-13
lines changed
 

‎docs/api/vi.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ Removes all timers that are scheduled to run. These timers will never run in the
690690

691691
- **Type**: `() => Date | null`
692692

693-
Returns mocked current date that was set using `setSystemTime`. If date is not mocked the method will return `null`.
693+
Returns mocked current date. If date is not mocked the method will return `null`.
694694

695695
### vi.getRealSystemTime
696696

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

+18-7
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,14 @@ import { mockDate, RealDate, resetDate } from './date'
1717
export class FakeTimers {
1818
private _global: typeof globalThis
1919
private _clock!: InstalledClock
20+
// | _fakingTime | _fakingDate |
21+
// +-------------+-------------+
22+
// | false | falsy | initial
23+
// | false | truethy | vi.setSystemTime called first (for mocking only Date without fake timers)
24+
// | true | falsy | vi.useFakeTimers called first
25+
// | true | truethy | unreachable
2026
private _fakingTime: boolean
21-
private _fakingDate: boolean
27+
private _fakingDate: Date | null
2228
private _fakeTimers: FakeTimerWithContext
2329
private _userConfig?: FakeTimerInstallOpts
2430
private _now = RealDate.now
@@ -32,7 +38,7 @@ export class FakeTimers {
3238
}) {
3339
this._userConfig = config
3440

35-
this._fakingDate = false
41+
this._fakingDate = null
3642

3743
this._fakingTime = false
3844
this._fakeTimers = withGlobal(global)
@@ -129,7 +135,7 @@ export class FakeTimers {
129135
useRealTimers(): void {
130136
if (this._fakingDate) {
131137
resetDate()
132-
this._fakingDate = false
138+
this._fakingDate = null
133139
}
134140

135141
if (this._fakingTime) {
@@ -177,16 +183,21 @@ export class FakeTimers {
177183
}
178184
}
179185

180-
setSystemTime(now?: number | Date): void {
186+
setSystemTime(now?: string | number | Date): void {
187+
const date = (typeof now === 'undefined' || now instanceof Date) ? now : new Date(now)
181188
if (this._fakingTime) {
182-
this._clock.setSystemTime(now)
189+
this._clock.setSystemTime(date)
183190
}
184191
else {
185-
mockDate(now ?? this.getRealSystemTime())
186-
this._fakingDate = true
192+
this._fakingDate = date ?? new Date(this.getRealSystemTime())
193+
mockDate(this._fakingDate)
187194
}
188195
}
189196

197+
getMockedSystemTime(): Date | null {
198+
return this._fakingTime ? new Date(this._clock.now) : this._fakingDate
199+
}
200+
190201
getRealSystemTime(): number {
191202
return this._now()
192203
}

‎packages/vitest/src/integrations/vi.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export interface VitestUtils {
8585
*/
8686
setSystemTime: (time: number | string | Date) => VitestUtils
8787
/**
88-
* Returns mocked current date that was set using `setSystemTime`. If date is not mocked the method will return `null`.
88+
* Returns mocked current date. If date is not mocked the method will return `null`.
8989
*/
9090
getMockedSystemTime: () => Date | null
9191
/**
@@ -502,14 +502,12 @@ function createVitest(): VitestUtils {
502502
},
503503

504504
setSystemTime(time: number | string | Date) {
505-
const date = time instanceof Date ? time : new Date(time)
506-
_mockedDate = date
507-
timers().setSystemTime(date)
505+
timers().setSystemTime(time)
508506
return utils
509507
},
510508

511509
getMockedSystemTime() {
512-
return _mockedDate
510+
return timers().getMockedSystemTime()
513511
},
514512

515513
getRealSystemTime() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { afterEach, expect, it, vi } from 'vitest'
2+
3+
afterEach(() => {
4+
vi.useRealTimers()
5+
})
6+
7+
it('with fake timers', () => {
8+
expect(vi.getMockedSystemTime()).toBe(null)
9+
10+
vi.useFakeTimers()
11+
expect(vi.getMockedSystemTime()).toEqual(new Date())
12+
13+
vi.setSystemTime(0)
14+
expect(vi.getMockedSystemTime()).toEqual(new Date())
15+
expect(vi.getMockedSystemTime()).toEqual(new Date(0))
16+
17+
vi.advanceTimersByTime(1234)
18+
expect(vi.getMockedSystemTime()).toEqual(new Date())
19+
expect(vi.getMockedSystemTime()).toEqual(new Date(1234))
20+
21+
vi.useRealTimers()
22+
expect(vi.getMockedSystemTime()).toBe(null)
23+
expect(new Date()).not.toEqual(new Date(1234))
24+
25+
vi.useFakeTimers({ now: 12345 })
26+
expect(vi.getMockedSystemTime()).toEqual(new Date())
27+
expect(vi.getMockedSystemTime()).toEqual(new Date(12345))
28+
})
29+
30+
it('without fake timers', () => {
31+
expect(vi.getMockedSystemTime()).toBe(null)
32+
33+
vi.setSystemTime(0)
34+
expect(vi.getMockedSystemTime()).toEqual(new Date())
35+
expect(vi.getMockedSystemTime()).toEqual(new Date(0))
36+
37+
vi.setSystemTime(1234)
38+
expect(vi.getMockedSystemTime()).toEqual(new Date())
39+
expect(vi.getMockedSystemTime()).toEqual(new Date(1234))
40+
41+
vi.useRealTimers()
42+
expect(vi.getMockedSystemTime()).toBe(null)
43+
expect(new Date()).not.toEqual(new Date(1234))
44+
45+
vi.setSystemTime(12345)
46+
expect(vi.getMockedSystemTime()).toEqual(new Date())
47+
expect(vi.getMockedSystemTime()).toEqual(new Date(12345))
48+
})

0 commit comments

Comments
 (0)
Please sign in to comment.