update
This commit is contained in:
@@ -1181,3 +1181,144 @@ async def test_namecheck_ok_behaelt_titel(testdb, tmp_path, monkeypatch):
|
||||
block = await db.kanban_get_card(TOPIC, B, "b-c9")
|
||||
assert block["payload"]["title"] == "Eigener Titel"
|
||||
assert block["payload"]["description"] == "Eigene Beschreibung"
|
||||
|
||||
|
||||
# ── Sanierung: Titel auf Korpus-Form, Beschreibungspflicht (QA: fremd/hygiene) ──────
|
||||
|
||||
def test_sanierung_schema_varianten():
|
||||
assert bi._sanierung_schema({"title": " k-Color ", "description": "d"}) == ("k-Color", "d")
|
||||
assert bi._sanierung_schema({"title": "", "description": "nur Beschreibung"}) == ("", "nur Beschreibung")
|
||||
assert bi._sanierung_schema({"title": "x" * 90, "description": "d"}) == ("", "d") # zu lang
|
||||
assert bi._sanierung_schema({"title": "", "description": ""}) is None
|
||||
assert bi._sanierung_schema("quatsch") is None
|
||||
|
||||
|
||||
def test_sanierung_noetig():
|
||||
ctoks = {"color", "graph"}
|
||||
assert bi._sanierung_noetig({"title": "k-Color", "description": ""}, ctoks) # leere Beschreibung
|
||||
assert bi._sanierung_noetig({"title": "k-Coloring", "description": "d"}, ctoks) # kein Korpus-Anker
|
||||
assert not bi._sanierung_noetig({"title": "k-Color", "description": "d"}, ctoks)
|
||||
assert not bi._sanierung_noetig({"title": "k-Coloring", "description": "d"}, None) # thema: kein Korpus
|
||||
|
||||
|
||||
def _sanierung_env(tmp_path, monkeypatch, antwort):
|
||||
"""Korpus mit 'k-Color'-Oberflächenform; Judge antwortet mit `antwort`."""
|
||||
(tmp_path / "korpus.txt").write_text(
|
||||
"Das k-Color Problem: Kann der Graph mit k Farben gefärbt werden? NP-vollständig.",
|
||||
encoding="utf-8")
|
||||
monkeypatch.setattr(bi, "source_folder", lambda t: tmp_path)
|
||||
seen = {}
|
||||
|
||||
async def fake_slot(ctx, label, *, key, prompt, role, capabilities, payload, timeout):
|
||||
seen[key] = prompt
|
||||
return "ok", payload((0, json.dumps(antwort["val"]), ""))
|
||||
|
||||
monkeypatch.setattr(bi, "run_single_slot", fake_slot)
|
||||
return GenContext(topic=TOPIC, provider="claude", is_cancelled=lambda: False), seen
|
||||
|
||||
|
||||
async def test_singleton_unverankert_wird_saniert(testdb, tmp_path, monkeypatch):
|
||||
"""Singleton-Cluster mit Reader-Titel ohne Korpus-Anker: Naming wird nicht mehr
|
||||
übersprungen — der Titel wird auf die Korpus-Oberflächenform umgeschrieben
|
||||
(gemessener aak-Fall 'k-Coloring' statt 'k-Color')."""
|
||||
db = testdb
|
||||
antwort = {"val": {"title": "k-Color", "description": "Kann der Graph mit k Farben gefärbt werden?"}}
|
||||
ctx, seen = _sanierung_env(tmp_path, monkeypatch, antwort)
|
||||
|
||||
async def fake_members(topic, cid):
|
||||
return [{"norm": "k-coloring", "title": "k-Coloring",
|
||||
"description": "Kann der Graph mit k Farben gefärbt werden?",
|
||||
"readers": ["r1", "r2"], "sources": []}]
|
||||
|
||||
monkeypatch.setattr(bi, "_member_rows", fake_members)
|
||||
payload = {"title": "k-Coloring", "description": "Kann der Graph mit k Farben gefärbt werden?"}
|
||||
await db.kanban_upsert_card(TOPIC, B, "c1", "cluster", "naming", payload)
|
||||
await bi._name_one(ctx, _mk_flow(tmp_path), {"card_id": "c1", "payload": payload})
|
||||
card = await db.kanban_get_card(TOPIC, B, "c1")
|
||||
assert card["stage"] == "naming_check"
|
||||
assert card["payload"]["title"] == "k-Color"
|
||||
assert any("-sanierung-" in k for k in seen)
|
||||
|
||||
|
||||
async def test_leere_beschreibung_wird_gefuellt(testdb, tmp_path, monkeypatch):
|
||||
"""Verankerter Titel, leere Beschreibung (gemessener aak-Fall der SetCover-Fragmente):
|
||||
Beschreibung wird belegt nachgefasst, Titel bleibt."""
|
||||
db = testdb
|
||||
antwort = {"val": {"title": "k-Color", "description": "Färbbarkeit mit k Farben."}}
|
||||
ctx, _seen = _sanierung_env(tmp_path, monkeypatch, antwort)
|
||||
|
||||
async def fake_members(topic, cid):
|
||||
return [{"norm": "k-color", "title": "k-Color", "description": "",
|
||||
"readers": ["r1"], "sources": []}]
|
||||
|
||||
monkeypatch.setattr(bi, "_member_rows", fake_members)
|
||||
payload = {"title": "k-Color", "description": ""}
|
||||
await db.kanban_upsert_card(TOPIC, B, "c5", "cluster", "naming", payload)
|
||||
await bi._name_one(ctx, _mk_flow(tmp_path), {"card_id": "c5", "payload": payload})
|
||||
card = await db.kanban_get_card(TOPIC, B, "c5")
|
||||
assert card["payload"]["title"] == "k-Color"
|
||||
assert card["payload"]["description"] == "Färbbarkeit mit k Farben."
|
||||
|
||||
|
||||
async def test_sanierung_unverankerter_vorschlag_verfaellt(testdb, tmp_path, monkeypatch):
|
||||
"""Judge-Vorschlag ohne Korpus-Anker wird verworfen (dieselbe Messlatte wie QA-fremd);
|
||||
die Beschreibung wird trotzdem übernommen."""
|
||||
db = testdb
|
||||
antwort = {"val": {"title": "Graphfärbungsproblem", "description": "Färbbarkeit mit k Farben."}}
|
||||
ctx, _seen = _sanierung_env(tmp_path, monkeypatch, antwort)
|
||||
|
||||
async def fake_members(topic, cid):
|
||||
return [{"norm": "k-coloring", "title": "k-Coloring",
|
||||
"description": "Kann der Graph mit k Farben gefärbt werden?",
|
||||
"readers": ["r1"], "sources": []}]
|
||||
|
||||
monkeypatch.setattr(bi, "_member_rows", fake_members)
|
||||
payload = {"title": "k-Coloring", "description": "Kann der Graph mit k Farben gefärbt werden?"}
|
||||
await db.kanban_upsert_card(TOPIC, B, "c2", "cluster", "naming", payload)
|
||||
await bi._name_one(ctx, _mk_flow(tmp_path), {"card_id": "c2", "payload": payload})
|
||||
card = await db.kanban_get_card(TOPIC, B, "c2")
|
||||
assert card["payload"]["title"] == "k-Coloring" # unverankert → verfällt
|
||||
assert card["stage"] == "naming_check"
|
||||
|
||||
|
||||
async def test_sanierung_fail_open(testdb, tmp_path, monkeypatch):
|
||||
"""Judge-Ausfall → Karte läuft unverändert weiter (kein Deadletter am Naming)."""
|
||||
db = testdb
|
||||
(tmp_path / "korpus.txt").write_text("Der Graph ist endlich.", encoding="utf-8")
|
||||
monkeypatch.setattr(bi, "source_folder", lambda t: tmp_path)
|
||||
|
||||
async def broken_slot(*a, **kw):
|
||||
return "failed", None
|
||||
|
||||
async def fake_members(topic, cid):
|
||||
return [{"norm": "x", "title": "Graph", "description": "", "readers": ["r1"], "sources": []}]
|
||||
|
||||
monkeypatch.setattr(bi, "run_single_slot", broken_slot)
|
||||
monkeypatch.setattr(bi, "_member_rows", fake_members)
|
||||
payload = {"title": "Graph", "description": ""}
|
||||
await db.kanban_upsert_card(TOPIC, B, "c3", "cluster", "naming", payload)
|
||||
ctx = GenContext(topic=TOPIC, provider="claude", is_cancelled=lambda: False)
|
||||
await bi._name_one(ctx, _mk_flow(tmp_path), {"card_id": "c3", "payload": payload})
|
||||
card = await db.kanban_get_card(TOPIC, B, "c3")
|
||||
assert card["stage"] == "naming_check" and card["payload"]["title"] == "Graph"
|
||||
|
||||
|
||||
async def test_sanierung_anker_und_beschreibung_ok_kein_judge(testdb, tmp_path, monkeypatch):
|
||||
"""Verankerter Titel + Beschreibung vorhanden → kein Sanierungs-Call."""
|
||||
db = testdb
|
||||
(tmp_path / "korpus.txt").write_text("Das k-Color Problem im Graph.", encoding="utf-8")
|
||||
monkeypatch.setattr(bi, "source_folder", lambda t: tmp_path)
|
||||
|
||||
async def never_slot(*a, **kw):
|
||||
raise AssertionError("Sanierung darf ohne Befund-Form nicht laufen")
|
||||
|
||||
async def fake_members(topic, cid):
|
||||
return [{"norm": "k-color", "title": "k-Color", "description": "d", "readers": ["r1"], "sources": []}]
|
||||
|
||||
monkeypatch.setattr(bi, "run_single_slot", never_slot)
|
||||
monkeypatch.setattr(bi, "_member_rows", fake_members)
|
||||
payload = {"title": "k-Color", "description": "d"}
|
||||
await db.kanban_upsert_card(TOPIC, B, "c4", "cluster", "naming", payload)
|
||||
ctx = GenContext(topic=TOPIC, provider="claude", is_cancelled=lambda: False)
|
||||
await bi._name_one(ctx, _mk_flow(tmp_path), {"card_id": "c4", "payload": payload})
|
||||
assert (await db.kanban_get_card(TOPIC, B, "c4"))["stage"] == "naming_check"
|
||||
|
||||
Reference in New Issue
Block a user