import { test } from 'node:test' import assert from 'node:assert/strict' import { createTaskPollingBaseline } from '../src/shared/task-polling-baseline.ts' interface FakeDetail { id: number name: string status: string } function detail(id: number): FakeDetail { return { id, name: `task-${id}`, status: id % 2 === 0 ? 'SUCCESS' : 'RUNNING' } } const byId = (d: FakeDetail) => d.id const enc = (v: unknown) => new TextEncoder().encode(JSON.stringify(v)).byteLength test('test_task_081_polling_frontend_normal_default_path', () => { const baseline = createTaskPollingBaseline() baseline.recordRequest() baseline.recordRequest() baseline.recordRequest() const inserted = baseline.recordResponseItems([detail(1), detail(2)], byId) assert.equal(inserted, 2) const stats = baseline.stats() assert.equal(stats.requestCount, 3) assert.equal(stats.entryCount, 2) assert.equal(stats.droppedCount, 0) assert.ok(stats.cachedBytes > 0) assert.ok(stats.cachedBytes <= 1024 * 1024) assert.equal(stats.totalResponseBytes, enc([detail(1), detail(2)])) assert.equal(stats.largestResponseBytes, stats.totalResponseBytes) assert.deepEqual(stats.entryKeys, [1, 2]) }) test('test_task_081_polling_frontend_normal_multiple_items', () => { const baseline = createTaskPollingBaseline() const items = Array.from({ length: 10 }, (_, i) => detail(i + 1)) const inserted = baseline.recordResponseItems(items, byId) assert.equal(inserted, 10) const stats = baseline.stats() assert.equal(stats.entryCount, 10) assert.deepEqual(stats.entryKeys, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) // 覆盖更新不改变首次到达顺序 baseline.recordResponseItems([detail(5)], byId) const after = baseline.stats() assert.equal(after.entryCount, 10) assert.deepEqual(after.entryKeys, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) assert.equal(after.totalResponseBytes, enc(items) + enc([detail(5)])) assert.equal(after.largestResponseBytes, enc(items)) }) test('test_task_081_polling_frontend_normal_repeated_operation_is_idempotent', () => { const baseline = createTaskPollingBaseline() const items = [detail(1), detail(2), detail(3)] baseline.recordResponseItems(items, byId) baseline.recordResponseItems(items, byId) const stats = baseline.stats() assert.equal(stats.entryCount, 3) assert.equal(stats.droppedCount, 0) const single = createTaskPollingBaseline() single.recordResponseItems(items, byId) assert.equal(stats.cachedBytes, single.stats().cachedBytes) assert.equal(stats.totalResponseBytes, single.stats().totalResponseBytes * 2) }) test('test_task_081_polling_frontend_boundary_empty_input', () => { const baseline = createTaskPollingBaseline() assert.equal(baseline.recordResponseItems([], byId), 0) assert.equal(baseline.recordResponseItems([], byId), 0) const stats = baseline.stats() assert.equal(stats.requestCount, 0) assert.equal(stats.totalResponseBytes, 0) assert.equal(stats.largestResponseBytes, 0) assert.equal(stats.entryCount, 0) assert.equal(stats.cachedBytes, 0) assert.equal(stats.droppedCount, 0) assert.deepEqual(stats.entryKeys, []) }) test('test_task_081_polling_frontend_boundary_single_item', () => { const baseline = createTaskPollingBaseline() const inserted = baseline.recordResponseItems([detail(7)], byId) assert.equal(inserted, 1) const stats = baseline.stats() assert.equal(stats.entryCount, 1) assert.deepEqual(stats.entryKeys, [7]) assert.equal(stats.cachedBytes, enc(detail(7)) + 64) assert.equal(stats.totalResponseBytes, enc([detail(7)])) }) test('test_task_081_polling_frontend_boundary_limit_and_overflow', () => { // 条目数超限:驱逐最旧,缓存有界 const byEntries = createTaskPollingBaseline({ maxEntries: 3, maxCacheBytes: 1_000_000 }) byEntries.recordResponseItems([detail(1), detail(2), detail(3), detail(4), detail(5)], byId) const s1 = byEntries.stats() assert.equal(s1.entryCount, 3) assert.deepEqual(s1.entryKeys, [3, 4, 5]) assert.equal(s1.droppedCount, 2) // 单条超过字节上限:直接拒绝 const small = createTaskPollingBaseline({ maxCacheBytes: 200 }) const big = { id: 9, name: 'x'.repeat(1000), status: 'RUNNING' } const inserted = small.recordResponseItems([big], byId) assert.equal(inserted, 0) const s2 = small.stats() assert.equal(s2.entryCount, 0) assert.equal(s2.droppedCount, 1) assert.ok(s2.cachedBytes <= 200) // 批量累积超限:逐条驱逐最旧直到有界 const tiny = createTaskPollingBaseline({ maxCacheBytes: 300 }) tiny.recordResponseItems([detail(1), detail(2), detail(3)], byId) const s3 = tiny.stats() assert.equal(s3.entryCount, 2) assert.deepEqual(s3.entryKeys, [2, 3]) assert.equal(s3.droppedCount, 1) assert.ok(s3.cachedBytes <= 300) }) test('test_task_081_polling_frontend_invalid_input_rejected', () => { const baseline = createTaskPollingBaseline() assert.throws(() => baseline.recordResponseItems(null as never, byId), /items 必须是数组/) assert.throws(() => baseline.recordResponseItems([detail(1)], null as never), /extractKey 必须是函数/) assert.throws(() => createTaskPollingBaseline({ maxEntries: 0 }), /上限配置必须为正数/) assert.throws(() => createTaskPollingBaseline({ maxCacheBytes: -1 }), /上限配置必须为正数/) // 非法 key 跳过而不是抛错(与轮询层行为一致) const inserted = baseline.recordResponseItems( [{ id: 0, name: 'x', status: 'y' }, detail(2)], byId, ) assert.equal(inserted, 1) }) test('test_task_081_polling_frontend_dependency_failure_releases_resources', () => { const baseline = createTaskPollingBaseline() baseline.recordRequest() assert.throws( () => baseline.recordResponseItems([detail(1)], () => { throw new Error('boom') }), /boom/, ) const after = baseline.stats() assert.equal(after.entryCount, 0) assert.equal(after.totalResponseBytes, 0) assert.equal(after.requestCount, 1) assert.equal(after.droppedCount, 0) baseline.reset() assert.deepEqual(baseline.stats(), { requestCount: 0, totalResponseBytes: 0, largestResponseBytes: 0, entryCount: 0, cachedBytes: 0, droppedCount: 0, entryKeys: [], }) // 错误可恢复:修复后同一实例继续工作 baseline.recordResponseItems([detail(1)], byId) assert.equal(baseline.stats().entryCount, 1) })