feat: add token breakdown helpers
This commit is contained in:
66
lib/token-breakdown.test.ts
Normal file
66
lib/token-breakdown.test.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import {
|
||||
getPrimaryModelNames,
|
||||
getSharePercent,
|
||||
getTokenDisplayName,
|
||||
getTokenRowKey,
|
||||
shouldShowTokenTab,
|
||||
sortTokenBreakdown,
|
||||
} from "./token-breakdown";
|
||||
|
||||
describe("token breakdown helpers", () => {
|
||||
const rows = [
|
||||
{
|
||||
name: "beta",
|
||||
calls: 2,
|
||||
total_tokens: 100,
|
||||
quota: 500,
|
||||
models: [{ name: "gpt-4o", calls: 1, total_tokens: 70, quota: 300 }],
|
||||
},
|
||||
{
|
||||
name: "alpha",
|
||||
calls: 5,
|
||||
total_tokens: 300,
|
||||
quota: 300,
|
||||
models: [{ name: "claude-sonnet-4", calls: 1, total_tokens: 200, quota: 200 }],
|
||||
},
|
||||
];
|
||||
|
||||
test("sorts token rows without mutating nested model data", () => {
|
||||
const sorted = sortTokenBreakdown(rows, "total_tokens", false);
|
||||
|
||||
expect(sorted.map((row) => row.name)).toEqual(["alpha", "beta"]);
|
||||
expect(sorted[0].models[0].name).toBe("claude-sonnet-4");
|
||||
expect(rows.map((row) => row.name)).toEqual(["beta", "alpha"]);
|
||||
});
|
||||
|
||||
test("uses a localized label for unnamed tokens", () => {
|
||||
expect(getTokenDisplayName("", "未命名令牌")).toBe("未命名令牌");
|
||||
expect(getTokenDisplayName("prod-key", "未命名令牌")).toBe("prod-key");
|
||||
});
|
||||
|
||||
test("keeps unnamed token row keys stable", () => {
|
||||
expect(getTokenRowKey("")).toBe("__unnamed_token__");
|
||||
expect(getTokenRowKey("prod-key")).toBe("prod-key");
|
||||
});
|
||||
|
||||
test("shows the token tab only for user details", () => {
|
||||
expect(shouldShowTokenTab("user")).toBe(true);
|
||||
expect(shouldShowTokenTab("model")).toBe(false);
|
||||
expect(shouldShowTokenTab("channel")).toBe(false);
|
||||
});
|
||||
|
||||
test("calculates share percentages and handles empty totals", () => {
|
||||
expect(getSharePercent(25, 100)).toBe(25);
|
||||
expect(getSharePercent(25, 0)).toBe(0);
|
||||
});
|
||||
|
||||
test("formats a compact primary model preview", () => {
|
||||
expect(getPrimaryModelNames([
|
||||
{ name: "a", calls: 1, total_tokens: 1, quota: 1 },
|
||||
{ name: "b", calls: 1, total_tokens: 1, quota: 1 },
|
||||
{ name: "c", calls: 1, total_tokens: 1, quota: 1 },
|
||||
{ name: "d", calls: 1, total_tokens: 1, quota: 1 },
|
||||
])).toBe("a, b, c");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user