jbuild 0.1.9

High-performance Java build tool supporting Maven and Gradle
Documentation
//! Test configuration and setup
//!
//! This module provides test configuration and setup utilities for all interactive tests

use std::path::Path;

/// Test configuration
pub struct TestConfig {
    /// Test timeout in seconds
    pub timeout: u64,
    /// Number of test iterations for performance tests
    pub iterations: usize,
    /// Whether to enable verbose output
    pub verbose: bool,
    /// Whether to cleanup test artifacts
    pub cleanup: bool,
}

impl Default for TestConfig {
    fn default() -> Self {
        Self {
            timeout: 30,
            iterations: 100,
            verbose: false,
            cleanup: true,
        }
    }
}

/// Test environment setup
pub struct TestEnvironment {
    /// Temporary directory for tests
    pub temp_dir: tempfile::TempDir,
    /// Project directory
    pub project_dir: std::path::PathBuf,
    /// Configuration
    pub config: TestConfig,
}

impl TestEnvironment {
    /// Create a new test environment
    pub fn new() -> Self {
        let temp_dir = tempfile::TempDir::new().expect("Failed to create test directory");
        let project_dir = temp_dir.path().to_path_buf();
        let config = TestConfig::default();
        
        Self {
            temp_dir,
            project_dir,
            config,
        }
    }
    
    /// Create a Maven project environment
    pub fn with_maven_project(mut self) -> Self {
        super::create_maven_project(&self.project_dir);
        self
    }
    
    /// Create a Gradle project environment
    pub fn with_gradle_project(mut self) -> Self {
        super::create_gradle_project(&self.project_dir);
        self
    }
    
    /// Create a minimal project environment
    pub fn with_minimal_project(mut self) -> Self {
        super::create_minimal_project(&self.project_dir);
        self
    }
    
    /// Create a multi-source project environment
    pub fn with_multi_source_project(mut self) -> Self {
        super::project_utils::create_multi_source_project(&self.project_dir);
        self
    }
    
    /// Create a large project environment
    pub fn with_large_project(mut self, num_files: usize) -> Self {
        super::project_utils::create_large_project(&self.project_dir, num_files);
        self
    }
    
    /// Set custom configuration
    pub fn with_config(mut self, config: TestConfig) -> Self {
        self.config = config;
        self
    }
    
    /// Enable verbose output
    pub fn with_verbose(mut self) -> Self {
        self.config.verbose = true;
        self
    }
    
    /// Get the project directory path
    pub fn project_path(&self) -> &Path {
        &self.project_dir
    }
    
    /// Get the temporary directory
    pub fn temp_path(&self) -> &Path {
        self.temp_dir.path()
    }
    
    /// Cleanup the test environment
    pub fn cleanup(&self) {
        if self.config.cleanup {
            // The temporary directory will be automatically cleaned up when dropped
        }
    }
}

/// Test categories
pub enum TestCategory {
    Unit,
    Integration,
    Performance,
    Stress,
}

impl TestCategory {
    pub fn as_str(&self) -> &'static str {
        match self {
            TestCategory::Unit => "unit",
            TestCategory::Integration => "integration",
            TestCategory::Performance => "performance",
            TestCategory::Stress => "stress",
        }
    }
}

/// Test runner configuration
pub struct TestRunnerConfig {
    /// Number of parallel test threads
    pub threads: usize,
    /// Test timeout in seconds
    pub timeout: u64,
    /// Whether to show detailed output
    pub verbose: bool,
    /// Whether to stop on first failure
    pub stop_on_failure: bool,
    /// Test categories to run
    pub categories: Vec<TestCategory>,
}

impl Default for TestRunnerConfig {
    fn default() -> Self {
        Self {
            threads: 1,
            timeout: 30,
            verbose: false,
            stop_on_failure: false,
            categories: vec![
                TestCategory::Unit,
                TestCategory::Integration,
                TestCategory::Performance,
            ],
        }
    }
}

/// Test results
pub struct TestResults {
    /// Total number of tests
    pub total: usize,
    /// Number of passed tests
    pub passed: usize,
    /// Number of failed tests
    pub failed: usize,
    /// List of failed test names
    pub failures: Vec<String>,
    /// Total execution time
    pub duration: std::time::Duration,
}

impl TestResults {
    /// Create new test results
    pub fn new() -> Self {
        Self {
            total: 0,
            passed: 0,
            failed: 0,
            failures: Vec::new(),
            duration: std::time::Duration::from_secs(0),
        }
    }
    
    /// Add a test result
    pub fn add_test(&mut self, name: &str, passed: bool) {
        self.total += 1;
        if passed {
            self.passed += 1;
        } else {
            self.failed += 1;
            self.failures.push(name.to_string());
        }
    }
    
    /// Calculate success rate
    pub fn success_rate(&self) -> f64 {
        if self.total == 0 {
            0.0
        } else {
            (self.passed as f64 / self.total as f64) * 100.0
        }
    }
    
    /// Check if all tests passed
    pub fn all_passed(&self) -> bool {
        self.failed == 0
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_test_environment_creation() {
        let env = TestEnvironment::new();
        assert!(env.project_path().exists());
        assert!(env.temp_path().exists());
    }
    
    #[test]
    fn test_test_environment_with_maven_project() {
        let env = TestEnvironment::new().with_maven_project();
        assert!(env.project_path().join("pom.xml").exists());
        assert!(env.project_path().join("src").join("main").join("java").exists());
    }
    
    #[test]
    fn test_test_environment_with_gradle_project() {
        let env = TestEnvironment::new().with_gradle_project();
        assert!(env.project_path().join("build.gradle").exists());
        assert!(env.project_path().join("src").join("main").join("java").exists());
    }
    
    #[test]
    fn test_test_configuration() {
        let config = TestConfig::default();
        assert_eq!(config.timeout, 30);
        assert_eq!(config.iterations, 100);
        assert!(!config.verbose);
        assert!(config.cleanup);
        
        let custom_config = TestConfig {
            timeout: 60,
            iterations: 200,
            verbose: true,
            cleanup: false,
        };
        
        assert_eq!(custom_config.timeout, 60);
        assert_eq!(custom_config.iterations, 200);
        assert!(custom_config.verbose);
        assert!(!custom_config.cleanup);
    }
    
    #[test]
    fn test_test_results() {
        let mut results = TestResults::new();
        
        assert_eq!(results.total, 0);
        assert_eq!(results.passed, 0);
        assert_eq!(results.failed, 0);
        assert!(results.failures.is_empty());
        assert_eq!(results.success_rate(), 0.0);
        assert!(results.all_passed());
        
        results.add_test("test1", true);
        results.add_test("test2", false);
        results.add_test("test3", true);
        
        assert_eq!(results.total, 3);
        assert_eq!(results.passed, 2);
        assert_eq!(results.failed, 1);
        assert_eq!(results.failures.len(), 1);
        assert_eq!(results.success_rate(), 66.66666666666666);
        assert!(!results.all_passed());
    }
    
    #[test]
    fn test_test_categories() {
        assert_eq!(TestCategory::Unit.as_str(), "unit");
        assert_eq!(TestCategory::Integration.as_str(), "integration");
        assert_eq!(TestCategory::Performance.as_str(), "performance");
        assert_eq!(TestCategory::Stress.as_str(), "stress");
    }
    
    #[test]
    fn test_test_runner_config() {
        let config = TestRunnerConfig::default();
        assert_eq!(config.threads, 1);
        assert_eq!(config.timeout, 30);
        assert!(!config.verbose);
        assert!(!config.stop_on_failure);
        assert_eq!(config.categories.len(), 3);
        
        let custom_config = TestRunnerConfig {
            threads: 4,
            timeout: 60,
            verbose: true,
            stop_on_failure: true,
            categories: vec![TestCategory::Unit],
        };
        
        assert_eq!(custom_config.threads, 4);
        assert_eq!(custom_config.timeout, 60);
        assert!(custom_config.verbose);
        assert!(custom_config.stop_on_failure);
        assert_eq!(custom_config.categories.len(), 1);
    }
}