import {describe, expect, it} from 'vitest' import {BlockingQueue} from '#lib/async/blocking-queue' describe('BlockingQueue', () => { it('enqueues and dequeues items in order', async () => { const queue = new BlockingQueue() queue.enqueue(1, 2, 3) expect(await queue.dequeue()).toBe(1) expect(await queue.dequeue()).toBe(2) expect(await queue.dequeue()).toBe(3) }) it('blocks dequeue until item is available', async () => { const queue = new BlockingQueue() setTimeout(() => { queue.enqueue('delayed') }, 10) const result = await queue.dequeue() expect(result).toBe('delayed') }) it('prequeues items at the front', async () => { const queue = new BlockingQueue() queue.enqueue(1, 2) queue.prequeue(3, 4) expect(await queue.dequeue()).toBe(3) expect(await queue.dequeue()).toBe(4) expect(await queue.dequeue()).toBe(1) expect(await queue.dequeue()).toBe(2) }) it('tracks queue depth', () => { const queue = new BlockingQueue() expect(queue.depth).toBe(0) queue.enqueue(1, 2, 3) expect(queue.depth).toBe(3) }) it('respects maxsize limit', () => { const queue = new BlockingQueue(3) queue.enqueue(1, 2, 3) expect(() => { queue.enqueue(4) }).toThrow('out of room') }) it('can be aborted with signal', async () => { const queue = new BlockingQueue() const controller = new AbortController() const promise = queue.dequeue(controller.signal) // Abort after promise is created await new Promise((resolve) => setTimeout(resolve, 5)) controller.abort(new DOMException('Aborted', 'AbortError')) await expect(promise).rejects.toThrow() }) it('throws if signal already aborted', async () => { const queue = new BlockingQueue() const controller = new AbortController() controller.abort(new DOMException('Aborted', 'AbortError')) await expect(queue.dequeue(controller.signal)).rejects.toThrow() }) it('handles prequeue with maxsize', () => { const queue = new BlockingQueue(3) queue.prequeue(1, 2, 3) expect(() => { queue.prequeue(4) }).toThrow('out of room') }) it('allows unlimited size when maxsize is 0', () => { const queue = new BlockingQueue(0) for (let i = 0; i < 2000; i++) { queue.enqueue(i) } expect(queue.depth).toBe(2000) }) it('reduces depth as items are dequeued', async () => { const queue = new BlockingQueue() queue.enqueue(1, 2, 3, 4, 5) expect(queue.depth).toBe(5) await queue.dequeue() expect(queue.depth).toBe(4) await queue.dequeue() expect(queue.depth).toBe(3) }) })