"""Auto-Repair-Loop-Primitive: Stopp bei 100 %, Stillstand (unbewegt), Limit.""" import auto_loop async def test_fertig_ohne_repair(): async def rep(): raise AssertionError("darf bei 100 % nie reparieren") r = await auto_loop.auto_repair_loop("x", 10.0, rep) assert r == {"ebene": "x", "note": 10.0, "runden": 0, "grund": "fertig"} async def test_verbessert_bis_voll(): noten = iter([9.0, 10.0]) async def rep(): return next(noten), True r = await auto_loop.auto_repair_loop("inv", 8.0, rep) # 8.0 → 9.0 → 10.0 assert r["grund"] == "fertig" and r["runden"] == 2 async def test_stillstand(): async def rep(): return 8.0, False # nichts getan, Note steht r = await auto_loop.auto_repair_loop("art", 8.0, rep) assert r["grund"] == "stillstand" and r["runden"] == 1 assert r["note"] == 8.0 async def test_bewegt_ohne_notengewinn_laeuft_weiter(): """Eine bewegte Runde (z. B. Lücken-Research senkt die Note transient) ist KEIN Stillstand — erst unbewegt + keine Verbesserung stoppt; max_iter begrenzt Livelocks.""" laeufe = iter([(7.5, True), (8.0, True), (8.0, False)]) async def rep(): return next(laeufe) r = await auto_loop.auto_repair_loop("inv", 8.0, rep) assert r["grund"] == "stillstand" and r["runden"] == 3 async def test_limit(): stand = {"n": 1.0} async def rep(): stand["n"] += 0.1 # verbessert stetig, erreicht aber nie 10.0 return stand["n"], True r = await auto_loop.auto_repair_loop("guide", 1.0, rep, max_iter=10) assert r["grund"] == "limit" and r["runden"] == 10