Catalogue: classify collection into system/faction/force-org class
- dlphelper/warhammer_data.py: keyword taxonomy (40k factions incl. Chaos and Xenos super-faction units, plus AoS/Heresy/Kill Team/Necromunda/Epic/OW) - dlphelper/catalogue.py: manifest+directory scanner, conservative keyword classifier (plural-tolerant word boundaries, longest match wins), markdown and jsonl reports, overrides support, audited --apply moves - catalogue.py CLI; tests/test_catalogue.py offline classifier test - real-data check on the user's dirs: 1624/3333 files classified so far
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Offline classifier test for the catalogue (no network, no deps).
|
||||
|
||||
Run with: python3 tests/test_catalogue.py
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||
|
||||
from dlphelper.catalogue import classify # noqa: E402
|
||||
|
||||
CASES = [
|
||||
# (filename, expected system, expected faction, expected class or None-any)
|
||||
("Thunderwolf Cavalry.7z", "Warhammer 40,000", "Adeptus Astartes", "Fast Attack"),
|
||||
("Wulfen.zip", "Warhammer 40,000", "Adeptus Astartes", "Elites"),
|
||||
("Keeper of Secrets & Shalaxi Helbane.7z", "Warhammer 40,000", "Chaos Daemons", "HQ"),
|
||||
("Assorted Drones.zip", "Warhammer 40,000", "T'au Empire", None),
|
||||
("Commander Shadowsun.zip", "Warhammer 40,000", "T'au Empire", "HQ"),
|
||||
("Devilfish.zip", "Warhammer 40,000", "T'au Empire", "Dedicated Transport"),
|
||||
("Battle Sister Scanz.zip", "Warhammer 40,000", "Adepta Sororitas", None),
|
||||
("Knights.zip", None, None, None), # ambiguous keyword alone: unclassified
|
||||
("Khorne Demon Enginez and skull lordz.zip", "Warhammer 40,000", "Chaos Daemons", None),
|
||||
("Cultists.zip", "Warhammer 40,000", "Chaos Space Marines", "Elites"),
|
||||
("Da Troopz.zip", "Warhammer 40,000", "Orks", None),
|
||||
("Seraphon.zip", "Other Systems", "Age of Sigmar", None),
|
||||
("Leviathan Dreadnought.zip", "Warhammer 40,000", "Adeptus Astartes", "Elites"),
|
||||
("Poxwalkers.zip", "Warhammer 40,000", "Death Guard", "Elites"),
|
||||
("Kabalite Warriors.zip", "Warhammer 40,000", "Drukhari", "Troops"),
|
||||
("Canoptek Wraiths.zip", "Warhammer 40,000", "Necrons", "Fast Attack"),
|
||||
("random thing with no keywords.zip", None, None, None),
|
||||
]
|
||||
|
||||
|
||||
def main() -> None:
|
||||
failures = 0
|
||||
for name, exp_system, exp_faction, exp_class in CASES:
|
||||
system, faction, klass = classify(name)
|
||||
problems = []
|
||||
if exp_system and system != exp_system:
|
||||
problems.append(f"system={system!r} != {exp_system!r}")
|
||||
if exp_faction and faction != exp_faction:
|
||||
problems.append(f"faction={faction!r} != {exp_faction!r}")
|
||||
if exp_class and klass != exp_class:
|
||||
problems.append(f"class={klass!r} != {exp_class!r}")
|
||||
if problems:
|
||||
failures += 1
|
||||
print(f"FAIL {name!r}: {', '.join(problems)}")
|
||||
else:
|
||||
print(f"ok {name!r} -> {system} / {faction} / {klass}")
|
||||
if failures:
|
||||
print(f"\n{failures} failures")
|
||||
sys.exit(1)
|
||||
print("\ntest_catalogue: OK")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user