import { test } from 'node:test' import assert from 'node:assert/strict' import { isRetryableStatus, deleteWithRetry, runWithConcurrency, } from '../delete-utils.js' const noSleep = () => Promise.resolve() test('isRetryableStatus 僅對暫時性狀態碼回傳 true', () => { for (const s of [429, 502, 503, 504]) assert.equal(isRetryableStatus(s), true) for (const s of [200, 204, 400, 401, 403, 404, 500]) { assert.equal(isRetryableStatus(s), false) } }) test('deleteWithRetry 成功(204)時不重試', async () => { let calls = 0 const client = { async deleteResource() { calls += 1 return 204 }, } const result = await deleteWithRetry(client, 'u', { sleep: noSleep }) assert.equal(result.status, 204) assert.equal(calls, 1) }) test('deleteWithRetry 對暫時性錯誤重試後成功', async () => { const statuses = [503, 503, 204] let i = 0 const client = { async deleteResource() { return statuses[i++] }, } const result = await deleteWithRetry(client, 'u', { sleep: noSleep }) assert.equal(result.status, 204) assert.equal(result.attempts, 3) }) test('deleteWithRetry 對永久性錯誤(403)立即停止重試', async () => { let calls = 0 const client = { async deleteResource() { calls += 1 return 403 }, } const result = await deleteWithRetry(client, 'u', { sleep: noSleep }) assert.equal(result.status, 403) assert.equal(calls, 1) }) test('deleteWithRetry 對網路例外重試至次數用盡並回傳 error', async () => { let calls = 0 const client = { async deleteResource() { calls += 1 throw new Error('network down') }, } const result = await deleteWithRetry(client, 'u', { attempts: 3, sleep: noSleep }) assert.equal(result.status, 0) assert.match(result.error.message, /network down/) assert.equal(calls, 3) }) test('runWithConcurrency 回傳對應輸入順序的結果', async () => { const items = [1, 2, 3, 4, 5] const out = await runWithConcurrency(items, async (n) => n * 2, 2) assert.deepEqual(out, [2, 4, 6, 8, 10]) }) test('runWithConcurrency 不超過併發上限', async () => { let active = 0 let maxActive = 0 const items = Array.from({ length: 10 }, (_, i) => i) await runWithConcurrency( items, async () => { active += 1 maxActive = Math.max(maxActive, active) await Promise.resolve() active -= 1 }, 3, ) assert.ok(maxActive <= 3, `maxActive=${maxActive} 應 <= 3`) }) test('runWithConcurrency 對空陣列回傳空陣列', async () => { const out = await runWithConcurrency([], async () => 1, 4) assert.deepEqual(out, []) })