Add immutable revisions, PGVN editor, asset replacement, merge and rebase workflows, authenticated media delivery and reachability GC. Harden the script interpreter, pin unrpyc and remove tracked build metadata. Include current compatibility checks, Naninovel import and regression tests.
83 lines
3.9 KiB
Python
83 lines
3.9 KiB
Python
import json
|
|
|
|
import pytest
|
|
|
|
from app import translation as tr
|
|
from app.config import get_settings
|
|
from app.converter.pipeline import convert_archive
|
|
from tests.make_sample import build
|
|
|
|
|
|
@pytest.fixture
|
|
def manifest(tmp_path, monkeypatch):
|
|
monkeypatch.setenv("DATA_DIR", str(tmp_path / "data"))
|
|
get_settings.cache_clear()
|
|
archive = build(tmp_path / "sample.zip")
|
|
yield convert_archive(archive, "sample.zip", tmp_path / "work", lambda _: None).manifest
|
|
get_settings.cache_clear()
|
|
|
|
|
|
def test_index_has_context(manifest):
|
|
idx = tr.text_index(manifest)
|
|
first = idx.lines[0]
|
|
assert first.label == "start" and first.scene == "images/bg room.webp"
|
|
assert idx.lines[1].who == "Эйлин" and idx.lines[1].prev == first.source
|
|
assert idx.strings["Пойдём гулять"] == "menu" and idx.strings["Эйлин"] == "name"
|
|
|
|
|
|
def test_edit_new_language_and_outdated(manifest):
|
|
idx = tr.text_index(manifest)
|
|
tid = idx.lines[0].tid
|
|
m = tr.apply_changes(manifest, "de", lines={tid: {"t": "Willkommen", "state": "approved"}},
|
|
strings={"Эйлин": {"t": "Eileen"}}, meta={"glossary": [{"src": "Эйлин", "t": "Eileen"}]})
|
|
lines, strings, meta = tr.locale_tables(m, "de")
|
|
assert lines[tid]["t"] == "Willkommen" and lines[tid]["state"] == "translated" # no approve right
|
|
assert strings["Эйлин"]["t"] == "Eileen" and meta["glossary"][0]["t"] == "Eileen"
|
|
game = tr.file_json(m, "game.json")
|
|
assert game["locales"]["de"]["renpy"] == "german" and game["locales"]["de"]["lines"] == 1
|
|
# the original line changed in a mod: the translation is kept but marked outdated
|
|
info = idx.by_tid[tid]
|
|
changed = tr.LineInfo(**{**info.__dict__, "source": "другой текст"})
|
|
assert tr.line_state(lines[tid], changed) == "outdated"
|
|
# removing an entry
|
|
m2 = tr.apply_changes(m, "de", lines={tid: None})
|
|
assert tid not in tr.locale_tables(m2, "de")[0]
|
|
with pytest.raises(ValueError):
|
|
tr.apply_changes(manifest, "ru", lines={tid: {"t": "x"}}) # source language
|
|
|
|
|
|
def test_merge_languages_keeps_target_untouched(manifest):
|
|
tid = tr.text_index(manifest).lines[0].tid
|
|
fork = tr.apply_changes(manifest, "de", lines={tid: {"t": "Hallo"}})
|
|
assert tr.changed_languages(fork, manifest) == ["de"]
|
|
merged = tr.merge_languages(manifest, fork, ["de"])
|
|
assert tr.locale_tables(merged, "de")[0][tid]["t"] == "Hallo"
|
|
assert tr.locale_tables(merged, "en")[0] == tr.locale_tables(manifest, "en")[0]
|
|
assert "de" not in (tr.file_json(manifest, "game.json").get("locales") or {})
|
|
|
|
|
|
def test_three_way_publication_keeps_independent_lines(manifest):
|
|
a, b = [line.tid for line in tr.text_index(manifest).lines[:2]]
|
|
left = tr.apply_changes(manifest, "de", lines={a: {"t": "One"}})
|
|
right = tr.apply_changes(manifest, "de", lines={b: {"t": "Two"}})
|
|
merged, conflicts = tr.merge_translation(manifest, left, right)
|
|
assert not conflicts
|
|
lines = tr.locale_tables(merged, "de")[0]
|
|
assert lines[a]["t"] == "One" and lines[b]["t"] == "Two"
|
|
conflict = tr.apply_changes(manifest, "de", lines={a: {"t": "Other"}})
|
|
_, conflicts = tr.merge_translation(manifest, left, conflict)
|
|
assert conflicts and any(a in c["path"] for c in conflicts)
|
|
|
|
|
|
def test_po_and_csv_roundtrip(manifest):
|
|
tid = tr.text_index(manifest).lines[0].tid
|
|
m = tr.apply_changes(manifest, "de", lines={tid: {"t": "Zeile 1\nZeile \"2\""}},
|
|
strings={"Эйлин": {"t": "Eileen"}})
|
|
lines, strings = tr.parse_po(tr.export_po(m, "de", "Test"))
|
|
assert lines[tid]["t"] == "Zeile 1\nZeile \"2\"" and strings["Эйлин"]["t"] == "Eileen"
|
|
lines, strings = tr.parse_csv(tr.export_csv(m, "de"))
|
|
assert lines[tid]["t"] == "Zeile 1\nZeile \"2\"" and strings["Эйлин"]["t"] == "Eileen"
|
|
st = tr.stats(m, "de")
|
|
assert st["translated"] == 1 and st["stringsTranslated"] == 1
|
|
assert json.dumps(st)
|