Luigit
repositories / pi-ext

pi-ext

bugabingas pi extensions

owned by admin

extensions/footer/__tests__/progress.test.ts

Raw
import { stripVTControlCharacters } from "node:util";
import { Theme } from "@earendil-works/pi-coding-agent";
import { visibleWidth } from "@earendil-works/pi-tui";
import { describe, expect, it } from "vitest";
import { renderBlocksBar } from "../progress.ts";

function makeTheme(dim: string | number, faint = false): Theme {
	// Supply renderer tokens and optional-token fallbacks through the public API.
	return new Theme(
		{
			dim,
			warning: 3,
			muted: 8,
			text: "",
			thinkingXhigh: 8,
		} as ConstructorParameters<typeof Theme>[0],
		{ selectedBg: "" } as ConstructorParameters<typeof Theme>[1],
		"truecolor",
		{ appearance: "dark", dim: faint ? ["dim"] : [] },
	);
}

describe("footer progress styling", () => {
	it.each([
		["terminal default", "", true],
		["indexed palette", 8, false],
		["RGB palette", "#666666", false],
	] as const)("paints a concrete track with %s colors", (_name, dim, faint) => {
		const bar = renderBlocksBar(50, 2, makeTheme(dim, faint), "warning");

		expect(stripVTControlCharacters(bar)).toBe("█ ");
		expect(visibleWidth(bar)).toBe(2);
		expect(bar).toContain("\x1b[48;");
		expect(bar).toContain("\x1b[49m");
		expect(bar).not.toContain("\x1b[2m");
	});

	it("closes faint foreground styling before subsequent footer text", () => {
		const bar = renderBlocksBar(100, 1, makeTheme("", true), "dim");

		expect(bar).toContain("\x1b[2m");
		expect(bar).toMatch(/\x1b\[[\d;]*22(?:;\d+)*m/u);
		expect(bar.lastIndexOf("22")).toBeGreaterThan(bar.indexOf("\x1b[2m"));
		expect(stripVTControlCharacters(`${bar} next`)).toBe("█ next");
	});

	it.each([
		[-10, "  "],
		[0, "  "],
		[25, "▄ "],
		[50, "█ "],
		[100, "██"],
		[110, "██"],
	] as const)("preserves block levels at %s%%", (percent, expected) => {
		const bar = renderBlocksBar(percent, 2, makeTheme(8), "warning");

		expect(stripVTControlCharacters(bar)).toBe(expected);
	});
});