// Testet die reine Urteils-/Blocker-Parselogik des /optimize-Loops. // Diese Funktionen entscheiden, ob der Coder einen Fix bekommt — Regressionen hier sind kritisch. import { test } from "node:test"; import assert from "node:assert/strict"; import { extractFn } from "./helpers.mjs"; const parseVerdict = extractFn("parseVerdict"); const parseBlockers = extractFn("parseBlockers"); const normalizeForComparison = extractFn("normalizeForComparison"); const licenceMd = extractFn("licenceMd"); test("parseVerdict: klares PASS", () => { assert.equal(parseVerdict("Review fertig.\nUrteil: PASS\nKeine Blocker."), "PASS"); }); test("parseVerdict: FAIL", () => { assert.equal(parseVerdict("Urteil: FAIL"), "FAIL"); }); test("parseVerdict: PASS WITH CONCERNS wird NICHT als PASS verkürzt (kritisch für Fix-Auslösung)", () => { // Würde die Regex hier 'PASS' zuerst matchen, käme kein Coder-Fix zustande. assert.equal(parseVerdict("Urteil: PASS WITH CONCERNS"), "PASS WITH CONCERNS"); }); test("parseVerdict: case-insensitiv und mit Bullet-Präfix", () => { assert.equal(parseVerdict("- urteil: pass with concerns"), "PASS WITH CONCERNS"); }); test("parseVerdict: ohne erkennbares Urteil → UNREADABLE", () => { assert.equal(parseVerdict("Sieht solide aus, keine Anmerkungen."), "UNREADABLE"); }); test("parseBlockers: extrahiert Bullet-Blocker und stoppt vor Major", () => { const txt = "- Blocker: B1 Argument-Handling unklar\n- Major: M1 chmod fehlt"; const blockers = parseBlockers(txt); assert.match(blockers, /B1 Argument-Handling/); assert.doesNotMatch(blockers, /M1/); }); test("parseBlockers: erkennt **Blocker**-Überschrift und stoppt vor Minor", () => { const txt = "**Blocker**\nKaputter Import in main.py\n**Minor**\nTippfehler"; const blockers = parseBlockers(txt); assert.match(blockers, /Kaputter Import/); assert.doesNotMatch(blockers, /Tippfehler/); }); test("parseBlockers: leer, wenn kein Blocker-Abschnitt vorhanden", () => { assert.equal(parseBlockers("Urteil: PASS\nAlles in Ordnung."), ""); }); test("normalizeForComparison: Whitespace-Kollaps, Kleinschreibung, trailing-Satzzeichen", () => { assert.equal( normalizeForComparison(" Blocker A. "), normalizeForComparison("blocker a") ); }); test("normalizeForComparison: gleiche Blocker trotz Formatierungsunterschied → Loop-Erkennung greift", () => { const a = "- Race Condition in waitForIdle!"; const b = "Race condition in waitForIdle"; assert.notEqual(normalizeForComparison(a), ""); // sanity assert.equal( normalizeForComparison(a.replace(/^- /, "")), normalizeForComparison(b) ); }); test("licenceMd: proprietärer Default mit eingesetztem Jahr und Inhaber", () => { const txt = licenceMd("2026", "Dieter Schlüter"); assert.match(txt, /^# Lizenz/); assert.match(txt, /Copyright \(c\) 2026 Dieter Schlüter/); assert.match(txt, /Alle Rechte vorbehalten\./); assert.match(txt, /ohne vorherige ausdrückliche schriftliche/); assert.match(txt, /OHNE MÄNGELGEWÄHR/); }); test("licenceMd: Platzhalter-Inhaber wird unverändert eingesetzt", () => { assert.match(licenceMd("2030", "[Rechteinhaber eintragen]"), /Copyright \(c\) 2030 \[Rechteinhaber eintragen\]/); });