From d565718922a7c29be95bf30f6e2201b88af2b8c4 Mon Sep 17 00:00:00 2001 From: mvalentsev Date: Mon, 13 Apr 2026 10:14:32 +0500 Subject: [PATCH] fix: address i18n review issues from PR #718 Three issues flagged by bensig on the i18n PR before merge: 1. ko.json: status_drawers used {drawers} instead of {count}, causing the Korean UI to show the raw template string instead of the actual drawer count. All other 7 languages use {count}. 2. Test file was shipped inside the package at mempalace/i18n/test_i18n.py with a sys.path.insert hack. Moved to tests/test_i18n.py per the project convention in AGENTS.md. 3. Dialect.from_config() passed lang=config.get("lang") which defaults to None, causing __init__ to inherit whatever language was loaded earlier via module-level state. Now defaults to "en" explicitly so from_config is deterministic regardless of prior load_lang() calls. Added two regression tests for the ko.json fix and the state leak. --- mempalace/dialect.py | 2 +- mempalace/i18n/ko.json | 2 +- {mempalace/i18n => tests}/test_i18n.py | 32 ++++++++++++++------------ 3 files changed, 19 insertions(+), 17 deletions(-) rename {mempalace/i18n => tests}/test_i18n.py (81%) diff --git a/mempalace/dialect.py b/mempalace/dialect.py index 3c51c52..b72c52c 100644 --- a/mempalace/dialect.py +++ b/mempalace/dialect.py @@ -362,7 +362,7 @@ class Dialect: return cls( entities=config.get("entities", {}), skip_names=config.get("skip_names", []), - lang=config.get("lang"), + lang=config.get("lang", "en"), ) def save_config(self, config_path: str): diff --git a/mempalace/i18n/ko.json b/mempalace/i18n/ko.json index 4ff37c7..bb8aea1 100644 --- a/mempalace/i18n/ko.json +++ b/mempalace/i18n/ko.json @@ -25,7 +25,7 @@ "status_palace": "궁전: {path}", "status_wings": "날개 {count}개", "status_closets": "벽장 {count}개", - "status_drawers": "서랍 {drawers}개", + "status_drawers": "서랍 {count}개", "init_complete": "{path}에 궁전 초기화 완료", "init_exists": "{path}에 궁전이 이미 존재합니다", "repair_complete": "수리 완료. {fixed}개 문제 해결.", diff --git a/mempalace/i18n/test_i18n.py b/tests/test_i18n.py similarity index 81% rename from mempalace/i18n/test_i18n.py rename to tests/test_i18n.py index e362c26..50e0044 100644 --- a/mempalace/i18n/test_i18n.py +++ b/tests/test_i18n.py @@ -1,11 +1,4 @@ -#!/usr/bin/env python3 -"""Quick smoke test for i18n dictionaries + Dialect integration.""" - -import sys -from pathlib import Path - -# Add parent to path so we can import mempalace -sys.path.insert(0, str(Path(__file__).resolve().parents[2])) +"""Smoke tests for i18n dictionaries + Dialect integration.""" from mempalace.i18n import load_lang, t, available_languages from mempalace.dialect import Dialect @@ -75,10 +68,19 @@ def test_dialect_compress_samples(): print(" PASS: compression works for all sample languages") -if __name__ == "__main__": - print("i18n smoke tests:") - test_all_languages_load() - test_interpolation() - test_dialect_loads_lang() - test_dialect_compress_samples() - print("\nAll tests passed.") +def test_korean_status_drawers_uses_count(): + """ko.json status_drawers must use {count}, not {drawers}.""" + load_lang("ko") + result = t("cli.status_drawers", count=42) + assert "42" in result, f"Expected '42' in '{result}' -- count variable not interpolated" + + +def test_from_config_defaults_to_english(tmp_path): + """Dialect.from_config without a lang key must not inherit module-level state.""" + load_lang("ko") # pollute module-level _current_lang + + config_path = tmp_path / "config.json" + config_path.write_text('{"entities": {}}') + + d = Dialect.from_config(str(config_path)) + assert d.lang == "en", f"Expected 'en', got '{d.lang}' -- state leak from prior load_lang"