#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
use tree_sitter::Parser;
fn parse_rust(source: &str) -> Tree {
let mut parser = Parser::new();
parser.set_language(&tree_sitter_rust::language()).unwrap();
parser.parse(source, None).unwrap()
}
#[test]
fn test_cyclomatic_complexity() {
let source = r#"
fn test() {
if x > 0 {
if y > 0 {
return 1;
}
}
while z < 10 {
z += 1;
}
}
"#;
let tree = parse_rust(source);
let scorer = StructuralComplexityScorer::new();
let complexity = scorer.calculate_cyclomatic_complexity(tree.root_node());
assert!(complexity >= 3);
}
#[test]
fn test_cognitive_complexity() {
let source = r#"
fn test() {
if x > 0 {
if y > 0 {
while z < 10 {
if w == 0 {
break;
}
}
}
}
}
"#;
let tree = parse_rust(source);
let scorer = SemanticComplexityScorer::new();
let complexity = scorer.calculate_cognitive_complexity(tree.root_node());
assert!(complexity > 0);
}
#[test]
fn test_function_extraction() {
let source = r#"
fn helper_one() {
println!("simple");
}
fn helper_two() {
if x > 0 {
return 1;
}
return 0;
}
fn main() {
helper_one();
helper_two();
}
"#;
let tree = parse_rust(source);
let scorer = StructuralComplexityScorer::new();
let functions = scorer.extract_functions(tree.root_node());
assert_eq!(functions.len(), 3);
}
#[test]
fn test_per_function_scoring() {
let source = r#"
fn emit_memory_section() -> Option<u32> {
if needs_memory() {
Some(1)
} else {
None
}
}
fn lower_while() -> Vec<u32> {
let mut v = vec![];
if condition() {
v.push(1);
}
v
}
fn lower_expression() -> u32 {
match get_type() {
1 => lower_while().len() as u32,
_ => 0,
}
}
fn needs_memory() -> bool { true }
fn condition() -> bool { false }
fn get_type() -> u32 { 1 }
"#;
let tree = parse_rust(source);
let scorer = StructuralComplexityScorer::new();
let functions = scorer.extract_functions(tree.root_node());
assert_eq!(functions.len(), 6);
for func in &functions {
let complexity = scorer.calculate_cyclomatic_complexity(*func);
assert!(complexity <= 10, "Function complexity {} exceeds Toyota Way limit", complexity);
}
}
#[test]
fn test_toyota_way_compliance() {
let good_source = r#"
fn a() { return 1; }
fn b() { return 2; }
fn c() { if x > 0 { return 3; } return 0; }
fn d() { return 4; }
fn e() { return 5; }
fn f() { return 6; }
fn g() { return 7; }
fn h() { return 8; }
fn i() { return 9; }
fn j() { return 10; }
fn k() { return 11; }
fn l() { return 12; }
"#;
let tree = parse_rust(good_source);
let scorer = StructuralComplexityScorer::new();
let config = TdgConfig::default();
let mut tracker = PenaltyTracker::new();
let score = scorer.score(&tree, good_source, Language::Rust, &config, &mut tracker).unwrap();
assert!(score >= 20.0, "Expected high score for well-decomposed code, got {}", score);
}
}