src/ws/backoff.test.ts
v0.3.0 · 1.3 KB
import { describe, expect, it } from 'vitest';
import { DEFAULT_RECONNECT_POLICY, reconnectDelay, WS_CLOSE_POLICY_VIOLATION } from './backoff.js';
describe('reconnectDelay', () => {
it('starts at 1 s and doubles', () => {
expect([0, 1, 2, 3, 4].map((a) => reconnectDelay(a, undefined))).toEqual([1_000, 2_000, 4_000, 8_000, 16_000]);
});
it('caps at 30 s', () => {
expect(reconnectDelay(5, 1006)).toBe(30_000);
expect(reconnectDelay(50, undefined)).toBe(30_000);
expect(reconnectDelay(10_000, undefined)).toBe(30_000); // 2^n overflows to Infinity and is capped
});
it('waits at least 60 s after close code 1008', () => {
expect(WS_CLOSE_POLICY_VIOLATION).toBe(1008);
expect(reconnectDelay(0, 1008)).toBe(60_000);
expect(reconnectDelay(10, 1008)).toBe(60_000);
expect(reconnectDelay(10, 1008, { ...DEFAULT_RECONNECT_POLICY, maxMs: 120_000 })).toBe(120_000);
});
it('treats negative / fractional attempts safely', () => {
expect(reconnectDelay(-3, undefined)).toBe(1_000);
expect(reconnectDelay(1.9, undefined)).toBe(2_000);
});
it('defaults: infinite attempts, 8 s stability window, frozen', () => {
expect(DEFAULT_RECONNECT_POLICY.maxAttempts).toBe(Number.POSITIVE_INFINITY);
expect(DEFAULT_RECONNECT_POLICY.stableMs).toBe(8_000);
expect(Object.isFrozen(DEFAULT_RECONNECT_POLICY)).toBe(true);
});
});