Files
oh-my-pi/packages/coding-agent/test/modes/controllers/usage-command.test.ts
T
can1357 eb4a02433c refactor: consolidated json parsing and stream utilities
- Centralized JSON parsing and stream processing logic by moving utilities from `packages/ai` to the shared `@oh-my-pi/pi-utils` package.
- Standardized import paths for JSON parsing and streaming across the agent, ai, and coding-agent packages.
- Refactored SSE stream handling to use consolidated `parseStreamingJson` logic and introduced robust error recovery for malformed container-shaped tail events.
- Cleaned up legacy bundled registry references and updated related module exports and tests to reflect the new utility structure.
2026-06-27 00:11:42 +02:00

69 lines
2.2 KiB
TypeScript

import { beforeAll, describe, expect, it, vi } from "bun:test";
import type { UsageReport } from "@oh-my-pi/pi-ai";
import { CommandController } from "@oh-my-pi/pi-coding-agent/modes/controllers/command-controller";
import { getThemeByName, setThemeInstance } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
import type { InteractiveModeContext } from "@oh-my-pi/pi-coding-agent/modes/types";
interface RenderableBlock {
render(width: number): string[];
}
function isRenderableBlock(value: unknown): value is RenderableBlock {
return value !== null && typeof value === "object" && "render" in value && typeof value.render === "function";
}
function renderPresentedBlocks(value: unknown): string {
const blocks = Array.isArray(value) ? value : [value];
return blocks
.filter(isRenderableBlock)
.flatMap(block => block.render(120))
.join("\n");
}
describe("CommandController /usage", () => {
beforeAll(async () => {
const theme = await getThemeByName("dark");
if (!theme) throw new Error("Expected dark theme");
setThemeInstance(theme);
});
it("renders bars and free percentage for limits that only report remainingFraction", async () => {
const present = vi.fn();
const ctx = {
session: {},
ui: { terminal: { columns: 100 } },
present,
showWarning: vi.fn(),
showError: vi.fn(),
} as unknown as InteractiveModeContext;
const controller = new CommandController(ctx);
const reports: UsageReport[] = [
{
provider: "openai-codex",
fetchedAt: 1_700_000_000_000,
limits: [
{
id: "codex-weekly",
label: "Weekly",
scope: { provider: "openai-codex", tier: "pro", accountId: "acct-1" },
window: { id: "weekly", label: "weekly" },
amount: { remainingFraction: 0.25, unit: "requests" },
status: "ok",
},
],
metadata: { email: "user@example.com" },
},
];
await controller.handleUsageCommand(reports);
expect(present).toHaveBeenCalledTimes(1);
const firstCall = present.mock.calls[0];
expect(firstCall).toBeDefined();
const output = renderPresentedBlocks(firstCall?.[0]);
expect(output).toContain("25% free");
expect(output).toContain("█");
expect(output).not.toContain("··········");
});
});