Skip to content

Commit

Permalink
fix: exclude queueMicrotask from default fake timers to not break n…
Browse files Browse the repository at this point in the history
…ode fetch (#7505)
  • Loading branch information
hi-ogawa authored Feb 18, 2025
1 parent 6cc408d commit 167a98d
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 5 deletions.
4 changes: 2 additions & 2 deletions docs/api/vi.md
Original file line number Diff line number Diff line change
Expand Up @@ -818,8 +818,8 @@ Mocking `nextTick` is not supported when running Vitest inside `node:child_proce
The implementation is based internally on [`@sinonjs/fake-timers`](https://github.com/sinonjs/fake-timers).

::: tip
`vi.useFakeTimers()` does not automatically mock `process.nextTick`.
But you can enable it by specifying the option in `toFake` argument: `vi.useFakeTimers({ toFake: ['nextTick'] })`.
`vi.useFakeTimers()` does not automatically mock `process.nextTick` and `queueMicrotask`.
But you can enable it by specifying the option in `toFake` argument: `vi.useFakeTimers({ toFake: ['nextTick', 'queueMicrotask'] })`.
:::

### vi.isFakeTimers {#vi-isfaketimers}
Expand Down
2 changes: 1 addition & 1 deletion docs/config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2345,7 +2345,7 @@ Installs fake timers with the specified Unix epoch.
#### fakeTimers.toFake

- **Type:** `('setTimeout' | 'clearTimeout' | 'setImmediate' | 'clearImmediate' | 'setInterval' | 'clearInterval' | 'Date' | 'nextTick' | 'hrtime' | 'requestAnimationFrame' | 'cancelAnimationFrame' | 'requestIdleCallback' | 'cancelIdleCallback' | 'performance' | 'queueMicrotask')[]`
- **Default:** everything available globally except `nextTick`
- **Default:** everything available globally except `nextTick` and `queueMicrotask`

An array with names of global methods and APIs to fake.

Expand Down
4 changes: 2 additions & 2 deletions packages/vitest/src/integrations/mock/timers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,9 @@ export class FakeTimers {

if (!this._fakingTime) {
const toFake = Object.keys(this._fakeTimers.timers)
// Do not mock nextTick by default. It can still be mocked through userConfig.
// Do not mock timers internally used by node by default. It can still be mocked through userConfig.
.filter(
timer => timer !== 'nextTick',
timer => timer !== 'nextTick' && timer !== 'queueMicrotask',
) as (keyof FakeTimerWithContext['timers'])[]

if (this._userConfig?.toFake?.includes('nextTick') && isChildProcess()) {
Expand Down
27 changes: 27 additions & 0 deletions test/core/test/timers-queueMicrotask.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { expect, onTestFinished, test, vi } from 'vitest'

test(`node fetch works without fake timers`, async () => {
expect(await Response.json('ok').json()).toBe('ok')
})

test(`node fetch works with fake timers`, async () => {
vi.useFakeTimers()
onTestFinished(() => {
vi.useRealTimers()
})
expect(await Response.json('ok').json()).toBe('ok')
})

// skipped since this might cause a weird OOM on CI
test.skip(`node fetch timeouts with fake queueMicrotask`, async () => {
vi.useFakeTimers({ toFake: ['queueMicrotask'] })
onTestFinished(() => {
vi.useRealTimers()
})
expect(
await Promise.race([
new Promise(r => setTimeout(() => r('timeout'), 200)),
Response.json('ok').json(),
]),
).toBe('timeout')
})

0 comments on commit 167a98d

Please sign in to comment.