/ src / lib / keyed-queue.test.ts
keyed-queue.test.ts
 1  import { describe, it } from 'node:test'
 2  import assert from 'node:assert/strict'
 3  import { KeyedAsyncQueue } from './keyed-queue'
 4  
 5  describe('KeyedAsyncQueue', () => {
 6    it('serializes tasks within the same key', async () => {
 7      const queue = new KeyedAsyncQueue()
 8      const order: number[] = []
 9      const delay = (ms: number) => new Promise(r => setTimeout(r, ms))
10  
11      const p1 = queue.enqueue('a', async () => { await delay(30); order.push(1) })
12      const p2 = queue.enqueue('a', async () => { order.push(2) })
13      await Promise.all([p1, p2])
14      assert.deepEqual(order, [1, 2])
15    })
16  
17    it('runs different keys in parallel', async () => {
18      const queue = new KeyedAsyncQueue()
19      const order: string[] = []
20      const delay = (ms: number) => new Promise(r => setTimeout(r, ms))
21  
22      const p1 = queue.enqueue('a', async () => { await delay(30); order.push('a') })
23      const p2 = queue.enqueue('b', async () => { order.push('b') })
24      await Promise.all([p1, p2])
25      assert.deepEqual(order, ['b', 'a'])
26    })
27  
28    it('isolates errors between tasks', async () => {
29      const queue = new KeyedAsyncQueue()
30      const p1 = queue.enqueue('a', async () => { throw new Error('fail') })
31      const p2 = queue.enqueue('a', async () => 'ok')
32      await assert.rejects(p1, /fail/)
33      assert.equal(await p2, 'ok')
34    })
35  
36    it('cleans up keys when queue drains', async () => {
37      const queue = new KeyedAsyncQueue()
38      assert.equal(queue.activeKeys, 0)
39      const p = queue.enqueue('x', async () => 42)
40      assert.equal(queue.activeKeys, 1)
41      await p
42      // Allow microtask for cleanup
43      await new Promise(r => setTimeout(r, 0))
44      assert.equal(queue.activeKeys, 0)
45    })
46  
47    it('returns the value produced by the enqueued function', async () => {
48      const queue = new KeyedAsyncQueue()
49      const result = await queue.enqueue('k', async () => 'hello')
50      assert.equal(result, 'hello')
51    })
52  })