diff --git a/packages/opencode/src/altimate/tools/finops-formatting.ts b/packages/opencode/src/altimate/tools/finops-formatting.ts index 7996fd1937..c88aa5579a 100644 --- a/packages/opencode/src/altimate/tools/finops-formatting.ts +++ b/packages/opencode/src/altimate/tools/finops-formatting.ts @@ -1,7 +1,9 @@ export function formatBytes(bytes: number): string { if (bytes === 0) return "0 B" + if (!Number.isFinite(bytes)) return "0 B" + const abs = Math.abs(bytes) const units = ["B", "KB", "MB", "GB", "TB", "PB"] - const i = Math.floor(Math.log(bytes) / Math.log(1024)) + const i = Math.max(0, Math.min(Math.floor(Math.log(abs) / Math.log(1024)), units.length - 1)) const value = bytes / Math.pow(1024, i) return `${value.toFixed(i === 0 ? 0 : 2)} ${units[i]}` } @@ -9,6 +11,9 @@ export function formatBytes(bytes: number): string { export function truncateQuery(text: string, maxLen: number): string { if (!text) return "(empty)" const oneLine = text.replace(/\s+/g, " ").trim() + if (!oneLine) return "(empty)" + if (maxLen <= 0) return "" + if (maxLen < 4) return oneLine.slice(0, maxLen) if (oneLine.length <= maxLen) return oneLine return oneLine.slice(0, maxLen - 3) + "..." } diff --git a/packages/opencode/test/altimate/tools/finops-formatting.test.ts b/packages/opencode/test/altimate/tools/finops-formatting.test.ts new file mode 100644 index 0000000000..6598177d2c --- /dev/null +++ b/packages/opencode/test/altimate/tools/finops-formatting.test.ts @@ -0,0 +1,78 @@ +import { describe, test, expect } from "bun:test" +import { formatBytes, truncateQuery } from "../../../src/altimate/tools/finops-formatting" + +describe("formatBytes: normal cases", () => { + test("zero returns 0 B", () => { + expect(formatBytes(0)).toBe("0 B") + }) + + test("exact unit boundaries", () => { + expect(formatBytes(1)).toBe("1 B") + expect(formatBytes(1024)).toBe("1.00 KB") + expect(formatBytes(1024 * 1024)).toBe("1.00 MB") + expect(formatBytes(1024 * 1024 * 1024)).toBe("1.00 GB") + }) + + test("non-boundary values", () => { + expect(formatBytes(500)).toBe("500 B") + expect(formatBytes(1536)).toBe("1.50 KB") + }) +}) + +describe("formatBytes: edge cases", () => { + test("negative bytes displays with sign", () => { + expect(formatBytes(-100)).toBe("-100 B") + expect(formatBytes(-1536)).toBe("-1.50 KB") + }) + + test("fractional bytes clamps to B unit", () => { + expect(formatBytes(0.5)).toBe("1 B") + }) + + test("NaN input returns 0 B", () => { + expect(formatBytes(NaN)).toBe("0 B") + }) + + test("Infinity input returns 0 B", () => { + expect(formatBytes(Infinity)).toBe("0 B") + expect(formatBytes(-Infinity)).toBe("0 B") + }) +}) + +describe("truncateQuery: normal cases", () => { + test("empty/falsy input returns (empty)", () => { + expect(truncateQuery("", 10)).toBe("(empty)") + }) + + test("short text returned as-is", () => { + expect(truncateQuery("SELECT 1", 50)).toBe("SELECT 1") + }) + + test("long text truncated with ellipsis", () => { + const long = "SELECT * FROM very_long_table_name WHERE id = 1" + const result = truncateQuery(long, 20) + expect(result.length).toBeLessThanOrEqual(20) + expect(result).toEndWith("...") + }) + + test("multiline collapsed to single line", () => { + const sql = "SELECT *\n FROM table\n WHERE id = 1" + expect(truncateQuery(sql, 100)).toBe("SELECT * FROM table WHERE id = 1") + }) +}) + +describe("truncateQuery: edge cases", () => { + test("whitespace-only returns (empty)", () => { + expect(truncateQuery(" ", 10)).toBe("(empty)") + }) + + test("maxLen smaller than 4 hard-truncates without ellipsis", () => { + expect(truncateQuery("hello world", 2)).toBe("he") + expect(truncateQuery("hello world", 3)).toBe("hel") + }) + + test("maxLen zero or negative returns empty string", () => { + expect(truncateQuery("hello", 0)).toBe("") + expect(truncateQuery("hello", -5)).toBe("") + }) +})