use debtmap::core::metrics::{
calculate_average_complexity, calculate_length_penalty, calculate_nesting_penalty,
count_high_complexity, find_max_complexity, group_by_file, sort_by_complexity,
};
use debtmap::core::FunctionMetrics;
use std::path::PathBuf;
#[test]
fn test_group_by_file_empty() {
let metrics = vec![];
let grouped = group_by_file(metrics);
assert!(grouped.is_empty());
}
#[test]
fn test_group_by_file_single_file() {
let metrics = vec![
FunctionMetrics::new("func1".to_string(), PathBuf::from("file1.rs"), 10),
FunctionMetrics::new("func2".to_string(), PathBuf::from("file1.rs"), 20),
];
let grouped = group_by_file(metrics);
assert_eq!(grouped.len(), 1);
assert!(grouped.contains_key(&PathBuf::from("file1.rs")));
assert_eq!(grouped[&PathBuf::from("file1.rs")].len(), 2);
}
#[test]
fn test_group_by_file_multiple_files() {
let metrics = vec![
FunctionMetrics::new("func1".to_string(), PathBuf::from("file1.rs"), 10),
FunctionMetrics::new("func2".to_string(), PathBuf::from("file2.rs"), 20),
FunctionMetrics::new("func3".to_string(), PathBuf::from("file1.rs"), 30),
FunctionMetrics::new("func4".to_string(), PathBuf::from("file3.rs"), 40),
];
let grouped = group_by_file(metrics);
assert_eq!(grouped.len(), 3);
assert_eq!(grouped[&PathBuf::from("file1.rs")].len(), 2);
assert_eq!(grouped[&PathBuf::from("file2.rs")].len(), 1);
assert_eq!(grouped[&PathBuf::from("file3.rs")].len(), 1);
}
#[test]
fn test_group_by_file_preserves_metrics() {
let mut metric = FunctionMetrics::new("complex_func".to_string(), PathBuf::from("file.rs"), 10);
metric.cyclomatic = 5;
metric.cognitive = 10;
metric.nesting = 3;
metric.length = 50;
let metrics = vec![metric.clone()];
let grouped = group_by_file(metrics);
let result = &grouped[&PathBuf::from("file.rs")][0];
assert_eq!(result.name, "complex_func");
assert_eq!(result.cyclomatic, 5);
assert_eq!(result.cognitive, 10);
assert_eq!(result.nesting, 3);
assert_eq!(result.length, 50);
}
#[test]
fn test_calculate_average_complexity_empty() {
let metrics = vec![];
let avg = calculate_average_complexity(&metrics);
assert_eq!(avg, 0.0);
}
#[test]
fn test_calculate_average_complexity_single() {
let mut metric = FunctionMetrics::new("func".to_string(), PathBuf::from("file.rs"), 10);
metric.cyclomatic = 5;
let metrics = vec![metric];
let avg = calculate_average_complexity(&metrics);
assert_eq!(avg, 5.0);
}
#[test]
fn test_calculate_average_complexity_multiple() {
let mut metric1 = FunctionMetrics::new("func1".to_string(), PathBuf::from("file.rs"), 10);
metric1.cyclomatic = 5;
let mut metric2 = FunctionMetrics::new("func2".to_string(), PathBuf::from("file.rs"), 20);
metric2.cyclomatic = 15;
let mut metric3 = FunctionMetrics::new("func3".to_string(), PathBuf::from("file.rs"), 30);
metric3.cyclomatic = 20;
let metrics = vec![metric1, metric2, metric3];
let avg = calculate_average_complexity(&metrics);
assert_eq!(avg, 40.0 / 3.0);
}
#[test]
fn test_find_max_complexity_empty() {
let metrics = vec![];
let max = find_max_complexity(&metrics);
assert_eq!(max, 0);
}
#[test]
fn test_find_max_complexity_single() {
let mut metric = FunctionMetrics::new("func".to_string(), PathBuf::from("file.rs"), 10);
metric.cyclomatic = 7;
let metrics = vec![metric];
let max = find_max_complexity(&metrics);
assert_eq!(max, 7);
}
#[test]
fn test_find_max_complexity_multiple() {
let mut metric1 = FunctionMetrics::new("func1".to_string(), PathBuf::from("file.rs"), 10);
metric1.cyclomatic = 5;
let mut metric2 = FunctionMetrics::new("func2".to_string(), PathBuf::from("file.rs"), 20);
metric2.cyclomatic = 15;
let mut metric3 = FunctionMetrics::new("func3".to_string(), PathBuf::from("file.rs"), 30);
metric3.cyclomatic = 10;
let metrics = vec![metric1, metric2, metric3];
let max = find_max_complexity(&metrics);
assert_eq!(max, 15);
}
#[test]
fn test_count_high_complexity_none() {
let mut metric1 = FunctionMetrics::new("func1".to_string(), PathBuf::from("file.rs"), 10);
metric1.cyclomatic = 5;
let mut metric2 = FunctionMetrics::new("func2".to_string(), PathBuf::from("file.rs"), 20);
metric2.cyclomatic = 8;
let metrics = vec![metric1, metric2];
let count = count_high_complexity(&metrics, 10);
assert_eq!(count, 0);
}
#[test]
fn test_count_high_complexity_some() {
let mut metric1 = FunctionMetrics::new("func1".to_string(), PathBuf::from("file.rs"), 10);
metric1.cyclomatic = 5;
let mut metric2 = FunctionMetrics::new("func2".to_string(), PathBuf::from("file.rs"), 20);
metric2.cyclomatic = 15;
let mut metric3 = FunctionMetrics::new("func3".to_string(), PathBuf::from("file.rs"), 30);
metric3.cyclomatic = 20;
let metrics = vec![metric1, metric2, metric3];
let count = count_high_complexity(&metrics, 10);
assert_eq!(count, 2); }
#[test]
fn test_sort_by_complexity() {
let mut metric1 = FunctionMetrics::new("low".to_string(), PathBuf::from("file.rs"), 10);
metric1.cyclomatic = 3;
let mut metric2 = FunctionMetrics::new("high".to_string(), PathBuf::from("file.rs"), 20);
metric2.cyclomatic = 20;
let mut metric3 = FunctionMetrics::new("medium".to_string(), PathBuf::from("file.rs"), 30);
metric3.cyclomatic = 10;
let metrics = vec![metric1, metric2, metric3];
let sorted = sort_by_complexity(metrics);
assert_eq!(sorted[0].name, "high");
assert_eq!(sorted[1].name, "medium");
assert_eq!(sorted[2].name, "low");
}
#[test]
fn test_calculate_nesting_penalty() {
assert_eq!(calculate_nesting_penalty(0), 0);
assert_eq!(calculate_nesting_penalty(1), 0);
assert_eq!(calculate_nesting_penalty(2), 0);
assert_eq!(calculate_nesting_penalty(3), 1);
assert_eq!(calculate_nesting_penalty(4), 1);
assert_eq!(calculate_nesting_penalty(5), 2);
assert_eq!(calculate_nesting_penalty(6), 2);
assert_eq!(calculate_nesting_penalty(7), 3);
}
#[test]
fn test_calculate_length_penalty() {
assert_eq!(calculate_length_penalty(10), 0);
assert_eq!(calculate_length_penalty(20), 0);
assert_eq!(calculate_length_penalty(21), 1);
assert_eq!(calculate_length_penalty(50), 1);
assert_eq!(calculate_length_penalty(51), 2);
assert_eq!(calculate_length_penalty(100), 2);
assert_eq!(calculate_length_penalty(101), 3);
}
#[test]
fn test_complexity_metrics_from_function() {
use debtmap::core::ComplexityMetrics;
let func = FunctionMetrics {
name: "test_func".to_string(),
file: PathBuf::from("test.rs"),
line: 42,
cyclomatic: 5,
cognitive: 8,
nesting: 2,
length: 30,
is_test: false,
visibility: None,
is_trait_method: false,
in_test_module: false,
entropy_score: None,
is_pure: None,
purity_confidence: None,
detected_patterns: None,
upstream_callers: None,
downstream_callees: None,
mapping_pattern_result: None,
adjusted_complexity: None,
composition_metrics: None,
language_specific: None,
purity_reason: None,
call_dependencies: None,
purity_level: None,
error_swallowing_count: None,
error_swallowing_patterns: None,
entropy_analysis: None,
};
let metrics = ComplexityMetrics::from_function(&func);
assert_eq!(metrics.functions.len(), 1);
assert_eq!(metrics.functions[0].name, "test_func");
assert_eq!(metrics.functions[0].cyclomatic, 5);
assert_eq!(metrics.functions[0].cognitive, 8);
assert_eq!(metrics.functions[0].nesting, 2);
assert_eq!(metrics.functions[0].length, 30);
assert_eq!(metrics.cyclomatic_complexity, 5);
assert_eq!(metrics.cognitive_complexity, 8);
}
#[test]
fn test_complexity_metrics_from_function_zero_values() {
use debtmap::core::ComplexityMetrics;
let func = FunctionMetrics {
name: "simple_func".to_string(),
file: PathBuf::from("simple.rs"),
line: 1,
cyclomatic: 0,
cognitive: 0,
nesting: 0,
length: 1,
is_test: false,
visibility: None,
is_trait_method: false,
in_test_module: false,
entropy_score: None,
is_pure: None,
purity_confidence: None,
detected_patterns: None,
upstream_callers: None,
downstream_callees: None,
mapping_pattern_result: None,
adjusted_complexity: None,
composition_metrics: None,
language_specific: None,
purity_reason: None,
call_dependencies: None,
purity_level: None,
error_swallowing_count: None,
error_swallowing_patterns: None,
entropy_analysis: None,
};
let metrics = ComplexityMetrics::from_function(&func);
assert_eq!(metrics.functions.len(), 1);
assert_eq!(metrics.cyclomatic_complexity, 0);
assert_eq!(metrics.cognitive_complexity, 0);
}
#[test]
fn test_complexity_metrics_from_function_high_values() {
use debtmap::core::ComplexityMetrics;
let func = FunctionMetrics {
name: "complex_func".to_string(),
file: PathBuf::from("complex.rs"),
line: 100,
cyclomatic: 50,
cognitive: 75,
nesting: 10,
length: 500,
is_test: false,
visibility: None,
is_trait_method: false,
in_test_module: false,
entropy_score: None,
is_pure: None,
purity_confidence: None,
detected_patterns: None,
upstream_callers: None,
downstream_callees: None,
mapping_pattern_result: None,
adjusted_complexity: None,
composition_metrics: None,
language_specific: None,
purity_reason: None,
call_dependencies: None,
purity_level: None,
error_swallowing_count: None,
error_swallowing_patterns: None,
entropy_analysis: None,
};
let metrics = ComplexityMetrics::from_function(&func);
assert_eq!(metrics.functions.len(), 1);
assert_eq!(metrics.cyclomatic_complexity, 50);
assert_eq!(metrics.cognitive_complexity, 75);
assert_eq!(metrics.functions[0].line, 100);
assert_eq!(metrics.functions[0].length, 500);
}
#[test]
fn test_complexity_metrics_from_function_preserves_path() {
use debtmap::core::ComplexityMetrics;
let complex_path = PathBuf::from("/src/deeply/nested/module/impl.rs");
let func = FunctionMetrics {
name: "nested_func".to_string(),
file: complex_path.clone(),
line: 200,
cyclomatic: 3,
cognitive: 4,
nesting: 1,
length: 15,
is_test: false,
visibility: None,
is_trait_method: false,
in_test_module: false,
entropy_score: None,
is_pure: None,
purity_confidence: None,
detected_patterns: None,
upstream_callers: None,
downstream_callees: None,
mapping_pattern_result: None,
adjusted_complexity: None,
composition_metrics: None,
language_specific: None,
purity_reason: None,
call_dependencies: None,
purity_level: None,
error_swallowing_count: None,
error_swallowing_patterns: None,
entropy_analysis: None,
};
let metrics = ComplexityMetrics::from_function(&func);
assert_eq!(metrics.functions[0].file, complex_path);
}