import { test } from 'node:test' import assert from 'node:assert/strict' import { formatCost, formatNumber, formatDuration, progressBar, renderConsoleReport, renderMarkdownReport, contextState } from '../src/reports.mjs' test('formatNumber uses en-US grouping', () => { assert.equal(formatNumber(1234567), '1,234,567') }) test('formatCost keeps precision for tiny values', () => { assert.equal(formatCost(0), '$0.0000') assert.match(formatCost(0.002106102), /^\$0\.00211$/) assert.match(formatCost(1.5), /^\$1\.5000$/) }) test('formatDuration renders mm:ss and hours', () => { assert.equal(formatDuration(65_000), '01:05') assert.equal(formatDuration(3_725_000), '1h 02m') }) test('progressBar clamps', () => { assert.equal(progressBar(0, 4), '░░░░') assert.equal(progressBar(100, 4), '████') assert.equal(progressBar(50, 4), '██░░') assert.equal(progressBar(999, 4), '████') }) test('contextState classifies thresholds', () => { assert.equal(contextState(10, 100), 'ok') assert.equal(contextState(80, 100), 'warn') assert.equal(contextState(120, 100), 'over') }) const report = { runId: 'run', iteration: 2, total: 5, status: 'completed', topic: 'Refactor settings', stageTitle: 'Stage 2', stageId: 's2', stageStatus: 'in_progress', percent: 42, nextStage: 'Stage 3', summary: 'Changed things and verified.', questions: [], tokens: { input: 1000, output: 200, reasoning: 10, cacheRead: 500, total: 1200 }, cost: 0.05, contextSize: 1200, contextState: 'ok', contextWarnTokens: 150000, durationMs: 65_000, filesChanged: ['a.ts', 'b.vue'], sessionID: 'ses_1', error: null, } test('renderConsoleReport contains the key report fields', async () => { const { setColorEnabled } = await import('../src/ansi.mjs') setColorEnabled(false) const text = renderConsoleReport(report, { cost: 0.2 }) assert.match(text, /Iteration 2\/5/) assert.match(text, /Refactor settings/) assert.match(text, /42%/) assert.match(text, /Stage 3/) assert.match(text, /1,200/) }) test('renderMarkdownReport emits a structured document', () => { const md = renderMarkdownReport(report) assert.match(md, /# Iteration 2\/5/) assert.match(md, /## Files changed/) assert.match(md, /`a\.ts`/) assert.match(md, /## Summary/) })