Skip to content

Commit d6ce827

Browse files
committed
Add comprehensive unit tests for formatTokens.ts
Created formatTokens.spec.ts with 21 tests covering: - formatTokenCount function with all edge cases - formatTokenStats function with cache and parameter combinations - 100% code coverage (statements, branches, functions, lines) Tests verify proper token formatting, cache handling, and error cases.
1 parent c6fd34e commit d6ce827

File tree

1 file changed

+197
-0
lines changed

1 file changed

+197
-0
lines changed
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
import { describe, it, expect, vi } from "vitest"
2+
import { formatTokenCount, formatTokenStats } from "../formatTokens"
3+
4+
// Mock i18next (same as in format.spec.ts)
5+
vi.mock("i18next", () => ({
6+
default: {
7+
t: vi.fn((key: string, options?: any) => {
8+
// Mock translations for testing
9+
const translations: Record<string, string> = {
10+
"common:number_format.billion_suffix": "b",
11+
"common:number_format.million_suffix": "m",
12+
"common:number_format.thousand_suffix": "k",
13+
}
14+
15+
let result = translations[key] || key
16+
if (options?.count !== undefined) {
17+
result = result.replace("{{count}}", options.count.toString())
18+
}
19+
return result
20+
}),
21+
language: "en",
22+
},
23+
}))
24+
25+
// Mock formatLargeNumber
26+
vi.mock("../format", () => ({
27+
formatLargeNumber: vi.fn((num: number) => {
28+
if (num >= 1e9) {
29+
return (num / 1e9).toFixed(1) + "b"
30+
}
31+
if (num >= 1e6) {
32+
return (num / 1e6).toFixed(1) + "m"
33+
}
34+
if (num >= 1e3) {
35+
return (num / 1e3).toFixed(1) + "k"
36+
}
37+
return num.toString()
38+
}),
39+
}))
40+
41+
describe("formatTokenCount", () => {
42+
it("should return '0' for undefined count", () => {
43+
expect(formatTokenCount(undefined)).toBe("0")
44+
})
45+
46+
it("should return '0' for count of 0", () => {
47+
expect(formatTokenCount(0)).toBe("0")
48+
})
49+
50+
it("should format small numbers as strings", () => {
51+
expect(formatTokenCount(42)).toBe("42")
52+
expect(formatTokenCount(999)).toBe("999")
53+
})
54+
55+
it("should format thousands correctly", () => {
56+
expect(formatTokenCount(1500)).toBe("1.5k")
57+
expect(formatTokenCount(2000)).toBe("2.0k")
58+
})
59+
60+
it("should format millions correctly", () => {
61+
expect(formatTokenCount(1500000)).toBe("1.5m")
62+
expect(formatTokenCount(2000000)).toBe("2.0m")
63+
})
64+
65+
it("should format billions correctly", () => {
66+
expect(formatTokenCount(1500000000)).toBe("1.5b")
67+
expect(formatTokenCount(2000000000)).toBe("2.0b")
68+
})
69+
})
70+
71+
describe("formatTokenStats", () => {
72+
describe("without cache reads", () => {
73+
it("should format input and output tokens without cache", () => {
74+
const result = formatTokenStats(1000, 500)
75+
expect(result).toEqual({
76+
input: "1.0k",
77+
output: "500",
78+
})
79+
})
80+
81+
it("should handle undefined tokens", () => {
82+
const result = formatTokenStats(undefined, undefined)
83+
expect(result).toEqual({
84+
input: "0",
85+
output: "0",
86+
})
87+
})
88+
89+
it("should handle zero tokens", () => {
90+
const result = formatTokenStats(0, 0)
91+
expect(result).toEqual({
92+
input: "0",
93+
output: "0",
94+
})
95+
})
96+
97+
it("should handle only input tokens", () => {
98+
const result = formatTokenStats(2000, undefined)
99+
expect(result).toEqual({
100+
input: "2.0k",
101+
output: "0",
102+
})
103+
})
104+
105+
it("should handle only output tokens", () => {
106+
const result = formatTokenStats(undefined, 3000)
107+
expect(result).toEqual({
108+
input: "0",
109+
output: "3.0k",
110+
})
111+
})
112+
113+
it("should handle large numbers", () => {
114+
const result = formatTokenStats(1500000, 2000000)
115+
expect(result).toEqual({
116+
input: "1.5m",
117+
output: "2.0m",
118+
})
119+
})
120+
})
121+
122+
describe("with cache reads", () => {
123+
it("should include cache reads in input display with default label", () => {
124+
const result = formatTokenStats(1000, 500, 200)
125+
expect(result).toEqual({
126+
input: "1.0k (200 cache)",
127+
output: "500",
128+
})
129+
})
130+
131+
it("should include cache reads in input display with custom label", () => {
132+
const result = formatTokenStats(1000, 500, 200, "cached")
133+
expect(result).toEqual({
134+
input: "1.0k (200 cached)",
135+
output: "500",
136+
})
137+
})
138+
139+
it("should handle cache reads with large numbers", () => {
140+
const result = formatTokenStats(1000000, 500000, 200000, "cache")
141+
expect(result).toEqual({
142+
input: "1.0m (200.0k cache)",
143+
output: "500.0k",
144+
})
145+
})
146+
147+
it("should handle zero cache reads (should not display cache)", () => {
148+
const result = formatTokenStats(1000, 500, 0)
149+
expect(result).toEqual({
150+
input: "1.0k",
151+
output: "500",
152+
})
153+
})
154+
155+
it("should handle undefined cache reads (should not display cache)", () => {
156+
const result = formatTokenStats(1000, 500, undefined)
157+
expect(result).toEqual({
158+
input: "1.0k",
159+
output: "500",
160+
})
161+
})
162+
163+
it("should handle negative cache reads (should not display cache)", () => {
164+
const result = formatTokenStats(1000, 500, -100)
165+
expect(result).toEqual({
166+
input: "1.0k",
167+
output: "500",
168+
})
169+
})
170+
})
171+
172+
describe("edge cases", () => {
173+
it("should handle very large numbers", () => {
174+
const result = formatTokenStats(5000000000, 1000000000)
175+
expect(result).toEqual({
176+
input: "5.0b",
177+
output: "1.0b",
178+
})
179+
})
180+
181+
it("should handle decimal numbers", () => {
182+
const result = formatTokenStats(1234.56, 567.89)
183+
expect(result).toEqual({
184+
input: "1.2k",
185+
output: "567.89", // formatLargeNumber preserves decimals for small numbers
186+
})
187+
})
188+
189+
it("should handle empty cache label", () => {
190+
const result = formatTokenStats(1000, 500, 200, "")
191+
expect(result).toEqual({
192+
input: "1.0k (200 )",
193+
output: "500",
194+
})
195+
})
196+
})
197+
})

0 commit comments

Comments
 (0)