update
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user