Files
hapi/ios/scripts/tests/test_localizations.py
T

86 lines
4.0 KiB
Python

import copy
import io
import json
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
import localizations
class LocalizationTests(unittest.TestCase):
def test_check_detects_automatic_entries_without_writing(self):
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "Localizable.xcstrings"
data = {"sourceLanguage": "en", "strings": {"Test": {}}, "version": "1.0"}
path.write_text(json.dumps(data), encoding="utf-8")
before = path.read_bytes()
result = subprocess.run([sys.executable, localizations.__file__, "--check", str(path)], capture_output=True)
self.assertEqual(result.returncode, 1)
self.assertEqual(path.read_bytes(), before)
data["strings"]["Test"]["extractionState"] = "manual"
path.write_text(json.dumps(data), encoding="utf-8")
result = subprocess.run([sys.executable, localizations.__file__, "--check", str(path)], capture_output=True)
self.assertEqual(result.returncode, 0, result.stderr)
def test_duplicate_keys_are_rejected(self):
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "Localizable.xcstrings"
path.write_text('{"strings":{"Test":{},"Test":{}}}', encoding="utf-8")
with self.assertRaisesRegex(ValueError, "Duplicate JSON key"):
localizations.load_catalog(path)
def test_fix_preserves_concurrent_edits(self):
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "Localizable.xcstrings"
original = {"sourceLanguage": "en", "strings": {"Test": {}}, "version": "1.0"}
path.write_text(json.dumps(original), encoding="utf-8")
edited = json.dumps({**original, "strings": {"New edit": {}}}).encode("utf-8")
def normalize_while_editing(data):
self.assertEqual(data, original)
path.write_bytes(edited)
return b"must not overwrite the edit"
with patch.object(sys, "argv", [localizations.__file__, "--fix", str(path)]), \
patch.object(localizations, "normalize", side_effect=normalize_while_editing), \
patch.object(sys, "stderr", new_callable=io.StringIO) as stderr:
self.assertEqual(localizations.main(), 1)
self.assertIn("Catalog changed while normalizing", stderr.getvalue())
self.assertEqual(path.read_bytes(), edited)
@unittest.skipUnless(sys.platform == "darwin", "Native formatting requires Xcode")
def test_xcode_normalization_preserves_content_and_is_idempotent(self):
data = {
"sourceLanguage": "en",
"strings": {
"zebra": {"extractionState": "stale", "comment": "Keep this comment", "localizations": {
"zh-Hans": {"stringUnit": {"state": "translated", "value": "斑马 🦓\n"}},
}},
"%lld items": {"localizations": {"en": {"variations": {"plural": {
"one": {"stringUnit": {"state": "translated", "value": "%lld item"}},
"other": {"stringUnit": {"state": "translated", "value": "%lld items"}},
}}}}},
"https://example.com/a": {"shouldTranslate": False},
"Untranslated": {},
},
"version": "1.0",
}
original = copy.deepcopy(data)
first = localizations.normalize(data)
self.assertEqual(data, original)
parsed = json.loads(first)
for key, entry in original["strings"].items():
self.assertEqual(parsed["strings"][key], {**entry, "extractionState": "manual"})
self.assertEqual(set(parsed["strings"]), set(original["strings"]))
self.assertIn(b'"sourceLanguage" : "en"', first)
self.assertEqual(first, localizations.normalize(parsed))
if __name__ == "__main__":
unittest.main()