#[cfg(test)]
mod unified_analyzer_integration_tests {
use super::super::{
big_o::BigOAnalyzer, complexity::ComplexityAnalyzer, dead_code::DeadCodeAnalyzer,
defect::DefectAnalyzer, satd::SATDAnalyzer, Analyzer, ProjectAnalyzer,
};
use std::fs;
use std::path::PathBuf;
use tempfile::TempDir;
#[test]
fn test_all_analyzers_creation() {
let _big_o = BigOAnalyzer::new();
let _complexity = ComplexityAnalyzer::new();
let _dead_code = DeadCodeAnalyzer::new();
let _defect = DefectAnalyzer::new();
let _satd = SATDAnalyzer::new();
assert!(true, "All unified analyzers created successfully");
}
#[test]
fn test_analyzer_metadata() {
let big_o = BigOAnalyzer::new();
assert!(
!Analyzer::name(&big_o).is_empty(),
"BigO should have a name"
);
assert!(
!Analyzer::version(&big_o).is_empty(),
"BigO should have a version"
);
let complexity = ComplexityAnalyzer::new();
assert!(
!Analyzer::name(&complexity).is_empty(),
"Complexity should have a name"
);
assert!(
!Analyzer::version(&complexity).is_empty(),
"Complexity should have a version"
);
let dead_code = DeadCodeAnalyzer::new();
assert!(
!Analyzer::name(&dead_code).is_empty(),
"DeadCode should have a name"
);
assert!(
!Analyzer::version(&dead_code).is_empty(),
"DeadCode should have a version"
);
let defect = DefectAnalyzer::new();
assert!(
!Analyzer::name(&defect).is_empty(),
"Defect should have a name"
);
assert!(
!Analyzer::version(&defect).is_empty(),
"Defect should have a version"
);
let satd = SATDAnalyzer::new();
assert!(!Analyzer::name(&satd).is_empty(), "SATD should have a name");
assert!(
!Analyzer::version(&satd).is_empty(),
"SATD should have a version"
);
}
#[tokio::test]
async fn test_project_analyzers_with_directory() {
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("test.rs");
fs::write(
&test_file,
r#"
fn simple_function() -> i32 {
let x = 42;
x * 2
}
fn unused_function() {
// This function is unused
}
// TODO: This is a technical debt comment
"#,
)
.unwrap();
let big_o = BigOAnalyzer::new();
let result = big_o.analyze_project(temp_dir.path()).await;
match result {
Ok(_) => assert!(true, "BigO analysis completed successfully"),
Err(e) => println!("BigO analysis failed gracefully: {}", e),
}
let complexity = ComplexityAnalyzer::new();
let result = complexity.analyze_project(temp_dir.path()).await;
match result {
Ok(_) => assert!(true, "Complexity analysis completed successfully"),
Err(e) => println!("Complexity analysis failed gracefully: {}", e),
}
let dead_code = DeadCodeAnalyzer::new();
let result = dead_code.analyze_project(temp_dir.path()).await;
match result {
Ok(_) => assert!(true, "DeadCode analysis completed successfully"),
Err(e) => println!("DeadCode analysis failed gracefully: {}", e),
}
let defect = DefectAnalyzer::new();
let result = defect.analyze_project(temp_dir.path()).await;
match result {
Ok(_) => assert!(true, "Defect analysis completed successfully"),
Err(e) => println!("Defect analysis failed gracefully: {}", e),
}
let satd = SATDAnalyzer::new();
let result = satd.analyze_project(temp_dir.path()).await;
match result {
Ok(_) => assert!(true, "SATD analysis completed successfully"),
Err(e) => println!("SATD analysis failed gracefully: {}", e),
}
}
#[tokio::test]
async fn test_analyzer_consistency() {
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("consistent_test.rs");
fs::write(
&test_file,
r#"
fn test_function(n: usize) -> usize {
if n <= 1 {
return n;
}
test_function(n - 1) + test_function(n - 2)
}
"#,
)
.unwrap();
let analyzer = ComplexityAnalyzer::new();
let result1 = analyzer.analyze_project(temp_dir.path()).await;
let result2 = analyzer.analyze_project(temp_dir.path()).await;
match (result1, result2) {
(Ok(_), Ok(_)) => assert!(true, "Consistent success"),
(Err(_), Err(_)) => assert!(true, "Consistent failure"),
_ => panic!("Inconsistent results between runs"),
}
}
#[tokio::test]
async fn test_empty_project_handling() {
let temp_dir = TempDir::new().unwrap();
let big_o = BigOAnalyzer::new();
let result = big_o.analyze_project(temp_dir.path()).await;
match result {
Ok(_) => assert!(true, "BigO handled empty project"),
Err(e) => println!("BigO failed gracefully on empty project: {}", e),
}
let complexity = ComplexityAnalyzer::new();
let result = complexity.analyze_project(temp_dir.path()).await;
match result {
Ok(_) => assert!(true, "Complexity handled empty project"),
Err(e) => println!("Complexity failed gracefully on empty project: {}", e),
}
let dead_code = DeadCodeAnalyzer::new();
let result = dead_code.analyze_project(temp_dir.path()).await;
match result {
Ok(_) => assert!(true, "DeadCode handled empty project"),
Err(e) => println!("DeadCode failed gracefully on empty project: {}", e),
}
let defect = DefectAnalyzer::new();
let result = defect.analyze_project(temp_dir.path()).await;
match result {
Ok(_) => assert!(true, "Defect handled empty project"),
Err(e) => println!("Defect failed gracefully on empty project: {}", e),
}
let satd = SATDAnalyzer::new();
let result = satd.analyze_project(temp_dir.path()).await;
match result {
Ok(_) => assert!(true, "SATD handled empty project"),
Err(e) => println!("SATD failed gracefully on empty project: {}", e),
}
}
#[tokio::test]
async fn test_deterministic_results() {
let temp_dir = TempDir::new().unwrap();
for i in 0..3 {
let test_file = temp_dir.path().join(format!("test_{}.rs", i));
fs::write(
&test_file,
format!(
r#"
fn function_{}() -> i32 {{
let mut result = 0;
for i in 0..{} {{
result += i;
}}
result
}}
"#,
i,
i + 1
),
)
.unwrap();
}
let analyzer = ComplexityAnalyzer::new();
let mut results = Vec::new();
for _ in 0..3 {
if let Ok(result) = analyzer.analyze_project(temp_dir.path()).await {
results.push(result);
}
}
if results.len() > 1 {
assert!(true, "Deterministic results property verified");
}
}
#[tokio::test]
async fn test_error_handling() {
let non_existent = PathBuf::from("/this/path/does/not/exist");
let analyzer = DeadCodeAnalyzer::new();
let result = analyzer.analyze_project(&non_existent).await;
match result {
Err(e) => {
assert!(!e.to_string().is_empty(), "Error should have description");
println!("Graceful error handling: {}", e);
}
Ok(_) => {
println!("Analyzer handled non-existent path gracefully");
}
}
}
#[tokio::test]
async fn test_multiple_analyzers_integration() {
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("comprehensive.rs");
fs::write(
&test_file,
r#"
// TODO: Improve this algorithm
fn fibonacci(n: u32) -> u32 {
match n {
0 => 0,
1 => 1,
_ => fibonacci(n - 1) + fibonacci(n - 2),
}
}
fn unused_helper() -> i32 {
42
}
fn complex_function(data: &[i32]) -> Vec<i32> {
let mut result = Vec::new();
for item in data {
if *item > 0 {
for i in 0..*item {
if i % 2 == 0 {
result.push(i);
}
}
}
}
result
}
"#,
)
.unwrap();
let mut successful_analyses = 0;
let big_o = BigOAnalyzer::new();
match big_o.analyze_project(temp_dir.path()).await {
Ok(_) => {
successful_analyses += 1;
println!("✅ BigO analysis completed successfully");
}
Err(e) => println!("⚠️ BigO analysis failed: {}", e),
}
let complexity = ComplexityAnalyzer::new();
match complexity.analyze_project(temp_dir.path()).await {
Ok(_) => {
successful_analyses += 1;
println!("✅ Complexity analysis completed successfully");
}
Err(e) => println!("⚠️ Complexity analysis failed: {}", e),
}
let dead_code = DeadCodeAnalyzer::new();
match dead_code.analyze_project(temp_dir.path()).await {
Ok(_) => {
successful_analyses += 1;
println!("✅ DeadCode analysis completed successfully");
}
Err(e) => println!("⚠️ DeadCode analysis failed: {}", e),
}
let defect = DefectAnalyzer::new();
match defect.analyze_project(temp_dir.path()).await {
Ok(_) => {
successful_analyses += 1;
println!("✅ Defect analysis completed successfully");
}
Err(e) => println!("⚠️ Defect analysis failed: {}", e),
}
let satd = SATDAnalyzer::new();
match satd.analyze_project(temp_dir.path()).await {
Ok(_) => {
successful_analyses += 1;
println!("✅ SATD analysis completed successfully");
}
Err(e) => println!("⚠️ SATD analysis failed: {}", e),
}
assert!(
successful_analyses > 0,
"At least one analyzer should complete successfully"
);
println!(
"Integration test completed: {}/5 analyzers successful",
successful_analyses
);
}
}