Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support for fake clock (new Date(), Date.now()...) in vitest timers #506

Closed
4 tasks done
cexbrayat opened this issue Jan 12, 2022 · 10 comments · Fixed by #531
Closed
4 tasks done

support for fake clock (new Date(), Date.now()...) in vitest timers #506

cexbrayat opened this issue Jan 12, 2022 · 10 comments · Fixed by #531

Comments

@cexbrayat
Copy link
Contributor

Clear and concise description of the problem

Jest support for timers has builtin support for clocks: when using jest.useFakeTimers(), a fake clock is instantiated. Then calls to jest.advanceTimersByTime() increase the fake clock time. Application code that use new Date(), or Date.now(), or performance.now() and others will get this fake time.

Jest leverages @sinonjs/fake-timers to do so (in its modern implementation, which is the default nowadays).

It would be super handy to have vitest do the same. Currently the API mimicks the one from Jest (which is awesome, don't get me wrong 🤗) but doesn't handle this feature, which makes a test suite migration a bit more difficult, as tests that rely on setTimeout orsetInterval will behave the same in vitest and Jest, but the one that leverage Date will not.

Suggested solution

It could be possible to do the same as Jest and directly leverage @sinonjs/fake-timers.

Alternative

It is possible for a developer who wants to have a fake clock in its test to use @sinonjs/fake-timers in addition to vitest

Additional context

No response

Validations

@sheremet-va
Copy link
Member

sheremet-va commented Jan 12, 2022

We can just mock date when interval moves in our implementation? (sinon has a simple hijackMethod method for that) We already have vi.mockCurrentDate that can do that.

I think, @sinonjs/fake-timers is too large for our needs

@sheremet-va
Copy link
Member

But to be clear I am not opposing using it. I think if community decides, we can easily migrate to it. Maybe start a discussion in discord?

@cexbrayat
Copy link
Contributor Author

Maybe just moving the mocked date could be enough. Ideally, these kinds of test would work out of the box:

test('new Date()', async() => {
  vi.useFakeTimers()

  const start = new Date().getTime()

  vi.advanceTimersByTime(2000)

  expect(new Date().getTime()).toBe(start + 2000)

  vi.useRealTimers()
})

test('Date.now()', async() => {
  vi.useFakeTimers()

  const start = Date.now()

  vi.advanceTimersByTime(2000)

  expect(Date.now()).toBe(start + 2000)

  vi.useRealTimers()
})

@fadi-george
Copy link

I feel mockCurrentDate should be changed (back?) to setSystemTime to make it more similar/consistent to jest.

@Smrtnyk
Copy link

Smrtnyk commented Jan 13, 2022

its not just moving the current time, its also about scheduling timers and firing them when they should fire.
Maybe it will need to wrap for example setTimeout and keep track of callbacks and timeouts and fire them when time is moved.
Probably sinon fake timers is the least painful approach and is already battletested

@sheremet-va
Copy link
Member

its not just moving the current time, its also about scheduling timers and firing them when they should fire.

It already does it tho?

@sheremet-va
Copy link
Member

I must've mistaken sinon/fake-timers with sinon. Now that I look at it, I think we can implement jest like methods using sinon/fake-timers inside without gaining much weight. Will make a PR soon.

@sheremet-va
Copy link
Member

Released in v0.2.0

@RPDeshaies
Copy link

@sheremet-va if vi.mockCurrentDate was changed to vi.setSystemTime, what hapenned with vi.restoreCurrentDate ?

@patak-dev
Copy link
Member

@RPDeshaies you would call vi.useRealTimers(). See the example here https://vitest.dev/api/#vi-setsystemtime

const date = new Date(1998, 11, 19)

vi.useFakeTimers()
vi.setSystemTime(date)

expect(Date.now()).toBe(date.valueOf())

vi.useRealTimers()

chaii3 pushed a commit to chaii3/vitest that referenced this issue May 13, 2022
chaii3 pushed a commit to chaii3/vitest that referenced this issue May 13, 2022
* feat(useTransition): support for vectors (vitest-dev#376)

* refactor(useTransition): cleaning up (vitest-dev#385)

* refactor(useWebWorkerFn): Small doc and type improvements (vitest-dev#382)

Co-authored-by: Anthony Fu <[email protected]>

* feat: pwa reload prompt

* chore: update docs

* refactor(useWebWorkerFn): Small doc and type improvements (vitest-dev#382)

Co-authored-by: Anthony Fu <[email protected]>

* chore: update docs

* test: simpilfy tests for useTransition

* chore: fix tests

* feat(useTransition): support for delayed transitions (vitest-dev#386)

* feat(useTransition): support for disabled transitions (vitest-dev#436)

* feat!: introduce `controls` option

* chore: update

* chore: update

* refactor(useRafFn): remove depreacted APIs

* chore: enabled tests for next branch

* fix(useFetch)!: allow setting response type before doing request (vitest-dev#454)

Co-authored-by: Anthony Fu <[email protected]>

* chore: resolve conflicts

* feat(useMediaControls): expose source types (vitest-dev#495)

* fix(useMediaControls): Removes tracks that have been inserted in html (vitest-dev#493)

* chore: release v4.9.3

* fix(usePermission): tolerate error on FireFox

* fix(useDevicesList): treat as premssion granted after getUserMedia

* chore: release v4.9.4

* chore: fix typo (vitest-dev#502)

* feat(useWebSocket): add immediate option (vitest-dev#503)

* feat(useAxios): bring API into line with useFetch (vitest-dev#499)

* feat(createEventHook): new function (#497)

* chore: release v4.10.0

* fix(useMediaControls): Doesn't rewrite default media properties (vitest-dev#500)

* feat(useMediaControls): add error event (vitest-dev#509)

* feat(useStorage): optimize event handling logic (vitest-dev#505)

* feat(useFetch): add afterFetch option, onFetchResponse, and onFetchError (vitest-dev#506)

* feat(useWebWoker): return worker (vitest-dev#507)

Co-authored-by: Anthony Fu <[email protected]>

* fix: Change `onMediaError` to `onSourceError` (vitest-dev#510)

* feat(onClickOutside): default to just pointerDown (vitest-dev#508)

Co-authored-by: Anthony Fu <[email protected]>
Co-authored-by: sibbng <[email protected]>

* chore: update docs

* chore: release v4.11.0

* fix(onClickOutside): duplicate code (vitest-dev#519)

Co-authored-by: Nurettin Kaya <[email protected]>

* feat(createEventHook): added interface (vitest-dev#531)

* feat(createEventHook): added interface

* added types for EventHookOn, EventHookOff, and EventHook trigger

* feat(useStorage): allow custom serializer (vitest-dev#528)

* feat(useStorage): allow custom serializer

* update test

* refactor(useMediaControls): Deprecate options that can simply be set as attributes (vitest-dev#514)

* useMediaControls: Add `volumechange` event listener

* fix: `mute` returned

* feat: Deprecate video options:
* `poster`
* `autoplay`
* `preload`
* `loop`
* `controls`
* `playsinline`
* `autoPictureInPicture`

* fix: Fix deprecated behaviour in demo

* fix: Remove deprecated usage from doc

* refactor: More polite messages

* fix: Remove `console.warn`s

* chore: release v4.11.1

* refactor!: remove deprecated apis

* chore: add next tag

* chore: release v5.0.0-beta.1

* feat: introduce `components` & `directives` (vitest-dev#486)

Co-authored-by: Anthony Fu <[email protected]>

* docs: re-organize

* chore: fix lint

* docs: about components

* chore: include directives

* chore: release v5.0.0-beta.2

* chore: rollback jest

* chore: fix docs build

* docs: readme for components

* docs: add @vueuse/gesture

* chore: ship indexes.json

* chore: release v5.0.0-beta.3

* feat(typedef): add return typedefs (vitest-dev#543) (vitest-dev#544)

* refactor!: change publish strcture and support submodules, close vitest-dev#469

* chore: cleanup stories.tsx

* docs: update docs about submodules

* chore: fix docs

* chore: release v5.0.0-beta.4

* chore: update lock

* chore: release v5.0.0-beta.5

* chore: update deps and extend publish memory

* refactor: remove `useDeviceLight`

* chore: update

* chore: fix tests

* chore: release v5.0.0-beta.7

* refactor(useWebSocket)!: change immediate default for 5.0.0 (vitest-dev#545)

* feat(useIpcRenderer): new add-one & new functions (vitest-dev#547)

Co-authored-by: Anthony Fu <[email protected]>

* chore: update deps

* chore: release v5.0.0-beta.8

* chore: fix docs build

* chore(usePointerSwipe): fix typo (vitest-dev#557)

* fix(useAuth): now reqiures the auth instance, close vitest-dev#538

* chore: update deps

* docs(biSyncRef): fix console output comment (vitest-dev#555)

* docs: removed deprecated value from example (vitest-dev#556)

* docs(guidlines): added guidelines (vitest-dev#535)

* docs: update guidelines

* chore: update guidelines

Co-authored-by: Scott Bedard <[email protected]>
Co-authored-by: Fabian <[email protected]>
Co-authored-by: Ismail Gjevori <[email protected]>
Co-authored-by: Alex Kozack <[email protected]>
Co-authored-by: Shinigami <[email protected]>
Co-authored-by: wheat <[email protected]>
Co-authored-by: sibbng <[email protected]>
Co-authored-by: JserWang <[email protected]>
Co-authored-by: Pig Fang <[email protected]>
Co-authored-by: ArcherGu <[email protected]>
Co-authored-by: Ilya Komichev <[email protected]>
Co-authored-by: Daiki Ojima <[email protected]>
Co-authored-by: Manaus <[email protected]>
@github-actions github-actions bot locked and limited conversation to collaborators Jun 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants