import { describe, expect, it } from "@suaveplan/testing/runner"; import { AsyncQueue } from "./queue.js"; describe("AsyncQueue", () => { it("enqueue preserves arrival order", { timeout: 5000 }, async () => { const q = new AsyncQueue(); const order: string[] = []; const results = await Promise.all([ q.enqueue(async () => { await new Promise((r) => setTimeout(r, 30)); order.push("A"); return "a"; }), q.enqueue(async () => { await new Promise((r) => setTimeout(r, 5)); order.push("B"); return "b"; }), q.enqueue(async () => { order.push("C"); return "c"; }), ]); expect(order).toEqual(["A", "B", "C"]); expect(results).toEqual(["a", "b", "c"]); }); it("rejection does not stall later operations", { timeout: 5000, }, async () => { const q = new AsyncQueue(); const order: string[] = []; const p1 = q .enqueue(async () => { order.push("first"); throw new Error("boom"); }) .catch((err: unknown) => err); const p2 = q.enqueue(async () => { order.push("second"); return 42; }); const [r1, r2] = await Promise.all([p1, p2]); expect((r1 as Error).message).toBe("boom"); expect(r2).toBe(42); expect(order).toEqual(["first", "second"]); }); it("drain awaits current tail", { timeout: 5000 }, async () => { const q = new AsyncQueue(); let done = false; q.enqueue(async () => { await new Promise((r) => setTimeout(r, 20)); done = true; }); await q.drain(); expect(done).toBe(true); }); it("enqueue after drain rejects", { timeout: 5000 }, async () => { const q = new AsyncQueue(); await q.drain(); await expect(q.enqueue(async () => 1)).rejects.toThrow( /enqueue after drain/ ); }); it("reset re-opens a drained queue", { timeout: 5000 }, async () => { const q = new AsyncQueue(); await q.drain(); q.reset(); await expect(q.enqueue(async () => "ok")).resolves.toBe("ok"); }); });