Files
mai-bot/pytests/prompt_test/test_prompt_i18n.py
2026-03-13 02:36:08 +09:00

128 lines
4.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from __future__ import annotations
from pathlib import Path
import pytest
from src.common.i18n import set_locale
from src.common.prompt_i18n import clear_prompt_cache, load_prompt, list_prompt_templates
from src.prompt.prompt_manager import PromptManager
@pytest.fixture(autouse=True)
def clear_prompt_i18n_cache() -> None:
set_locale("zh-CN")
clear_prompt_cache()
yield
clear_prompt_cache()
set_locale("zh-CN")
def write_prompt(prompt_dir: Path, locale: str | None, name: str, content: str) -> None:
base_dir = prompt_dir if locale is None else prompt_dir / locale
base_dir.mkdir(parents=True, exist_ok=True)
(base_dir / f"{name}.prompt").write_text(content, encoding="utf-8")
def test_load_prompt_prefers_requested_locale(tmp_path: Path) -> None:
prompts_root = tmp_path / "prompts"
write_prompt(prompts_root, "zh-CN", "replyer", "你好,{user_name}")
write_prompt(prompts_root, "en-US", "replyer", "Hello, {user_name}")
rendered = load_prompt("replyer", locale="en-US", prompts_root=prompts_root, user_name="Mai")
assert rendered == "Hello, Mai"
def test_load_prompt_falls_back_to_default_locale(tmp_path: Path) -> None:
prompts_root = tmp_path / "prompts"
write_prompt(prompts_root, "zh-CN", "replyer", "你好,{user_name}")
rendered = load_prompt("replyer", locale="en-US", prompts_root=prompts_root, user_name="Mai")
assert rendered == "你好Mai"
def test_load_prompt_does_not_fall_back_to_legacy_root(tmp_path: Path) -> None:
prompts_root = tmp_path / "prompts"
write_prompt(prompts_root, None, "replyer", "Legacy {user_name}")
with pytest.raises(FileNotFoundError):
load_prompt("replyer", locale="en-US", prompts_root=prompts_root, user_name="Mai")
def test_load_prompt_with_category_falls_back_to_default_locale_root(tmp_path: Path) -> None:
prompts_root = tmp_path / "prompts"
write_prompt(prompts_root, "zh-CN", "replyer", "你好,{user_name}")
rendered = load_prompt("replyer", locale="en-US", category="chat", prompts_root=prompts_root, user_name="Mai")
assert rendered == "你好Mai"
def test_load_prompt_strict_mode_raises_on_missing_placeholder(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
prompts_root = tmp_path / "prompts"
write_prompt(prompts_root, "zh-CN", "replyer", "你好,{user_name},现在是 {current_time}")
monkeypatch.setenv("MAIBOT_PROMPT_I18N_STRICT", "1")
with pytest.raises(KeyError) as exc_info:
load_prompt("replyer", locale="zh-CN", prompts_root=prompts_root, user_name="Mai")
assert "current_time" in str(exc_info.value)
def test_load_prompt_rejects_path_traversal(tmp_path: Path) -> None:
prompts_root = tmp_path / "prompts"
write_prompt(prompts_root, "zh-CN", "replyer", "你好")
with pytest.raises(ValueError):
load_prompt("../replyer", locale="zh-CN", prompts_root=prompts_root)
def test_list_prompt_templates_prefers_locale_specific_files(tmp_path: Path) -> None:
prompts_root = tmp_path / "prompts"
write_prompt(prompts_root, "zh-CN", "replyer", "中文")
write_prompt(prompts_root, "en-US", "replyer", "English")
set_locale("en-US")
prompt_templates = list_prompt_templates(prompts_root=prompts_root)
assert prompt_templates["replyer"].read_text(encoding="utf-8") == "English"
def test_list_prompt_templates_reports_duplicate_name_with_custom_root(tmp_path: Path) -> None:
prompts_root = tmp_path / "prompts"
first_dir = prompts_root / "zh-CN" / "chat"
second_dir = prompts_root / "zh-CN" / "system"
first_dir.mkdir(parents=True, exist_ok=True)
second_dir.mkdir(parents=True, exist_ok=True)
(first_dir / "replyer.prompt").write_text("chat", encoding="utf-8")
(second_dir / "replyer.prompt").write_text("system", encoding="utf-8")
with pytest.raises(ValueError) as exc_info:
list_prompt_templates(prompts_root=prompts_root)
assert "zh-CN/chat/replyer.prompt" in str(exc_info.value)
assert "zh-CN/system/replyer.prompt" in str(exc_info.value)
def test_prompt_manager_load_prompts_prefers_locale_dir(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
prompts_root = tmp_path / "prompts"
custom_prompts_root = tmp_path / "data" / "custom_prompts"
custom_prompts_root.mkdir(parents=True, exist_ok=True)
write_prompt(prompts_root, "zh-CN", "replyer", "中文模板")
write_prompt(prompts_root, "en-US", "replyer", "English template")
set_locale("en-US")
monkeypatch.setattr("src.prompt.prompt_manager.PROMPTS_DIR", prompts_root, raising=False)
monkeypatch.setattr("src.prompt.prompt_manager.CUSTOM_PROMPTS_DIR", custom_prompts_root, raising=False)
monkeypatch.setattr("src.prompt.prompt_manager.SUFFIX_PROMPT", ".prompt", raising=False)
manager = PromptManager()
manager.load_prompts()
assert manager.get_prompt("replyer").template == "English template"