"""
Tests for the tracer tool functionality
"""
import pytest
from tools.models import ToolModelCategory
from tools.tracer import TracerRequest, TracerTool
class TestTracerTool:
"""Test suite for the Tracer tool"""
@pytest.fixture
def tracer_tool(self):
"""Create a tracer tool instance for testing"""
return TracerTool()
def test_get_name(self, tracer_tool):
"""Test that the tool returns the correct name"""
assert tracer_tool.get_name() == "tracer"
def test_get_description(self, tracer_tool):
"""Test that the tool returns a comprehensive description"""
description = tracer_tool.get_description()
assert "code tracing" in description
assert "precision" in description
assert "dependencies" in description
assert "systematic" in description
def test_get_input_schema(self, tracer_tool):
"""Test that the input schema includes required fields"""
schema = tracer_tool.get_input_schema()
assert schema["type"] == "object"
assert "target_description" in schema["properties"]
assert "trace_mode" in schema["properties"]
assert "step" in schema["properties"]
assert "step_number" in schema["properties"]
# Check trace_mode enum values
trace_enum = schema["properties"]["trace_mode"]["enum"]
assert "precision" in trace_enum
assert "dependencies" in trace_enum
# Check required fields include workflow fields
required_fields = set(schema["required"])
assert "target_description" in required_fields
assert "trace_mode" in required_fields
def test_get_model_category(self, tracer_tool):
"""Test that the tracer tool uses EXTENDED_REASONING category"""
category = tracer_tool.get_model_category()
assert category == ToolModelCategory.EXTENDED_REASONING
def test_request_model_validation(self, tracer_tool):
"""Test TracerRequest model validation"""
# Valid request
request = TracerRequest(
step="Analyze BookingManager finalizeInvoice method execution flow",
step_number=1,
total_steps=3,
next_step_required=True,
findings="Initial investigation of booking finalization process",
target_description="BookingManager finalizeInvoice method",
trace_mode="precision",
)
assert request.target_description == "BookingManager finalizeInvoice method"
assert request.trace_mode == "precision"
assert request.step_number == 1
# Test invalid trace_mode
with pytest.raises(ValueError):
TracerRequest(
step="Test step",
step_number=1,
total_steps=1,
next_step_required=False,
findings="Test findings",
trace_mode="invalid_mode",
)
def test_get_required_actions(self, tracer_tool):
"""Test that required actions are provided for each step"""
# Step 1 - initial investigation (in ask mode by default)
actions = tracer_tool.get_required_actions(1, "exploring", "Initial findings", 3)
assert len(actions) > 0
# Default is ask mode, so should ask for mode selection
if tracer_tool.get_trace_mode() == "ask":
assert any("ask user" in action.lower() for action in actions)
assert any("precision mode" in action.lower() for action in actions)
# Test with initialized trace_config for non-ask mode
tracer_tool.trace_config = {"trace_mode": "precision"}
actions = tracer_tool.get_required_actions(1, "exploring", "Initial findings", 3)
assert len(actions) > 0
assert any("search" in action.lower() for action in actions)
assert any("locate" in action.lower() for action in actions)
# Later steps with low confidence
actions = tracer_tool.get_required_actions(2, "low", "Some findings", 3)
assert len(actions) > 0
assert any("trace" in action.lower() for action in actions)
# High confidence steps
actions = tracer_tool.get_required_actions(3, "high", "Strong findings", 3)
assert len(actions) > 0
assert any("verify" in action.lower() for action in actions)
def test_workflow_tool_characteristics(self, tracer_tool):
"""Test that tracer has proper workflow tool characteristics"""
# Should not require external expert analysis
assert not tracer_tool.requires_expert_analysis()
# Should return TracerRequest as the workflow model
assert tracer_tool.get_workflow_request_model() == TracerRequest
# Should not require AI model at MCP boundary
assert not tracer_tool.requires_model()
def test_get_rendering_instructions_precision(self, tracer_tool):
"""Test rendering instructions for precision mode"""
instructions = tracer_tool._get_rendering_instructions("precision")
assert "PRECISION TRACE" in instructions
assert "CALL FLOW DIAGRAM" in instructions
assert "ADDITIONAL ANALYSIS VIEWS" in instructions
assert "ClassName::MethodName" in instructions
assert "↓" in instructions
def test_get_rendering_instructions_dependencies(self, tracer_tool):
"""Test rendering instructions for dependencies mode"""
instructions = tracer_tool._get_rendering_instructions("dependencies")
assert "DEPENDENCIES TRACE" in instructions
assert "DEPENDENCY FLOW DIAGRAM" in instructions
assert "DEPENDENCY TABLE" in instructions
assert "INCOMING DEPENDENCIES" in instructions
assert "OUTGOING DEPENDENCIES" in instructions
assert "←" in instructions
assert "→" in instructions
def test_rendering_instructions_consistency(self, tracer_tool):
"""Test that rendering instructions are consistent between modes"""
precision_instructions = tracer_tool._get_precision_rendering_instructions()
dependencies_instructions = tracer_tool._get_dependencies_rendering_instructions()
# Both should have mandatory instructions
assert "MANDATORY RENDERING INSTRUCTIONS" in precision_instructions
assert "MANDATORY RENDERING INSTRUCTIONS" in dependencies_instructions
# Both should have specific styling requirements
assert "ONLY" in precision_instructions
assert "ONLY" in dependencies_instructions
# Both should have absolute requirements
assert "ABSOLUTE REQUIREMENTS" in precision_instructions
assert "ABSOLUTE REQUIREMENTS" in dependencies_instructions
def test_mode_selection_guidance(self, tracer_tool):
"""Test that the schema provides clear guidance on when to use each mode"""
schema = tracer_tool.get_input_schema()
trace_mode_desc = schema["properties"]["trace_mode"]["description"]
# Should clearly indicate precision is for methods/functions
assert "execution flow" in trace_mode_desc
# Should clearly indicate dependencies is for structural relationships
assert "structural relationships" in trace_mode_desc