124 lines
4.7 KiB
Python
124 lines
4.7 KiB
Python
"""
|
|
Tests for prompt templates and PromptLoader module.
|
|
Task 1: Test prompt template files exist with variable placeholders.
|
|
Task 2: Test PromptLoader loads and renders templates correctly.
|
|
"""
|
|
import pytest
|
|
from pathlib import Path
|
|
|
|
# Path to prompts directory
|
|
PROMPTS_DIR = Path(__file__).parent.parent / "src" / "gsd_openclaw" / "prompts"
|
|
|
|
|
|
class TestPromptTemplatesExist:
|
|
"""Test that prompt template files exist and contain variable placeholders."""
|
|
|
|
def test_context_recovery_template_exists(self):
|
|
"""context_recovery.md template exists."""
|
|
template_path = PROMPTS_DIR / "context_recovery.md"
|
|
assert template_path.exists(), f"Template not found: {template_path}"
|
|
|
|
def test_command_mapping_template_exists(self):
|
|
"""command_mapping.md template exists."""
|
|
template_path = PROMPTS_DIR / "command_mapping.md"
|
|
assert template_path.exists(), f"Template not found: {template_path}"
|
|
|
|
def test_error_recovery_template_exists(self):
|
|
"""error_recovery.md template exists."""
|
|
template_path = PROMPTS_DIR / "error_recovery.md"
|
|
assert template_path.exists(), f"Template not found: {template_path}"
|
|
|
|
def test_templates_contain_variable_placeholders(self):
|
|
"""All templates contain {{variable}} placeholders."""
|
|
template_files = [
|
|
PROMPTS_DIR / "context_recovery.md",
|
|
PROMPTS_DIR / "command_mapping.md",
|
|
PROMPTS_DIR / "error_recovery.md",
|
|
]
|
|
for template_path in template_files:
|
|
content = template_path.read_text(encoding='utf-8')
|
|
# Check for at least one {{variable}} pattern
|
|
assert "{{" in content and "}}" in content, \
|
|
f"Template {template_path.name} has no {{variable}} placeholders"
|
|
|
|
|
|
class TestPromptLoader:
|
|
"""Test PromptLoader class for loading and rendering templates."""
|
|
|
|
def test_render_substitutes_variables(self):
|
|
"""PromptLoader.render substitutes variables correctly."""
|
|
from gsd_openclaw.prompt_loader import PromptLoader
|
|
|
|
loader = PromptLoader(PROMPTS_DIR)
|
|
result = loader.render(
|
|
"context_recovery",
|
|
project_name="test-project",
|
|
last_active_at="2026-03-11",
|
|
current_phase="Phase 1",
|
|
command_count="5",
|
|
last_output_snapshot="Last output"
|
|
)
|
|
|
|
assert "test-project" in result
|
|
assert "{{project_name}}" not in result
|
|
|
|
def test_render_handles_missing_variables(self):
|
|
"""PromptLoader.render leaves missing variables as literal {{variable}}."""
|
|
from gsd_openclaw.prompt_loader import PromptLoader
|
|
|
|
loader = PromptLoader(PROMPTS_DIR)
|
|
# Render with only partial variables - missing ones should remain as {{var}}
|
|
result = loader.render(
|
|
"context_recovery",
|
|
project_name="test-project"
|
|
# Missing: last_active_at, current_phase, etc.
|
|
)
|
|
|
|
# Should have substituted project_name
|
|
assert "test-project" in result
|
|
# Missing variables should remain as {{variable}}
|
|
assert "{{last_active_at}}" in result or "{{current_phase}}" in result
|
|
|
|
def test_render_raises_for_missing_template(self):
|
|
"""PromptLoader.render raises FileNotFoundError for missing template."""
|
|
from gsd_openclaw.prompt_loader import PromptLoader
|
|
|
|
loader = PromptLoader(PROMPTS_DIR)
|
|
|
|
with pytest.raises(FileNotFoundError, match="Template not found"):
|
|
loader.render("nonexistent_template")
|
|
|
|
def test_get_returns_raw_template_content(self):
|
|
"""PromptLoader.get returns raw template content (cached)."""
|
|
from gsd_openclaw.prompt_loader import PromptLoader
|
|
|
|
loader = PromptLoader(PROMPTS_DIR)
|
|
content = loader.get("context_recovery")
|
|
|
|
assert isinstance(content, str)
|
|
assert "{{project_name}}" in content
|
|
assert len(content) > 0
|
|
|
|
def test_get_caches_template(self):
|
|
"""PromptLoader caches templates after first load."""
|
|
from gsd_openclaw.prompt_loader import PromptLoader
|
|
|
|
loader = PromptLoader(PROMPTS_DIR)
|
|
|
|
# First load
|
|
content1 = loader.get("context_recovery")
|
|
# Second load (should be from cache)
|
|
content2 = loader.get("context_recovery")
|
|
|
|
# Should be the same object (cached)
|
|
assert content1 == content2
|
|
assert "context_recovery" in loader._cache
|
|
|
|
def test_default_template_dir(self):
|
|
"""PromptLoader uses default prompts directory when none specified."""
|
|
from gsd_openclaw.prompt_loader import PromptLoader
|
|
|
|
loader = PromptLoader()
|
|
expected_dir = Path(__file__).parent.parent / "src" / "gsd_openclaw" / "prompts"
|
|
assert loader.template_dir == expected_dir
|