import { beforeAll, describe, expect, test, vi } from "bun:test"; import { initTheme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme"; import { UiHelpers } from "@oh-my-pi/pi-coding-agent/modes/utils/ui-helpers"; import { Container } from "@oh-my-pi/pi-tui"; function renderLastLine(container: Container, width = 120): string { const last = container.children[container.children.length - 1]; if (!last) return ""; return last.render(width).join("\n"); } describe("InteractiveMode.showStatus", () => { beforeAll(() => { // showStatus uses the global theme instance initTheme(); }); test("coalesces immediately-sequential status messages", () => { const ctx: any = { chatContainer: new Container(), ui: { requestRender: vi.fn() }, isBackgrounded: false, lastStatusSpacer: undefined, lastStatusText: undefined, }; const helpers = new UiHelpers(ctx); helpers.showStatus("STATUS_ONE"); expect(ctx.chatContainer.children).toHaveLength(2); expect(renderLastLine(ctx.chatContainer)).toContain("STATUS_ONE"); helpers.showStatus("STATUS_TWO"); // second status updates the previous line instead of appending expect(ctx.chatContainer.children).toHaveLength(2); expect(renderLastLine(ctx.chatContainer)).toContain("STATUS_TWO"); expect(renderLastLine(ctx.chatContainer)).not.toContain("STATUS_ONE"); }); test("appends a new status line if something else was added in between", () => { const ctx: any = { chatContainer: new Container(), ui: { requestRender: vi.fn() }, isBackgrounded: false, lastStatusSpacer: undefined, lastStatusText: undefined, }; const helpers = new UiHelpers(ctx); helpers.showStatus("STATUS_ONE"); expect(ctx.chatContainer.children).toHaveLength(2); // Something else gets added to the chat in between status updates ctx.chatContainer.addChild({ render: () => ["OTHER"], invalidate: () => {} }); expect(ctx.chatContainer.children).toHaveLength(3); helpers.showStatus("STATUS_TWO"); // adds spacer + text expect(ctx.chatContainer.children).toHaveLength(5); expect(renderLastLine(ctx.chatContainer)).toContain("STATUS_TWO"); }); });