Skip to content
markpaper

src/ws/backoff.test.ts

v0.3.0 · 1.3 KB

Download file
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);
  });
});
All files