This commit is contained in:
183
app/tests/test_core.py
Normal file
183
app/tests/test_core.py
Normal file
@@ -0,0 +1,183 @@
|
||||
import pytest
|
||||
|
||||
from promptforge.core.prompt import Prompt, PromptVariable, VariableType
|
||||
from promptforge.core.template import TemplateEngine
|
||||
from promptforge.core.exceptions import MissingVariableError, InvalidPromptError
|
||||
|
||||
|
||||
class TestPromptModel:
|
||||
"""Tests for Prompt model."""
|
||||
|
||||
def test_prompt_creation(self):
|
||||
"""Test basic prompt creation."""
|
||||
prompt = Prompt(
|
||||
name="Test Prompt",
|
||||
content="Hello, {{name}}!",
|
||||
variables=[
|
||||
PromptVariable(name="name", type=VariableType.STRING, required=True)
|
||||
]
|
||||
)
|
||||
assert prompt.name == "Test Prompt"
|
||||
assert len(prompt.variables) == 1
|
||||
assert prompt.version == "1.0.0"
|
||||
|
||||
def test_prompt_from_yaml(self, sample_prompt_yaml):
|
||||
"""Test parsing prompt from YAML."""
|
||||
prompt = Prompt.from_yaml(sample_prompt_yaml)
|
||||
assert prompt.name == "Test Prompt"
|
||||
assert prompt.description == "A test prompt for unit testing"
|
||||
assert len(prompt.variables) == 2
|
||||
assert prompt.variables[0].name == "name"
|
||||
assert prompt.variables[0].required is True
|
||||
|
||||
def test_prompt_to_yaml(self, sample_prompt_yaml):
|
||||
"""Test exporting prompt to YAML."""
|
||||
prompt = Prompt.from_yaml(sample_prompt_yaml)
|
||||
yaml_str = prompt.to_yaml()
|
||||
assert "---\n" in yaml_str
|
||||
assert "name: Test Prompt" in yaml_str
|
||||
|
||||
def test_prompt_save_and_load(self, temp_prompts_dir, sample_prompt_yaml):
|
||||
"""Test saving and loading prompts."""
|
||||
prompt = Prompt.from_yaml(sample_prompt_yaml)
|
||||
filepath = prompt.save(temp_prompts_dir)
|
||||
|
||||
assert filepath.exists()
|
||||
loaded = Prompt.load(filepath)
|
||||
assert loaded.name == prompt.name
|
||||
assert loaded.content == prompt.content
|
||||
|
||||
def test_prompt_list(self, temp_prompts_dir):
|
||||
"""Test listing prompts."""
|
||||
prompts = Prompt.list(temp_prompts_dir)
|
||||
assert len(prompts) == 0
|
||||
|
||||
prompt = Prompt(name="Test1", content="Test")
|
||||
prompt.save(temp_prompts_dir)
|
||||
|
||||
prompts = Prompt.list(temp_prompts_dir)
|
||||
assert len(prompts) == 1
|
||||
assert prompts[0].name == "Test1"
|
||||
|
||||
def test_variable_types(self):
|
||||
"""Test different variable types."""
|
||||
string_var = PromptVariable(name="text", type=VariableType.STRING)
|
||||
int_var = PromptVariable(name="number", type=VariableType.INTEGER)
|
||||
bool_var = PromptVariable(name="flag", type=VariableType.BOOLEAN)
|
||||
choice_var = PromptVariable(
|
||||
name="choice",
|
||||
type=VariableType.CHOICE,
|
||||
choices=["a", "b", "c"]
|
||||
)
|
||||
|
||||
assert string_var.type == VariableType.STRING
|
||||
assert int_var.type == VariableType.INTEGER
|
||||
assert bool_var.type == VariableType.BOOLEAN
|
||||
assert choice_var.choices == ["a", "b", "c"]
|
||||
|
||||
|
||||
class TestTemplateEngine:
|
||||
"""Tests for TemplateEngine."""
|
||||
|
||||
def test_get_variables(self):
|
||||
"""Test extracting variables from template."""
|
||||
engine = TemplateEngine()
|
||||
content = "Hello, {{name}}! You have {{count}} items."
|
||||
vars = engine.get_variables(content)
|
||||
assert "name" in vars
|
||||
assert "count" in vars
|
||||
|
||||
def test_render_basic(self):
|
||||
"""Test basic template rendering."""
|
||||
engine = TemplateEngine()
|
||||
content = "Hello, {{name}}!"
|
||||
result = engine.render(content, {"name": "World"})
|
||||
assert result == "Hello, World!"
|
||||
|
||||
def test_render_multiple_vars(self, sample_prompt_content):
|
||||
"""Test rendering with multiple variables."""
|
||||
engine = TemplateEngine()
|
||||
result = engine.render(
|
||||
sample_prompt_content,
|
||||
{"name": "Alice", "count": 5}
|
||||
)
|
||||
assert result == "Hello, Alice! You have 5 messages."
|
||||
|
||||
def test_render_missing_required(self):
|
||||
"""Test missing required variable raises error."""
|
||||
engine = TemplateEngine()
|
||||
content = "Hello, {{name}}!"
|
||||
with pytest.raises(Exception): # StrictUndefined raises on missing vars
|
||||
engine.render(content, {})
|
||||
|
||||
def test_render_with_defaults(self):
|
||||
"""Test rendering with default values."""
|
||||
engine = TemplateEngine()
|
||||
content = "Hello, {{name}}!"
|
||||
variables = [
|
||||
PromptVariable(name="name", required=False, default="Guest")
|
||||
]
|
||||
result = engine.render(content, {}, variables)
|
||||
assert result == "Hello, Guest!"
|
||||
|
||||
def test_validate_variables_valid(self):
|
||||
"""Test variable validation with valid values."""
|
||||
engine = TemplateEngine()
|
||||
variables = [
|
||||
PromptVariable(name="name", type=VariableType.STRING, required=True),
|
||||
PromptVariable(name="count", type=VariableType.INTEGER, required=False),
|
||||
]
|
||||
errors = engine.validate_variables(
|
||||
{"name": "Alice", "count": 5},
|
||||
variables
|
||||
)
|
||||
assert len(errors) == 0
|
||||
|
||||
def test_validate_variables_missing_required(self):
|
||||
"""Test validation fails for missing required variable."""
|
||||
engine = TemplateEngine()
|
||||
variables = [
|
||||
PromptVariable(name="name", type=VariableType.STRING, required=True),
|
||||
]
|
||||
errors = engine.validate_variables({}, variables)
|
||||
assert len(errors) == 1
|
||||
assert "name" in errors[0]
|
||||
|
||||
def test_validate_variables_type_error(self):
|
||||
"""Test validation fails for wrong type."""
|
||||
engine = TemplateEngine()
|
||||
variables = [
|
||||
PromptVariable(name="count", type=VariableType.INTEGER, required=True),
|
||||
]
|
||||
errors = engine.validate_variables({"count": "not a number"}, variables)
|
||||
assert len(errors) == 1
|
||||
assert "integer" in errors[0].lower()
|
||||
|
||||
def test_validate_choices(self):
|
||||
"""Test choice validation."""
|
||||
engine = TemplateEngine()
|
||||
variables = [
|
||||
PromptVariable(
|
||||
name="color",
|
||||
type=VariableType.CHOICE,
|
||||
required=True,
|
||||
choices=["red", "green", "blue"]
|
||||
),
|
||||
]
|
||||
errors = engine.validate_variables({"color": "yellow"}, variables)
|
||||
assert len(errors) == 1
|
||||
assert "one of" in errors[0].lower()
|
||||
|
||||
|
||||
class TestExceptions:
|
||||
"""Tests for custom exceptions."""
|
||||
|
||||
def test_missing_variable_error(self):
|
||||
"""Test MissingVariableError."""
|
||||
error = MissingVariableError("Missing: name")
|
||||
assert "name" in str(error)
|
||||
|
||||
def test_invalid_prompt_error(self):
|
||||
"""Test InvalidPromptError."""
|
||||
error = InvalidPromptError("Invalid YAML")
|
||||
assert "YAML" in str(error)
|
||||
Reference in New Issue
Block a user