AUDIT / src /lib /__tests__ /buildFailureHandler.test.ts
Arypulka98's picture
feat(audit): deploy full backend cluster node (part 2)
cc11e77 verified
Raw
History Blame Contribute Delete
5.4 kB
/**
* buildFailureHandler.test.ts — Build Failure Handler (S40)
* 14 test: action mapping, priority, targetFiles, instructions, DI, guards
*/
import { describe, it, expect, beforeEach } from "vitest";
import {
handleBuildFailure,
shouldUseCriticMode,
extractTargetFiles,
_setTestHandler,
_resetHandler,
} from "@/lib/buildFailureHandler";
beforeEach(() => _resetHandler());
// ── handleBuildFailure ────────────────────────────────────────────────────
describe("handleBuildFailure", () => {
it("1. errore triviale → action=patch, priority=low", () => {
const d = handleBuildFailure("Unused variable 'x' at line 5.");
expect(d.action).toBe("patch");
expect(d.priority).toBe("low");
});
it("2. errore serio → action ≠ patch o almeno priority >= medium", () => {
const d = handleBuildFailure("Cannot find module '@/lib/missing'");
// action può essere patch/rewrite/split ma priority NON può essere low
if (d.action === "patch") {
expect(["medium", "high", "critical"]).toContain(d.priority);
} else {
expect(["rewrite", "split", "escalate"]).toContain(d.action);
}
});
it("3. retryCount >= 3 → action=escalate, priority=critical", () => {
const d = handleBuildFailure("Cannot find module '@/missing'", { retryCount: 3 });
expect(d.action).toBe("escalate");
expect(d.priority).toBe("critical");
});
it("4. action=split → priority=high", () => {
// Forza split_task via DI
_setTestHandler({
classify: () => "serious",
analyze: () => ({
scope: "systemic", strategy: "split_task", confidence: 0.6,
reason: "Too many retries", affectedFiles: [],
suggestedAction: "split it", escalate: false,
}),
});
const d = handleBuildFailure("any error", { retryCount: 2 });
expect(d.priority).toBe("high");
});
it("5. instructions è stringa non vuota", () => {
const d = handleBuildFailure("Build error occurred");
expect(typeof d.instructions).toBe("string");
expect(d.instructions.length).toBeGreaterThan(10);
});
it("6. instructions contiene [PATCH] per azione patch", () => {
_setTestHandler({
classify: () => "trivial",
analyze: () => ({
scope: "local", strategy: "patch", confidence: 0.9,
reason: "trivial", affectedFiles: ["src/foo.ts"],
suggestedAction: "fix it", escalate: false,
}),
});
const d = handleBuildFailure("Unused variable");
expect(d.instructions).toContain("[PATCH]");
});
it("7. instructions contiene [ESCALATE] per action=escalate", () => {
const d = handleBuildFailure("Cannot find module '@/lib/missing'", { retryCount: 4 });
expect(d.instructions).toContain("[ESCALATE]");
});
it("8. targetFiles è array (anche vuoto)", () => {
const d = handleBuildFailure("Generic build error");
expect(Array.isArray(d.targetFiles)).toBe(true);
});
it("9. targetFiles include i file se l'errore li contiene", () => {
const d = handleBuildFailure(
"Error in src/lib/taskClassifier.ts: Cannot find module",
);
expect(d.targetFiles.some(f => f.includes("taskClassifier.ts"))).toBe(true);
});
it("10. usesCriticMode=true per errore serio", () => {
const d = handleBuildFailure("Cannot find module '@/lib/planner'");
expect(d.usesCriticMode).toBe(true);
});
it("10b. usesCriticMode=false per errore triviale + retryCount=0", () => {
const d = handleBuildFailure("Unused variable 'x'.");
expect(d.usesCriticMode).toBe(false);
});
it("11. errorSummary è stringa ≤ 200 char", () => {
const longErr = "E".repeat(500);
const d = handleBuildFailure(longErr);
expect(d.errorSummary.length).toBeLessThanOrEqual(200);
});
it("12. tutti i campi obbligatori presenti", () => {
const d = handleBuildFailure("Any error");
const keys: (keyof typeof d)[] = [
"action", "priority", "targetFiles", "instructions", "usesCriticMode", "errorSummary",
];
for (const k of keys) {
expect(d).toHaveProperty(k);
}
});
});
// ── shouldUseCriticMode ───────────────────────────────────────────────────
describe("shouldUseCriticMode", () => {
it("13. cannot find module → true", () => {
expect(shouldUseCriticMode("Cannot find module '@/foo'")).toBe(true);
});
it("13b. unused variable → false", () => {
expect(shouldUseCriticMode("Unused variable 'y'.")).toBe(false);
});
it("13c. retryCount=2 → true qualunque errore", () => {
expect(shouldUseCriticMode("Minor warning", 2)).toBe(true);
});
});
// ── extractTargetFiles ────────────────────────────────────────────────────
describe("extractTargetFiles", () => {
it("14. estrae file da errore con path", () => {
const files = extractTargetFiles("Error in src/core/agentLoop.ts line 42");
expect(files.some(f => f.includes("agentLoop.ts"))).toBe(true);
});
it("14b. nessun path → array (anche vuoto, non crasha)", () => {
const files = extractTargetFiles("Build failed.");
expect(Array.isArray(files)).toBe(true);
});
});