test_reflection.py•3.65 kB
"""unit tests for reflection engine."""
import pytest
from src.reflection import ReflectionEngine, ToolMetadata
def sample_function(x: int, y: str = "default") -> str:
"""sample function for testing."""
return f"{x}:{y}"
def delete_something():
"""destructive function."""
pass
class SampleClass:
"""sample class for testing."""
def read_data(self, id: int):
"""read operation."""
return f"data-{id}"
def update_data(self, id: int, value: str):
"""update operation."""
pass
def test_reflection_discovers_functions():
"""test that reflection discovers module-level functions."""
import types
module = types.ModuleType("test_module")
module.sample_function = sample_function
engine = ReflectionEngine(allow_patterns=["*"])
tools = engine.discover_tools(module, "test_module")
assert len(tools) > 0
assert any(t.fq_name == "test_module.sample_function" for t in tools)
def test_reflection_discovers_class_methods():
"""test that reflection discovers class methods."""
import types
module = types.ModuleType("test_module")
module.SampleClass = SampleClass
engine = ReflectionEngine(allow_patterns=["*"])
tools = engine.discover_tools(module, "test_module")
tool_names = [t.fq_name for t in tools]
assert "test_module.SampleClass.read_data" in tool_names
assert "test_module.SampleClass.update_data" in tool_names
def test_reflection_respects_allow_patterns():
"""test that allow patterns work."""
import types
module = types.ModuleType("test_module")
module.sample_function = sample_function
module.delete_something = delete_something
engine = ReflectionEngine(allow_patterns=["*.sample_*"])
tools = engine.discover_tools(module, "test_module")
tool_names = [t.fq_name for t in tools]
assert "test_module.sample_function" in tool_names
assert "test_module.delete_something" not in tool_names
def test_reflection_respects_deny_patterns():
"""test that deny patterns work."""
import types
module = types.ModuleType("test_module")
module.sample_function = sample_function
module.delete_something = delete_something
engine = ReflectionEngine(allow_patterns=["*"], deny_patterns=["*delete*"])
tools = engine.discover_tools(module, "test_module")
tool_names = [t.fq_name for t in tools]
assert "test_module.sample_function" in tool_names
assert "test_module.delete_something" not in tool_names
def test_reflection_detects_mutating_operations():
"""test that mutating operations are detected."""
import types
module = types.ModuleType("test_module")
module.SampleClass = SampleClass
engine = ReflectionEngine(allow_patterns=["*"], allow_mutating=True)
tools = engine.discover_tools(module, "test_module")
read_tool = next(t for t in tools if "read_data" in t.fq_name)
update_tool = next(t for t in tools if "update_data" in t.fq_name)
assert not read_tool.is_mutating
assert update_tool.is_mutating
def test_reflection_blocks_mutating_by_default():
"""test that mutating operations are blocked by default."""
import types
module = types.ModuleType("test_module")
module.SampleClass = SampleClass
engine = ReflectionEngine(allow_patterns=["*"], allow_mutating=False)
tools = engine.discover_tools(module, "test_module")
tool_names = [t.fq_name for t in tools]
assert "test_module.SampleClass.read_data" in tool_names
assert "test_module.SampleClass.update_data" not in tool_names