Skip to content

Commit 0b5f799

Browse files
Julia Millerhexeberlin
authored andcommitted
docs: add examples to new and updated fake timers pages
Each new clock API page now includes a runnable test file wired up via the VitePress <<< snippet include. Tests are written to match the real behavior validated in sinonjs/fake-timers: - jump: ignores timers outside window, fires at destination time, fires intervals at most once, accepts human-readable strings - runToLast: returns time of last timer, skips timers added beyond last scheduled time, runToLastAsync resolves microtasks first - runToFrame: advances to successive 16ms boundaries, fires timers in frame - runMicrotasks: flushes nextTick and queueMicrotask, skips setTimeout - countTimers: zero on fresh clock, counts remaining after tick, includes nextTick microtasks - setSystemTime: does not affect timer scheduling (key subtlety), accepts number or Date - reset: empties queue and returns to install time Also adds <<< snippet include to index.md (existing _index.test.js).
1 parent cd58d01 commit 0b5f799

15 files changed

Lines changed: 367 additions & 0 deletions

docs/concepts/fake-timers/count-timers.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ description: Returns the number of waiting timers.
66
# `clock.countTimers()`
77

88
Returns the number of waiting timers.
9+
10+
<<< ../../.vitepress/tests/docs/fake-timers/api/count-timers.test.js

docs/concepts/fake-timers/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ Fake timers provide a `clock` object to pass time, which can also be used to con
1313

1414
For standalone usage of fake timers it is recommended to use [fake-timers](https://github.com/sinonjs/fake-timers) package instead. It provides the same
1515
set of features (Sinon uses it under the hood) and was previously extracted from Sinon.JS.
16+
17+
<<< ../../.vitepress/tests/docs/fake-timers/_index.test.js

docs/concepts/fake-timers/jump.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ Advance the clock by jumping forward in time, firing callbacks at most once.
99
`time` takes the same formats as [`clock.tick`](./tick).
1010

1111
This can be used to simulate the JS engine (such as a browser) being put to sleep and resumed later, skipping intermediary timers.
12+
13+
<<< ../../.vitepress/tests/docs/fake-timers/api/jump.test.js

docs/concepts/fake-timers/reset.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ description: Resets the clock to its initial now value and clears all pending ti
66
# `clock.reset()`
77

88
Resets the clock to its initial `now` value and clears all pending timers.
9+
10+
<<< ../../.vitepress/tests/docs/fake-timers/api/reset.test.js

docs/concepts/fake-timers/run-microtasks.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ description: Runs all pending microtasks such as process.nextTick or Promise cal
66
# `clock.runMicrotasks()`
77

88
Runs all pending microtasks (e.g. `process.nextTick` or `Promise` callbacks).
9+
10+
<<< ../../.vitepress/tests/docs/fake-timers/api/run-microtasks.test.js

docs/concepts/fake-timers/run-to-frame.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ description: Advances the clock to the next animation frame (standard 16ms).
66
# `clock.runToFrame()`
77

88
Advances the clock to the next animation frame (standard 16ms).
9+
10+
<<< ../../.vitepress/tests/docs/fake-timers/api/run-to-frame.test.js

docs/concepts/fake-timers/run-to-last.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ description: Runs all pending timers until the last timer has been fired. Use ru
88
This runs all pending timers until the last timer has been fired. If new timers are added while it is executing they will be run as well.
99

1010
The `runToLastAsync()` will also break the event loop, allowing any scheduled promise callbacks to execute _before_ running the timers.
11+
12+
<<< ../../.vitepress/tests/docs/fake-timers/api/run-to-last.test.js

docs/concepts/fake-timers/set-system-time.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ description: Change the system time without firing any timers.
66
# `clock.setSystemTime([now])`
77

88
This allows you to change the system time to the provided `now` (number or Date) without firing any timers.
9+
10+
<<< ../../.vitepress/tests/docs/fake-timers/api/set-system-time.test.js
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import t from "tap";
2+
import sinon from "sinon";
3+
4+
t.test("clock.countTimers returns zero for a fresh clock", (t) => {
5+
const clock = sinon.useFakeTimers();
6+
7+
t.equal(clock.countTimers(), 0, "fresh clock should have no pending timers");
8+
9+
clock.restore();
10+
t.end();
11+
});
12+
13+
t.test("clock.countTimers counts remaining timers after a tick", (t) => {
14+
const clock = sinon.useFakeTimers();
15+
16+
setTimeout(() => {}, 100);
17+
setTimeout(() => {}, 200);
18+
setTimeout(() => {}, 300);
19+
20+
clock.tick(150);
21+
22+
t.equal(clock.countTimers(), 2, "two timers should remain after 150ms");
23+
24+
clock.restore();
25+
t.end();
26+
});
27+
28+
t.test("clock.countTimers includes microtasks such as nextTick", (t) => {
29+
const clock = sinon.useFakeTimers({ toFake: ["nextTick"] });
30+
31+
process.nextTick(() => {});
32+
33+
t.equal(
34+
clock.countTimers(),
35+
1,
36+
"nextTick callback should count as a pending timer"
37+
);
38+
39+
clock.restore();
40+
t.end();
41+
});
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import t from "tap";
2+
import sinon from "sinon";
3+
4+
t.test("clock.jump ignores timers not within the jump window", (t) => {
5+
const clock = sinon.useFakeTimers({ now: 0 });
6+
7+
let called = false;
8+
setTimeout(() => {
9+
called = true;
10+
}, 1000);
11+
12+
clock.jump(500);
13+
14+
t.notOk(called, "timer beyond jump window should not have fired");
15+
16+
clock.restore();
17+
t.end();
18+
});
19+
20+
t.test("clock.jump fires timers within the jump window at the destination time", (t) => {
21+
const clock = sinon.useFakeTimers({ now: 0 });
22+
23+
let calledAt = null;
24+
setTimeout(() => {
25+
calledAt = Date.now();
26+
}, 1000);
27+
28+
clock.jump(2000);
29+
30+
t.equal(calledAt, 2000, "timer should fire and see the jump destination as the current time");
31+
32+
clock.restore();
33+
t.end();
34+
});
35+
36+
t.test(
37+
"clock.jump fires each interval at most once regardless of elapsed time",
38+
(t) => {
39+
const clock = sinon.useFakeTimers({ now: 0 });
40+
41+
let callCount = 0;
42+
setInterval(() => {
43+
callCount++;
44+
}, 100);
45+
46+
// A plain tick(1500) would fire the interval ~15 times; jump fires it once
47+
clock.jump(1500);
48+
49+
t.equal(callCount, 1, "interval should have fired at most once");
50+
51+
clock.restore();
52+
t.end();
53+
}
54+
);
55+
56+
t.test("clock.jump supports human-readable string time arguments", (t) => {
57+
const clock = sinon.useFakeTimers({ now: 0 });
58+
59+
let called = false;
60+
setTimeout(() => {
61+
called = true;
62+
}, 100000); // 1 minute 40 seconds
63+
64+
clock.jump("01:50"); // 1 minute 50 seconds
65+
66+
t.ok(called, "timer should have fired after string-format jump");
67+
68+
clock.restore();
69+
t.end();
70+
});

0 commit comments

Comments
 (0)