Skip to content

Commit

Permalink
fix(testing): FakeTime fakes AbortSignal.timeout (#5500)
Browse files Browse the repository at this point in the history
Co-authored-by: Asher Gomez <ashersaupingomez@gmail.com>
  • Loading branch information
Milly and iuioiua authored Jul 22, 2024
1 parent 88019ee commit 55297e9
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 1 deletion.
1 change: 1 addition & 0 deletions testing/_time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export const _internals = {
clearTimeout,
setInterval,
clearInterval,
AbortSignalTimeout: AbortSignal.timeout,
};
10 changes: 10 additions & 0 deletions testing/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,21 @@ function setTimer(
return id;
}

function fakeAbortSignalTimeout(delay: number): AbortSignal {
const aborter = new AbortController();
fakeSetTimeout(() => {
aborter.abort(new DOMException("Signal timed out.", "TimeoutError"));
}, delay);
return aborter.signal;
}

function overrideGlobals() {
globalThis.Date = FakeDate;
globalThis.setTimeout = fakeSetTimeout;
globalThis.clearTimeout = fakeClearTimeout;
globalThis.setInterval = fakeSetInterval;
globalThis.clearInterval = fakeClearInterval;
AbortSignal.timeout = fakeAbortSignalTimeout;
}

function restoreGlobals() {
Expand All @@ -211,6 +220,7 @@ function restoreGlobals() {
globalThis.clearTimeout = _internals.clearTimeout;
globalThis.setInterval = _internals.setInterval;
globalThis.clearInterval = _internals.clearInterval;
AbortSignal.timeout = _internals.AbortSignalTimeout;
}

function* timerIdGen() {
Expand Down
66 changes: 65 additions & 1 deletion testing/time_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import {
import { FakeTime, TimeError } from "./time.ts";
import { _internals } from "./_time.ts";
import { assertSpyCall, spy, type SpyCall } from "./mock.ts";
import { deadline, delay } from "@std/async";

function fromNow(): () => number {
function fromNow(): (..._args: unknown[]) => number {
const start: number = Date.now();
return () => Date.now() - start;
}
Expand Down Expand Up @@ -722,3 +723,66 @@ Deno.test("time.start returns the started time of the fake time", () => {
time.now = 2000;
assertEquals(time.start, 1000);
});

Deno.test("FakeTime doesn't affect AbortSignal.timeout unchanged if uninitialized", () => {
assertStrictEquals(AbortSignal.timeout, _internals.AbortSignalTimeout);
});

Deno.test("FakeTime fakes AbortSignal.timeout", () => {
{
using _time = new FakeTime(9001);
assertNotEquals(AbortSignal.timeout, _internals.AbortSignalTimeout);
}
assertStrictEquals(AbortSignal.timeout, _internals.AbortSignalTimeout);
});

Deno.test("FakeTime controls AbortSignal.timeout", () => {
using time: FakeTime = new FakeTime();
const cb = spy(fromNow());
const expected: SpyCall[] = [];

const signal = AbortSignal.timeout(1000);
signal.onabort = () => cb();
time.tick(250);
assertEquals(cb.calls, expected);
time.tick(250);
assertEquals(cb.calls, expected);
time.tick(500);
expected.push({ args: [], returned: 1000 });
assertEquals(cb.calls, expected);
time.tick(2500);
assertEquals(cb.calls, expected);

assertEquals(signal.aborted, true);
assertInstanceOf(signal.reason, DOMException);
assertEquals(signal.reason.name, "TimeoutError");
assertEquals(signal.reason.message, "Signal timed out.");

const signalA = AbortSignal.timeout(1000);
signalA.addEventListener("abort", () => cb("a"));
const signalB = AbortSignal.timeout(2000);
signalB.addEventListener("abort", () => cb("b"));
const signalC = AbortSignal.timeout(1500);
signalC.addEventListener("abort", () => cb("c"));
assertEquals(cb.calls, expected);
time.tick(2500);
expected.push({ args: ["a"], returned: 4500 });
expected.push({ args: ["c"], returned: 5000 });
expected.push({ args: ["b"], returned: 5500 });
assertEquals(cb.calls, expected);
});

// https://github.com/denoland/std/issues/5499
Deno.test("FakeTime regression test for issue #5499", async () => {
using t = new FakeTime();
const p = deadline(delay(1_000), 10);
let state: "pending" | "rejected" | "fulfilled" = "pending";
p.then(() => {
state = "fulfilled";
}).catch(() => {
state = "rejected";
});
await t.tickAsync(10);
await t.runMicrotasks();
assertEquals(state, "rejected");
});

0 comments on commit 55297e9

Please sign in to comment.