ai-code-buddy 0.4.20

An AI-powered code review tool with elegant Bevy-based TUI
Documentation
// Comprehensive functional tests for main.rs to achieve full coverage
// Tests all main functions including app initialization, event handling, and system setup

use ai_code_buddy::{
    app_events_handler,
    args::{Args, OutputFormat},
    bevy_states::app::AppState,
    events::app::AppEvent,
    initialize_app,
};
use bevy::{
    app::{App, AppExit, Update},
    prelude::*,
    state::app::StatesPlugin,
};

// Test initialize_app function coverage
#[test]
fn test_initialize_app_function() {
    let mut app = App::new();
    app.add_plugins(StatesPlugin)
        .insert_resource(Args {
            repo_path: "test_repo".to_string(),
            source_branch: "main".to_string(),
            target_branch: "feature".to_string(),
            cli_mode: false,
            verbose: false,
            show_credits: false,
            output_format: OutputFormat::Summary,
            exclude_patterns: vec![],
            include_patterns: vec![],
            use_gpu: false,
            force_cpu: true,
            parallel: false,
            disable_ai: false,
        })
        .init_state::<AppState>()
        .add_systems(Update, initialize_app);

    // Run the system once to test initialization
    app.update();

    // Check that state is set correctly
    let state = app.world().resource::<State<AppState>>();
    assert_eq!(state.get(), &AppState::Overview);
}

// Test app_events_handler function coverage
#[test]
fn test_app_events_handler_switch_state() {
    let mut app = App::new();
    app.add_plugins(StatesPlugin)
        .init_state::<AppState>()
        .add_event::<AppEvent>()
        .add_event::<AppExit>()
        .add_systems(Update, app_events_handler);

    // Send a state switch event
    let mut events = app.world_mut().resource_mut::<Events<AppEvent>>();
    events.send(AppEvent::SwitchTo(AppState::Analysis));

    // Multiple updates to ensure state change propagates
    app.update();
    app.update();

    // Check that state changed
    let state = app.world().resource::<State<AppState>>();
    assert_eq!(state.get(), &AppState::Analysis);
}

#[test]
fn test_app_events_handler_exit() {
    let mut app = App::new();
    app.add_plugins(StatesPlugin)
        .init_state::<AppState>()
        .add_event::<AppEvent>()
        .add_event::<AppExit>()
        .add_systems(Update, app_events_handler);

    // Send an exit event
    let mut events = app.world_mut().resource_mut::<Events<AppEvent>>();
    events.send(AppEvent::Exit);

    app.update();

    // Check that exit event was sent (check using cursor method)
    let exit_events = app.world().resource::<Events<AppExit>>();
    let cursor = exit_events.get_cursor();
    assert!(cursor.len(exit_events) > 0);
}

// Test multiple state transitions
#[test]
fn test_multiple_state_transitions() {
    let mut app = App::new();
    app.add_plugins(StatesPlugin)
        .init_state::<AppState>()
        .add_event::<AppEvent>()
        .add_event::<AppExit>()
        .add_systems(Update, app_events_handler);

    // Test multiple state transitions
    let states = [AppState::Analysis, AppState::Reports, AppState::Overview];

    for target_state in states {
        let mut events = app.world_mut().resource_mut::<Events<AppEvent>>();
        events.send(AppEvent::SwitchTo(target_state));
        // Multiple updates to ensure state change propagates
        app.update();
        app.update();

        let state = app.world().resource::<State<AppState>>();
        assert_eq!(state.get(), &target_state);
    }
}

// Test CLI mode detection and configuration
#[test]
fn test_main_app_configuration() {
    // Test that we can create the basic app structure without running it
    let args = Args {
        repo_path: ".".to_string(),
        source_branch: "main".to_string(),
        target_branch: "HEAD".to_string(),
        cli_mode: false,
        verbose: false,
        show_credits: false,
        output_format: OutputFormat::Summary,
        exclude_patterns: vec![],
        include_patterns: vec![],
        use_gpu: false,
        force_cpu: true,
        parallel: false,
        disable_ai: false,
    };

    // Test CLI mode detection
    assert!(!args.cli_mode);

    // Test frame rate calculation (60 FPS)
    let frame_rate = std::time::Duration::from_secs_f64(1.0 / 60.0);
    assert_eq!(frame_rate.as_millis(), 16); // ~16ms for 60 FPS
}

// Test different app state variants
#[test]
fn test_app_state_variants() {
    let states = vec![AppState::Overview, AppState::Analysis, AppState::Reports];

    for state in states {
        let mut app = App::new();
        app.add_plugins(StatesPlugin)
            .insert_resource(State::new(state))
            .add_event::<AppEvent>()
            .add_event::<AppExit>()
            .add_systems(Update, app_events_handler);

        // Check that state is set correctly
        let current_state = app.world().resource::<State<AppState>>();
        assert_eq!(current_state.get(), &state);
    }
}

// Test resource configuration
#[test]
fn test_resource_setup() {
    let args = Args {
        repo_path: "/test/path".to_string(),
        source_branch: "develop".to_string(),
        target_branch: "main".to_string(),
        cli_mode: true,
        verbose: true,
        show_credits: true,
        output_format: OutputFormat::Json,
        exclude_patterns: vec!["*.log".to_string()],
        include_patterns: vec!["*.rs".to_string()],
        use_gpu: true,
        force_cpu: false,
        parallel: false,
        disable_ai: false,
    };

    let mut app = App::new();
    app.add_plugins(StatesPlugin)
        .insert_resource(args.clone())
        .init_state::<AppState>();

    let stored_args = app.world().resource::<Args>();
    assert_eq!(stored_args.repo_path, args.repo_path);
    assert_eq!(stored_args.source_branch, args.source_branch);
    assert_eq!(stored_args.target_branch, args.target_branch);
    assert_eq!(stored_args.cli_mode, args.cli_mode);
    assert_eq!(stored_args.verbose, args.verbose);
    assert_eq!(stored_args.show_credits, args.show_credits);
    assert_eq!(stored_args.use_gpu, args.use_gpu);
    assert_eq!(stored_args.force_cpu, args.force_cpu);
}

// Test state initialization
#[test]
fn test_state_initialization() {
    let mut app = App::new();
    app.add_plugins(StatesPlugin).init_state::<AppState>();

    let state = app.world().resource::<State<AppState>>();
    // Default state should be Overview
    assert_eq!(state.get(), &AppState::Overview);
}

// Test app event variants
#[test]
fn test_app_event_enum_variants() {
    let events = [
        AppEvent::SwitchTo(AppState::Overview),
        AppEvent::SwitchTo(AppState::Analysis),
        AppEvent::SwitchTo(AppState::Reports),
        AppEvent::Exit,
    ];

    for event in events {
        let mut app = App::new();
        app.add_plugins(StatesPlugin)
            .init_state::<AppState>()
            .add_event::<AppEvent>()
            .add_event::<AppExit>()
            .add_systems(Update, app_events_handler);

        let mut event_writer = app.world_mut().resource_mut::<Events<AppEvent>>();
        event_writer.send(event);
        app.update();

        // Events should be processed without panicking
    }
}

// Test args output format variants
#[test]
fn test_output_format_variants() {
    let formats = [
        OutputFormat::Summary,
        OutputFormat::Json,
        OutputFormat::Detailed,
    ];

    for format in formats {
        let args = Args {
            repo_path: ".".to_string(),
            source_branch: "main".to_string(),
            target_branch: "HEAD".to_string(),
            cli_mode: false,
            verbose: false,
            show_credits: false,
            output_format: format.clone(),
            exclude_patterns: vec![],
            include_patterns: vec![],
            use_gpu: false,
            force_cpu: false,
            parallel: false,
            disable_ai: false,
        };

        assert_eq!(args.output_format, format);
    }
}

// Test initialization with different args configurations
#[test]
fn test_initialize_with_different_configs() {
    let configs = vec![
        Args {
            repo_path: ".".to_string(),
            source_branch: "main".to_string(),
            target_branch: "develop".to_string(),
            cli_mode: false,
            verbose: false,
            show_credits: false,
            output_format: OutputFormat::Summary,
            exclude_patterns: vec![],
            include_patterns: vec![],
            use_gpu: false,
            force_cpu: true,
            parallel: false,
            disable_ai: false,
        },
        Args {
            repo_path: "/custom/path".to_string(),
            source_branch: "feature-branch".to_string(),
            target_branch: "main".to_string(),
            cli_mode: true,
            verbose: true,
            show_credits: true,
            output_format: OutputFormat::Json,
            exclude_patterns: vec!["*.tmp".to_string()],
            include_patterns: vec!["src/**".to_string()],
            use_gpu: true,
            force_cpu: false,
            parallel: false,
            disable_ai: false,
        },
    ];

    for config in configs {
        let mut app = App::new();
        app.add_plugins(StatesPlugin)
            .insert_resource(config)
            .init_state::<AppState>()
            .add_systems(Update, initialize_app);

        app.update();

        let state = app.world().resource::<State<AppState>>();
        assert_eq!(state.get(), &AppState::Overview);
    }
}