Emit a ### Changed Files Markdown table (| File | +/− | Type | rows plus total added/removed) ahead of the raw diff in both committed and uncommitted review prompts, parsed from the diff via the shared parseDiff engine. Add an ### Excluded Files (n) section listing filtered noise (path, +/− counts, reason), and replace byte-truncation of oversized diffs with a file-list + read instruction when the cleaned diff exceeds 50KB or touches more than 20 files. Also: distinguish diff-computation failure from genuinely no changes in the review loop (tri-state result, never treats a broken base ref as a clean verified task), map critical→blocker in finding severity parsing, inject a per-review custom focus/instructions section from config, and make the noise-filter ignore rules project-configurable via review.extraIgnorePatterns and review.ignorePaths. Add same-model retry before cycling to the next model in task/follow-up/fix sessions.
54 lines
1.8 KiB
TypeScript
54 lines
1.8 KiB
TypeScript
/**
|
|
* Tests for the severity taxonomy alignment in review verdict parsing
|
|
* (src/review.ts): the `critical` token is accepted and normalized to
|
|
* ralpi's `blocker` severity, mirroring @piex-dev/review's grading.
|
|
*/
|
|
|
|
import { describe, test, expect } from "bun:test";
|
|
import { extractReview } from "../src/review";
|
|
|
|
/** Build a full review-agent output ending in a REVIEW VERDICT block. */
|
|
function reviewOutput(findings: string[]): string {
|
|
return [
|
|
"Prose: looks mostly fine, a few issues to fix.",
|
|
"## REVIEW VERDICT",
|
|
"VERDICT: fail",
|
|
"SUMMARY: Needs fixes.",
|
|
"FINDINGS:",
|
|
...findings,
|
|
].join("\n");
|
|
}
|
|
|
|
describe("extractReview severity normalization", () => {
|
|
test("maps critical → blocker, keeps warning/nit/info", () => {
|
|
const out = reviewOutput([
|
|
"- [critical] src/auth.ts:12 hardcoded secret",
|
|
"- [warning] src/auth.ts:30 unused import",
|
|
"- [nit] src/auth.ts:5 style",
|
|
"- [info] src/auth.ts:1 note",
|
|
]);
|
|
const review = extractReview(out, "01", "abc1234");
|
|
expect(review).not.toBeNull();
|
|
const severities = review!.findings.map((f) => f.severity);
|
|
expect(severities).toEqual(["blocker", "warning", "nit", "info"]);
|
|
});
|
|
|
|
test("normalizes the warn synonym to warning", () => {
|
|
const out = reviewOutput(["- [warn] src/a.ts:2 thing"]);
|
|
const review = extractReview(out, "01", "abc1234");
|
|
expect(review!.findings[0].severity).toBe("warning");
|
|
});
|
|
|
|
test("uppercase CRITICAL token also maps to blocker", () => {
|
|
const out = reviewOutput(["- [CRITICAL] src/a.ts:2 thing"]);
|
|
const review = extractReview(out, "01", "abc1234");
|
|
expect(review!.findings[0].severity).toBe("blocker");
|
|
});
|
|
|
|
test("findings without a severity are still parsed", () => {
|
|
const out = reviewOutput(["- src/a.ts:2 plain line"]);
|
|
const review = extractReview(out, "01", "abc1234");
|
|
expect(review!.findings[0].severity).toBe("info");
|
|
});
|
|
});
|