codeburn/tests/overview.test.ts
AgentSeal 8d727d9cc4 feat(overview): full comma-grouped numbers for a precise, spacious look
Render token counts as full thousands-grouped integers (e.g.
3,926,923,819) instead of abbreviated M/B, so the roomy tables read like
a precise statement. Update the overview test to match.
2026-06-20 19:12:26 +02:00

103 lines
3.6 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { describe, it, expect } from 'vitest'
import { renderOverview } from '../src/overview.js'
import type { ProjectSummary } from '../src/types.js'
function makeProject(opts: {
project: string
projectPath: string
cost: number
calls: number
model: string
provider: string
tokens: { input: number; output: number; cacheR: number; cacheW: number }
}): ProjectSummary {
const usage = {
inputTokens: opts.tokens.input,
outputTokens: opts.tokens.output,
cacheReadInputTokens: opts.tokens.cacheR,
cacheCreationInputTokens: opts.tokens.cacheW,
}
return {
project: opts.project,
projectPath: opts.projectPath,
totalCostUSD: opts.cost,
totalSavingsUSD: 0,
totalProxiedCostUSD: 0,
totalApiCalls: opts.calls,
sessions: [{
sessionId: 's1',
project: opts.project,
totalInputTokens: opts.tokens.input,
totalOutputTokens: opts.tokens.output,
totalCacheReadTokens: opts.tokens.cacheR,
totalCacheWriteTokens: opts.tokens.cacheW,
apiCalls: opts.calls,
modelBreakdown: { [opts.model]: { calls: opts.calls, costUSD: opts.cost, savingsUSD: 0, tokens: usage } },
categoryBreakdown: { coding: { turns: 1, costUSD: opts.cost, savingsUSD: 0, retries: 0, editTurns: 1, oneShotTurns: 1 } },
toolBreakdown: { Bash: { calls: 5 }, Read: { calls: 2 } },
mcpBreakdown: {},
bashBreakdown: {},
skillBreakdown: {},
subagentBreakdown: {},
turns: [{
userMessage: 'hi',
timestamp: '2026-06-15T10:00:00Z',
sessionId: 's1',
category: 'coding',
retries: 0,
hasEdits: true,
assistantCalls: [{ provider: opts.provider, model: opts.model, costUSD: opts.cost, usage }],
}],
}],
} as unknown as ProjectSummary
}
describe('renderOverview', () => {
it('renders the detailed sections from real aggregation', () => {
const out = renderOverview([makeProject({
project: 'myproject',
projectPath: '/Users/test/myproject',
cost: 12.5,
calls: 3,
model: 'claude-opus-4-8',
provider: 'claude',
tokens: { input: 1000, output: 200, cacheR: 5000, cacheW: 100 },
})], { label: 'June 2026', color: false })
for (const section of ['Totals', 'By tool', 'Top models', 'Highest-value days', 'Top projects', 'Daily', 'By activity', 'Tools']) {
expect(out).toContain(section)
}
expect(out).toContain('Opus 4.8') // model display name
expect(out).toContain('claude') // provider in By tool
expect(out).toContain('myproject') // clean project name from path basename
expect(out).toContain('$12.50')
expect(out).toContain('2026-06-15')
expect(out).toContain('Coding')
expect(out).toContain('Bash')
})
it('uses thousands separators and a B unit, and strips color in no-color mode', () => {
const out = renderOverview([makeProject({
project: 'big',
projectPath: '/Users/test/big',
cost: 1234.56,
calls: 10,
model: 'claude-opus-4-8',
provider: 'claude',
tokens: { input: 1_000_000, output: 1_000_000, cacheR: 2_000_000_000, cacheW: 0 },
})], { label: 'June 2026', color: false })
expect(out).toContain('$1,234.56')
// tokens render as full, comma-grouped numbers (not abbreviated)
expect(out).toContain('2,002,000,000')
// no-color mode must not emit ANSI escape codes
// eslint-disable-next-line no-control-regex
expect(out).not.toMatch(/\[/)
})
it('reports no usage for an empty range', () => {
const out = renderOverview([], { label: 'June 2026', color: false })
expect(out).toContain('No usage found for June 2026')
})
})