clanker-agent/packages/coding-agent/test/footer-width.test.ts
Harivansh Rathi 536241053c refactor: finish companion rename migration
Complete the remaining pi-to-companion rename across companion-os, web, vm-orchestrator, docker, and archived fixtures.

Verification:
- semantic rg sweeps for Pi/piConfig/getPi/.pi runtime references
- npm run check in apps/companion-os (fails in this worktree: biome not found)

Co-authored-by: Codex <noreply@openai.com>
2026-03-10 07:39:32 -05:00

114 lines
3 KiB
TypeScript

import { visibleWidth } from "@mariozechner/companion-tui";
import { beforeAll, describe, expect, it } from "vitest";
import type { AgentSession } from "../src/core/agent-session.js";
import type { ReadonlyFooterDataProvider } from "../src/core/footer-data-provider.js";
import { FooterComponent } from "../src/modes/interactive/components/footer.js";
import { initTheme } from "../src/modes/interactive/theme/theme.js";
type AssistantUsage = {
input: number;
output: number;
cacheRead: number;
cacheWrite: number;
cost: { total: number };
};
function createSession(options: {
sessionName: string;
modelId?: string;
provider?: string;
reasoning?: boolean;
thinkingLevel?: string;
usage?: AssistantUsage;
}): AgentSession {
const usage = options.usage;
const entries =
usage === undefined
? []
: [
{
type: "message",
message: {
role: "assistant",
usage,
},
},
];
const session = {
state: {
model: {
id: options.modelId ?? "test-model",
provider: options.provider ?? "test",
contextWindow: 200_000,
reasoning: options.reasoning ?? false,
},
thinkingLevel: options.thinkingLevel ?? "off",
},
sessionManager: {
getEntries: () => entries,
getSessionName: () => options.sessionName,
},
getContextUsage: () => ({ contextWindow: 200_000, percent: 12.3 }),
modelRegistry: {
isUsingOAuth: () => false,
},
};
return session as unknown as AgentSession;
}
function createFooterData(providerCount: number): ReadonlyFooterDataProvider {
const provider = {
getGitBranch: () => "main",
getExtensionStatuses: () => new Map<string, string>(),
getAvailableProviderCount: () => providerCount,
onBranchChange: (callback: () => void) => {
void callback;
return () => {};
},
};
return provider;
}
describe("FooterComponent width handling", () => {
beforeAll(() => {
initTheme(undefined, false);
});
it("keeps all lines within width for wide session names", () => {
const width = 93;
const session = createSession({ sessionName: "한글".repeat(30) });
const footer = new FooterComponent(session, createFooterData(1));
const lines = footer.render(width);
for (const line of lines) {
expect(visibleWidth(line)).toBeLessThanOrEqual(width);
}
});
it("keeps stats line within width for wide model and provider names", () => {
const width = 60;
const session = createSession({
sessionName: "",
modelId: "模".repeat(30),
provider: "공급자",
reasoning: true,
thinkingLevel: "high",
usage: {
input: 12_345,
output: 6_789,
cacheRead: 0,
cacheWrite: 0,
cost: { total: 1.234 },
},
});
const footer = new FooterComponent(session, createFooterData(2));
const lines = footer.render(width);
for (const line of lines) {
expect(visibleWidth(line)).toBeLessThanOrEqual(width);
}
});
});