autocal layout first design
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
"""Locale files: same keys everywhere, and a real fallback.
|
||||
|
||||
``Translator`` returns the key itself when a string is missing, which is silent
|
||||
in production — a label would simply read ``axes.nope``. The studio suite guards
|
||||
this by comparing key sets; the same guard applies here.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from orisys_autocal.preferences import load_preferences
|
||||
|
||||
LOCALES = Path(__file__).resolve().parents[1] / "config" / "locales"
|
||||
LANGUAGES = ("zh_CN", "en_US")
|
||||
|
||||
|
||||
def _load(language: str) -> dict:
|
||||
return json.loads((LOCALES / f"{language}.json").read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def _flatten(node: dict, prefix: str = "") -> set[str]:
|
||||
keys: set[str] = set()
|
||||
for key, value in node.items():
|
||||
path = f"{prefix}{key}"
|
||||
if isinstance(value, dict):
|
||||
keys |= _flatten(value, f"{path}.")
|
||||
else:
|
||||
keys.add(path)
|
||||
return keys
|
||||
|
||||
|
||||
def test_every_locale_file_exists():
|
||||
for language in LANGUAGES:
|
||||
assert (LOCALES / f"{language}.json").is_file(), language
|
||||
|
||||
|
||||
def test_locales_have_identical_key_sets():
|
||||
reference = _flatten(_load("zh_CN"))
|
||||
for language in LANGUAGES[1:]:
|
||||
other = _flatten(_load(language))
|
||||
assert other == reference, {
|
||||
f"{language}_only": sorted(other - reference),
|
||||
f"zh_CN_only": sorted(reference - other),
|
||||
}
|
||||
|
||||
|
||||
def test_no_translation_is_empty_where_a_label_is_expected():
|
||||
"""A blank string renders as an empty widget, which looks like a bug."""
|
||||
for language in LANGUAGES:
|
||||
for key, value in _walk(_load(language)):
|
||||
assert str(value).strip(), f"{language}: {key} is blank"
|
||||
|
||||
|
||||
def test_the_product_name_is_localised():
|
||||
"""The window title is Chinese in zh_CN and English in en_US."""
|
||||
assert _load("zh_CN")["app"]["title"] != _load("en_US")["app"]["title"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("language", LANGUAGES)
|
||||
def test_every_locale_loads_through_the_translator(language):
|
||||
from orisys_app_shared.i18n import Translator
|
||||
|
||||
translator = Translator(LOCALES, locale=language)
|
||||
for key in sorted(_flatten(_load(language))):
|
||||
assert translator.t(key) != key, f"{language}: {key} did not resolve"
|
||||
|
||||
|
||||
def test_the_default_preferences_file_matches_the_schema_shape():
|
||||
"""A shipped default that names a key the app does not have is dead weight."""
|
||||
shipped = json.loads(
|
||||
(LOCALES.parent / "preferences.default.json").read_text(encoding="utf-8")
|
||||
)
|
||||
schema = load_preferences()
|
||||
for key in shipped:
|
||||
assert key in schema, f"preferences.default.json has an unknown key: {key}"
|
||||
|
||||
|
||||
def _walk(node, prefix: str = ""):
|
||||
for key, value in node.items():
|
||||
path = f"{prefix}{key}"
|
||||
if isinstance(value, dict):
|
||||
yield from _walk(value, f"{path}.")
|
||||
else:
|
||||
yield path, value
|
||||
Reference in New Issue
Block a user