#!/usr/bin/env python3
"""
Standalone test script for the l8n localization plugin.
This script tests the core functionality without MindRoot dependencies.
"""
import asyncio
import os
import re
from pathlib import Path
# Simulate the command decorator for testing
[docs]
def command():
def decorator(func):
return func
return decorator
# Copy the core functions from mod.py without MindRoot dependencies
TRANSLATIONS = {}
LOCALIZED_FILES_DIR = Path(__file__).parent / "localized_files"
[docs]
def get_localized_file_path(original_path: str) -> Path:
"""Convert an original file path to its localized version path."""
plugin_root = extract_plugin_root(original_path)
path = Path(plugin_root)
# Determine if this is a core plugin or external plugin
if any(core_plugin in plugin_root for core_plugin in ['chat', 'admin', 'l8n']):
# Core plugin
base_dir = LOCALIZED_FILES_DIR / "coreplugins"
else:
# External plugin
base_dir = LOCALIZED_FILES_DIR / "external_plugins"
# Add .i18n before the file extension
stem = path.stem
suffix = path.suffix
new_filename = f"{stem}.i18n{suffix}"
localized_path = base_dir / path.parent / new_filename
return localized_path
[docs]
async def write_localized_file(original_path: str, content: str, context=None):
"""Write a localized version of a file with static placeholders."""
try:
localized_path = get_localized_file_path(original_path)
# Create directory if it doesn't exist
localized_path.parent.mkdir(parents=True, exist_ok=True)
# Write the content
with open(localized_path, 'w', encoding='utf-8') as f:
f.write(content)
return f"Localized file written to: {localized_path}"
except Exception as e:
return f"Error writing localized file: {str(e)}"
[docs]
async def append_localized_file(original_path: str, content: str, context=None):
"""Append content to an existing localized file."""
try:
localized_path = get_localized_file_path(original_path)
# Create directory if it doesn't exist
localized_path.parent.mkdir(parents=True, exist_ok=True)
# Append the content
with open(localized_path, 'a', encoding='utf-8') as f:
f.write(content)
return f"Content appended to: {localized_path}"
except Exception as e:
return f"Error appending to localized file: {str(e)}"
[docs]
async def set_translations(language: str, translations: dict, context=None):
"""Set translations for a specific language."""
try:
if not isinstance(translations, dict):
return "Error: translations must be a dictionary"
# Validate translation keys
invalid_keys = []
for key in translations.keys():
if not re.match(r'^[a-z0-9_]+$', key):
invalid_keys.append(key)
if invalid_keys:
return f"Error: Invalid translation keys: {invalid_keys}"
# Store translations
if language not in TRANSLATIONS:
TRANSLATIONS[language] = {}
TRANSLATIONS[language].update(translations)
return f"Set {len(translations)} translations for language '{language}'. Total languages: {len(TRANSLATIONS)}"
except Exception as e:
return f"Error setting translations: {str(e)}"
[docs]
async def get_translations(language: str = None, context=None):
"""Get translations for a specific language or all languages."""
try:
if language:
return TRANSLATIONS.get(language, {})
else:
return TRANSLATIONS
except Exception as e:
return f"Error getting translations: {str(e)}"
[docs]
async def list_localized_files(context=None):
"""List all localized files that have been created."""
try:
localized_files = []
if LOCALIZED_FILES_DIR.exists():
for file_path in LOCALIZED_FILES_DIR.rglob("*.i18n.*"):
localized_files.append(str(file_path.relative_to(LOCALIZED_FILES_DIR)))
return {
"count": len(localized_files),
"files": sorted(localized_files)
}
except Exception as e:
return f"Error listing localized files: {str(e)}"
[docs]
def replace_placeholders(content: str, language: str) -> str:
"""Replace __TRANSLATE_key__ placeholders with actual translations."""
if language not in TRANSLATIONS:
return content
translations = TRANSLATIONS[language]
def replace_match(match):
key = match.group(1)
return translations.get(key, match.group(0)) # Return original if no translation
# Replace all __TRANSLATE_key__ patterns
return re.sub(r'__TRANSLATE_([a-z0-9_]+)__', replace_match, content)
[docs]
async def test_basic_functionality():
"""Test the basic l8n functionality."""
print("Testing MindRoot l8n Plugin (Standalone)...\n")
# Test 1: Create a localized file
print("1. Testing write_localized_file...")
test_path = "/files/mindroot/src/mindroot/coreplugins/chat/templates/chat.jinja2"
test_content = "<h1>__TRANSLATE_chat_title__</h1><button>__TRANSLATE_buttons_send__</button>"
result = await write_localized_file(test_path, test_content)
print(f" Result: {result}")
# Test 2: Append to the file
print("\n2. Testing append_localized_file...")
append_content = "<p>__TRANSLATE_welcome_message__</p>"
result = await append_localized_file(test_path, append_content)
print(f" Result: {result}")
# Test 3: Set translations
print("\n3. Testing set_translations...")
spanish_translations = {
'chat_title': 'Interfaz de Chat',
'buttons_send': 'Enviar Mensaje',
'welcome_message': 'Bienvenido al chat'
}
result = await set_translations('es', spanish_translations)
print(f" Result: {result}")
# Test 4: Set more translations
french_translations = {
'chat_title': 'Interface de Chat',
'buttons_send': 'Envoyer le Message',
'welcome_message': 'Bienvenue dans le chat'
}
result = await set_translations('fr', french_translations)
print(f" Result: {result}")
# Test 5: Get translations
print("\n4. Testing get_translations...")
es_translations = await get_translations('es')
print(f" Spanish translations: {es_translations}")
all_translations = await get_translations()
print(f" All languages: {list(all_translations.keys())}")
# Test 6: List localized files
print("\n5. Testing list_localized_files...")
files_result = await list_localized_files()
print(f" Result: {files_result}")
# Test 7: Test placeholder replacement
print("\n6. Testing placeholder replacement...")
test_template = "<h1>__TRANSLATE_chat_title__</h1><button>__TRANSLATE_buttons_send__</button><p>__TRANSLATE_welcome_message__</p>"
spanish_result = replace_placeholders(test_template, 'es')
print(f" Spanish: {spanish_result}")
french_result = replace_placeholders(test_template, 'fr')
print(f" French: {french_result}")
# Test 8: Test with unknown language (should return original)
unknown_result = replace_placeholders(test_template, 'de')
print(f" German (unknown): {unknown_result}")
# Test 9: Check created file content
print("\n7. Checking created file content...")
localized_path = get_localized_file_path(test_path)
if localized_path.exists():
with open(localized_path, 'r', encoding='utf-8') as f:
file_content = f.read()
print(f" File content: {repr(file_content)}")
# Test replacement on actual file content
spanish_file_result = replace_placeholders(file_content, 'es')
print(f" Spanish version: {spanish_file_result}")
else:
print(f" File not found: {localized_path}")
print("\n✅ All tests completed!")
if __name__ == "__main__":
asyncio.run(test_basic_functionality())