Files
dev/third_party/pi/packages/coding-agent/test/status-indicator.test.ts

78 lines
2.8 KiB
TypeScript

import { type TUI, visibleWidth } from "@earendil-works/pi-tui";
import { afterEach, describe, expect, it, vi } from "vitest";
import { KeybindingsManager } from "../src/core/keybindings.ts";
import { CustomEditor } from "../src/modes/interactive/components/custom-editor.ts";
import {
IdleStatus,
RetryStatusIndicator,
WorkingStatusIndicator,
} from "../src/modes/interactive/components/status-indicator.ts";
import { getEditorTheme, initTheme, theme } from "../src/modes/interactive/theme/theme.ts";
import { stripAnsi } from "../src/utils/ansi.ts";
describe("status indicators", () => {
afterEach(() => {
vi.useRealTimers();
});
it("keeps idle status at the same height as standalone status indicators", () => {
const idleStatus = new IdleStatus();
const lines = idleStatus.render(20);
expect(lines).toHaveLength(2);
expect(lines).toEqual([" ".repeat(20), " ".repeat(20)]);
});
it("keeps the top border unchanged unless the editor opts in", () => {
initTheme("dark");
const tui = {
requestRender: vi.fn(),
terminal: { rows: 10 },
} as unknown as TUI;
const editor = new CustomEditor(tui, getEditorTheme(), KeybindingsManager.create());
const indicator = new WorkingStatusIndicator(tui, "Working");
editor.setWorkingStatusIndicator(indicator);
expect(stripAnsi(editor.render(20)[0]!)).toBe("─".repeat(20));
const standaloneLine = indicator.render(20)[1]!;
expect(standaloneLine).toContain(theme.getFgAnsi("accent"));
expect(standaloneLine).toContain(theme.getFgAnsi("muted"));
indicator.dispose();
});
it("embeds the working indicator when the editor opts in", () => {
initTheme("dark");
const tui = {
requestRender: vi.fn(),
terminal: { rows: 10 },
} as unknown as TUI;
const editor = new CustomEditor(tui, getEditorTheme(), KeybindingsManager.create(), {
embedWorkingStatus: true,
});
expect(editor.embedWorkingStatus).toBe(true);
editor.borderColor = theme.getThinkingBorderColor("high");
const indicator = new WorkingStatusIndicator(tui, "Working", undefined, (text) => editor.borderColor(text));
editor.setWorkingStatusIndicator(indicator);
const topBorder = editor.render(20)[0]!;
expect(stripAnsi(topBorder)).toBe("── ⠋ Working ───────");
expect(visibleWidth(topBorder)).toBe(20);
expect(topBorder.split(theme.getFgAnsi("thinkingHigh"))).toHaveLength(5);
indicator.dispose();
});
it("disposes retry countdown updates", () => {
initTheme("dark");
vi.useFakeTimers();
const requestRender = vi.fn();
const tui = { requestRender } as unknown as TUI;
const indicator = new RetryStatusIndicator(tui, 1, 3, 1000);
const callsBeforeDispose = requestRender.mock.calls.length;
indicator.dispose();
vi.advanceTimersByTime(2000);
expect(requestRender).toHaveBeenCalledTimes(callsBeforeDispose);
});
});