Files
asepharyana 608b52a0e5 feat(server): port /describe and /improve tools + real analytics
Phase 8 (extras) complete:
- describe.ts — full port of pr_description: type/title/description/diagram/
  per-file walkthrough table, PATCH /pulls to update description, optional
  labels. Verified live: PR #19 body updated with AI description (Type,
  Description bullets, mermaid diagram, file walkthrough table).
- improve.ts — full port of pr_code_suggestions summarize path:
  getPrMultiDiffs chunking, parallel LLM calls, score filtering, category
  table with unified diff snippets + persistent comment with history.
  Verified live: persistent update of existing '## PR Code Suggestions ✨'
  comment (updated_at 07:26:53) with new table.
- prompts.ts — verbatim pr_description_prompts.toml + code_suggestions prompts
- github.ts — getLineLink (SHA-256 diff anchor like pr_agent), getLabels,
  updateDescription (pulls.update); getPrMultiDiffs in diff.ts
- index.ts — real analytics: readLegacy pr-agent.*.log files (mtime-sorted,
  fixes pid-filename ordering bug), logReviewEvent writes legacy-format
  events, /api/metrics + /api/analytics now serve real data (427 events,
  per-command breakdown)
- cli.ts — --tool review|describe|improve
- tests 16/16, tsc clean
2026-09-21 14:36:02 +07:00

39 lines
1.4 KiB
TypeScript

// Tests for the PR description tool helpers (pure functions).
import { describe, expect, test } from "bun:test";
import {
deriveLabels,
sanitizeDiagram,
insertBrAfterXChars,
} from "../src/describe";
describe("describe helpers", () => {
test("deriveLabels from type list", () => {
expect(deriveLabels({ type: ["Bug fix", "Enhancement"] })).toEqual([
"Bug fix",
"Enhancement",
]);
expect(deriveLabels({ type: "Bug fix, Tests" })).toEqual(["Bug fix", "Tests"]);
expect(deriveLabels({ labels: ["Bug fix"], type: ["Other"] })).toEqual(["Bug fix"]);
expect(deriveLabels({})).toEqual([]);
});
test("sanitizeDiagram strips fences and rejects non-diagrams", () => {
expect(sanitizeDiagram("```mermaid\nflowchart LR\n A --> B\n```")).toBe(
"flowchart LR\n A --> B",
);
expect(sanitizeDiagram("plain text without diagram")).toBe("");
expect(sanitizeDiagram("")).toBe("");
expect(sanitizeDiagram("graph TD\n A --> B")).toBe("graph TD\n A --> B");
});
test("insertBrAfterXChars wraps long text", () => {
const long = "a".repeat(80);
const wrapped = insertBrAfterXChars(long, 70);
expect(wrapped).toContain("<br>");
expect(wrapped.replace(/<br>/g, "")).toBe(long);
// html tags don't count toward the budget
const withTag = insertBrAfterXChars("<code>abcdef</code>", 70);
expect(withTag.length).toBe("<code>abcdef</code>".length);
});
});