Skip to content

Commit f8b1532

Browse files
hi-ogawaOpenCode (claude-opus-4-8)
andauthored
feat!: update @sinonjs/fake-timers and support mocking Temporal (#10654)
Co-authored-by: Hiroshi Ogawa <4232207+hi-ogawa@users.noreply.github.com> Co-authored-by: OpenCode (claude-opus-4-8) <noreply@opencode.ai>
1 parent 1761bb1 commit f8b1532

7 files changed

Lines changed: 75 additions & 32 deletions

File tree

docs/config/faketimers.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Installs fake timers with the specified Unix epoch.
1818

1919
## fakeTimers.toFake
2020

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

2424
An array with names of global methods and APIs to fake. For example, to only mock `setTimeout()` and `nextTick()`, specify this property as `['setTimeout', 'nextTick']`.
@@ -27,7 +27,7 @@ Mocking `nextTick` is not supported when running Vitest inside `node:child_proce
2727

2828
## fakeTimers.toNotFake
2929

30-
- **Type:** `('setTimeout' | 'clearTimeout' | 'setImmediate' | 'clearImmediate' | 'setInterval' | 'clearInterval' | 'Date' | 'nextTick' | 'hrtime' | 'requestAnimationFrame' | 'cancelAnimationFrame' | 'requestIdleCallback' | 'cancelIdleCallback' | 'performance' | 'queueMicrotask')[]`
30+
- **Type:** `('setTimeout' | 'clearTimeout' | 'setImmediate' | 'clearImmediate' | 'setInterval' | 'clearInterval' | 'Date' | 'nextTick' | 'hrtime' | 'requestAnimationFrame' | 'cancelAnimationFrame' | 'requestIdleCallback' | 'cancelIdleCallback' | 'performance' | 'queueMicrotask' | 'Intl' | 'Temporal')[]`
3131
- **Default:** `[]`
3232

3333
An array with names of global methods and APIs to keep native. All other available timers will be mocked. For example, to keep `setInterval()` native and mock all other timers, specify this property as `['setInterval']`.

docs/guide/migration.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,24 @@ vitest --ui
5252
# UI started at http://localhost:51204/__vitest__/?token=...
5353
```
5454

55+
### Fake Timers Now Mock `Temporal`
56+
57+
Vitest now mocks the [`Temporal`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal) API alongside `Date` when fake timers are enabled, following the [`@sinonjs/fake-timers` v15.4 update](https://github.com/sinonjs/fake-timers/blob/main/CHANGELOG.md#1540--2026-05-05). This only takes effect when `Temporal` is available on the global object — either natively (Node.js >= 26 by default, behind `--harmony-temporal` on older versions, and supporting browsers) or through a globally installed polyfill such as `import 'temporal-polyfill/global'`.
58+
59+
Previously `Temporal.Now` kept returning the real wall-clock time even when [`vi.useFakeTimers()`](/api/vi#vi-usefaketimers) was active. Now it follows the mocked clock:
60+
61+
```ts
62+
vi.useFakeTimers({ now: 0 })
63+
64+
Temporal.Now.instant().epochMilliseconds // 0 (was the real time in v4)
65+
```
66+
67+
`Temporal` is part of the default set of faked APIs, so it is controlled by [`fakeTimers.toFake`](/config/#faketimers-tofake) and [`fakeTimers.toNotFake`](/config/#faketimers-tonotfake). To keep `Temporal` native, add it to `toNotFake`:
68+
69+
```ts
70+
vi.useFakeTimers({ toNotFake: ['Temporal'] })
71+
```
72+
5573
### Removed `test.sequential`, `describe.sequential`, and `sequential` Options
5674

5775
Vitest 5.0 removes the deprecated `test.sequential`, `describe.sequential`, and `sequential` test options. Use `concurrent: false` when you need a test or suite to opt out of inherited or globally configured concurrency.

packages/vitest/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@
192192
"@edge-runtime/vm": "^5.0.0",
193193
"@jridgewell/trace-mapping": "catalog:",
194194
"@opentelemetry/api": "^1.9.0",
195-
"@sinonjs/fake-timers": "15.3.2",
195+
"@sinonjs/fake-timers": "15.4.0",
196196
"@types/estree": "catalog:",
197197
"@types/istanbul-lib-coverage": "catalog:",
198198
"@types/istanbul-reports": "catalog:",

patches/@sinonjs__fake-timers@15.3.2.patch renamed to patches/@sinonjs__fake-timers@15.4.0.patch

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
diff --git a/src/fake-timers-src.js b/src/fake-timers-src.js
2-
index 7d4cfa1b6b8aebc8575e08bd432f8f8ca43d3c4f..09d12bec356aa1048f09771e915075fdecb065b9 100644
2+
index 241a7ad3eeb8b5eb691439fab31a87ef13c76345..2df1b2086670bfa06cdb148a9dbe61cd41680f2e 100644
33
--- a/src/fake-timers-src.js
44
+++ b/src/fake-timers-src.js
55
@@ -2,14 +2,14 @@
@@ -20,7 +20,7 @@ index 7d4cfa1b6b8aebc8575e08bd432f8f8ca43d3c4f..09d12bec356aa1048f09771e915075fd
2020
} catch {
2121
// ignored
2222
}
23-
@@ -510,7 +510,7 @@ function withGlobal(_global) {
23+
@@ -537,7 +537,7 @@ function withGlobal(_global) {
2424
isPresent.hrtime && typeof _global.process.hrtime.bigint === "function";
2525
isPresent.nextTick =
2626
_global.process && typeof _global.process.nextTick === "function";

pnpm-lock.yaml

Lines changed: 24 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ overrides:
3939
vite: 'catalog:'
4040
vitest: workspace:*
4141
patchedDependencies:
42-
'@sinonjs/fake-timers@15.3.2': patches/@sinonjs__fake-timers@15.3.2.patch
42+
'@sinonjs/fake-timers@15.4.0': patches/@sinonjs__fake-timers@15.4.0.patch
4343
acorn@8.11.3: patches/acorn@8.11.3.patch
4444
cac@6.7.14: patches/cac@6.7.14.patch
4545
istanbul-lib-instrument: patches/istanbul-lib-instrument.patch
@@ -87,7 +87,7 @@ catalog:
8787
playwright: ^1.61.0
8888
rollup: ^4.59.0
8989
semver: ^7.8.3
90-
sinon: ^21.0.3
90+
sinon: ^22.0.0
9191
sinon-chai: ^4.0.1
9292
sirv: ^3.0.2
9393
std-env: ^4.0.0-rc.1
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { afterEach, expect, it, vi } from 'vitest'
2+
3+
// use polyfill for node < 26
4+
if (!globalThis.Temporal) {
5+
await import('temporal-polyfill/global')
6+
}
7+
8+
afterEach(() => {
9+
vi.useRealTimers()
10+
})
11+
12+
it('Temporal.Now follows fake timers', () => {
13+
const real = globalThis.Temporal
14+
15+
vi.useFakeTimers({ now: 0 })
16+
expect(globalThis.Temporal).not.toBe(real)
17+
expect(globalThis.Temporal.Now.instant().epochMilliseconds).toBe(0)
18+
19+
vi.advanceTimersByTime(1234)
20+
expect(globalThis.Temporal.Now.instant().epochMilliseconds).toBe(1234)
21+
22+
// restore
23+
vi.useRealTimers()
24+
expect(globalThis.Temporal).toBe(real)
25+
expect(globalThis.Temporal.Now.instant().epochMilliseconds).not.toBe(1234)
26+
})

0 commit comments

Comments
 (0)