Files
Termind/Scripts/Tests/test_cjk_localization.py
T

122 lines
5.8 KiB
Python

from __future__ import annotations
import importlib.util
from pathlib import Path
import unittest
SPEC = importlib.util.spec_from_file_location(
"check_localization", Path(__file__).resolve().parents[1] / "check-cjk-localization.py"
)
assert SPEC is not None and SPEC.loader is not None
CHECK = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(CHECK)
def catalog(key: str, value: str, state: str = "translated") -> dict:
return {
"sourceLanguage": "en",
"strings": {key: {"localizations": {"ja": {"stringUnit": {"state": state, "value": value}}}}},
}
def japanese_problems(data):
return CHECK.problems(data, languages=("ja",))
class JapaneseLocalizationTests(unittest.TestCase):
def test_rejects_spaces_in_both_directions_for_all_japanese_scripts(self):
for value in ["日本語 API", "API 日本語", "ひらがな SSH", "SSH ひらがな", "サーバ API", "API サーバ",
"サーバ\tSSH", "SSH\u00a0サーバ", "サーバ\u3000SSH", "3 台", "サーバ 3"]:
with self.subTest(value=value):
self.assertTrue(any("spacing" in p for p in japanese_problems(catalog("Label", value))))
def test_retains_english_protocol_spaces_and_japanese_label_spacing(self):
for key, value in [("Label", "ssh user@hostで接続"), ("Label", "種類 不明"), ("Label", "SSHサーバ"),
("Type %@", "種類 %@"), ("Type %@", "種類 %1$@")]:
with self.subTest(value=value):
self.assertEqual(japanese_problems(catalog(key, value)), [])
def test_type_exception_is_narrow(self):
self.assertTrue(japanese_problems(catalog("Label %@", "種類 %@")))
self.assertTrue(japanese_problems(catalog("Type %@", "種類 %@")))
self.assertTrue(japanese_problems(catalog("Type %@", "種類 %@の SSH鍵")))
def test_reordered_arguments_keep_their_original_types(self):
self.assertEqual(japanese_problems(catalog("%lld on %@", "%2$@で%1$lld件")), [])
self.assertTrue(japanese_problems(catalog("%lld on %@", "%1$@で%2$lld件")))
self.assertTrue(japanese_problems(catalog("%lld on %@", "%@で%lld件")))
def test_rejects_lost_arguments_and_literal_percent(self):
self.assertTrue(japanese_problems(catalog("%lld%% complete", "%lld完了")))
self.assertTrue(japanese_problems(catalog("Host %@", "ホスト")))
self.assertEqual(japanese_problems(catalog("%lld%% complete", "%lld%%完了")), [])
def test_uses_localized_english_value_for_metadata_keys(self):
data = catalog("NSCameraUsageDescription", "カメラを使用します。")
data["strings"]["NSCameraUsageDescription"]["localizations"]["en"] = {
"stringUnit": {"state": "translated", "value": "Use the camera."}
}
self.assertEqual(japanese_problems(data), [])
def test_rejects_missing_unfinished_and_empty_translations(self):
data = catalog("Settings", "設定")
data["strings"]["Settings"]["localizations"] = {}
self.assertTrue(japanese_problems(data))
self.assertTrue(japanese_problems(catalog("Settings", "設定", "needs_review")))
self.assertTrue(japanese_problems(catalog("Settings", "")))
self.assertEqual(japanese_problems(catalog("", "")), [])
def test_checks_plural_units_and_rejects_non_japanese_categories(self):
data = catalog("%lld files", "%lld個のファイル")
localizations = data["strings"]["%lld files"]["localizations"]
unit = localizations["ja"]
localizations["en"] = {"variations": {"plural": {
"one": {"stringUnit": {"state": "translated", "value": "%lld file"}},
"other": {"stringUnit": {"state": "translated", "value": "%lld files"}},
}}}
self.assertTrue(japanese_problems(data))
localizations["ja"] = {"variations": {"plural": {"other": unit}}}
self.assertEqual(japanese_problems(data), [])
unit["stringUnit"]["value"] = "%lld ファイル"
self.assertTrue(japanese_problems(data))
unit["stringUnit"]["value"] = "%lld個のファイル"
localizations["ja"]["variations"]["plural"]["one"] = unit
self.assertTrue(japanese_problems(data))
def test_respects_nontranslatable_entries(self):
data = catalog("Identifier", "")
data["strings"]["Identifier"]["shouldTranslate"] = False
self.assertEqual(japanese_problems(data), [])
class ChineseLocalizationTests(unittest.TestCase):
def check(self, key, value, language):
data = catalog(key, value)
localizations = data["strings"][key]["localizations"]
localizations[language] = localizations.pop("ja")
return CHECK.problems(data, languages=(language,))
def test_preserves_chinese_spacing_and_punctuation_checks(self):
for language in ["zh-Hans", "zh-Hant"]:
for value in ["中文 SSH", "SSH 中文", "中文,", "中文: SSH", "SSH :中文"]:
with self.subTest(language=language, value=value):
self.assertTrue(self.check("Label", value, language))
self.assertEqual(self.check("Label", "中文SSH", language), [])
def test_preserves_type_subtitle_exception(self):
for language, label in [("zh-Hans", "类型"), ("zh-Hant", "類型")]:
self.assertEqual(self.check("Type %@", label + " %@", language), [])
self.assertTrue(self.check("Other %@", label + " %@", language))
def test_shared_validation_requires_every_supported_language(self):
data = catalog("Settings", "設定")
failures = CHECK.problems(data)
self.assertEqual(len(failures), 2)
self.assertTrue(any("zh-Hans" in failure for failure in failures))
self.assertTrue(any("zh-Hant" in failure for failure in failures))
if __name__ == "__main__":
unittest.main()