78 lines
2.8 KiB
TypeScript
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);
|
|
});
|
|
});
|