import { beforeAll, describe, expect, it } from "bun:test"; import { ThinkingLevel } from "@oh-my-pi/pi-agent-core"; import type { SegmentContext } from "@oh-my-pi/pi-coding-agent/modes/components/status-line/segments"; import { renderSegment } from "@oh-my-pi/pi-coding-agent/modes/components/status-line/segments"; import { initTheme, theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme"; beforeAll(async () => { await initTheme(); }); function createModelContext(advisorActive: boolean): SegmentContext { return { session: { state: { model: { id: "test-model", name: "Test Model" } }, isFastModeActive: () => false, isAutoThinking: false, autoResolvedThinkingLevel: () => undefined, isAdvisorActive: () => advisorActive, getAdvisorStatusOverview: () => ({ configured: advisorActive, advisors: advisorActive ? [{ name: "default", status: "running" }] : [], }), } as unknown as SegmentContext["session"], width: 120, compactThinkingLevel: false, options: {}, planMode: null, loopMode: null, prewalk: null, goalMode: null, vibeMode: null, collab: null, usageStats: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, orchestrationInput: 0, orchestrationOutput: 0, orchestrationCacheRead: 0, premiumRequests: 0, cost: 0, tokensPerSecond: null, }, contextPercent: 0, contextTokens: 0, contextWindow: 0, autoCompactEnabled: false, compactionSpeculation: "idle", speculationBlinkOn: true, subagentCount: 0, activeMs: 0, activeRepo: null, worktree: null, git: { branch: null, status: null, pr: null }, usage: null, }; } describe("status line model segment advisor badge", () => { it("appends a success-colored ++ badge when all advisors run", () => { const rendered = renderSegment("model", createModelContext(true)); expect(rendered.content).toContain("Test Model"); expect(rendered.content).toContain(theme.fg("success", "++")); }); it("colors the badge by the worst roster status", () => { const ctx = createModelContext(true); ctx.session.getAdvisorStatusOverview = () => ({ configured: true, advisors: [ { name: "a", status: "running" }, { name: "b", status: "quota_exhausted" }, ], }); expect(renderSegment("model", ctx).content).toContain(theme.fg("warning", "++")); ctx.session.getAdvisorStatusOverview = () => ({ configured: true, advisors: [ { name: "a", status: "error" }, { name: "b", status: "quota_exhausted" }, ], }); expect(renderSegment("model", ctx).content).toContain(theme.fg("error", "++")); }); it("omits the badge when the advisor is inactive", () => { const rendered = renderSegment("model", createModelContext(false)); expect(rendered.content).toContain("Test Model"); expect(rendered.content).not.toContain("++"); }); }); describe("status line model segment compact thinking level", () => { function createThinkingContext(compactThinkingLevel: boolean): SegmentContext { return { ...createModelContext(false), compactThinkingLevel, session: { state: { model: { id: "test-model", name: "Test Model", thinking: true }, thinkingLevel: ThinkingLevel.High, }, isFastModeActive: () => false, isAutoThinking: false, autoResolvedThinkingLevel: () => undefined, isAdvisorActive: () => false, getAdvisorStatusOverview: () => ({ configured: false, advisors: [] }), } as unknown as SegmentContext["session"], }; } it("trails the level as a ` ยท ` suffix when compact mode is off", () => { const display = theme.thinking.high; const modelPrefix = theme.icon.model ? `${theme.icon.model} ` : ""; const rendered = renderSegment("model", createThinkingContext(false)); expect(Bun.stripANSI(rendered.content)).toBe(`${modelPrefix}Test Model${theme.sep.dot}${display}`); }); it("swaps the model icon for the level glyph and drops the suffix when compact", () => { const display = theme.thinking.high; const glyph = display.includes(" ") ? display.slice(0, display.indexOf(" ")) : display; const rendered = renderSegment("model", createThinkingContext(true)); expect(Bun.stripANSI(rendered.content)).toBe(`${glyph} Test Model`); expect(Bun.stripANSI(rendered.content)).not.toContain(theme.sep.dot); }); });