DazedTL/tests/test_wolf_names.py
2026-07-09 08:04:53 -05:00

215 lines
7.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""Unit tests for WolfDawn names.json helpers in util/wolfdawn/names.py."""
from __future__ import annotations
import json
import os
import sys
import tempfile
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
os.chdir(ROOT)
sys.path.insert(0, str(ROOT))
from util.wolfdawn import names as wn # noqa: E402
class TestNameTranslatable(unittest.TestCase):
def test_safe_is_translatable(self):
self.assertTrue(wn.is_name_translatable({"safety": "safe"}))
def test_refs_verify_and_missing_are_not_translatable(self):
self.assertFalse(wn.is_name_translatable({"safety": "refs"}))
self.assertFalse(wn.is_name_translatable({"safety": "verify"}))
self.assertFalse(wn.is_name_translatable({}))
self.assertFalse(wn.is_name_translatable({"safety": ""}))
class TestVocabHarvestCandidate(unittest.TestCase):
def test_short_weapon_name_harvests(self):
entry = {"source": "ダガー", "note": "武器", "safety": "safe"}
self.assertTrue(wn.is_vocab_harvest_candidate(entry))
def test_multiline_profile_skipped(self):
entry = {
"source": "セルリアと申します。\nよろしくお願いいたします。",
"note": "├■プロフィール",
"safety": "safe",
}
self.assertFalse(wn.is_vocab_harvest_candidate(entry))
def test_profile_note_skipped_even_when_single_line(self):
entry = {"source": "ローザだ。", "note": "├■プロフィール", "safety": "safe"}
self.assertFalse(wn.is_vocab_harvest_candidate(entry))
def test_resistance_label_still_harvests(self):
entry = {"source": "物理50軽減", "note": "┣ 属性耐性", "safety": "safe"}
self.assertTrue(wn.is_vocab_harvest_candidate(entry))
class TestCountNameSafety(unittest.TestCase):
DOC = {
"kind": "names",
"names": [
{"source": "a", "safety": "safe"},
{"source": "b", "safety": "refs"},
{"source": "c", "safety": "verify"},
{"source": "d"},
],
}
def test_counts_badges(self):
counts = wn.count_name_safety(self.DOC)
self.assertEqual(counts["safe"], 1)
self.assertEqual(counts["refs"], 1)
self.assertEqual(counts["verify"], 1)
self.assertEqual(counts["unknown"], 1)
self.assertEqual(counts["translatable"], 1)
def test_summary_mentions_translatable_count(self):
summary = wn.format_name_safety_summary(self.DOC)
self.assertIn("1 of 4", summary)
self.assertIn("verify", summary)
class TestNoteHeader(unittest.TestCase):
def test_static_fallback_is_bilingual(self):
self.assertEqual(wn.note_header("武器"), "Weapon · 武器")
def test_live_db_label_wins_over_static(self):
labels = {"武器": "Blade"}
self.assertEqual(wn.note_header("武器", labels), "Blade · 武器")
def test_unknown_note_stays_japanese_only(self):
self.assertEqual(wn.note_header("■MOBセリフ"), "■MOBセリフ")
class TestCollectNameNotes(unittest.TestCase):
DOC = {
"kind": "names",
"names": [
{"source": "a", "note": "武器"},
{"source": "b", "note": "技能"},
{"source": "c", "note": "武器"},
{"source": "d"},
],
}
def test_collects_unique_sorted_notes(self):
self.assertEqual(wn.collect_name_notes(self.DOC), ["技能", "武器"])
class TestDeriveDbLabels(unittest.TestCase):
def setUp(self):
self._tmp = tempfile.TemporaryDirectory()
self.dir = Path(self._tmp.name)
def tearDown(self):
self._tmp.cleanup()
def test_parses_bilingual_typenames_from_db_files(self):
(self.dir / "DataBase.project.json").write_text(
json.dumps({
"kind": "db",
"groups": [
{"typeName": "Weapon · 武器", "lines": []},
{"typeName": "Skill · 技能", "lines": []},
],
}),
encoding="utf-8",
)
labels = wn.derive_db_labels(self.dir)
self.assertEqual(labels, {"武器": "Weapon", "技能": "Skill"})
def test_missing_dir_returns_empty(self):
self.assertEqual(wn.derive_db_labels(self.dir / "nope"), {})
class TestNameWrapRoles(unittest.TestCase):
def setUp(self):
self._tmp = tempfile.TemporaryDirectory()
self.dir = Path(self._tmp.name)
self.names = self.dir / "names.json"
self.names.write_text("{}", encoding="utf-8")
def tearDown(self):
self._tmp.cleanup()
def test_upsert_load_and_update_name_wrap_role(self):
roles_path = wn.roles_json_path_for_names(self.names)
self.assertEqual(roles_path, self.dir / "wolfdawn-roles.json")
wn.upsert_name_wrap_role(roles_path, "説明", width=40, font=14)
wn.upsert_name_wrap_role(roles_path, "説明", width=52, max_lines=4)
role = wn.get_name_wrap_role(wn.load_name_wrap_roles(roles_path), "説明")
self.assertEqual(role["width"], 52)
self.assertEqual(role["maxLines"], 4)
self.assertEqual(role["font"], 14)
class TestNameReconcile(unittest.TestCase):
def test_glossary_wins_over_divergent_extracts(self):
names = {
"kind": "names",
"names": [{"source": "牧場主", "text": "Rancher", "safety": "safe"}],
}
db = {
"kind": "db",
"groups": [
{
"type": 1,
"lines": [
{"source": "牧場主", "text": "Ranch Owner"},
{"source": "牧場主", "text": "Rancher"},
{"source": "牧場主", "text": "牧場主"},
],
}
],
}
report = wn.reconcile_names_to_glossary(names, {"DataBase.project.json": db})
self.assertEqual(report.changed, 2) # Owner + identity → Rancher
texts = [ln["text"] for ln in db["groups"][0]["lines"]]
self.assertEqual(texts, ["Rancher", "Rancher", "Rancher"])
self.assertTrue(all(c.reason == "glossary" for c in report.changes))
def test_majority_when_glossary_still_japanese(self):
names = {
"kind": "names",
"names": [{"source": "魔獣マニア", "text": "魔獣マニア", "safety": "refs"}],
}
db = {
"kind": "db",
"groups": [
{
"type": 1,
"lines": [
{"source": "魔獣マニア", "text": "Beast Maniac"},
{"source": "魔獣マニア", "text": "Monster Beast Maniac"},
{"source": "魔獣マニア", "text": "Monster Beast Maniac"},
],
}
],
}
report = wn.reconcile_names_to_glossary(names, {"DataBase.project.json": db})
self.assertEqual(report.changed, 1)
self.assertEqual(report.changes[0].new_text, "Monster Beast Maniac")
self.assertEqual(report.changes[0].reason, "majority")
texts = [ln["text"] for ln in db["groups"][0]["lines"]]
self.assertEqual(
texts,
["Monster Beast Maniac", "Monster Beast Maniac", "Monster Beast Maniac"],
)
def test_tie_breaks_lexicographically(self):
chosen, reason = wn.choose_canonical(
"牧場主",
"牧場主",
{"Ranch Owner": 4, "Rancher": 4},
)
self.assertEqual(reason, "majority")
self.assertEqual(chosen, "Ranch Owner")
if __name__ == "__main__":
unittest.main()