This commit is contained in:
team3
2026-07-03 12:50:32 +02:00
parent 9754cbcfae
commit 91b0d00aa1
27 changed files with 203 additions and 580 deletions

View File

@@ -764,3 +764,78 @@ def test_per_block_functions_accept_wrapper_kwargs():
assert "seeds" in inspect.signature(blx._subblocks_block).parameters
for fn in ("_subblocks_block", "_facts_block"): # Board 2 reicht die Block-Quellen durch
assert "sources" in inspect.signature(getattr(blx, fn)).parameters, fn
# ── Inventar-Härtung: Sanitizer, Akronym-Regel, Supplement-Beleg ─────────────────────
def test_clean_title_strips_markdown_only():
"""`**` und Backticks fliegen; Math-Zeichen (|, _, einzelnes *) bleiben."""
from textkit import clean_title
assert clean_title("**ListScheduling**") == "ListScheduling"
assert clean_title("**LPT** - Algo") == "LPT - Algo"
assert clean_title("`code` doppelt") == "code doppelt"
assert clean_title("2|prec, pi∈{1,2}|Cmax") == "2|prec, pi∈{1,2}|Cmax"
assert clean_title("x_i und P*") == "x_i und P*"
def test_title_variants_acronym_expansion():
from blocks import _title_variants
assert _title_variants("Satisfiability Problem (SAT)") == {"satisfiability problem", "sat"}
assert _title_variants("DEA (Deterministischer Endlicher Automat)") == {
"dea", "deterministischer endlicher automat"}
assert _title_variants("SAT") == set()
assert _title_variants("2|prec, pi∈{1,2}|Cmax") == set()
async def test_dedup_acronym_pair_judged(board_env, tmp_path, monkeypatch, emb_on):
"""Kurzform vs. Langform liegt unterm Embedding-Floor (real: Cos 0.53) — die
Akronym-Regel macht das Paar trotzdem zum Kandidaten, das Panel merged bei 2× ja."""
monkeypatch.setattr(bi, "_vec_rows", _angle_vecs({})) # alles orthogonal
counter = {}
monkeypatch.setattr(bi, "run_single_slot", _slot_router([
("-dedup-", {"pairs": {"1": "ja"}}),
], counter))
await _run_dedup(board_env[0], board_env[1], tmp_path, [
("b-1", {"title": "SAT", "description": "kurz"}),
("b-2", {"title": "Satisfiability Problem (SAT)", "description": "lang"}),
])
stages = sorted([(await board_env[0].kanban_get_card(TOPIC, B, c))["stage"]
for c in ("b-1", "b-2")])
assert stages == ["grouped", "grouping"]
assert counter["-dedup-"] == 2 # Panel lief — kein Auto-Merge
async def test_supplement_beleg_gate(board_env, tmp_path, monkeypatch):
"""Ohne Auszugs-Treffer fällt ein Vorschlag sofort; der Judge verwirft „nein";
nur belegte Vorschläge überleben. Antwort ist Text (no-tool), Engine persistiert."""
db, ctx, files = board_env
korpus = tmp_path / "korpus"
korpus.mkdir()
(korpus / "Skript.txt").write_text(
"Kapitel 1\nVertex Cover Definition und Übung dazu.\nMatching Grundlagen kurz.\n",
encoding="utf-8")
monkeypatch.setattr(bi, "source_folder", lambda t: korpus)
calls = {}
async def fake_slot(ctx2, label, *, key, prompt, role, capabilities, payload, timeout, on_line=None):
calls["key"], calls["caps"], calls["prompt"] = key, capabilities, prompt
return bi.OK, payload((0, '{"relevant": {"1": "ja", "2": "nein"}}', ""))
monkeypatch.setattr(bi, "run_single_slot", fake_slot)
kept = await bi._supplement_beleg(ctx, _mk_flow(tmp_path), [
("Vertex Cover", "Knotenüberdeckung"),
("Matching", "Paarung"),
("Quantencomputer", "nicht im Material"),
])
assert kept == [("Vertex Cover", "Knotenüberdeckung")]
assert calls["caps"] == "none" and "-supplement-beleg" in calls["key"]
assert "Quantencomputer" not in calls["prompt"] # fiel schon am Auszugs-Filter
assert (tmp_path / "supplement-beleg.json").exists() # Resume-Guard
async def test_ingest_strips_markdown_title(testdb, tmp_path):
flow = _mk_flow(tmp_path)
n = await bi._ingest_titles(flow, "1. **ListScheduling** — Greedy-Verfahren", "r1")
assert n == 1
card = await testdb.kanban_get_card(TOPIC, B, "listscheduling")
assert card["payload"]["title"] == "ListScheduling"

View File

@@ -117,7 +117,7 @@ async def test_learnstate_smoke(testdb):
"""Regression: P5-Ausbau hatte die _LEVEL_CASE-Konstante mitgerissen —
load_learnstate (Guide-Start-Pfad) muss ohne NameError laufen."""
from rules import load_learnstate
guides, progress, levels = await load_learnstate()
guides, levels = await load_learnstate()
assert isinstance(levels, dict)