import os, sys, tempfile, yaml sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) from taxonomy import classify ONT = {"version": "test", "assignment_rule": {"threshold": 1.0}, "categories": [ {"id": "llm", "number": 1, "name": "LLM", "child_of": "foundation_models", "openalex_topics": [{"id": "T10028", "weight": 0.6}], "keywords": [{"pattern": r"(?i)\blarge language models?\b", "weight": 1.0, "field": "both"}], "arxiv_categories": [{"id": "cs.CL", "weight": 0.4}]}, {"id": "foundation_models", "number": 2, "name": "FM", "openalex_topics": [{"id": "T10028", "weight": 0.6}], "keywords": [{"pattern": r"(?i)\bfoundation models?\b", "weight": 1.0}]}, {"id": "crypto", "number": 27, "name": "Crypto", "openalex_topics": [{"id": "T11000", "weight": 1.0}], "exclusions": [r"(?i)\bcryptocurrency\b"], "dblp_streams": [{"key": "conf/crypto", "weight": 1.0}]}, ]} def setup_module(module): d = tempfile.mkdtemp(); p = os.path.join(d, "ont.yaml"); yaml.safe_dump(ONT, open(p, "w")); classify._init(p) def test_keyword_alone_reaches_threshold_and_child_wins_tie(): res = classify.score_row("Scaling large language models", "", [], [], [], []) ids = {r[0] for r in res}; assert ids == {"llm"} res = classify.score_row("Foundation models and large language models", "", [10028], [], [], []) scores = {r[0]: r[3] for r in res}; assert scores["llm"] == 1.6 and scores["foundation_models"] == 1.6 parents = {r[2] for r in res if r[2]} best = sorted(res, key=lambda r: (-r[3], 1 if r[0] in parents else 0, r[1]))[0]; assert best[0] == "llm" def test_signal_types_capped_and_summed(): res = classify.score_row("x", "y", [10028, 10028, 10028], [], ["cs.CL"], []) s = {r[0]: r for r in res}; assert "llm" in s and s["llm"][4] == 0.6 and s["llm"][6] == 0.4 and abs(s["llm"][3] - 1.0) < 1e-6 def test_exclusion_vetoes(): assert {r[0] for r in classify.score_row("Lattice signatures", "", [11000], [], [], [])} == {"crypto"} assert classify.score_row("Cryptocurrency price prediction", "", [11000], [], [], []) == [] assert {r[0] for r in classify.score_row("a", "b", [], [], [], ["conf/crypto"])} == {"crypto"}