Skip to content

Commit

Permalink
fix: fix getMockedSystemTime for useFakeTimer (#7405)
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa authored Feb 4, 2025
1 parent d3acbd8 commit 03912b4
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 13 deletions.
2 changes: 1 addition & 1 deletion docs/api/vi.md
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ Removes all timers that are scheduled to run. These timers will never run in the

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

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

### vi.getRealSystemTime

Expand Down
25 changes: 18 additions & 7 deletions packages/vitest/src/integrations/mock/timers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@ import { mockDate, RealDate, resetDate } from './date'
export class FakeTimers {
private _global: typeof globalThis
private _clock!: InstalledClock
// | _fakingTime | _fakingDate |
// +-------------+-------------+
// | false | falsy | initial
// | false | truethy | vi.setSystemTime called first (for mocking only Date without fake timers)
// | true | falsy | vi.useFakeTimers called first
// | true | truethy | unreachable
private _fakingTime: boolean
private _fakingDate: boolean
private _fakingDate: Date | null
private _fakeTimers: FakeTimerWithContext
private _userConfig?: FakeTimerInstallOpts
private _now = RealDate.now
Expand All @@ -32,7 +38,7 @@ export class FakeTimers {
}) {
this._userConfig = config

this._fakingDate = false
this._fakingDate = null

this._fakingTime = false
this._fakeTimers = withGlobal(global)
Expand Down Expand Up @@ -129,7 +135,7 @@ export class FakeTimers {
useRealTimers(): void {
if (this._fakingDate) {
resetDate()
this._fakingDate = false
this._fakingDate = null
}

if (this._fakingTime) {
Expand Down Expand Up @@ -177,16 +183,21 @@ export class FakeTimers {
}
}

setSystemTime(now?: number | Date): void {
setSystemTime(now?: string | number | Date): void {
const date = (typeof now === 'undefined' || now instanceof Date) ? now : new Date(now)
if (this._fakingTime) {
this._clock.setSystemTime(now)
this._clock.setSystemTime(date)
}
else {
mockDate(now ?? this.getRealSystemTime())
this._fakingDate = true
this._fakingDate = date ?? new Date(this.getRealSystemTime())
mockDate(this._fakingDate)
}
}

getMockedSystemTime(): Date | null {
return this._fakingTime ? new Date(this._clock.now) : this._fakingDate
}

getRealSystemTime(): number {
return this._now()
}
Expand Down
8 changes: 3 additions & 5 deletions packages/vitest/src/integrations/vi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export interface VitestUtils {
*/
setSystemTime: (time: number | string | Date) => VitestUtils
/**
* Returns mocked current date that was set using `setSystemTime`. If date is not mocked the method will return `null`.
* Returns mocked current date. If date is not mocked the method will return `null`.
*/
getMockedSystemTime: () => Date | null
/**
Expand Down Expand Up @@ -502,14 +502,12 @@ function createVitest(): VitestUtils {
},

setSystemTime(time: number | string | Date) {
const date = time instanceof Date ? time : new Date(time)
_mockedDate = date
timers().setSystemTime(date)
timers().setSystemTime(time)
return utils
},

getMockedSystemTime() {
return _mockedDate
return timers().getMockedSystemTime()
},

getRealSystemTime() {
Expand Down
48 changes: 48 additions & 0 deletions test/core/test/timers-getMockedSystemTime.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { afterEach, expect, it, vi } from 'vitest'

afterEach(() => {
vi.useRealTimers()
})

it('with fake timers', () => {
expect(vi.getMockedSystemTime()).toBe(null)

vi.useFakeTimers()
expect(vi.getMockedSystemTime()).toEqual(new Date())

vi.setSystemTime(0)
expect(vi.getMockedSystemTime()).toEqual(new Date())
expect(vi.getMockedSystemTime()).toEqual(new Date(0))

vi.advanceTimersByTime(1234)
expect(vi.getMockedSystemTime()).toEqual(new Date())
expect(vi.getMockedSystemTime()).toEqual(new Date(1234))

vi.useRealTimers()
expect(vi.getMockedSystemTime()).toBe(null)
expect(new Date()).not.toEqual(new Date(1234))

vi.useFakeTimers({ now: 12345 })
expect(vi.getMockedSystemTime()).toEqual(new Date())
expect(vi.getMockedSystemTime()).toEqual(new Date(12345))
})

it('without fake timers', () => {
expect(vi.getMockedSystemTime()).toBe(null)

vi.setSystemTime(0)
expect(vi.getMockedSystemTime()).toEqual(new Date())
expect(vi.getMockedSystemTime()).toEqual(new Date(0))

vi.setSystemTime(1234)
expect(vi.getMockedSystemTime()).toEqual(new Date())
expect(vi.getMockedSystemTime()).toEqual(new Date(1234))

vi.useRealTimers()
expect(vi.getMockedSystemTime()).toBe(null)
expect(new Date()).not.toEqual(new Date(1234))

vi.setSystemTime(12345)
expect(vi.getMockedSystemTime()).toEqual(new Date())
expect(vi.getMockedSystemTime()).toEqual(new Date(12345))
})

0 comments on commit 03912b4

Please sign in to comment.