bashrs 6.66.0

Rust-to-Shell transpiler for deterministic bootstrap scripts
use super::*;

#[test]
fn test_parser_error_injection() {
    let mut tester = ErrorInjectionTester::new(Config::default());
    let results = tester.test_parser_failures().unwrap();

    assert!(results.total_injections > 20);
    assert!(
        results.success_rate() > 75.0,
        "Parser error handling success rate too low: {:.1}%",
        results.success_rate()
    );

    if !results.failure_details.is_empty() {
        println!(
            "Parser error injection failures: {:?}",
            results.failure_details
        );
    }
}

#[test]
fn test_validation_error_injection() {
    let mut tester = ErrorInjectionTester::new(Config::default());
    let results = tester.test_validation_failures().unwrap();

    assert!(results.total_injections > 0);
    assert!(
        results.success_rate() > 35.0,
        "Validation error handling success rate too low: {:.1}%",
        results.success_rate()
    );
}

#[test]
fn test_full_error_injection_suite() {
    let mut tester = ErrorInjectionTester::new(Config::default());
    let results = tester.run_error_injection_tests().unwrap();

    assert!(results.total_injections > 40);
    assert!(
        results.success_rate() > 70.0,
        "Overall error injection success rate too low: {:.1}%",
        results.success_rate()
    );
    assert_eq!(
        results.panics, 0,
        "Panics detected during error injection testing"
    );

    println!(
        "Error injection testing complete: {}/{} handled gracefully ({:.1}%)",
        results.graceful_failures,
        results.total_injections,
        results.success_rate()
    );
}

// ===== Additional tests for coverage =====

#[test]
fn test_failure_point_creation() {
    let fp = FailurePoint {
        location: "test_location".to_string(),
        failure_type: FailureType::MemoryAllocation,
        trigger_count: 5,
        activated: false,
    };
    assert_eq!(fp.location, "test_location");
    assert_eq!(fp.trigger_count, 5);
    assert!(!fp.activated);
}

#[test]
fn test_failure_point_clone() {
    let fp = FailurePoint {
        location: "parser".to_string(),
        failure_type: FailureType::Parse,
        trigger_count: 10,
        activated: true,
    };
    let cloned = fp.clone();
    assert_eq!(cloned.location, "parser");
    assert!(cloned.activated);
}

#[test]
fn test_failure_type_variants() {
    let types = [
        FailureType::MemoryAllocation,
        FailureType::FileIO,
        FailureType::NetworkIO,
        FailureType::Parse,
        FailureType::Validation,
        FailureType::CodeGeneration,
    ];
    assert_eq!(types.len(), 6);

    // Test cloning
    let mem = FailureType::MemoryAllocation;
    let _cloned = mem.clone();
}

#[test]
fn test_error_injection_results_default() {
    let results = ErrorInjectionResults::default();
    assert_eq!(results.total_injections, 0);
    assert_eq!(results.graceful_failures, 0);
    assert_eq!(results.panics, 0);
    assert_eq!(results.memory_leaks, 0);
    assert_eq!(results.corruption_detected, 0);
    assert!(results.failure_details.is_empty());
}

#[test]
fn test_error_injection_results_success_rate_zero() {
    let results = ErrorInjectionResults::default();
    assert_eq!(results.success_rate(), 0.0);
}

#[test]
fn test_error_injection_results_success_rate() {
    let results = ErrorInjectionResults {
        total_injections: 100,
        graceful_failures: 75,
        panics: 0,
        memory_leaks: 0,
        corruption_detected: 0,
        failure_details: vec![],
    };
    assert_eq!(results.success_rate(), 75.0);
}

#[test]
fn test_error_injection_results_merge() {
    let mut results1 = ErrorInjectionResults {
        total_injections: 10,
        graceful_failures: 8,
        panics: 1,
        memory_leaks: 0,
        corruption_detected: 0,
        failure_details: vec!["error1".to_string()],
    };

    let results2 = ErrorInjectionResults {
        total_injections: 5,
        graceful_failures: 4,
        panics: 0,
        memory_leaks: 1,
        corruption_detected: 1,
        failure_details: vec!["error2".to_string()],
    };

    results1.merge(results2);

    assert_eq!(results1.total_injections, 15);
    assert_eq!(results1.graceful_failures, 12);
    assert_eq!(results1.panics, 1);
    assert_eq!(results1.memory_leaks, 1);
    assert_eq!(results1.corruption_detected, 1);
    assert_eq!(results1.failure_details.len(), 2);
}

#[test]
fn test_allocation_failures() {
    let mut tester = ErrorInjectionTester::new(Config::default());
    let results = tester.test_allocation_failures().unwrap();

    assert!(results.total_injections > 0);
    assert!(results.success_rate() >= 0.0);
}

#[test]
fn test_io_failures() {
    let mut tester = ErrorInjectionTester::new(Config::default());
    let results = tester.test_io_failures().unwrap();

    assert!(results.total_injections > 0);
    assert!(results.graceful_failures > 0);
}

#[test]
fn test_codegen_failures() {
    let mut tester = ErrorInjectionTester::new(Config::default());
    let results = tester.test_codegen_failures().unwrap();

    assert!(results.total_injections > 0);
}

#[test]
fn test_deeply_nested_input() {
    let tester = ErrorInjectionTester::new(Config::default());
    let input = tester.create_deeply_nested_input(5);
    assert!(input.contains("fn main()"));
    assert!(input.contains("if true"));
    assert!(input.contains("let x0"));
    assert!(input.contains("let x4"));
}

#[test]
fn test_failing_allocator_creation() {
    let allocator = FailingAllocator::new(100);
    assert_eq!(allocator.fail_after, 100);
}

#[test]
fn test_test_with_allocation_failure() {
    let tester = ErrorInjectionTester::new(Config::default());
    let result = tester.test_with_allocation_failure("fn main() { let x = 42; }", 10);
    // Should succeed since we don't actually fail allocations
    assert!(result.is_ok() || result.is_err());
}

#[test]
fn test_test_with_memory_pressure() {
    let tester = ErrorInjectionTester::new(Config::default());
    let result = tester.test_with_memory_pressure("fn main() { let x = 42; }");
    // Should succeed since we don't actually apply memory pressure
    assert!(result.is_ok() || result.is_err());
}

#[test]
fn test_test_with_io_failure() {
    let tester = ErrorInjectionTester::new(Config::default());
    let result = tester.test_with_io_failure("fn main() { let x = 42; }");
    // Should succeed since we don't actually fail I/O
    assert!(result.is_ok() || result.is_err());
}

#[test]
fn test_failure_point_debug() {
    let fp = FailurePoint {
        location: "test".to_string(),
        failure_type: FailureType::FileIO,
        trigger_count: 1,
        activated: true,
    };
    let debug_output = format!("{:?}", fp);
    assert!(debug_output.contains("location"));
    assert!(debug_output.contains("test"));
}

#[test]
fn test_failure_type_debug() {
    let ft = FailureType::NetworkIO;
    let debug_output = format!("{:?}", ft);
    assert!(debug_output.contains("NetworkIO"));
}

#[test]
fn test_error_injection_results_debug() {
    let results = ErrorInjectionResults {
        total_injections: 10,
        graceful_failures: 9,
        panics: 0,
        memory_leaks: 0,
        corruption_detected: 0,
        failure_details: vec![],
    };
    let debug_output = format!("{:?}", results);
    assert!(debug_output.contains("total_injections"));
    assert!(debug_output.contains("10"));
}