This commit is contained in:
DazedAnon 2026-07-09 08:30:49 -05:00
parent 944b03c0c7
commit 30853060ca
2 changed files with 54 additions and 64 deletions

View file

@ -615,14 +615,14 @@ class WolfWorkflowTab(QWidget):
_tab_defs = [
("0 Project", self._build_step0),
("1 Pre-process", self._build_step1_preprocess),
("2 Glossary", self._build_step1_glossary),
("2 Glossary", self._build_step2_glossary),
("3 Names", self._build_step3_names),
("4 Database", self._build_step4_database),
("5 Maps/Events", self._build_step5_maps_events),
("6 Precheck", self._build_step6_precheck),
("7 Inject", self._build_step4_inject),
("8 Package", self._build_step5_package),
("9 Fix wrap", self._build_step7_relayout),
("7 Inject", self._build_step7_inject),
("8 Package", self._build_step8_package),
("9 Fix wrap", self._build_step9_relayout),
]
self._step_labels = [label for label, _ in _tab_defs]
@ -1738,7 +1738,7 @@ class WolfWorkflowTab(QWidget):
# ── Step 2: Glossary ───────────────────────────────────────────────────────
def _build_step1_glossary(self, layout: QVBoxLayout):
def _build_step2_glossary(self, layout: QVBoxLayout):
layout.addWidget(_make_section_label("Step 2 · Glossary (build before translating)"))
layout.addWidget(self._desc(
"vocab.txt is the project-wide glossary used by every translation batch to keep "
@ -2353,7 +2353,7 @@ class WolfWorkflowTab(QWidget):
lambda: tt.start_translation(skip_confirm=True) if tt is not None else None,
)
# ── Step 2: Names ──────────────────────────────────────────────────────────
# ── Step 3: Names ──────────────────────────────────────────────────────────
def _build_step3_names(self, layout: QVBoxLayout):
layout.addWidget(_make_section_label("Step 3 · Translate Name Values (names.json)"))
@ -2520,7 +2520,7 @@ class WolfWorkflowTab(QWidget):
# ── Step 7: Inject ─────────────────────────────────────────────────────────
def _build_step4_inject(self, layout: QVBoxLayout):
def _build_step7_inject(self, layout: QVBoxLayout):
layout.addWidget(_make_section_label("Step 7 · Inject Translations"))
layout.addWidget(self._desc(
"Tick translated JSON files below, then inject them into the game's Data/ "
@ -2604,7 +2604,7 @@ class WolfWorkflowTab(QWidget):
))
self._refresh_inject_list()
def _build_step7_relayout(self, layout: QVBoxLayout):
def _build_step9_relayout(self, layout: QVBoxLayout):
"""Search-first fix wrapping: find sheet by in-game text, wrap, re-inject."""
layout.addWidget(_make_section_label("Step 9 · Fix wrapping"))
layout.addWidget(self._desc(
@ -3903,7 +3903,7 @@ class WolfWorkflowTab(QWidget):
# ── Step 8: Package (+ optional saves) ─────────────────────────────────────
def _build_step5_package(self, layout: QVBoxLayout):
def _build_step8_package(self, layout: QVBoxLayout):
layout.addWidget(_make_section_label("Step 8 · Package the Translated Game"))
layout.addWidget(self._desc(
"Make the injected build playable so you can spot overflow in-game, then "

View file

@ -141,12 +141,18 @@ TXTDIR_DOC = {
class TestCollectEntries(unittest.TestCase):
def test_counts_per_kind(self):
self.assertEqual(len(wd.collectEntries(MAP_DOC)), 2)
self.assertEqual(len(wd.collectEntries(DB_DOC)), 1)
self.assertEqual(len(wd.collectEntries(GAMEDAT_DOC)), 1)
# All name leaves, including verify — safety filtering is in parseDocument.
self.assertEqual(len(wd.collectEntries(NAMES_DOC)), 3)
self.assertEqual(len(wd.collectEntries(TXTDIR_DOC)), 1)
# Live .env may still have a DB sheet filter from the last GUI run.
orig_filter = wd.wolf_db.load_db_filter_config
wd.wolf_db.load_db_filter_config = lambda: (frozenset(), frozenset())
try:
self.assertEqual(len(wd.collectEntries(MAP_DOC)), 2)
self.assertEqual(len(wd.collectEntries(DB_DOC)), 1)
self.assertEqual(len(wd.collectEntries(GAMEDAT_DOC)), 1)
# All name leaves, including verify - safety filtering is in parseDocument.
self.assertEqual(len(wd.collectEntries(NAMES_DOC)), 3)
self.assertEqual(len(wd.collectEntries(TXTDIR_DOC)), 1)
finally:
wd.wolf_db.load_db_filter_config = orig_filter
class TestTranslationWriteback(unittest.TestCase):
@ -248,20 +254,15 @@ class TestTranslationWriteback(unittest.TestCase):
self.assertEqual(data["scenes"][0]["lines"][0]["text"], "こんにちは")
def test_collect_pass_does_not_mutate_or_write(self):
"""Batch collect must not reflow JP into text or overwrite translated/."""
"""Batch collect must not overwrite translated/ with Japanese source."""
orig_phase = os.environ.get("BATCH_PHASE")
os.environ["BATCH_PHASE"] = "collect"
orig_wrap = wd.WRAP
orig_width = wd.WRAPWIDTH
wd.WRAP = True
wd.WRAPWIDTH = 20
try:
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
(root / "files").mkdir()
(root / "translated").mkdir()
doc = copy.deepcopy(MAP_DOC)
# A long JP line that wrap would reflow if write-back ran.
doc["scenes"][0]["lines"][0]["source"] = "" * 40
doc["scenes"][0]["lines"][0]["text"] = "" * 40
src_path = root / "files" / "Map001.mps.json"
@ -292,56 +293,45 @@ class TestTranslationWriteback(unittest.TestCase):
'{"kind":"map","marker":"keep-me"}',
)
finally:
wd.WRAP = orig_wrap
wd.WRAPWIDTH = orig_width
if orig_phase is None:
os.environ.pop("BATCH_PHASE", None)
else:
os.environ["BATCH_PHASE"] = orig_phase
def test_echoed_source_does_not_get_wrapped_into_text(self):
"""If the model/collect echoes JP source, leave text alone even with wrap on."""
orig_wrap = wd.WRAP
orig_width = wd.WRAPWIDTH
wd.WRAP = True
wd.WRAPWIDTH = 10
def test_echoed_source_does_not_overwrite_text(self):
"""If the model/collect echoes JP source, leave text alone."""
doc = {
"kind": "map",
"scenes": [
{
"event": 1,
"name": "ev",
"lines": [
{
"cmd": 0,
"str": 0,
"source": "あいうえおかきくけこさしすせそ",
"text": "あいうえおかきくけこさしすせそ",
},
],
}
],
}
def echo(text, history, history_ctx=None):
return [text if isinstance(text, list) else text, [1, 1]]
orig_t = wd.translateAI
wd.translateAI = echo
try:
doc = {
"kind": "map",
"scenes": [
{
"event": 1,
"name": "ev",
"lines": [
{
"cmd": 0,
"str": 0,
"source": "あいうえおかきくけこさしすせそ",
"text": "あいうえおかきくけこさしすせそ",
},
],
}
],
}
def echo(text, history, history_ctx=None):
return [text if isinstance(text, list) else text, [1, 1]]
orig_t = wd.translateAI
wd.translateAI = echo
try:
data, _tok, err = wd.parseDocument(copy.deepcopy(doc), "echo.mps.json")
finally:
wd.translateAI = orig_t
self.assertIsNone(err)
# Must still be the unbroken source, not a wrapped JP reflow.
self.assertEqual(
data["scenes"][0]["lines"][0]["text"],
"あいうえおかきくけこさしすせそ",
)
data, _tok, err = wd.parseDocument(copy.deepcopy(doc), "echo.mps.json")
finally:
wd.WRAP = orig_wrap
wd.WRAPWIDTH = orig_width
wd.translateAI = orig_t
self.assertIsNone(err)
self.assertEqual(
data["scenes"][0]["lines"][0]["text"],
"あいうえおかきくけこさしすせそ",
)
def test_skips_already_translated_text(self):
doc = {