Skip to content

Commit e3d827a

Browse files
committed
test: scope fake timers to beforeEach/afterEach to prevent leaks
1 parent 39164a3 commit e3d827a

1 file changed

Lines changed: 43 additions & 38 deletions

File tree

src/lib/utils/__tests__/polling.test.ts

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { PollExhaustedError, PollTimeoutError, isThrottlingError, poll } from '../polling.js';
2-
import { describe, expect, it, vi } from 'vitest';
2+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
33

44
/* eslint-disable @typescript-eslint/require-await */
55

@@ -35,46 +35,51 @@ describe('poll', () => {
3535
);
3636
});
3737

38-
it('applies exponential backoff', async () => {
39-
vi.useFakeTimers();
40-
let count = 0;
41-
const promise = poll({
42-
fn: async () => {
43-
count++;
44-
return count === 4 ? { done: true, value: 'done' } : { done: false };
45-
},
46-
maxAttempts: 5,
47-
delayMs: 100,
48-
backoffFactor: 2,
38+
describe('backoff', () => {
39+
beforeEach(() => {
40+
vi.useFakeTimers();
4941
});
50-
// Advance through iterations
51-
await vi.advanceTimersByTimeAsync(100); // 1st delay: 100
52-
await vi.advanceTimersByTimeAsync(200); // 2nd delay: 200
53-
await vi.advanceTimersByTimeAsync(400); // 3rd delay: 400
54-
const result = await promise;
55-
expect(result).toBe('done');
56-
vi.useRealTimers();
57-
});
5842

59-
it('caps delay at maxDelayMs', async () => {
60-
vi.useFakeTimers();
61-
let count = 0;
62-
const promise = poll({
63-
fn: async () => {
64-
count++;
65-
return count === 4 ? { done: true, value: 'done' } : { done: false };
66-
},
67-
maxAttempts: 5,
68-
delayMs: 100,
69-
backoffFactor: 10,
70-
maxDelayMs: 500,
43+
afterEach(() => {
44+
vi.useRealTimers();
45+
});
46+
47+
it('applies exponential backoff', async () => {
48+
let count = 0;
49+
const promise = poll({
50+
fn: async () => {
51+
count++;
52+
return count === 4 ? { done: true, value: 'done' } : { done: false };
53+
},
54+
maxAttempts: 5,
55+
delayMs: 100,
56+
backoffFactor: 2,
57+
});
58+
await vi.advanceTimersByTimeAsync(100); // 1st delay: 100
59+
await vi.advanceTimersByTimeAsync(200); // 2nd delay: 200
60+
await vi.advanceTimersByTimeAsync(400); // 3rd delay: 400
61+
const result = await promise;
62+
expect(result).toBe('done');
63+
});
64+
65+
it('caps delay at maxDelayMs', async () => {
66+
let count = 0;
67+
const promise = poll({
68+
fn: async () => {
69+
count++;
70+
return count === 4 ? { done: true, value: 'done' } : { done: false };
71+
},
72+
maxAttempts: 5,
73+
delayMs: 100,
74+
backoffFactor: 10,
75+
maxDelayMs: 500,
76+
});
77+
await vi.advanceTimersByTimeAsync(100); // 1st: 100
78+
await vi.advanceTimersByTimeAsync(500); // 2nd: capped at 500
79+
await vi.advanceTimersByTimeAsync(500); // 3rd: capped at 500
80+
const result = await promise;
81+
expect(result).toBe('done');
7182
});
72-
await vi.advanceTimersByTimeAsync(100); // 1st: 100
73-
await vi.advanceTimersByTimeAsync(500); // 2nd: capped at 500
74-
await vi.advanceTimersByTimeAsync(500); // 3rd: capped at 500
75-
const result = await promise;
76-
expect(result).toBe('done');
77-
vi.useRealTimers();
7883
});
7984

8085
it('retries on error by default', async () => {

0 commit comments

Comments
 (0)