import { describe, expect, test } from "bun:test"; import { buildPkbReminder } from "./pkb-reminder-builder.js"; // Byte-for-byte fixture of the PKB reminder. Asserted verbatim so that any // future edit to the BODY text is caught by tests. const BASE_REMINDER = "" + "\nStay present in this conversation. Use `remember` when something feels worth pausing to mark — corrections (highest priority), plans, decisions, felt moments. You don't have to capture everything in the moment — a retrospective pass reviews this conversation in the background and saves what you didn't capture." + "\nIf you're unsure about something that may live in the workspace — past decisions, prior conversations, files — use `recall` before asking or guessing." + "\n"; describe("buildPkbReminder", () => { test("empty hints returns exact base reminder byte-for-byte", () => { expect(buildPkbReminder([])).toBe(BASE_REMINDER); }); test("single hint renders one bullet with no duplicates or trailing blank line", () => { const out = buildPkbReminder(["projects/alpha.md"]); const expected = "" + "\nStay present in this conversation. Use `remember` when something feels worth pausing to mark — corrections (highest priority), plans, decisions, felt moments. You don't have to capture everything in the moment — a retrospective pass reviews this conversation in the background and saves what you didn't capture." + "\nIf you're unsure about something that may live in the workspace — past decisions, prior conversations, files — use `recall` before asking or guessing." + "\nBased on the current context, these files look especially relevant:" + "\n- projects/alpha.md" + "\n"; expect(out).toBe(expected); // Exactly one bullet. const bulletCount = (out.match(/^- /gm) ?? []).length; expect(bulletCount).toBe(1); // No blank line before closing tag. expect(out.includes("\n\n")).toBe(false); }); test("three hints render all three in order", () => { const hints = ["a.md", "sub/b.md", "c/d/e.md"]; const out = buildPkbReminder(hints); const expected = "" + "\nStay present in this conversation. Use `remember` when something feels worth pausing to mark — corrections (highest priority), plans, decisions, felt moments. You don't have to capture everything in the moment — a retrospective pass reviews this conversation in the background and saves what you didn't capture." + "\nIf you're unsure about something that may live in the workspace — past decisions, prior conversations, files — use `recall` before asking or guessing." + "\nBased on the current context, these files look especially relevant:" + "\n- a.md" + "\n- sub/b.md" + "\n- c/d/e.md" + "\n"; expect(out).toBe(expected); // Order check — each should appear after the previous. const idxA = out.indexOf("- a.md"); const idxB = out.indexOf("- sub/b.md"); const idxC = out.indexOf("- c/d/e.md"); expect(idxA).toBeGreaterThan(-1); expect(idxB).toBeGreaterThan(idxA); expect(idxC).toBeGreaterThan(idxB); }); test("hints with special chars (< and &) are emitted verbatim (no escaping)", () => { const hints = ["weird.md", "foo&bar.md"]; const out = buildPkbReminder(hints); expect(out).toContain("- weird.md"); expect(out).toContain("- foo&bar.md"); // Ensure no HTML-style escaping happened. expect(out).not.toContain("<"); expect(out).not.toContain("&"); }); });