use super::*;
use crate::checkpoint::state::{
AgentConfigSnapshot, CheckpointParams, CliArgsSnapshot, EnvironmentSnapshot, RebaseState,
};
fn make_test_checkpoint(phase: PipelinePhase, iteration: u32, pass: u32) -> PipelineCheckpoint {
let cli_args = CliArgsSnapshot::new(5, 3, None, true, 2, false, None);
let dev_config =
AgentConfigSnapshot::new("claude".into(), "cmd".into(), "-o".into(), None, true);
let rev_config =
AgentConfigSnapshot::new("codex".into(), "cmd".into(), "-o".into(), None, true);
let run_id = uuid::Uuid::new_v4().to_string();
PipelineCheckpoint::from_params(CheckpointParams {
phase,
iteration,
total_iterations: 5,
reviewer_pass: pass,
total_reviewer_passes: 3,
developer_agent: "claude",
reviewer_agent: "codex",
cli_args,
developer_agent_config: dev_config,
reviewer_agent_config: rev_config,
rebase_state: RebaseState::default(),
git_user_name: None,
git_user_email: None,
run_id: &run_id,
parent_run_id: None,
resume_count: 0,
actual_developer_runs: iteration,
actual_reviewer_runs: pass,
working_dir: "/test/repo".to_string(),
prompt_md_checksum: None,
config_path: None,
config_checksum: None,
})
}
#[test]
fn test_restored_context_from_checkpoint() {
let checkpoint = make_test_checkpoint(PipelinePhase::Development, 3, 0);
let context = RestoredContext::from_checkpoint(&checkpoint);
assert_eq!(context.phase, PipelinePhase::Development);
assert_eq!(context.resume_iteration, 3);
assert_eq!(context.total_iterations, 5);
assert_eq!(context.resume_reviewer_pass, 0);
assert_eq!(context.developer_agent, "claude");
assert!(context.cli_args.is_some());
}
#[test]
fn test_should_use_checkpoint_iterations() {
let checkpoint = make_test_checkpoint(PipelinePhase::Development, 3, 0);
let context = RestoredContext::from_checkpoint(&checkpoint);
assert!(context.should_use_checkpoint_iterations());
}
#[test]
fn test_calculate_start_iteration_development() {
let checkpoint = make_test_checkpoint(PipelinePhase::Development, 3, 0);
let start = calculate_start_iteration(&checkpoint, 5);
assert_eq!(start, 3);
}
#[test]
fn test_calculate_start_iteration_later_phase() {
let checkpoint = make_test_checkpoint(PipelinePhase::Review, 5, 1);
let start = calculate_start_iteration(&checkpoint, 5);
assert_eq!(start, 5); }
#[test]
fn test_calculate_start_reviewer_pass() {
let checkpoint = make_test_checkpoint(PipelinePhase::Review, 5, 2);
let start = calculate_start_reviewer_pass(&checkpoint, 3);
assert_eq!(start, 2);
}
#[test]
fn test_calculate_start_reviewer_pass_early_phase() {
let checkpoint = make_test_checkpoint(PipelinePhase::Development, 3, 0);
let start = calculate_start_reviewer_pass(&checkpoint, 3);
assert_eq!(start, 1); }
#[test]
fn test_should_skip_phase() {
let checkpoint = make_test_checkpoint(PipelinePhase::Review, 5, 1);
assert!(should_skip_phase(PipelinePhase::Planning, &checkpoint));
assert!(should_skip_phase(PipelinePhase::Development, &checkpoint));
assert!(!should_skip_phase(PipelinePhase::Review, &checkpoint));
assert!(!should_skip_phase(
PipelinePhase::FinalValidation,
&checkpoint
));
}
#[test]
fn test_resume_context_from_checkpoint() {
let checkpoint = make_test_checkpoint(PipelinePhase::Development, 3, 1);
let resume_ctx = checkpoint.resume_context();
assert_eq!(resume_ctx.phase, PipelinePhase::Development);
assert_eq!(resume_ctx.iteration, 3);
assert_eq!(resume_ctx.total_iterations, 5);
assert_eq!(resume_ctx.reviewer_pass, 1);
assert_eq!(resume_ctx.total_reviewer_passes, 3);
assert_eq!(resume_ctx.resume_count, 0);
assert_eq!(resume_ctx.run_id, checkpoint.run_id);
assert!(resume_ctx.prompt_history.is_none());
}
#[test]
fn test_resume_context_phase_name_development() {
let ctx = ResumeContext {
phase: PipelinePhase::Development,
iteration: 2,
total_iterations: 5,
reviewer_pass: 0,
total_reviewer_passes: 3,
resume_count: 0,
rebase_state: RebaseState::default(),
run_id: "test".to_string(),
prompt_history: None,
execution_history: None,
};
assert_eq!(ctx.phase_name(), "Development iteration 2/5");
}
#[test]
fn test_resume_context_phase_name_review() {
let ctx = ResumeContext {
phase: PipelinePhase::Review,
iteration: 5,
total_iterations: 5,
reviewer_pass: 1,
total_reviewer_passes: 3,
resume_count: 0,
rebase_state: RebaseState::default(),
run_id: "test".to_string(),
prompt_history: None,
execution_history: None,
};
assert_eq!(ctx.phase_name(), "Review (pass 1/3)");
}
#[test]
fn test_restore_environment_skips_sensitive_vars() {
let snapshot = EnvironmentSnapshot {
ralph_vars: [
("RALPH_SAFE_SETTING".to_string(), "ok".to_string()),
("RALPH_API_TOKEN".to_string(), "secret".to_string()),
]
.into_iter()
.collect(),
other_vars: [
("EDITOR".to_string(), "vim".to_string()),
("GIT_PASSWORD".to_string(), "nope".to_string()),
]
.into_iter()
.collect(),
};
let checkpoint = PipelineCheckpoint {
env_snapshot: Some(snapshot),
..make_test_checkpoint(PipelinePhase::Development, 1, 0)
};
let set_calls = restore_environment_impl(&checkpoint);
assert_eq!(set_calls.len(), 1);
}