import { test } from '@japa/runner' import { hedge, type Request } from '#lib/nntp/index' /** A request answering `value` after ms (or failing), recording whether it was cancelled. */ function request(ms: number, value: T, fail = false) { const r = { cancelled: false } as Request & { cancelled: boolean } r.done = new Promise((resolve, reject) => setTimeout(() => (fail ? reject(new Error(String(value))) : resolve(value)), ms)) r.cancel = () => (r.cancelled = true) return r } test.group('nntp / hedge', () => { test('a quick answer: no second request', async ({ assert }) => { let asked = 0 const result = await hedge(() => request(5, 'a'), () => (asked++, request(5, 'b')), 50) assert.deepEqual(result, { value: 'a', late: false, hedged: false, secondWon: false }) assert.equal(asked, 0) }) test('a stalled request: the second answers, the first is cancelled', async ({ assert }) => { const first = request(1000, 'a') const result = await hedge(() => first, () => request(10, 'b'), 20) assert.deepEqual(result, { value: 'b', late: true, hedged: true, secondWon: true }) assert.isTrue(first.cancelled) }) test('late, but the first still wins: the second is cancelled', async ({ assert }) => { const second = request(1000, 'b') const result = await hedge(() => request(40, 'a'), () => second, 20) assert.deepEqual(result, { value: 'a', late: true, hedged: true, secondWon: false }) assert.isTrue(second.cancelled) }) test('no connection free: waits for the first', async ({ assert }) => { const result = await hedge(() => request(40, 'a'), () => null, 10) assert.deepEqual(result, { value: 'a', late: true, hedged: false, secondWon: false }) }) test('one fails: the other answers; both fail: the first error', async ({ assert }) => { const result = await hedge(() => request(30, 'a', true), () => request(40, 'b'), 10) assert.equal(result.value, 'b') await assert.rejects(() => hedge(() => request(30, 'a', true), () => request(40, 'b', true), 10), 'a') }) test('a failure before afterMs fails at once', async ({ assert }) => { let asked = 0 await assert.rejects(() => hedge(() => request(5, 'a', true), () => (asked++, request(5, 'b')), 50), 'a') assert.equal(asked, 0) }) })