rewrite tests with mocked timers
This commit is contained in:
parent
d715fabeb5
commit
463b0db759
4 changed files with 49 additions and 28 deletions
|
|
@ -8,4 +8,4 @@ module.exports = {
|
|||
transform: {
|
||||
...tsJestTransformCfg,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
import { AsyncTaskQueue } from "./index";
|
||||
|
||||
test("example evaluates correctly", async () => {
|
||||
const q = new AsyncTaskQueue<number>(
|
||||
async () => {/* no-op */},
|
||||
)
|
||||
// Handler will receive up to 4 items per batch.
|
||||
.batchSize(4)
|
||||
// Handler will be called at most once per 100 milliseconds.
|
||||
.throttleMs(100);
|
||||
|
||||
// Add items to the queue.
|
||||
for (let n = 0; n < 1000; n++) {
|
||||
q.push(n);
|
||||
}
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 4000));
|
||||
|
||||
expect(q.size()).toBeLessThan(900);
|
||||
expect(q.size()).toBeGreaterThan(800);
|
||||
|
||||
q.drain();
|
||||
expect(q.size()).toEqual(0);
|
||||
});
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { withRetry } from "./retries";
|
||||
import { withRetry } from "../src/retries";
|
||||
|
||||
const FAST_RETRY_CONFIG: Parameters<typeof withRetry>[1] = {
|
||||
attempts: 6,
|
||||
|
|
@ -42,6 +42,8 @@ test("parameters are passed through", async () => {
|
|||
});
|
||||
|
||||
test("retries back off with expected delays", async () => {
|
||||
// Don't enable the `advanceTimers` configuration or else risk skewing the
|
||||
// timing scheme used in this test.
|
||||
jest.useFakeTimers();
|
||||
|
||||
let n = 0;
|
||||
|
|
@ -93,7 +95,8 @@ test("retries back off with expected delays", async () => {
|
|||
|
||||
await expect(promise).resolves.toEqual("success!")
|
||||
|
||||
// Fake timers don't play nicely with the `expect().rejects` API, so disable
|
||||
// them again for other tests.
|
||||
// Mock timers without auto-advance enabled are a pain to manage when merely
|
||||
// counting retries, so use real timers and a very short backoff duration in
|
||||
// other tests instead.
|
||||
jest.useRealTimers();
|
||||
});
|
||||
42
test/task-queue.test.ts
Normal file
42
test/task-queue.test.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import { AsyncTaskQueue } from "../src/index";
|
||||
|
||||
test("example evaluates correctly", async () => {
|
||||
jest.useFakeTimers();
|
||||
|
||||
const THROTTLE_DELAY_MS = 100;
|
||||
|
||||
const q = new AsyncTaskQueue<number>(
|
||||
async () => {/* no-op */ },
|
||||
)
|
||||
// Handler will receive up to 4 items per batch.
|
||||
.batchSize(4)
|
||||
// Handler will be called at most once per 100 milliseconds.
|
||||
.throttleMs(THROTTLE_DELAY_MS);
|
||||
|
||||
// Add items to the queue.
|
||||
for (let n = 0; n < 1000; n++) {
|
||||
q.push(n);
|
||||
}
|
||||
|
||||
// Advance the clock incrementally and asynchronously so that we yield to the
|
||||
// task queue control loop frequently. This should allow it to complete its
|
||||
// work more or less as it would with real timers.
|
||||
//
|
||||
// Advance timers by a shorter duration than THROTTLE_DELAY_MS to test that
|
||||
// the task queue throttles correctly according to wall time and not merely
|
||||
// according to event loop ticks.
|
||||
const fakeTimerIncrementMs = Math.ceil(THROTTLE_DELAY_MS / 2);
|
||||
for (
|
||||
let mockDelayMs = 0;
|
||||
mockDelayMs < 4000;
|
||||
mockDelayMs += fakeTimerIncrementMs
|
||||
) {
|
||||
await jest.advanceTimersByTimeAsync(fakeTimerIncrementMs);
|
||||
}
|
||||
|
||||
expect(q.size()).toBeLessThan(850);
|
||||
expect(q.size()).toBeGreaterThan(825);
|
||||
|
||||
q.drain();
|
||||
expect(q.size()).toEqual(0);
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue