std/testing/time_test.ts

817 lines
24 KiB
TypeScript
Raw Permalink Normal View History

// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import {
assert,
assertAlmostEquals,
assertEquals,
assertInstanceOf,
assertMatch,
assertNotEquals,
assertRejects,
assertStrictEquals,
assertThrows,
} from "@std/assert";
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(): (..._args: unknown[]) => number {
const start: number = Date.now();
return () => Date.now() - start;
}
Deno.test("FakeTime doesn't affect Date unchanged if uninitialized", () => {
assertStrictEquals(Date, _internals.Date);
});
Deno.test("FakeTime fakes Date", () => {
{
using _time = new FakeTime(9001);
assertNotEquals(Date, _internals.Date);
}
assertStrictEquals(Date, _internals.Date);
});
Deno.test("FakeTime causes date parse and UTC behave the same", () => {
const expectedUTC = Date.UTC(96, 1, 2, 3, 4, 5);
const expectedParse = Date.parse("04 Dec 1995 00:12:00 GMT");
using _time = new FakeTime();
assertEquals(
Date.UTC(96, 1, 2, 3, 4, 5),
expectedUTC,
);
assertEquals(
Date.parse("04 Dec 1995 00:12:00 GMT"),
expectedParse,
);
});
Deno.test("FakeTime causes Date.now() returns current fake time", () => {
const time: FakeTime = new FakeTime(9001);
const now = spy(_internals.Date, "now");
try {
try {
assertEquals(Date.now(), 9001);
assertEquals(now.calls.length, 0);
time.tick(1523);
assertEquals(Date.now(), 10524);
assertEquals(now.calls.length, 0);
} finally {
time.restore();
}
assertNotEquals(Date.now(), 10524);
assertEquals(now.calls.length, 1);
} finally {
now.restore();
}
});
Deno.test("FakeTime causes Date instance methods passthrough to real Date instance methods", () => {
using _time = new FakeTime();
const now = new Date("2020-05-25T05:00:00.12345Z");
assertEquals(now.toISOString(), "2020-05-25T05:00:00.123Z");
const func1 = spy(
_internals.Date.prototype,
"toISOString",
);
try {
now.toISOString();
assertSpyCall(func1, 0, {
args: [],
returned: "2020-05-25T05:00:00.123Z",
});
assertInstanceOf(func1.calls?.[0]?.self, _internals.Date);
} finally {
func1.restore();
}
const func2 = spy(
_internals.Date.prototype,
Symbol.toPrimitive,
);
try {
Number(now);
assertSpyCall(func2, 0, {
args: ["number"],
returned: 1590382800123,
});
} finally {
func2.restore();
}
});
Deno.test("FakeTime causes Date function to return the string representation of the current faked time", () => {
using _time = new FakeTime(24 * 60 * 60 * 1000);
assertMatch(Date(), /(Fri|Thu) Jan 0(1|2) 1970/);
});
Deno.test("FakeTime timeout functions unchanged if FakeTime is uninitialized", () => {
assertStrictEquals(setTimeout, _internals.setTimeout);
assertStrictEquals(clearTimeout, _internals.clearTimeout);
});
Deno.test("FakeTime timeout functions are fake if FakeTime is initialized", () => {
{
using _time: FakeTime = new FakeTime();
assertNotEquals(setTimeout, _internals.setTimeout);
assertNotEquals(clearTimeout, _internals.clearTimeout);
}
assertStrictEquals(setTimeout, _internals.setTimeout);
assertStrictEquals(clearTimeout, _internals.clearTimeout);
});
Deno.test("FakeTime only ticks forward when setting now or calling tick", () => {
using time: FakeTime = new FakeTime();
const start: number = Date.now();
assertEquals(Date.now(), start);
time.tick(5);
assertEquals(Date.now(), start + 5);
time.now = start + 1000;
assertEquals(Date.now(), start + 1000);
assert(_internals.Date.now() < start + 1000);
});
Deno.test("FakeTime controls timeouts", () => {
using time: FakeTime = new FakeTime();
const start: number = Date.now();
const cb = spy(fromNow());
const expected: SpyCall[] = [];
setTimeout(cb, 1000);
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);
setTimeout(cb, 1000, "a");
setTimeout(cb, 2000, "b");
setTimeout(cb, 1500, "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);
setTimeout(cb, 1000, "a");
setTimeout(cb, 1500, "b");
const timeout: number = setTimeout(cb, 1750, "c");
setTimeout(cb, 2000, "d");
time.tick(1250);
expected.push({ args: ["a"], returned: 7000 });
assertEquals(cb.calls, expected);
assertEquals(Date.now(), start + 7250);
clearTimeout(timeout);
time.tick(500);
expected.push({ args: ["b"], returned: 7500 });
assertEquals(cb.calls, expected);
assertEquals(Date.now(), start + 7750);
time.tick(250);
expected.push({ args: ["d"], returned: 8000 });
assertEquals(cb.calls, expected);
});
Deno.test("FakeTime interval functions unchanged if FakeTime is uninitialized", () => {
assertStrictEquals(setInterval, _internals.setInterval);
assertStrictEquals(clearInterval, _internals.clearInterval);
});
Deno.test("FakeTime fakes interval functions", () => {
{
using _time: FakeTime = new FakeTime();
assertNotEquals(setInterval, _internals.setInterval);
assertNotEquals(clearInterval, _internals.clearInterval);
}
assertStrictEquals(setInterval, _internals.setInterval);
assertStrictEquals(clearInterval, _internals.clearInterval);
});
Deno.test("FakeTime controls intervals", () => {
using time: FakeTime = new FakeTime();
const cb = spy(fromNow());
const expected: SpyCall[] = [];
const interval: number = setInterval(cb, 1000);
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);
expected.push({ args: [], returned: 2000 });
expected.push({ args: [], returned: 3000 });
assertEquals(cb.calls, expected);
clearInterval(interval);
time.tick(1000);
assertEquals(cb.calls, expected);
});
Deno.test("FakeTime calls timeout and interval callbacks in correct order", () => {
using time: FakeTime = new FakeTime();
const cb = spy(fromNow());
const timeoutCb = spy(cb);
const intervalCb = spy(cb);
const expected: SpyCall[] = [];
const timeoutExpected: SpyCall[] = [];
const intervalExpected: SpyCall[] = [];
const interval: number = setInterval(intervalCb, 1000);
setTimeout(timeoutCb, 500);
time.tick(250);
assertEquals(intervalCb.calls, intervalExpected);
time.tick(250);
setTimeout(timeoutCb, 1000);
let expect: SpyCall = { args: [], returned: 500 };
expected.push(expect);
timeoutExpected.push(expect);
assertEquals(cb.calls, expected);
assertEquals(timeoutCb.calls, timeoutExpected);
assertEquals(cb.calls, expected);
assertEquals(intervalCb.calls, intervalExpected);
time.tick(500);
expect = { args: [], returned: 1000 };
expected.push(expect);
intervalExpected.push(expect);
assertEquals(cb.calls, expected);
assertEquals(intervalCb.calls, intervalExpected);
time.tick(2500);
expect = { args: [], returned: 1500 };
expected.push(expect);
timeoutExpected.push(expect);
expect = { args: [], returned: 2000 };
expected.push(expect);
intervalExpected.push(expect);
expect = { args: [], returned: 3000 };
expected.push(expect);
intervalExpected.push(expect);
assertEquals(cb.calls, expected);
assertEquals(timeoutCb.calls, timeoutExpected);
assertEquals(intervalCb.calls, intervalExpected);
clearInterval(interval);
time.tick(1000);
assertEquals(cb.calls, expected);
assertEquals(timeoutCb.calls, timeoutExpected);
assertEquals(intervalCb.calls, intervalExpected);
});
Deno.test("FakeTime.restoreFor() restores real time temporarily", async () => {
using time: FakeTime = new FakeTime();
const start: number = Date.now();
assertEquals(Date.now(), start);
time.tick(1000);
assertEquals(Date.now(), start + 1000);
assert(_internals.Date.now() < start + 1000);
await FakeTime.restoreFor(() => {
assert(Date.now() < start + 1000);
});
assertEquals(Date.now(), start + 1000);
assert(_internals.Date.now() < start + 1000);
});
Deno.test("FakeTime.restoreFor() restores real time and re-overridden atomically", async () => {
using _time: FakeTime = new FakeTime();
const fakeSetTimeout = setTimeout;
const actualSetTimeouts: (typeof setTimeout)[] = [];
const asyncFn = async () => {
actualSetTimeouts.push(setTimeout);
await Promise.resolve();
actualSetTimeouts.push(setTimeout);
await Promise.resolve();
actualSetTimeouts.push(setTimeout);
};
const promise = asyncFn();
await new Promise((resolve) => {
FakeTime.restoreFor(() => setTimeout(resolve, 0));
});
await promise;
assertEquals(actualSetTimeouts, [
fakeSetTimeout,
fakeSetTimeout,
fakeSetTimeout,
]);
});
Deno.test("FakeTime.restoreFor() returns promise that resolved to result of callback", async () => {
using _time: FakeTime = new FakeTime();
const resultSync = await FakeTime.restoreFor(() => "a");
assertEquals(resultSync, "a");
const resultAsync = await FakeTime.restoreFor(() => Promise.resolve("b"));
assertEquals(resultAsync, "b");
});
Deno.test("FakeTime.restoreFor() returns promise that rejected to error in callback", async () => {
using _time: FakeTime = new FakeTime();
await assertRejects(
() =>
FakeTime.restoreFor(() => {
throw new Error("Error in sync callback");
}),
Error,
"Error in sync callback",
);
await assertRejects(
() =>
FakeTime.restoreFor(() => {
return Promise.reject(new Error("Error in async callback"));
}),
Error,
"Error in async callback",
);
});
Deno.test("FakeTime.restoreFor() returns promise that rejected to TimeError if FakeTime is uninitialized", async () => {
await assertRejects(
() => FakeTime.restoreFor(() => {}),
TimeError,
"Cannot restore time: time is not faked",
);
});
Deno.test("FakeTime.delay() uses real time", async () => {
using time: FakeTime = new FakeTime();
const start: number = Date.now();
assertEquals(Date.now(), start);
await time.delay(20);
assert(_internals.Date.now() >= start + 20);
assertEquals(Date.now(), start);
});
Deno.test("FakeTime.delay() runs all microtasks before resolving", async () => {
using time: FakeTime = new FakeTime();
const seq = [];
queueMicrotask(() => seq.push(2));
queueMicrotask(() => seq.push(3));
seq.push(1);
await time.delay(20);
seq.push(4);
assertEquals(seq, [1, 2, 3, 4]);
});
Deno.test("FakeTime.delay() works with abort", async () => {
using time: FakeTime = new FakeTime();
const seq = [];
const abort = new AbortController();
const { signal } = abort;
const delayedPromise = time.delay(100, { signal });
seq.push(1);
await FakeTime.restoreFor(() => {
setTimeout(() => {
seq.push(2);
abort.abort();
}, 0);
});
await assertRejects(
() => delayedPromise,
DOMException,
"Delay was aborted",
);
seq.push(3);
assertEquals(seq, [1, 2, 3]);
});
Deno.test("FakeTime.runMicrotasks() runs all microtasks before resolving", async () => {
using time: FakeTime = new FakeTime();
const start: number = Date.now();
const seq = [];
queueMicrotask(() => seq.push(2));
queueMicrotask(() => seq.push(3));
seq.push(1);
await time.runMicrotasks();
seq.push(4);
assertEquals(seq, [1, 2, 3, 4]);
assertEquals(Date.now(), start);
});
Deno.test("FakeTime.tickAsync() runs all microtasks and runs timers if ticks past due", async () => {
using time: FakeTime = new FakeTime();
const start: number = Date.now();
const cb = spy(fromNow());
const expected: SpyCall[] = [];
const seq: number[] = [];
setTimeout(cb, 1000);
queueMicrotask(() => seq.push(2));
queueMicrotask(() => seq.push(3));
seq.push(1);
await time.tickAsync(250);
seq.push(4);
assertEquals(cb.calls, expected);
await time.tickAsync(250);
assertEquals(cb.calls, expected);
queueMicrotask(() => seq.push(6));
seq.push(5);
await time.tickAsync(500);
seq.push(7);
expected.push({ args: [], returned: 1000 });
assertEquals(cb.calls, expected);
assertEquals(Date.now(), start + 1000);
assertEquals(seq, [1, 2, 3, 4, 5, 6, 7]);
});
Deno.test("FakeTime.next() runs next timer without running microtasks", async () => {
using time: FakeTime = new FakeTime();
const start: number = Date.now();
const cb = spy(fromNow());
const seq: number[] = [];
// Callback is called by `next`.
setTimeout(cb, 1000);
queueMicrotask(() => seq.push(3));
queueMicrotask(() => seq.push(4));
seq.push(1);
const hasNextTimer = time.next();
seq.push(2);
assertEquals(hasNextTimer, true);
const expectedCalls = [{ args: [] as [], returned: 1000 }];
assertEquals(cb.calls, expectedCalls);
assertEquals(Date.now(), start + 1000);
await time.runMicrotasks();
// Callback is already called before `next` called.
queueMicrotask(() => seq.push(7));
queueMicrotask(() => seq.push(8));
seq.push(5);
const hasNextTimerAfterCalled = time.next();
seq.push(6);
await time.runMicrotasks();
assertEquals(hasNextTimerAfterCalled, false);
assertEquals(cb.calls, expectedCalls);
assertEquals(Date.now(), start + 1000);
// Callbacks are cleared before `next` called.
const id1 = setTimeout(cb, 1000);
const id2 = setTimeout(cb, 2000);
clearTimeout(id1);
clearTimeout(id2);
queueMicrotask(() => seq.push(11));
queueMicrotask(() => seq.push(12));
seq.push(9);
const hasNextTimerAfterCleared = time.next();
seq.push(10);
await time.runMicrotasks();
assertEquals(hasNextTimerAfterCleared, false);
assertEquals(cb.calls, expectedCalls);
assertEquals(Date.now(), start + 1000);
// Callback is partially cleared before `next` called.
const id3 = setTimeout(cb, 1500);
setTimeout(cb, 1500);
clearTimeout(id3);
queueMicrotask(() => seq.push(15));
queueMicrotask(() => seq.push(16));
seq.push(13);
const hasNextTimerAfterPartiallyCleared = time.next();
seq.push(14);
await time.runMicrotasks();
assertEquals(hasNextTimerAfterPartiallyCleared, true);
const expectedCalls2 = [
{ args: [] as [], returned: 1000 },
{ args: [] as [], returned: 1000 + 1500 },
];
assertEquals(cb.calls, expectedCalls2);
assertEquals(Date.now(), start + 1000 + 1500);
assertEquals(seq, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
});
Deno.test("FakeTime.nextAsync() runs all microtasks and next timer", async () => {
using time: FakeTime = new FakeTime();
const start: number = Date.now();
const cb = spy(fromNow());
const seq: number[] = [];
// Callback is called by `nextAsync`.
setTimeout(cb, 1000);
queueMicrotask(() => seq.push(2));
queueMicrotask(() => seq.push(3));
seq.push(1);
const hasNextTimer = await time.nextAsync();
seq.push(4);
assertEquals(hasNextTimer, true);
const expectedCalls = [{ args: [] as [], returned: 1000 }];
assertEquals(cb.calls, expectedCalls);
assertEquals(Date.now(), start + 1000);
// Callback is already called before `nextAsync` called.
queueMicrotask(() => seq.push(6));
queueMicrotask(() => seq.push(7));
seq.push(5);
const hasNextTimerAfterCalled = await time.nextAsync();
seq.push(8);
assertEquals(hasNextTimerAfterCalled, false);
assertEquals(cb.calls, expectedCalls);
assertEquals(Date.now(), start + 1000);
// Callbacks are cleared before `nextAsync` called.
const id1 = setTimeout(cb, 1000);
const id2 = setTimeout(cb, 2000);
clearTimeout(id1);
clearTimeout(id2);
queueMicrotask(() => seq.push(10));
queueMicrotask(() => seq.push(11));
seq.push(9);
const hasNextTimerAfterCleared = await time.nextAsync();
seq.push(12);
assertEquals(hasNextTimerAfterCleared, false);
assertEquals(cb.calls, expectedCalls);
assertEquals(Date.now(), start + 1000);
// Callback is partially cleared before `nextAsync` called.
const id3 = setTimeout(cb, 1500);
setTimeout(cb, 1500);
clearTimeout(id3);
queueMicrotask(() => seq.push(14));
queueMicrotask(() => seq.push(15));
seq.push(13);
const hasNextTimerAfterPartiallyCleared = await time.nextAsync();
seq.push(16);
await time.runMicrotasks();
assertEquals(hasNextTimerAfterPartiallyCleared, true);
const expectedCalls2 = [
{ args: [] as [], returned: 1000 },
{ args: [] as [], returned: 1000 + 1500 },
];
assertEquals(cb.calls, expectedCalls2);
assertEquals(Date.now(), start + 1000 + 1500);
assertEquals(seq, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
});
Deno.test("FakeTime.runAll() runs all timers without running microtasks", async () => {
using time: FakeTime = new FakeTime();
const start: number = Date.now();
const cb = spy(fromNow());
const seq: number[] = [];
setTimeout(cb, 1000);
setTimeout(cb, 1500);
queueMicrotask(() => seq.push(3));
queueMicrotask(() => seq.push(4));
seq.push(1);
time.runAll();
seq.push(2);
const expectedCalls = [
{ args: [] as [], returned: 1000 },
{ args: [] as [], returned: 1500 },
];
assertEquals(cb.calls, expectedCalls);
assertEquals(Date.now(), start + 1500);
await time.runMicrotasks();
queueMicrotask(() => seq.push(7));
queueMicrotask(() => seq.push(8));
seq.push(5);
time.runAll();
seq.push(6);
await time.runMicrotasks();
assertEquals(cb.calls, expectedCalls);
assertEquals(Date.now(), start + 1500);
assertEquals(seq, [1, 2, 3, 4, 5, 6, 7, 8]);
});
Deno.test("FakeTime.runAllAsync() runs all microtasks and timers", async () => {
using time: FakeTime = new FakeTime();
const start: number = Date.now();
const cb = spy(fromNow());
const seq: number[] = [];
setTimeout(cb, 1000);
setTimeout(cb, 1500);
queueMicrotask(() => seq.push(2));
queueMicrotask(() => seq.push(3));
seq.push(1);
await time.runAllAsync();
seq.push(4);
const expectedCalls = [
{ args: [] as [], returned: 1000 },
{ args: [] as [], returned: 1500 },
];
assertEquals(cb.calls, expectedCalls);
assertEquals(Date.now(), start + 1500);
queueMicrotask(() => seq.push(6));
queueMicrotask(() => seq.push(7));
seq.push(5);
await time.runAllAsync();
seq.push(8);
assertEquals(cb.calls, expectedCalls);
assertEquals(Date.now(), start + 1500);
assertEquals(seq, [1, 2, 3, 4, 5, 6, 7, 8]);
});
const Date_ = Date;
Deno.test("Date from FakeTime is structured cloneable", () => {
using _time: FakeTime = new FakeTime();
const date: Date = new Date();
assert(date instanceof Date);
assert(date instanceof Date_);
const cloned: Date = structuredClone(date);
assertEquals(cloned.getTime(), date.getTime());
assert(date instanceof Date);
assert(cloned instanceof Date_);
});
Deno.test("new FakeTime() throws if the time is already faked", () => {
using _time = new FakeTime();
assertThrows(() => new FakeTime());
});
Deno.test("Faked timer functions throws when called after FakeTime is restored", () => {
let fakeSetTimeout: typeof setTimeout;
let fakeClearTimeout: typeof clearTimeout;
let fakeSetInterval: typeof setInterval;
let fakeClearInterval: typeof clearInterval;
{
using _time: FakeTime = new FakeTime();
fakeSetTimeout = setTimeout;
fakeClearTimeout = clearTimeout;
fakeSetInterval = setInterval;
fakeClearInterval = clearInterval;
}
assertThrows(
() => fakeSetTimeout(() => {}, 0),
TimeError,
"Cannot set timeout: time is not faked",
);
assertThrows(
() => fakeClearTimeout(0),
TimeError,
"Cannot clear timeout: time is not faked",
);
assertThrows(
() => fakeSetInterval(() => {}, 0),
TimeError,
"Cannot set interval: time is not faked",
);
assertThrows(
() => fakeClearInterval(0),
TimeError,
"Cannot clear interval: time is not faked",
);
});
Deno.test("Faked Date.now returns real time after FakeTime is restored", () => {
let fakeDateNow: typeof Date.now;
{
using _time: FakeTime = new FakeTime();
fakeDateNow = Date.now;
}
assertAlmostEquals(Date.now(), fakeDateNow());
});
Deno.test("FakeTime can be constructed with number, Date, or string", () => {
{
using _time = new FakeTime(1000);
assertEquals(Date.now(), 1000);
}
{
using _time = new FakeTime(new Date(2000));
assertEquals(Date.now(), 2000);
}
{
using _time = new FakeTime("Thu Jan 01 1970 00:00:03 GMT+0000");
assertEquals(Date.now(), 3000);
}
});
Deno.test("FakeTime throws when NaN is provided", () => {
assertThrows(
() => new FakeTime(NaN),
TypeError,
"Cannot construct FakeTime: invalid start time NaN",
);
});
Deno.test("FakeTime.restore() throws when the time is already restored", () => {
const _time = new FakeTime();
FakeTime.restore();
assertThrows(
() => FakeTime.restore(),
TimeError,
"Cannot restore time: time is already restored",
);
});
Deno.test("time.restore() throws when the time is already restored", () => {
const time = new FakeTime();
time.restore();
assertThrows(
() => time.restore(),
TimeError,
"Cannot restore time: time is already restored",
);
});
Deno.test("time.now = N throws when N < time.now", () => {
using time = new FakeTime(1000);
assertThrows(
() => {
time.now = 999;
},
RangeError,
"Cannot set current time in the past, time must be >= 1000: received 999",
);
});
Deno.test("time.start returns the started time of the fake time", () => {
using time = new FakeTime(1000);
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");
});