#![cfg_attr(coverage_nightly, coverage(off))]
use super::*;
use std::collections::HashMap;
use std::path::PathBuf;
use std::time::Duration;
pub fn create_minimal_analysis_results() -> AnalysisResults {
AnalysisResults {
total_duration: Duration::from_secs(5),
analyzed_files: 10,
total_lines: 1000,
complexity_analysis: None,
dead_code_analysis: None,
duplication_analysis: None,
tdg_analysis: None,
big_o_analysis: None,
}
}
pub fn create_full_analysis_results() -> AnalysisResults {
AnalysisResults {
total_duration: Duration::from_secs(60),
analyzed_files: 100,
total_lines: 50000,
complexity_analysis: Some(ComplexityAnalysis {
total_cyclomatic: 800,
total_cognitive: 1200,
functions: 80,
max_cyclomatic: 25,
high_complexity_functions: 12,
distribution: vec![20, 30, 15, 10, 5],
}),
dead_code_analysis: Some(DeadCodeAnalysis {
dead_lines: 500,
dead_functions: 15,
dead_code_percentage: 1.0,
}),
duplication_analysis: Some(DuplicationAnalysis {
duplicated_lines: 800,
duplicate_blocks: 25,
duplication_percentage: 1.6,
}),
tdg_analysis: Some(TdgAnalysis {
average_tdg: 3.5,
max_tdg: 6.0,
high_tdg_files: 8,
}),
big_o_analysis: Some(BigOAnalysis {
analyzed_functions: 80,
high_complexity_count: 5,
complexity_distribution: {
let mut map = HashMap::new();
map.insert("O(1)".to_string(), 30);
map.insert("O(n)".to_string(), 35);
map.insert("O(n^2)".to_string(), 10);
map.insert("O(log n)".to_string(), 5);
map
},
}),
}
}
pub fn create_healthy_analysis_results() -> AnalysisResults {
AnalysisResults {
total_duration: Duration::from_secs(30),
analyzed_files: 50,
total_lines: 20000,
complexity_analysis: Some(ComplexityAnalysis {
total_cyclomatic: 300,
total_cognitive: 400,
functions: 60,
max_cyclomatic: 10,
high_complexity_functions: 0,
distribution: vec![40, 15, 5, 0, 0],
}),
dead_code_analysis: Some(DeadCodeAnalysis {
dead_lines: 50,
dead_functions: 2,
dead_code_percentage: 0.25,
}),
duplication_analysis: Some(DuplicationAnalysis {
duplicated_lines: 100,
duplicate_blocks: 5,
duplication_percentage: 0.5,
}),
tdg_analysis: Some(TdgAnalysis {
average_tdg: 2.0,
max_tdg: 3.0,
high_tdg_files: 2,
}),
big_o_analysis: None,
}
}
pub fn create_unhealthy_analysis_results() -> AnalysisResults {
AnalysisResults {
total_duration: Duration::from_secs(120),
analyzed_files: 200,
total_lines: 100000,
complexity_analysis: Some(ComplexityAnalysis {
total_cyclomatic: 6000,
total_cognitive: 8000,
functions: 100,
max_cyclomatic: 80,
high_complexity_functions: 40,
distribution: vec![5, 10, 20, 25, 40],
}),
dead_code_analysis: Some(DeadCodeAnalysis {
dead_lines: 20000,
dead_functions: 100,
dead_code_percentage: 20.0,
}),
duplication_analysis: Some(DuplicationAnalysis {
duplicated_lines: 25000,
duplicate_blocks: 150,
duplication_percentage: 25.0,
}),
tdg_analysis: Some(TdgAnalysis {
average_tdg: 7.0,
max_tdg: 12.0,
high_tdg_files: 50,
}),
big_o_analysis: Some(BigOAnalysis {
analyzed_functions: 100,
high_complexity_count: 30,
complexity_distribution: {
let mut map = HashMap::new();
map.insert("O(n^3)".to_string(), 20);
map.insert("O(n^2)".to_string(), 40);
map.insert("O(n)".to_string(), 30);
map.insert("O(1)".to_string(), 10);
map
},
}),
}
}
pub fn create_test_report_config() -> ReportConfig {
ReportConfig {
project_path: PathBuf::from("/test/project"),
output_format: ReportFormat::Markdown,
include_visualizations: true,
include_executive_summary: true,
include_recommendations: true,
confidence_threshold: 80,
output_path: None,
}
}
#[test]
fn test_health_score_calculation() {
let service = EnhancedReportingService::default();
let results = AnalysisResults {
total_duration: std::time::Duration::from_secs(10),
analyzed_files: 100,
total_lines: 10000,
complexity_analysis: Some(ComplexityAnalysis {
total_cyclomatic: 500,
total_cognitive: 800,
functions: 50,
max_cyclomatic: 15,
high_complexity_functions: 5,
distribution: vec![10, 20, 15, 3, 2],
}),
dead_code_analysis: Some(DeadCodeAnalysis {
dead_lines: 100,
dead_functions: 5,
dead_code_percentage: 1.0,
}),
duplication_analysis: None,
tdg_analysis: None,
big_o_analysis: None,
};
let score = service.calculate_health_score(&results);
assert!(score > 80.0);
assert!(score <= 100.0);
}
#[test]
fn test_risk_assessment() {
let service = EnhancedReportingService::default();
let results = AnalysisResults {
total_duration: std::time::Duration::from_secs(10),
analyzed_files: 100,
total_lines: 10000,
complexity_analysis: Some(ComplexityAnalysis {
total_cyclomatic: 2000,
total_cognitive: 3000,
functions: 50,
max_cyclomatic: 50,
high_complexity_functions: 20,
distribution: vec![5, 10, 10, 10, 15],
}),
dead_code_analysis: Some(DeadCodeAnalysis {
dead_lines: 2000,
dead_functions: 50,
dead_code_percentage: 20.0,
}),
duplication_analysis: Some(DuplicationAnalysis {
duplicated_lines: 1500,
duplicate_blocks: 30,
duplication_percentage: 15.0,
}),
tdg_analysis: Some(TdgAnalysis {
average_tdg: 5.0,
max_tdg: 8.0,
high_tdg_files: 20,
}),
big_o_analysis: None,
};
let risk = service.assess_overall_risk(&results);
assert!(matches!(risk, RiskLevel::High | RiskLevel::Critical));
}
#[test]
fn test_service_creation() {
let service = EnhancedReportingService::new();
assert!(service.is_ok());
}
#[test]
fn test_service_default() {
let service = EnhancedReportingService::default();
assert!(true, "Service created via Default trait");
drop(service);
}
#[test]
fn test_health_score_minimal_results() {
let service = EnhancedReportingService::default();
let results = create_minimal_analysis_results();
let score = service.calculate_health_score(&results);
assert_eq!(score, 100.0);
}
#[test]
fn test_health_score_healthy_results() {
let service = EnhancedReportingService::default();
let results = create_healthy_analysis_results();
let score = service.calculate_health_score(&results);
assert!(score >= 80.0, "Expected score >= 80.0, got {}", score);
assert!(score <= 100.0, "Expected score <= 100.0, got {}", score);
}
#[test]
fn test_health_score_unhealthy_results() {
let service = EnhancedReportingService::default();
let results = create_unhealthy_analysis_results();
let score = service.calculate_health_score(&results);
assert!(score < 50.0, "Expected score < 50.0, got {}", score);
assert!(score >= 0.0, "Score should never be negative");
}
#[test]
fn test_health_score_only_complexity() {
let service = EnhancedReportingService::default();
let results = AnalysisResults {
total_duration: Duration::from_secs(10),
analyzed_files: 50,
total_lines: 10000,
complexity_analysis: Some(ComplexityAnalysis {
total_cyclomatic: 1500,
total_cognitive: 2000,
functions: 50,
max_cyclomatic: 35,
high_complexity_functions: 15,
distribution: vec![10, 15, 10, 10, 5],
}),
dead_code_analysis: None,
duplication_analysis: None,
tdg_analysis: None,
big_o_analysis: None,
};
let score = service.calculate_health_score(&results);
assert!(score <= 80.0, "Expected score <= 80.0, got {}", score);
assert!(score >= 60.0, "Expected score >= 60.0, got {}", score);
}
#[test]
fn test_health_score_only_dead_code() {
let service = EnhancedReportingService::default();
let results = AnalysisResults {
total_duration: Duration::from_secs(10),
analyzed_files: 50,
total_lines: 10000,
complexity_analysis: None,
dead_code_analysis: Some(DeadCodeAnalysis {
dead_lines: 1500,
dead_functions: 30,
dead_code_percentage: 15.0,
}),
duplication_analysis: None,
tdg_analysis: None,
big_o_analysis: None,
};
let score = service.calculate_health_score(&results);
assert!(score <= 85.0, "Expected score <= 85.0, got {}", score);
}
#[test]
fn test_health_score_only_duplication() {
let service = EnhancedReportingService::default();
let results = AnalysisResults {
total_duration: Duration::from_secs(10),
analyzed_files: 50,
total_lines: 10000,
complexity_analysis: None,
dead_code_analysis: None,
duplication_analysis: Some(DuplicationAnalysis {
duplicated_lines: 2000,
duplicate_blocks: 40,
duplication_percentage: 20.0,
}),
tdg_analysis: None,
big_o_analysis: None,
};
let score = service.calculate_health_score(&results);
assert!(score <= 85.0, "Expected score <= 85.0, got {}", score);
}
#[test]
fn test_health_score_only_tdg() {
let service = EnhancedReportingService::default();
let results = AnalysisResults {
total_duration: Duration::from_secs(10),
analyzed_files: 50,
total_lines: 10000,
complexity_analysis: None,
dead_code_analysis: None,
duplication_analysis: None,
tdg_analysis: Some(TdgAnalysis {
average_tdg: 7.0,
max_tdg: 12.0,
high_tdg_files: 15,
}),
big_o_analysis: None,
};
let score = service.calculate_health_score(&results);
assert!(score <= 80.0, "Expected score <= 80.0, got {}", score);
}
#[test]
fn test_health_score_never_negative() {
let service = EnhancedReportingService::default();
let results = AnalysisResults {
total_duration: Duration::from_secs(1000),
analyzed_files: 1000,
total_lines: 1000,
complexity_analysis: Some(ComplexityAnalysis {
total_cyclomatic: 100000,
total_cognitive: 200000,
functions: 100,
max_cyclomatic: 500,
high_complexity_functions: 80,
distribution: vec![0, 0, 0, 0, 100],
}),
dead_code_analysis: Some(DeadCodeAnalysis {
dead_lines: 500,
dead_functions: 50,
dead_code_percentage: 50.0,
}),
duplication_analysis: Some(DuplicationAnalysis {
duplicated_lines: 800,
duplicate_blocks: 80,
duplication_percentage: 80.0,
}),
tdg_analysis: Some(TdgAnalysis {
average_tdg: 20.0,
max_tdg: 50.0,
high_tdg_files: 100,
}),
big_o_analysis: None,
};
let score = service.calculate_health_score(&results);
assert!(
score >= 0.0,
"Score should never be negative, got {}",
score
);
}