prodigy 0.4.4

Turn ad-hoc Claude sessions into reproducible development pipelines with parallel AI agents
Documentation
//! Unit tests for dry-run functionality

#[cfg(test)]
mod tests {
    use std::path::PathBuf;

    #[test]
    fn test_dry_run_flag_in_cook_command() {
        use crate::cook::command::CookCommand;
        use clap::Parser;

        // Test that dry-run flag is correctly parsed
        #[derive(Debug, Parser)]
        struct TestCli {
            #[command(flatten)]
            cook: CookCommand,
        }

        let args = TestCli::parse_from(["test", "workflow.yaml", "--dry-run"]);

        assert!(args.cook.dry_run);
        assert_eq!(args.cook.playbook, PathBuf::from("workflow.yaml"));
    }

    #[test]
    fn test_dry_run_with_iterations() {
        use crate::cook::command::CookCommand;
        use clap::Parser;

        #[derive(Debug, Parser)]
        struct TestCli {
            #[command(flatten)]
            cook: CookCommand,
        }

        let args = TestCli::parse_from(["test", "workflow.yaml", "--dry-run", "-n", "5"]);

        assert!(args.cook.dry_run);
        assert_eq!(args.cook.max_iterations, 5);
    }

    #[test]
    fn test_dry_run_always_uses_worktree() {
        use crate::cook::command::CookCommand;
        use clap::Parser;

        #[derive(Debug, Parser)]
        struct TestCli {
            #[command(flatten)]
            cook: CookCommand,
        }

        let args = TestCli::parse_from(["test", "workflow.yaml", "--dry-run"]);

        assert!(args.cook.dry_run);
        // In dry-run mode, worktree should not actually be created but would be in real mode
    }

    #[test]
    fn test_dry_run_with_auto_accept() {
        use crate::cook::command::CookCommand;
        use clap::Parser;

        #[derive(Debug, Parser)]
        struct TestCli {
            #[command(flatten)]
            cook: CookCommand,
        }

        let args = TestCli::parse_from(["test", "workflow.yaml", "--dry-run", "--yes"]);

        assert!(args.cook.dry_run);
        assert!(args.cook.auto_accept);
    }

    #[test]
    fn test_dry_run_with_verbosity() {
        use crate::cook::command::CookCommand;
        use clap::Parser;

        #[derive(Debug, Parser)]
        struct TestCli {
            #[command(flatten)]
            cook: CookCommand,
        }

        let args = TestCli::parse_from(["test", "workflow.yaml", "--dry-run", "-vv"]);

        assert!(args.cook.dry_run);
        assert_eq!(args.cook.verbosity, 2);
    }

    #[test]
    fn test_dry_run_workflow_config() {
        use crate::config::workflow::WorkflowConfig;

        let workflow = WorkflowConfig {
            name: None,
            commands: vec![],
            env: None,
            secrets: None,
            env_files: None,
            profiles: None,
            merge: None,
        };

        assert!(workflow.commands.is_empty());
        // In dry-run mode, this workflow should be analyzed but not executed
    }

    #[test]
    fn test_retention_analysis_serialization() {
        use crate::cook::execution::events::retention::RetentionAnalysis;
        use std::path::PathBuf;

        let analysis = RetentionAnalysis {
            file_path: PathBuf::from("/test/path"),
            events_total: 100,
            events_retained: 80,
            events_to_remove: 20,
            events_to_archive: 20,
            original_size_bytes: 10000,
            projected_size_bytes: 8000,
            space_to_save: 2000,
            estimated_duration_secs: 2.5,
            warnings: vec!["Test warning".to_string()],
        };

        // Test that the analysis can be serialized to JSON
        let json = serde_json::to_string(&analysis);
        assert!(json.is_ok());

        let json_str = json.unwrap();
        assert!(json_str.contains("\"events_total\":100"));
        assert!(json_str.contains("\"events_retained\":80"));
        assert!(json_str.contains("\"events_to_remove\":20"));
    }
}