import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { waitForTransportReady } from "./transport-ready.js"; // Perf: `sleepWithAbort` uses `node:timers/promises` which isn't controlled by fake timers. // Route sleeps through global `setTimeout` so tests can advance time deterministically. vi.mock("./backoff.js", () => ({ sleepWithAbort: async (ms: number) => { if (ms <= 0) { return; } await new Promise((resolve) => setTimeout(resolve, ms)); }, })); function createRuntime() { return { log: vi.fn(), error: vi.fn(), exit: vi.fn() }; } describe("waitForTransportReady", () => { beforeEach(() => { vi.useFakeTimers(); }); afterEach(() => { vi.useRealTimers(); }); it("returns when the check succeeds and logs after the delay", async () => { const runtime = createRuntime(); let attempts = 0; const readyPromise = waitForTransportReady({ label: "test transport", timeoutMs: 220, // Deterministic: first attempt at t=0 won't log; second attempt at t=50 will. logAfterMs: 1, logIntervalMs: 1_000, pollIntervalMs: 50, runtime, check: async () => { attempts += 1; if (attempts > 2) { return { ok: true }; } return { ok: false, error: "not ready" }; }, }); await vi.advanceTimersByTimeAsync(200); await readyPromise; expect(runtime.error).toHaveBeenCalled(); }); it("throws after the timeout", async () => { const runtime = createRuntime(); const waitPromise = waitForTransportReady({ label: "test transport", timeoutMs: 110, logAfterMs: 0, logIntervalMs: 1_000, pollIntervalMs: 50, runtime, check: async () => ({ ok: false, error: "still down" }), }); const asserted = expect(waitPromise).rejects.toThrow("test transport not ready"); await vi.advanceTimersByTimeAsync(200); await asserted; expect(runtime.error).toHaveBeenCalled(); }); it("returns early when aborted", async () => { const runtime = createRuntime(); const controller = new AbortController(); controller.abort(); await waitForTransportReady({ label: "test transport", timeoutMs: 200, runtime, abortSignal: controller.signal, check: async () => ({ ok: false, error: "still down" }), }); expect(runtime.error).not.toHaveBeenCalled(); }); });