use std::path::Path;
pub struct TestConfig {
pub timeout: u64,
pub iterations: usize,
pub verbose: bool,
pub cleanup: bool,
}
impl Default for TestConfig {
fn default() -> Self {
Self {
timeout: 30,
iterations: 100,
verbose: false,
cleanup: true,
}
}
}
pub struct TestEnvironment {
pub temp_dir: tempfile::TempDir,
pub project_dir: std::path::PathBuf,
pub config: TestConfig,
}
impl TestEnvironment {
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,
}
}
pub fn with_maven_project(mut self) -> Self {
super::create_maven_project(&self.project_dir);
self
}
pub fn with_gradle_project(mut self) -> Self {
super::create_gradle_project(&self.project_dir);
self
}
pub fn with_minimal_project(mut self) -> Self {
super::create_minimal_project(&self.project_dir);
self
}
pub fn with_multi_source_project(mut self) -> Self {
super::project_utils::create_multi_source_project(&self.project_dir);
self
}
pub fn with_large_project(mut self, num_files: usize) -> Self {
super::project_utils::create_large_project(&self.project_dir, num_files);
self
}
pub fn with_config(mut self, config: TestConfig) -> Self {
self.config = config;
self
}
pub fn with_verbose(mut self) -> Self {
self.config.verbose = true;
self
}
pub fn project_path(&self) -> &Path {
&self.project_dir
}
pub fn temp_path(&self) -> &Path {
self.temp_dir.path()
}
pub fn cleanup(&self) {
if self.config.cleanup {
}
}
}
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",
}
}
}
pub struct TestRunnerConfig {
pub threads: usize,
pub timeout: u64,
pub verbose: bool,
pub stop_on_failure: bool,
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,
],
}
}
}
pub struct TestResults {
pub total: usize,
pub passed: usize,
pub failed: usize,
pub failures: Vec<String>,
pub duration: std::time::Duration,
}
impl TestResults {
pub fn new() -> Self {
Self {
total: 0,
passed: 0,
failed: 0,
failures: Vec::new(),
duration: std::time::Duration::from_secs(0),
}
}
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());
}
}
pub fn success_rate(&self) -> f64 {
if self.total == 0 {
0.0
} else {
(self.passed as f64 / self.total as f64) * 100.0
}
}
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);
}
}