Luigit
repositories / pi-ext

pi-ext

bugabingas pi extensions

owned by admin

extensions/good-job/__tests__/ui.test.ts

Raw
import { visibleWidth } from "@earendil-works/pi-tui";
import { describe, expect, it, vi } from "vitest";
import type { GoodJobRecord } from "../core.js";
import { formatLearningMarkdown, LearningListComponent } from "../ui.js";

const record: GoodJobRecord = {
	version: 2,
	id: "gj-123456789a",
	createdAt: "2026-01-01T00:00:00.000Z",
	completedAt: "2026-01-01T00:01:00.000Z",
	kind: "praise",
	feedback: "gj",
	source: {
		type: "session",
		cwd: "/work/shared-route",
		sessionPath: "/sessions/one.jsonl",
		sessionId: "session-1",
		sessionName: "Shared route",
		leafId: "leaf-1",
		agentModel: { provider: "openai", id: "worker" },
	},
	analysisModel: { provider: "openai", id: "worker" },
	learning: {
		slug: "shared-route-first",
		summary: "Fixed the shared route",
		evidence: ["All focused tests passed"],
		behaviors: ["Inspected callers before editing"],
		candidateRule: "Fix the shared route before leaf callers.",
	},
	usage: {
		input: 10,
		output: 5,
		cacheRead: 0,
		cacheWrite: 0,
		totalTokens: 15,
		cost: 0.01,
	},
};

describe("good-job UI", () => {
	it("renders slug, short ID, and labeled learning sections", () => {
		const markdown = formatLearningMarkdown(record);
		expect(markdown).toContain("## shared-route-first\nFixed the shared route");
		expect(markdown).toContain("## Feedback\ngj");
		expect(markdown).toContain("## Evidence\n- All focused tests passed");
		expect(markdown).toContain("## Behaviors");
		expect(markdown).toContain("gj-123456789a");
		expect(markdown).not.toContain('"learning"');
	});

	it("renders imported problem records without model or usage metadata", () => {
		const imported: GoodJobRecord = {
			...record,
			id: "wtf-123456789a",
			kind: "problem",
			feedback: "unexpected scope expansion",
			source: {
				type: "import",
				importer: "legacy-wtf-v1",
				fingerprint: "abc123",
				importedAt: "2026-01-02T00:00:00.000Z",
			},
			analysisModel: null,
			usage: null,
			learning: {
				...record.learning,
				slug: "avoid-scope-expansion",
			},
		};
		const markdown = formatLearningMarkdown(imported);
		expect(markdown).toContain("## avoid-scope-expansion");
		expect(markdown).toContain("problem · wtf-123456789a");
		expect(markdown).toContain("legacy-wtf-v1");

		const done = vi.fn();
		const theme = {
			fg: (_color: string, text: string) => text,
			bold: (text: string) => text,
		} as never;
		const component = new LearningListComponent(
			theme,
			[imported],
			{ pending: 0, processing: 0, failed: 0, records: 1 },
			vi.fn(),
			done,
		);
		for (const character of "legacy-wtf") component.handleInput(character);
		expect(component.render(80).join("\n")).toContain("avoid-scope-expansion");
	});

	it("renders a width-safe searchable list and returns the selected id", () => {
		const done = vi.fn();
		const requestRender = vi.fn();
		const theme = {
			fg: (_color: string, text: string) => text,
			bold: (text: string) => text,
		} as never;
		const component = new LearningListComponent(
			theme,
			[record],
			{ pending: 1, processing: 0, failed: 0, records: 1 },
			requestRender,
			done,
		);
		for (const character of "shared-route") component.handleInput(character);
		const lines = component.render(48);
		expect(lines.join("\n")).toContain("shared-route-first");
		expect(lines.every((line) => visibleWidth(line) <= 48)).toBe(true);
		expect(requestRender).toHaveBeenCalled();
		component.handleInput("\r");
		expect(done).toHaveBeenCalledWith(record.id);
	});
});