use super::*;
#[test]
fn test_agent_loop_new() {
let loop_ctrl = AgentLoop::new(100);
assert_eq!(loop_ctrl.max_iterations, 100);
assert_eq!(loop_ctrl.current_step, 0);
assert_eq!(loop_ctrl.iteration, 0);
}
#[test]
fn test_agent_loop_initial_state_is_planning() {
let mut loop_ctrl = AgentLoop::new(100);
let state = loop_ctrl.next_state();
assert!(matches!(state, Some(AgentState::Planning)));
}
#[test]
fn test_agent_loop_set_state() {
let mut loop_ctrl = AgentLoop::new(100);
loop_ctrl
.transition_to(AgentState::Executing { step: 0 })
.unwrap();
let state = loop_ctrl.next_state();
assert!(matches!(state, Some(AgentState::Executing { step: 0 })));
}
#[test]
fn test_agent_loop_increment_step() {
let mut loop_ctrl = AgentLoop::new(100);
assert_eq!(loop_ctrl.current_step(), 0);
loop_ctrl.increment_step().unwrap();
assert_eq!(loop_ctrl.current_step(), 1);
loop_ctrl.increment_step().unwrap();
assert_eq!(loop_ctrl.current_step(), 2);
}
#[test]
fn test_agent_loop_max_iterations_exceeded() {
let mut loop_ctrl = AgentLoop::new(3);
assert!(loop_ctrl.next_state().is_some());
loop_ctrl
.transition_to(AgentState::Executing { step: 0 })
.unwrap();
assert!(loop_ctrl.next_state().is_some());
assert!(loop_ctrl.next_state().is_some());
assert!(loop_ctrl.next_state().is_some());
let state = loop_ctrl.next_state();
assert!(
matches!(state, Some(AgentState::Failed { reason }) if reason == "Max iterations exceeded")
);
}
#[test]
fn test_agent_state_error_recovery() {
let mut loop_ctrl = AgentLoop::new(100);
loop_ctrl
.transition_to(AgentState::ErrorRecovery {
error: "Test error".to_string(),
})
.unwrap();
let state = loop_ctrl.next_state();
match state {
Some(AgentState::ErrorRecovery { error }) => {
assert_eq!(error, "Test error");
}
_ => panic!("Expected ErrorRecovery state"),
}
}
#[test]
fn test_agent_state_failed() {
let mut loop_ctrl = AgentLoop::new(100);
loop_ctrl
.transition_to(AgentState::Failed {
reason: "Something went wrong".to_string(),
})
.unwrap();
let state = loop_ctrl.next_state();
match state {
Some(AgentState::Failed { reason }) => {
assert_eq!(reason, "Something went wrong");
}
_ => panic!("Expected Failed state"),
}
}
#[test]
fn test_executing_state_tracks_step() {
let state = AgentState::Executing { step: 5 };
match state {
AgentState::Executing { step } => assert_eq!(step, 5),
_ => panic!("Expected Executing state"),
}
}
#[test]
fn test_increment_step_updates_state() {
let mut loop_ctrl = AgentLoop::new(100);
loop_ctrl.increment_step().unwrap();
match &loop_ctrl.state {
AgentState::Executing { step } => assert_eq!(*step, 1),
_ => panic!("Expected Executing state after increment"),
}
}
#[test]
fn test_reset_for_task() {
let mut loop_ctrl = AgentLoop::new(10);
loop_ctrl.next_state(); loop_ctrl
.transition_to(AgentState::Executing { step: 0 })
.unwrap();
loop_ctrl.next_state(); loop_ctrl.next_state(); loop_ctrl.next_state(); loop_ctrl.increment_step().unwrap();
loop_ctrl.increment_step().unwrap();
assert_eq!(loop_ctrl.iteration, 3);
assert_eq!(loop_ctrl.current_step(), 2);
loop_ctrl.reset_for_task();
assert_eq!(loop_ctrl.iteration, 0);
assert_eq!(loop_ctrl.current_step(), 0);
assert!(matches!(loop_ctrl.state, AgentState::Planning));
loop_ctrl.next_state(); loop_ctrl
.transition_to(AgentState::Executing { step: 0 })
.unwrap();
for _ in 0..10 {
let state = loop_ctrl.next_state();
assert!(!matches!(state, Some(AgentState::Failed { .. })));
}
let state = loop_ctrl.next_state();
assert!(matches!(state, Some(AgentState::Failed { .. })));
}
#[test]
fn test_restore_progress() {
let mut loop_ctrl = AgentLoop::new(10);
loop_ctrl.restore_progress(3, 7);
assert_eq!(loop_ctrl.current_step(), 3);
assert_eq!(loop_ctrl.current_iteration(), 7);
assert!(matches!(loop_ctrl.state, AgentState::Executing { step: 3 }));
}
#[test]
fn test_invalid_transition_rejected() {
let mut loop_ctrl = AgentLoop::new(10);
let error = loop_ctrl.transition_to(AgentState::Completed).unwrap_err();
assert_eq!(
error.to_string(),
"invalid agent state transition from 'planning' to 'completed'"
);
}
#[test]
fn test_approaching_limit_warning_none_early() {
let mut loop_ctrl = AgentLoop::new(100);
loop_ctrl
.transition_to(AgentState::Executing { step: 0 })
.unwrap();
for _ in 0..50 {
loop_ctrl.next_state();
}
assert!(loop_ctrl.approaching_limit_warning().is_none());
}
#[test]
fn test_approaching_limit_warning_at_80_pct() {
let mut loop_ctrl = AgentLoop::new(100);
loop_ctrl
.transition_to(AgentState::Executing { step: 0 })
.unwrap();
for _ in 0..80 {
loop_ctrl.next_state();
}
let warning = loop_ctrl.approaching_limit_warning();
assert!(warning.is_some());
assert!(warning.unwrap().contains("wrapping up"));
}
#[test]
fn test_approaching_limit_warning_at_90_pct() {
let mut loop_ctrl = AgentLoop::new(100);
loop_ctrl
.transition_to(AgentState::Executing { step: 0 })
.unwrap();
for _ in 0..90 {
loop_ctrl.next_state();
}
let warning = loop_ctrl.approaching_limit_warning();
assert!(warning.is_some());
assert!(warning.unwrap().contains("final answer"));
}
#[test]
fn test_approaching_limit_warning_zero_max() {
let loop_ctrl = AgentLoop::new(0);
assert!(loop_ctrl.approaching_limit_warning().is_none());
}