Public Access
101 lines
4.0 KiB
Python
101 lines
4.0 KiB
Python
"""Unit tests for devx.i18n."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
import devx.i18n as i18n_mod
|
|
from devx.i18n import _, configure_i18n
|
|
|
|
|
|
class TestTranslate:
|
|
def test_returns_english_by_default(self) -> None:
|
|
with pytest.MonkeyPatch().context() as mp:
|
|
mp.delenv("DEVX_LANG", raising=False)
|
|
assert _("Running tests") == "Running tests"
|
|
|
|
def test_returns_key_when_missing(self) -> None:
|
|
with pytest.MonkeyPatch().context() as mp:
|
|
mp.delenv("DEVX_LANG", raising=False)
|
|
assert _("nonexistent.key.xyz") == "nonexistent.key.xyz"
|
|
|
|
def test_formats_kwargs(self) -> None:
|
|
# Find a key with format placeholders
|
|
for key, translations in i18n_mod.TRANSLATIONS.items():
|
|
en = translations.get("en", "")
|
|
if "{" in en:
|
|
with pytest.MonkeyPatch().context() as mp:
|
|
mp.delenv("DEVX_LANG", raising=False)
|
|
result = _(key, **dict.fromkeys(_extract_format_keys(en), "x"))
|
|
assert "{" not in result
|
|
return
|
|
pytest.skip("No key with format placeholders found")
|
|
|
|
def test_invalid_lang_falls_back_to_english(self) -> None:
|
|
with pytest.MonkeyPatch().context() as mp:
|
|
mp.setenv("DEVX_LANG", "fr")
|
|
assert _("Running tests") == "Running tests"
|
|
|
|
def test_bulgarian_translation(self) -> None:
|
|
with pytest.MonkeyPatch().context() as mp:
|
|
mp.setenv("DEVX_LANG", "bg")
|
|
# Find a key that has a Bulgarian translation
|
|
for key, translations in i18n_mod.TRANSLATIONS.items():
|
|
if "bg" in translations:
|
|
result = _(key)
|
|
assert result == translations["bg"]
|
|
return
|
|
pytest.skip("No Bulgarian translation found")
|
|
|
|
|
|
class TestConfigureI18n:
|
|
def test_custom_lang_env_var(self) -> None:
|
|
configure_i18n(lang_env_var="GRM_LANG")
|
|
try:
|
|
with pytest.MonkeyPatch().context() as mp:
|
|
mp.setenv("GRM_LANG", "bg")
|
|
mp.delenv("DEVX_LANG", raising=False)
|
|
# Find a key with Bulgarian translation
|
|
for key, translations in i18n_mod.TRANSLATIONS.items():
|
|
if "bg" in translations:
|
|
assert _(key) == translations["bg"]
|
|
return
|
|
pytest.skip("No Bulgarian translation found")
|
|
finally:
|
|
configure_i18n() # Reset to defaults
|
|
|
|
def test_custom_translations_path_env_var(self, tmp_path) -> None:
|
|
custom_translations = {"custom.key": {"en": "Custom Value", "bg": "Персонализирано"}}
|
|
custom_file = tmp_path / "custom.json"
|
|
custom_file.write_text(__import__("json").dumps(custom_translations))
|
|
|
|
configure_i18n(translations_path_env_var="GRM_TRANSLATIONS_PATH")
|
|
try:
|
|
# Use i18n_mod.TRANSLATIONS (not a stale import) — other tests
|
|
# may call importlib.reload(devx.i18n), replacing the dict object.
|
|
translations = i18n_mod.TRANSLATIONS
|
|
original = dict(translations)
|
|
translations.update(custom_translations)
|
|
try:
|
|
with pytest.MonkeyPatch().context() as mp:
|
|
mp.setenv("GRM_TRANSLATIONS_PATH", str(custom_file))
|
|
assert _("custom.key") == "Custom Value"
|
|
finally:
|
|
translations.clear()
|
|
translations.update(original)
|
|
finally:
|
|
configure_i18n() # Reset to defaults
|
|
|
|
def test_reset_to_defaults(self) -> None:
|
|
configure_i18n(lang_env_var="GRM_LANG")
|
|
configure_i18n() # Reset
|
|
assert i18n_mod._lang_env_var == "DEVX_LANG"
|
|
assert i18n_mod._translations_path_env_var == "DEVX_TRANSLATIONS_PATH"
|
|
|
|
|
|
def _extract_format_keys(template: str) -> list[str]:
|
|
"""Extract {key} format placeholders from a template string."""
|
|
import re
|
|
|
|
return re.findall(r"\{(\w+)\}", template)
|