#![cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod property_tests {
use crate::unified_quality::enhanced_parser::EnhancedParser;
use proptest::prelude::*;
use std::path::PathBuf;
fn valid_rust_identifier() -> impl Strategy<Value = String> {
prop::string::string_regex("[a-zA-Z_][a-zA-Z0-9_]*").unwrap()
}
fn simple_rust_function(name: String) -> String {
format!("fn {}() {{ }}", name)
}
fn rust_function_with_if(name: String, condition: String) -> String {
format!(
r#"
fn {}() {{
if {} {{
return;
}}
}}
"#,
name, condition
)
}
proptest! {
#[test]
#[ignore] fn parser_handles_valid_identifiers(name in valid_rust_identifier()) {
let mut parser = EnhancedParser::new();
let code = simple_rust_function(name);
let path = PathBuf::from("test.rs");
let result = parser.parse_incremental(&path, &code);
prop_assert!(result.is_ok());
let metrics = result.unwrap();
prop_assert_eq!(metrics.functions, 1);
prop_assert!(metrics.complexity >= 1); }
#[test]
#[ignore = "requires quality framework setup"]
fn complexity_increases_with_control_flow(
name in valid_rust_identifier(),
condition in valid_rust_identifier()
) {
let mut parser = EnhancedParser::new();
let simple_code = simple_rust_function(name.clone());
let complex_code = rust_function_with_if(name, condition);
let path1 = PathBuf::from("simple.rs");
let path2 = PathBuf::from("complex.rs");
let simple_metrics = parser.parse_incremental(&path1, &simple_code).unwrap();
let complex_metrics = parser.parse_incremental(&path2, &complex_code).unwrap();
prop_assert!(complex_metrics.complexity > simple_metrics.complexity);
prop_assert_eq!(simple_metrics.functions, complex_metrics.functions);
}
#[test]
#[ignore = "requires quality framework setup"]
fn cache_consistency(
name in valid_rust_identifier(),
_content_variations in prop::collection::vec(valid_rust_identifier(), 1..10)
) {
let mut parser = EnhancedParser::new();
let path = PathBuf::from("cache_test.rs");
let base_code = simple_rust_function(name);
let first_result = parser.parse_incremental(&path, &base_code).unwrap();
let second_result = parser.parse_incremental(&path, &base_code).unwrap();
prop_assert_eq!(first_result.complexity, second_result.complexity);
prop_assert_eq!(first_result.functions, second_result.functions);
prop_assert_eq!(first_result.lines, second_result.lines);
}
#[test]
fn hash_calculation_stable(content in "[a-zA-Z0-9\\s\\n{}();]{10,500}") {
let parser = EnhancedParser::new();
let hash1 = parser.calculate_hash(&content);
let hash2 = parser.calculate_hash(&content);
prop_assert_eq!(hash1, hash2);
let modified_content = format!("{} // comment", content);
let hash3 = parser.calculate_hash(&modified_content);
prop_assert_ne!(hash1, hash3);
}
#[test]
#[ignore = "requires quality framework setup"]
fn satd_detection_accuracy(
base_code in "[a-zA-Z0-9\\s\\n{}();]{50,200}",
satd_count in 0usize..5
) {
let mut parser = EnhancedParser::new();
let path = PathBuf::from("satd_test.rs");
let satd_comments = ["TODO", "FIXME", "HACK", "XXX", "BUG"];
let mut enhanced_code = base_code;
for i in 0..satd_count {
let comment_type = &satd_comments[i % satd_comments.len()];
enhanced_code.push_str(&format!("\n// {}: test comment", comment_type));
}
let code = format!("fn test() {{\n{}\n}}", enhanced_code);
let metrics = parser.parse_incremental(&path, &code).unwrap();
prop_assert_eq!(metrics.satd_count, satd_count as u32);
}
#[test]
#[ignore = "requires quality framework setup"]
fn nesting_affects_cognitive_complexity(
function_name in valid_rust_identifier(),
nesting_levels in 1usize..5
) {
let mut parser = EnhancedParser::new();
let path = PathBuf::from("nesting_test.rs");
let mut code = format!("fn {}() {{\n", function_name);
for level in 0..nesting_levels {
code.push_str(&" ".repeat(level + 1));
code.push_str(&format!("if condition_{} {{\n", level));
}
for level in (0..nesting_levels).rev() {
code.push_str(&" ".repeat(level + 1));
code.push_str("}\n");
}
code.push('}');
let metrics = parser.parse_incremental(&path, &code).unwrap();
prop_assert!(metrics.cognitive >= metrics.complexity);
prop_assert!(metrics.complexity >= (nesting_levels as u32 + 1)); }
#[test]
fn line_counting_accuracy(
line_count in 5usize..100,
chars_per_line in 10usize..80
) {
let mut parser = EnhancedParser::new();
let path = PathBuf::from("lines_test.rs");
let mut code = String::new();
for i in 0..line_count {
let line_content = "a".repeat(chars_per_line % 50); code.push_str(&format!("// Line {}: {}\n", i, line_content));
}
code.push_str("fn test() {}");
let expected_lines = line_count + 1; let metrics = parser.parse_incremental(&path, &code).unwrap();
prop_assert_eq!(metrics.lines as usize, expected_lines);
}
#[test]
#[ignore = "requires quality framework setup"]
fn cache_invalidation_works(
name in valid_rust_identifier(),
content1 in "[a-zA-Z0-9]{10,100}",
content2 in "[a-zA-Z0-9]{10,100}"
) {
let mut parser = EnhancedParser::new();
let path = PathBuf::from("invalidation_test.rs");
let code1 = format!("fn {}() {{ /* {} */ }}", name, content1);
let code2 = format!("fn {}() {{ /* {} */ }}", name, content2);
let metrics1 = parser.parse_incremental(&path, &code1).unwrap();
prop_assert!(parser.get_cached_metrics(&path).is_some());
let metrics2 = parser.parse_incremental(&path, &code2).unwrap();
if code1 != code2 {
prop_assert!(metrics1.timestamp <= metrics2.timestamp);
}
}
#[test]
#[ignore = "requires quality framework setup"]
fn match_expression_complexity(
function_name in valid_rust_identifier(),
arm_count in 2usize..8
) {
let mut parser = EnhancedParser::new();
let path = PathBuf::from("match_test.rs");
let mut code = format!("fn {}() {{\n match x {{\n", function_name);
for i in 0..arm_count {
code.push_str(&format!(" {} => {},\n", i, i * 2));
}
code.push_str(" }\n}");
let metrics = parser.parse_incremental(&path, &code).unwrap();
prop_assert!(metrics.complexity >= (arm_count as u32 + 1)); prop_assert_eq!(metrics.functions, 1);
}
#[test]
fn parser_memory_usage_bounded(
file_count in 1usize..20,
content_size in 100usize..1000
) {
let mut parser = EnhancedParser::new();
for i in 0..file_count {
let path = PathBuf::from(format!("file_{}.rs", i));
let content = "a".repeat(content_size);
let code = format!("fn test_{}() {{ /* {} */ }}", i, content);
let _metrics = parser.parse_incremental(&path, &code).unwrap();
}
let stats = parser.cache_stats();
prop_assert_eq!(stats.total_entries, file_count);
prop_assert!(stats.memory_usage_estimate > 0);
prop_assert!(stats.memory_usage_estimate < file_count * 10000); }
}
}