repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
extensions/good-job/__tests__/ui.test.ts
Rawimport { 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);
});
});