diff --git a/src/infra/provider-usage.format.test.ts b/src/infra/provider-usage.format.test.ts index 3063a571a24..d87d6a73c17 100644 --- a/src/infra/provider-usage.format.test.ts +++ b/src/infra/provider-usage.format.test.ts @@ -54,6 +54,18 @@ describe("provider-usage.format", () => { expect(summary).toBe("A 90% left · B 80% left"); }); + it("treats non-positive max windows as all windows and clamps overused percentages", () => { + const summary = formatUsageWindowSummary( + makeSnapshot([ + { label: "Over", usedPercent: 120, resetAt: now + 60_000 }, + { label: "Under", usedPercent: -10 }, + ]), + { now, maxWindows: 0, includeResets: true }, + ); + + expect(summary).toBe("Over 0% left ⏱1m · Under 100% left"); + }); + it("formats summary line from highest-usage window and provider cap", () => { const summary: UsageSummary = { updatedAt: now, @@ -79,6 +91,27 @@ describe("provider-usage.format", () => { ); }); + it("returns null summary line when providers are errored or have no windows", () => { + expect( + formatUsageSummaryLine({ + updatedAt: now, + providers: [ + { + provider: "anthropic", + displayName: "Claude", + windows: [], + error: "HTTP 401", + }, + { + provider: "zai", + displayName: "z.ai", + windows: [], + }, + ], + }), + ).toBeNull(); + }); + it("formats report output for empty, error, no-data, and plan entries", () => { expect(formatUsageReportLines({ updatedAt: now, providers: [] })).toEqual([ "Usage: no provider usage available.", @@ -107,4 +140,24 @@ describe("provider-usage.format", () => { " Xiaomi: no data", ]); }); + + it("formats detailed report lines with reset windows", () => { + const summary: UsageSummary = { + updatedAt: now, + providers: [ + { + provider: "anthropic", + displayName: "Claude", + plan: "Pro", + windows: [{ label: "Daily", usedPercent: 25, resetAt: now + 2 * 60 * 60_000 }], + }, + ], + }; + + expect(formatUsageReportLines(summary, { now })).toEqual([ + "Usage:", + " Claude (Pro)", + " Daily: 75% left · resets 2h", + ]); + }); }); diff --git a/src/infra/runtime-status.test.ts b/src/infra/runtime-status.test.ts new file mode 100644 index 00000000000..fc79afe5bee --- /dev/null +++ b/src/infra/runtime-status.test.ts @@ -0,0 +1,30 @@ +import { describe, expect, it } from "vitest"; +import { formatRuntimeStatusWithDetails } from "./runtime-status.js"; + +describe("formatRuntimeStatusWithDetails", () => { + it("falls back to unknown when status is missing", () => { + expect(formatRuntimeStatusWithDetails({})).toBe("unknown"); + }); + + it("includes pid, distinct state, and non-empty details", () => { + expect( + formatRuntimeStatusWithDetails({ + status: "running", + pid: 1234, + state: "sleeping", + details: ["healthy", "", "port 18789"], + }), + ).toBe("running (pid 1234, state sleeping, healthy, port 18789)"); + }); + + it("omits duplicate state text and falsy pid values", () => { + expect( + formatRuntimeStatusWithDetails({ + status: "running", + pid: 0, + state: "RUNNING", + details: [], + }), + ).toBe("running"); + }); +});