#![cfg_attr(coverage_nightly, coverage(off))]
#![cfg(feature = "mutation-testing")]
use crate::services::mutation::language::LanguageAdapter;
use crate::services::mutation::{
DistributedConfig, Language, LanguageRegistry, Mutant, MutantStatus, MutationConfig,
MutationEngine, MutationOperatorType, MutationProgress, MutationResult, MutationScore,
MutationScorer, MutationState, MutationStateConfig, MutationStrategy, RustAdapter,
SourceLocation, TestRunResult, WeakSpot,
};
use std::collections::HashSet;
use std::path::PathBuf;
use std::sync::Arc;
fn create_test_location(line: usize, column: usize) -> SourceLocation {
SourceLocation {
line,
column,
end_line: line,
end_column: column + 10,
}
}
fn create_test_mutant(id: &str, status: MutantStatus) -> Mutant {
Mutant {
id: id.to_string(),
original_file: PathBuf::from("test.rs"),
mutated_source: "fn test() {}".to_string(),
location: create_test_location(1, 1),
operator: MutationOperatorType::ArithmeticReplacement,
hash: format!("hash_{}", id),
status,
}
}
fn create_test_result(status: MutantStatus, file: &str, line: usize) -> MutationResult {
MutationResult {
mutant: Mutant {
id: format!("{}_{}", file.replace(".rs", ""), line),
original_file: PathBuf::from(file),
mutated_source: "mutated".to_string(),
location: create_test_location(line, 1),
operator: MutationOperatorType::ArithmeticReplacement,
hash: format!("hash_{}_{}", file, line),
status: status.clone(),
},
status,
test_failures: vec![],
execution_time_ms: 100,
error_message: None,
}
}
#[test]
fn test_mutation_operator_type_all_variants_debug() {
let variants = vec![
MutationOperatorType::ArithmeticReplacement,
MutationOperatorType::RelationalReplacement,
MutationOperatorType::ConditionalReplacement,
MutationOperatorType::ConstantReplacement,
MutationOperatorType::StatementDeletion,
MutationOperatorType::ReturnReplacement,
MutationOperatorType::VariableReplacement,
MutationOperatorType::ConditionalReturn,
MutationOperatorType::BoundaryValue,
MutationOperatorType::ExceptionHandlerRemoval,
MutationOperatorType::ReturnValueReplacement,
MutationOperatorType::UnaryReplacement,
MutationOperatorType::BitwiseReplacement,
MutationOperatorType::AssignmentReplacement,
MutationOperatorType::PointerReplacement,
MutationOperatorType::MemberAccessReplacement,
MutationOperatorType::RangeReplacement,
MutationOperatorType::PatternReplacement,
MutationOperatorType::MethodChainReplacement,
MutationOperatorType::BorrowReplacement,
MutationOperatorType::Custom("custom_op".to_string()),
MutationOperatorType::None,
];
for variant in variants {
let debug_str = format!("{:?}", variant);
assert!(!debug_str.is_empty());
}
}
#[test]
fn test_mutation_operator_type_clone() {
let original = MutationOperatorType::Custom("test".to_string());
let cloned = original.clone();
assert_eq!(original, cloned);
}
#[test]
fn test_mutation_operator_type_ordering() {
let ops: Vec<MutationOperatorType> = vec![
MutationOperatorType::ArithmeticReplacement,
MutationOperatorType::RelationalReplacement,
MutationOperatorType::ConditionalReplacement,
];
let mut sorted = ops.clone();
sorted.sort();
assert_eq!(sorted.len(), 3);
}
#[test]
fn test_mutation_operator_type_hash() {
let mut set: HashSet<MutationOperatorType> = HashSet::new();
set.insert(MutationOperatorType::ArithmeticReplacement);
set.insert(MutationOperatorType::RelationalReplacement);
set.insert(MutationOperatorType::ArithmeticReplacement);
assert_eq!(set.len(), 2);
}
#[test]
fn test_mutation_operator_type_custom_variants() {
let custom1 = MutationOperatorType::Custom("op1".to_string());
let custom2 = MutationOperatorType::Custom("op2".to_string());
let custom1_dup = MutationOperatorType::Custom("op1".to_string());
assert_ne!(custom1, custom2);
assert_eq!(custom1, custom1_dup);
}
#[test]
fn test_mutant_status_all_variants_debug() {
let variants = vec![
MutantStatus::Pending,
MutantStatus::Killed,
MutantStatus::Survived,
MutantStatus::CompileError,
MutantStatus::Timeout,
MutantStatus::Equivalent,
];
for status in variants {
let debug_str = format!("{:?}", status);
assert!(!debug_str.is_empty());
}
}
#[test]
fn test_mutant_status_equality() {
assert_eq!(MutantStatus::Pending, MutantStatus::Pending);
assert_eq!(MutantStatus::Killed, MutantStatus::Killed);
assert_ne!(MutantStatus::Killed, MutantStatus::Survived);
assert_ne!(MutantStatus::CompileError, MutantStatus::Timeout);
}
#[test]
fn test_mutant_status_hash() {
let mut set: HashSet<MutantStatus> = HashSet::new();
set.insert(MutantStatus::Pending);
set.insert(MutantStatus::Killed);
set.insert(MutantStatus::Pending);
assert_eq!(set.len(), 2);
}
#[test]
fn test_mutant_status_clone() {
let status = MutantStatus::Killed;
let cloned = status.clone();
assert_eq!(status, cloned);
}
#[test]
fn test_source_location_creation() {
let loc = SourceLocation {
line: 10,
column: 5,
end_line: 15,
end_column: 20,
};
assert_eq!(loc.line, 10);
assert_eq!(loc.column, 5);
assert_eq!(loc.end_line, 15);
assert_eq!(loc.end_column, 20);
}
#[test]
fn test_source_location_zero_values() {
let loc = SourceLocation {
line: 0,
column: 0,
end_line: 0,
end_column: 0,
};
assert_eq!(loc.line, 0);
assert_eq!(loc.column, 0);
}
#[test]
fn test_source_location_max_values() {
let loc = SourceLocation {
line: usize::MAX,
column: usize::MAX,
end_line: usize::MAX,
end_column: usize::MAX,
};
assert_eq!(loc.line, usize::MAX);
assert_eq!(loc.column, usize::MAX);
}
#[test]
fn test_source_location_clone() {
let loc = create_test_location(42, 10);
let cloned = loc.clone();
assert_eq!(loc, cloned);
}
#[test]
fn test_source_location_hash() {
let mut set: HashSet<SourceLocation> = HashSet::new();
set.insert(create_test_location(1, 1));
set.insert(create_test_location(2, 2));
set.insert(create_test_location(1, 1));
assert_eq!(set.len(), 2);
}
#[test]
fn test_mutant_creation_complete() {
let mutant = Mutant {
id: "test_123".to_string(),
original_file: PathBuf::from("src/lib.rs"),
mutated_source: "fn mutated() { }".to_string(),
location: create_test_location(10, 5),
operator: MutationOperatorType::ArithmeticReplacement,
hash: "abc123def456".to_string(),
status: MutantStatus::Pending,
};
assert_eq!(mutant.id, "test_123");
assert_eq!(mutant.original_file, PathBuf::from("src/lib.rs"));
assert_eq!(mutant.mutated_source, "fn mutated() { }");
assert_eq!(mutant.location.line, 10);
assert_eq!(mutant.hash, "abc123def456");
assert_eq!(mutant.status, MutantStatus::Pending);
}
#[test]
fn test_mutant_clone_and_equality() {
let mutant = create_test_mutant("m1", MutantStatus::Pending);
let cloned = mutant.clone();
assert_eq!(mutant, cloned);
assert_eq!(mutant.id, cloned.id);
assert_eq!(mutant.hash, cloned.hash);
}
#[test]
fn test_mutant_hash_in_collection() {
let mut set: HashSet<Mutant> = HashSet::new();
set.insert(create_test_mutant("m1", MutantStatus::Pending));
set.insert(create_test_mutant("m2", MutantStatus::Killed));
set.insert(create_test_mutant("m1", MutantStatus::Pending));
assert_eq!(set.len(), 2);
}
#[test]
fn test_mutant_debug_format() {
let mutant = create_test_mutant("debug_test", MutantStatus::Survived);
let debug_str = format!("{:?}", mutant);
assert!(debug_str.contains("debug_test"));
assert!(debug_str.contains("Survived"));
}
#[test]
fn test_mutation_result_creation_killed() {
let result = MutationResult {
mutant: create_test_mutant("killed_test", MutantStatus::Killed),
status: MutantStatus::Killed,
test_failures: vec!["test_add".to_string(), "test_sub".to_string()],
execution_time_ms: 250,
error_message: None,
};
assert_eq!(result.status, MutantStatus::Killed);
assert_eq!(result.test_failures.len(), 2);
assert_eq!(result.execution_time_ms, 250);
assert!(result.error_message.is_none());
}
#[test]
fn test_mutation_result_with_error() {
let result = MutationResult {
mutant: create_test_mutant("error_test", MutantStatus::CompileError),
status: MutantStatus::CompileError,
test_failures: vec![],
execution_time_ms: 0,
error_message: Some("error[E0308]: mismatched types".to_string()),
};
assert!(result.error_message.is_some());
assert!(result.error_message.unwrap().contains("E0308"));
}
#[test]
fn test_mutation_result_timeout() {
let result = MutationResult {
mutant: create_test_mutant("timeout_test", MutantStatus::Timeout),
status: MutantStatus::Timeout,
test_failures: vec![],
execution_time_ms: 60000,
error_message: Some("Test exceeded timeout of 60s".to_string()),
};
assert_eq!(result.status, MutantStatus::Timeout);
assert_eq!(result.execution_time_ms, 60000);
}
#[test]
fn test_mutation_result_clone() {
let result = create_test_result(MutantStatus::Survived, "test.rs", 10);
let cloned = result.clone();
assert_eq!(result.status, cloned.status);
assert_eq!(result.execution_time_ms, cloned.execution_time_ms);
}
#[test]
fn test_mutation_score_from_empty_results() {
let results: Vec<MutationResult> = vec![];
let score = MutationScore::from_results(&results);
assert_eq!(score.total, 0);
assert_eq!(score.killed, 0);
assert_eq!(score.survived, 0);
assert_eq!(score.score, 0.0);
}
#[test]
fn test_mutation_score_all_killed() {
let results = vec![
create_test_result(MutantStatus::Killed, "a.rs", 1),
create_test_result(MutantStatus::Killed, "a.rs", 2),
create_test_result(MutantStatus::Killed, "a.rs", 3),
];
let score = MutationScore::from_results(&results);
assert_eq!(score.total, 3);
assert_eq!(score.killed, 3);
assert_eq!(score.survived, 0);
assert_eq!(score.score, 1.0);
}
#[test]
fn test_mutation_score_all_survived() {
let results = vec![
create_test_result(MutantStatus::Survived, "a.rs", 1),
create_test_result(MutantStatus::Survived, "a.rs", 2),
];
let score = MutationScore::from_results(&results);
assert_eq!(score.killed, 0);
assert_eq!(score.survived, 2);
assert_eq!(score.score, 0.0);
}
#[test]
fn test_mutation_score_mixed_results() {
let results = vec![
create_test_result(MutantStatus::Killed, "a.rs", 1),
create_test_result(MutantStatus::Killed, "a.rs", 2),
create_test_result(MutantStatus::Survived, "a.rs", 3),
create_test_result(MutantStatus::Equivalent, "a.rs", 4),
create_test_result(MutantStatus::CompileError, "a.rs", 5),
];
let score = MutationScore::from_results(&results);
assert_eq!(score.total, 5);
assert_eq!(score.killed, 2);
assert_eq!(score.survived, 1);
assert_eq!(score.equivalent, 1);
assert_eq!(score.compile_errors, 1);
}
#[test]
fn test_mutation_score_all_equivalent() {
let results = vec![
create_test_result(MutantStatus::Equivalent, "a.rs", 1),
create_test_result(MutantStatus::Equivalent, "a.rs", 2),
];
let score = MutationScore::from_results(&results);
assert_eq!(score.equivalent, 2);
assert_eq!(score.score, 0.0); }
#[test]
fn test_mutation_score_all_compile_errors() {
let results = vec![
create_test_result(MutantStatus::CompileError, "a.rs", 1),
create_test_result(MutantStatus::CompileError, "a.rs", 2),
];
let score = MutationScore::from_results(&results);
assert_eq!(score.compile_errors, 2);
assert_eq!(score.score, 0.0); }
#[test]
fn test_mutation_score_clone() {
let results = vec![create_test_result(MutantStatus::Killed, "a.rs", 1)];
let score = MutationScore::from_results(&results);
let cloned = score.clone();
assert_eq!(score.total, cloned.total);
assert_eq!(score.score, cloned.score);
}
#[test]
fn test_weak_spot_creation() {
let weak_spot = WeakSpot {
file: PathBuf::from("src/vulnerable.rs"),
line_range: (10, 50),
survived_mutants: 5,
suggestions: vec![
"Add edge case tests".to_string(),
"Test error handling".to_string(),
],
};
assert_eq!(weak_spot.file, PathBuf::from("src/vulnerable.rs"));
assert_eq!(weak_spot.line_range, (10, 50));
assert_eq!(weak_spot.survived_mutants, 5);
assert_eq!(weak_spot.suggestions.len(), 2);
}
#[test]
fn test_weak_spot_clone() {
let weak_spot = WeakSpot {
file: PathBuf::from("test.rs"),
line_range: (1, 10),
survived_mutants: 3,
suggestions: vec!["suggestion".to_string()],
};
let cloned = weak_spot.clone();
assert_eq!(weak_spot.file, cloned.file);
assert_eq!(weak_spot.line_range, cloned.line_range);
}
#[test]
fn test_mutation_scorer_new() {
let results = vec![create_test_result(MutantStatus::Killed, "a.rs", 1)];
let scorer = MutationScorer::new(results);
let score = scorer.calculate_score();
assert_eq!(score.total, 1);
}
#[test]
fn test_mutation_scorer_weak_spots_empty() {
let results: Vec<MutationResult> = vec![];
let scorer = MutationScorer::new(results);
let weak_spots = scorer.weak_spots();
assert!(weak_spots.is_empty());
}
#[test]
fn test_mutation_scorer_weak_spots_no_survivors() {
let results = vec![
create_test_result(MutantStatus::Killed, "a.rs", 1),
create_test_result(MutantStatus::Killed, "b.rs", 1),
];
let scorer = MutationScorer::new(results);
let weak_spots = scorer.weak_spots();
assert!(weak_spots.is_empty());
}
#[test]
fn test_mutation_scorer_weak_spots_sorted() {
let results = vec![
create_test_result(MutantStatus::Survived, "a.rs", 1),
create_test_result(MutantStatus::Survived, "b.rs", 1),
create_test_result(MutantStatus::Survived, "b.rs", 2),
create_test_result(MutantStatus::Survived, "b.rs", 3),
];
let scorer = MutationScorer::new(results);
let weak_spots = scorer.weak_spots();
assert_eq!(weak_spots.len(), 2);
assert_eq!(weak_spots[0].survived_mutants, 3);
assert_eq!(weak_spots[1].survived_mutants, 1);
}
#[test]
fn test_mutation_scorer_summary() {
let results = vec![
create_test_result(MutantStatus::Killed, "a.rs", 1),
create_test_result(MutantStatus::Survived, "a.rs", 2),
create_test_result(MutantStatus::CompileError, "a.rs", 3),
];
let scorer = MutationScorer::new(results);
let summary = scorer.summary();
assert_eq!(summary.total_mutants, 3);
assert_eq!(summary.killed, 1);
assert_eq!(summary.survived, 1);
assert_eq!(summary.compile_errors, 1);
}
#[test]
fn test_mutation_progress_percentage_zero_total() {
let progress = MutationProgress {
total: 0,
completed: 0,
in_progress: 0,
killed: 0,
survived: 0,
failed: 0,
};
assert_eq!(progress.percentage(), 100.0);
}
#[test]
fn test_mutation_progress_percentage_partial() {
let progress = MutationProgress {
total: 100,
completed: 25,
in_progress: 5,
killed: 20,
survived: 5,
failed: 0,
};
assert_eq!(progress.percentage(), 25.0);
}
#[test]
fn test_mutation_progress_mutation_score() {
let progress = MutationProgress {
total: 100,
completed: 100,
in_progress: 0,
killed: 80,
survived: 20,
failed: 0,
};
assert_eq!(progress.mutation_score(), 80.0);
}
#[test]
fn test_mutation_progress_mutation_score_no_tested() {
let progress = MutationProgress {
total: 100,
completed: 0,
in_progress: 0,
killed: 0,
survived: 0,
failed: 0,
};
assert_eq!(progress.mutation_score(), 0.0);
}
#[test]
fn test_mutation_progress_clone() {
let progress = MutationProgress {
total: 50,
completed: 25,
in_progress: 5,
killed: 20,
survived: 5,
failed: 0,
};
let cloned = progress.clone();
assert_eq!(progress.total, cloned.total);
assert_eq!(progress.completed, cloned.completed);
}
#[test]
fn test_mutation_state_new() {
let mutants = vec![
create_test_mutant("m1", MutantStatus::Pending),
create_test_mutant("m2", MutantStatus::Pending),
];
let state = MutationState::new(std::path::Path::new("/project"), mutants, 60, true, Some(4));
assert_eq!(state.pending_mutants.len(), 2);
assert!(state.completed_mutants.is_empty());
assert!(!state.is_complete());
assert_eq!(state.total_mutants(), 2);
}
#[test]
fn test_mutation_state_add_result() {
let mutants = vec![create_test_mutant("m1", MutantStatus::Pending)];
let mut state = MutationState::new(std::path::Path::new("/project"), mutants, 60, false, None);
let result = MutationResult {
mutant: create_test_mutant("m1", MutantStatus::Killed),
status: MutantStatus::Killed,
test_failures: vec!["test".to_string()],
execution_time_ms: 100,
error_message: None,
};
state.add_result(result);
assert!(state.pending_mutants.is_empty());
assert_eq!(state.completed_mutants.len(), 1);
assert!(state.is_complete());
}
#[test]
fn test_mutation_state_completion_percentage() {
let mutants = vec![
create_test_mutant("m1", MutantStatus::Pending),
create_test_mutant("m2", MutantStatus::Pending),
];
let mut state = MutationState::new(std::path::Path::new("/project"), mutants, 60, false, None);
assert_eq!(state.completion_percentage(), 0.0);
let result = MutationResult {
mutant: create_test_mutant("m1", MutantStatus::Killed),
status: MutantStatus::Killed,
test_failures: vec![],
execution_time_ms: 100,
error_message: None,
};
state.add_result(result);
assert_eq!(state.completion_percentage(), 50.0);
}
#[test]
fn test_mutation_state_empty() {
let state = MutationState::new(std::path::Path::new("/project"), vec![], 60, false, None);
assert!(state.is_complete());
assert_eq!(state.completion_percentage(), 100.0);
}
#[test]
fn test_mutation_state_default_path() {
let path = MutationState::default_state_path(std::path::Path::new("/my/project"));
assert!(path.to_string_lossy().contains(".pmat"));
assert!(path.to_string_lossy().contains("mutation_state.json"));
}
#[test]
fn test_mutation_state_config() {
let config = MutationStateConfig {
timeout_secs: 120,
worker_count: Some(8),
parallel: true,
};
assert_eq!(config.timeout_secs, 120);
assert_eq!(config.worker_count, Some(8));
assert!(config.parallel);
}
#[test]
fn test_mutation_config_default() {
let config = MutationConfig::default();
assert!(matches!(config.strategy, MutationStrategy::Selective));
assert_eq!(config.max_mutants, 0);
assert!(config.parallel_threads > 0);
}
#[test]
fn test_mutation_config_custom() {
let config = MutationConfig {
strategy: MutationStrategy::Random,
max_mutants: 100,
parallel_threads: 4,
};
assert!(matches!(config.strategy, MutationStrategy::Random));
assert_eq!(config.max_mutants, 100);
assert_eq!(config.parallel_threads, 4);
}
#[test]
fn test_mutation_strategy_hybrid() {
let strategy = MutationStrategy::Hybrid {
selective: 0.7,
random: 0.3,
};
if let MutationStrategy::Hybrid { selective, random } = strategy {
assert!((selective - 0.7).abs() < 0.001);
assert!((random - 0.3).abs() < 0.001);
} else {
panic!("Expected Hybrid strategy");
}
}
#[test]
fn test_distributed_config_default() {
let config = DistributedConfig::default();
assert!(config.worker_count > 0);
assert!(config.max_concurrent >= config.worker_count);
assert_eq!(config.queue_size, 1000);
assert!(config.track_progress);
}
#[test]
fn test_distributed_config_custom() {
let config = DistributedConfig {
worker_count: 8,
max_concurrent: 16,
queue_size: 500,
track_progress: false,
};
assert_eq!(config.worker_count, 8);
assert_eq!(config.max_concurrent, 16);
assert_eq!(config.queue_size, 500);
assert!(!config.track_progress);
}
#[test]
fn test_distributed_config_clone() {
let config = DistributedConfig::default();
let cloned = config.clone();
assert_eq!(config.worker_count, cloned.worker_count);
assert_eq!(config.track_progress, cloned.track_progress);
}
#[test]
fn test_language_from_extension_rust() {
let lang = Language::from_extension(std::path::Path::new("test.rs"));
assert_eq!(lang, Language::Rust);
assert_eq!(lang.name(), "Rust");
assert!(lang.is_supported());
}
#[test]
fn test_language_from_extension_python() {
let lang = Language::from_extension(std::path::Path::new("test.py"));
assert_eq!(lang, Language::Python);
assert_eq!(lang.name(), "Python");
assert!(lang.is_supported());
}
#[test]
fn test_language_from_extension_typescript() {
let lang = Language::from_extension(std::path::Path::new("test.ts"));
assert_eq!(lang, Language::TypeScript);
let tsx_lang = Language::from_extension(std::path::Path::new("test.tsx"));
assert_eq!(tsx_lang, Language::TypeScript);
}
#[test]
fn test_language_from_extension_javascript() {
let lang = Language::from_extension(std::path::Path::new("test.js"));
assert_eq!(lang, Language::JavaScript);
let jsx_lang = Language::from_extension(std::path::Path::new("test.jsx"));
assert_eq!(jsx_lang, Language::JavaScript);
}
#[test]
fn test_language_from_extension_go() {
let lang = Language::from_extension(std::path::Path::new("test.go"));
assert_eq!(lang, Language::Go);
assert_eq!(lang.name(), "Go");
}
#[test]
fn test_language_from_extension_cpp() {
let extensions = vec!["cpp", "cc", "cxx", "hpp", "hxx", "h"];
for ext in extensions {
let path = format!("test.{}", ext);
let lang = Language::from_extension(std::path::Path::new(&path));
assert_eq!(lang, Language::Cpp, "Failed for extension: {}", ext);
}
}
#[test]
fn test_language_from_extension_unsupported() {
let lang = Language::from_extension(std::path::Path::new("test.xyz"));
assert_eq!(lang, Language::Unsupported);
assert!(!lang.is_supported());
assert_eq!(lang.name(), "Unsupported");
}
#[test]
fn test_language_extensions() {
assert_eq!(Language::Rust.extensions(), vec!["rs"]);
assert_eq!(Language::Python.extensions(), vec!["py"]);
assert_eq!(Language::Go.extensions(), vec!["go"]);
assert!(Language::Unsupported.extensions().is_empty());
}
#[test]
fn test_language_case_sensitive() {
let lang = Language::from_extension(std::path::Path::new("test.RS"));
assert_eq!(lang, Language::Unsupported);
}
#[test]
fn test_language_registry_new() {
let registry = LanguageRegistry::new();
assert!(registry.languages().is_empty());
}
#[test]
fn test_language_registry_default() {
let registry = LanguageRegistry::default();
assert!(registry.languages().is_empty());
}
#[test]
fn test_language_registry_register_rust() {
let mut registry = LanguageRegistry::new();
registry.register(Arc::new(RustAdapter::new()));
assert!(registry.languages().contains(&"rust"));
assert!(registry.get_adapter("rust").is_some());
}
#[test]
fn test_language_registry_detect_rust() {
let mut registry = LanguageRegistry::new();
registry.register(Arc::new(RustAdapter::new()));
let detected = registry.detect_language(std::path::Path::new("test.rs"));
assert!(detected.is_some());
assert_eq!(detected.unwrap().name(), "rust");
}
#[test]
fn test_language_registry_detect_unknown() {
let registry = LanguageRegistry::new();
let detected = registry.detect_language(std::path::Path::new("test.xyz"));
assert!(detected.is_none());
}
#[test]
fn test_language_registry_get_adapter_unknown() {
let registry = LanguageRegistry::new();
assert!(registry.get_adapter("unknown").is_none());
}
#[test]
fn test_test_run_result_passed() {
let result = TestRunResult {
passed: true,
failures: vec![],
execution_time_ms: 100,
stdout: "All tests passed".to_string(),
stderr: String::new(),
};
assert!(result.passed);
assert!(result.failures.is_empty());
}
#[test]
fn test_test_run_result_failed() {
let result = TestRunResult {
passed: false,
failures: vec!["test_add".to_string(), "test_sub".to_string()],
execution_time_ms: 500,
stdout: "running 2 tests".to_string(),
stderr: "thread panicked".to_string(),
};
assert!(!result.passed);
assert_eq!(result.failures.len(), 2);
assert!(result.stderr.contains("panicked"));
}
#[test]
fn test_test_run_result_clone() {
let result = TestRunResult {
passed: true,
failures: vec![],
execution_time_ms: 100,
stdout: "output".to_string(),
stderr: String::new(),
};
let cloned = result.clone();
assert_eq!(result.passed, cloned.passed);
assert_eq!(result.execution_time_ms, cloned.execution_time_ms);
}
#[test]
fn test_mutation_engine_default_rust() {
let engine = MutationEngine::default_rust();
assert!(std::mem::size_of_val(&engine) > 0);
}
#[test]
fn test_mutation_engine_new() {
let adapter = Arc::new(RustAdapter::new());
let config = MutationConfig::default();
let engine = MutationEngine::new(adapter, config);
assert!(std::mem::size_of_val(&engine) > 0);
}
#[test]
fn test_mutation_engine_default() {
let engine = MutationEngine::default();
assert!(std::mem::size_of_val(&engine) > 0);
}
#[test]
fn test_rust_adapter_new() {
let adapter = RustAdapter::new();
assert_eq!(adapter.name(), "rust");
}
#[test]
fn test_rust_adapter_extensions() {
let adapter = RustAdapter::new();
assert_eq!(adapter.extensions(), &["rs"]);
}
#[test]
fn test_rust_adapter_mutation_operators() {
let adapter = RustAdapter::new();
let operators = adapter.mutation_operators();
assert!(!operators.is_empty());
let names: Vec<&str> = operators.iter().map(|op| op.name()).collect();
assert!(names.contains(&"AOR"));
assert!(names.contains(&"ROR"));
}