"""Tests for state machine."""
import pytest
from pathfinder_mcp.state import Phase, PhaseState
class TestPhase:
"""Tests for Phase enum."""
def test_phase_values(self) -> None:
"""Phase enum has correct values."""
assert Phase.RESEARCH.value == "research"
assert Phase.PLAN.value == "plan"
assert Phase.IMPLEMENT.value == "implement"
def test_phase_is_string_enum(self) -> None:
"""Phase enum values are strings."""
assert isinstance(Phase.RESEARCH.value, str)
class TestPhaseState:
"""Tests for PhaseState class."""
def test_initial_state_is_research(self) -> None:
"""New PhaseState defaults to RESEARCH."""
state = PhaseState(session_id="test")
assert state.current_phase == Phase.RESEARCH
assert state.is_research
def test_can_transition_research_to_plan(self, research_state: PhaseState) -> None:
"""Can transition from RESEARCH to PLAN."""
assert research_state.can_transition_to(Phase.PLAN)
def test_cannot_transition_research_to_implement(
self, research_state: PhaseState
) -> None:
"""Cannot skip PLAN phase."""
assert not research_state.can_transition_to(Phase.IMPLEMENT)
def test_can_transition_plan_to_implement(self, plan_state: PhaseState) -> None:
"""Can transition from PLAN to IMPLEMENT."""
assert plan_state.can_transition_to(Phase.IMPLEMENT)
def test_cannot_transition_backwards(self, plan_state: PhaseState) -> None:
"""Cannot transition backwards."""
assert not plan_state.can_transition_to(Phase.RESEARCH)
def test_implement_is_terminal(self, implement_state: PhaseState) -> None:
"""IMPLEMENT phase has no valid transitions."""
assert not implement_state.can_transition_to(Phase.RESEARCH)
assert not implement_state.can_transition_to(Phase.PLAN)
def test_transition_to_valid_phase(self, research_state: PhaseState) -> None:
"""transition_to returns new state with updated phase."""
new_state = research_state.transition_to(Phase.PLAN)
assert new_state.current_phase == Phase.PLAN
assert new_state.is_plan
# Original unchanged
assert research_state.current_phase == Phase.RESEARCH
def test_transition_to_invalid_raises(self, research_state: PhaseState) -> None:
"""transition_to raises ValueError for invalid transition."""
with pytest.raises(ValueError, match="Invalid transition"):
research_state.transition_to(Phase.IMPLEMENT)
def test_phase_properties(self) -> None:
"""Phase property methods work correctly."""
research = PhaseState(session_id="t", current_phase=Phase.RESEARCH)
plan = PhaseState(session_id="t", current_phase=Phase.PLAN)
impl = PhaseState(session_id="t", current_phase=Phase.IMPLEMENT)
assert (
research.is_research and not research.is_plan and not research.is_implement
)
assert plan.is_plan and not plan.is_research and not plan.is_implement
assert impl.is_implement and not impl.is_research and not impl.is_plan