#![cfg_attr(coverage_nightly, coverage(off))]
use super::*;
mod tests_output {
use super::*;
use std::fs;
use tempfile::TempDir;
#[test]
fn test_generate_recommendations_high_complexity() {
let analyzer = SimpleDeepContext;
let metrics = ComplexityMetrics {
total_functions: 10,
high_complexity_count: 3,
avg_complexity: 4.0,
};
let recommendations = analyzer.generate_recommendations(&metrics);
assert!(!recommendations.is_empty());
assert!(recommendations
.iter()
.any(|r| r.contains("refactoring") && r.contains("3")));
}
#[test]
fn test_generate_recommendations_high_avg_complexity() {
let analyzer = SimpleDeepContext;
let metrics = ComplexityMetrics {
total_functions: 10,
high_complexity_count: 0,
avg_complexity: 7.5,
};
let recommendations = analyzer.generate_recommendations(&metrics);
assert!(!recommendations.is_empty());
assert!(recommendations
.iter()
.any(|r| r.contains("Average") && r.contains("7.5")));
}
#[test]
fn test_generate_recommendations_no_functions() {
let analyzer = SimpleDeepContext;
let metrics = ComplexityMetrics {
total_functions: 0,
high_complexity_count: 0,
avg_complexity: 0.0,
};
let recommendations = analyzer.generate_recommendations(&metrics);
assert!(!recommendations.is_empty());
assert!(recommendations
.iter()
.any(|r| r.contains("No functions detected")));
}
#[test]
fn test_generate_recommendations_good_code() {
let analyzer = SimpleDeepContext;
let metrics = ComplexityMetrics {
total_functions: 20,
high_complexity_count: 0,
avg_complexity: 2.5,
};
let recommendations = analyzer.generate_recommendations(&metrics);
assert!(!recommendations.is_empty());
assert!(recommendations.iter().any(|r| r.contains("looks good")));
}
#[test]
fn test_format_as_json_empty_report() {
let analyzer = SimpleDeepContext;
let report = SimpleAnalysisReport {
file_count: 0,
analysis_duration: std::time::Duration::from_millis(100),
complexity_metrics: ComplexityMetrics {
total_functions: 0,
high_complexity_count: 0,
avg_complexity: 0.0,
},
recommendations: vec!["No files found".to_string()],
file_complexity_details: vec![],
};
let json = analyzer.format_as_json(&report).unwrap();
assert!(json.contains("\"file_count\": 0"));
assert!(json.contains("\"total_functions\": 0"));
assert!(json.contains("\"recommendations\""));
}
#[test]
fn test_format_as_json_with_files() {
let analyzer = SimpleDeepContext;
let report = SimpleAnalysisReport {
file_count: 2,
analysis_duration: std::time::Duration::from_millis(500),
complexity_metrics: ComplexityMetrics {
total_functions: 15,
high_complexity_count: 3,
avg_complexity: 5.5,
},
recommendations: vec!["Consider refactoring".to_string()],
file_complexity_details: vec![
FileComplexityDetail {
file_path: PathBuf::from("src/main.rs"),
function_count: 10,
high_complexity_functions: 2,
avg_complexity: 6.0,
complexity_score: 8.0,
function_names: vec!["main".to_string()],
},
FileComplexityDetail {
file_path: PathBuf::from("src/lib.rs"),
function_count: 5,
high_complexity_functions: 1,
avg_complexity: 4.5,
complexity_score: 5.0,
function_names: vec!["process".to_string()],
},
],
};
let json = analyzer.format_as_json(&report).unwrap();
assert!(json.contains("\"file_count\": 2"));
assert!(json.contains("\"total_functions\": 15"));
assert!(json.contains("main.rs"));
assert!(json.contains("lib.rs"));
let parsed: serde_json::Value = serde_json::from_str(&json).unwrap();
assert_eq!(parsed["summary"]["file_count"], 2);
}
#[test]
fn test_format_as_markdown_empty_report() {
let analyzer = SimpleDeepContext;
let report = SimpleAnalysisReport {
file_count: 0,
analysis_duration: std::time::Duration::from_millis(50),
complexity_metrics: ComplexityMetrics {
total_functions: 0,
high_complexity_count: 0,
avg_complexity: 0.0,
},
recommendations: vec!["No files found".to_string()],
file_complexity_details: vec![],
};
let markdown = analyzer.format_as_markdown(&report, 10);
assert!(markdown.contains("# Deep Context Analysis Report"));
assert!(markdown.contains("**Files Analyzed**: 0"));
assert!(markdown.contains("## Recommendations"));
}
#[test]
fn test_format_as_markdown_with_files() {
let analyzer = SimpleDeepContext;
let report = SimpleAnalysisReport {
file_count: 3,
analysis_duration: std::time::Duration::from_secs(1),
complexity_metrics: ComplexityMetrics {
total_functions: 30,
high_complexity_count: 5,
avg_complexity: 6.2,
},
recommendations: vec!["Consider refactoring".to_string(), "Add tests".to_string()],
file_complexity_details: vec![
FileComplexityDetail {
file_path: PathBuf::from("complex.rs"),
function_count: 15,
high_complexity_functions: 3,
avg_complexity: 8.0,
complexity_score: 12.0,
function_names: vec![],
},
FileComplexityDetail {
file_path: PathBuf::from("medium.rs"),
function_count: 10,
high_complexity_functions: 2,
avg_complexity: 5.0,
complexity_score: 7.0,
function_names: vec![],
},
],
};
let markdown = analyzer.format_as_markdown(&report, 10);
assert!(markdown.contains("**Files Analyzed**: 3"));
assert!(markdown.contains("**Total Functions**: 30"));
assert!(markdown.contains("**High Complexity Functions**: 5"));
assert!(markdown.contains("## Top Files by Complexity"));
let complex_pos = markdown.find("complex.rs").unwrap_or(usize::MAX);
let medium_pos = markdown.find("medium.rs").unwrap_or(usize::MAX);
assert!(complex_pos < medium_pos);
}
#[test]
fn test_format_as_markdown_zero_top_files() {
let analyzer = SimpleDeepContext;
let report = SimpleAnalysisReport {
file_count: 1,
analysis_duration: std::time::Duration::from_millis(100),
complexity_metrics: ComplexityMetrics {
total_functions: 5,
high_complexity_count: 1,
avg_complexity: 3.0,
},
recommendations: vec![],
file_complexity_details: vec![FileComplexityDetail {
file_path: PathBuf::from("test.rs"),
function_count: 5,
high_complexity_functions: 1,
avg_complexity: 3.0,
complexity_score: 5.0,
function_names: vec![],
}],
};
let markdown = analyzer.format_as_markdown(&report, 0);
assert!(markdown.contains("test.rs"));
}
#[tokio::test]
#[ignore] async fn test_extract_function_names_rust() {
let analyzer = SimpleDeepContext;
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("test.rs");
fs::write(
&test_file,
"fn main() {}\npub fn helper() -> i32 { 42 }\nasync fn async_func() {}\npub(crate) fn crate_visible() {}\n",
)
.unwrap();
let names = analyzer
.extract_function_names_heuristic(&test_file, "rs")
.await
.unwrap();
assert!(names.contains(&"main".to_string()));
assert!(names.contains(&"helper".to_string()));
}
#[tokio::test]
async fn test_extract_function_names_python() {
let analyzer = SimpleDeepContext;
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("test.py");
fs::write(
&test_file,
"def main():\n pass\n\nasync def async_handler():\n await something()\n\ndef helper_func(x, y):\n return x + y\n",
)
.unwrap();
let names = analyzer
.extract_function_names_heuristic(&test_file, "py")
.await
.unwrap();
assert!(names.contains(&"main".to_string()));
assert!(names.contains(&"async_handler".to_string()));
assert!(names.contains(&"helper_func".to_string()));
}
#[tokio::test]
async fn test_extract_function_names_kotlin() {
let analyzer = SimpleDeepContext;
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("test.kt");
fs::write(
&test_file,
"fun main() {\n println(\"Hello\")\n}\n\nsuspend fun asyncOperation() {\n delay(100)\n}\n\nfun processData(data: String): Int {\n return data.length\n}\n",
)
.unwrap();
let names = analyzer
.extract_function_names_heuristic(&test_file, "kt")
.await
.unwrap();
assert!(names.contains(&"main".to_string()));
assert!(names.contains(&"asyncOperation".to_string()));
assert!(names.contains(&"processData".to_string()));
}
#[tokio::test]
async fn test_extract_function_names_go() {
let analyzer = SimpleDeepContext;
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("test.go");
fs::write(
&test_file,
"func main() {\n fmt.Println(\"hello\")\n}\n\nfunc (s *Server) HandleRequest() {\n // method\n}\n\nfunc processData(data string) int {\n return len(data)\n}\n",
)
.unwrap();
let names = analyzer
.extract_function_names_heuristic(&test_file, "go")
.await
.unwrap();
assert!(names.contains(&"main".to_string()));
assert!(names.contains(&"HandleRequest".to_string()));
assert!(names.contains(&"processData".to_string()));
}
#[tokio::test]
async fn test_extract_function_names_unknown_extension() {
let analyzer = SimpleDeepContext;
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("test.xyz");
fs::write(&test_file, "some content").unwrap();
let names = analyzer
.extract_function_names_heuristic(&test_file, "xyz")
.await
.unwrap();
assert!(names.is_empty());
}
#[tokio::test]
async fn test_analyze_complexity_multiple_files() {
let analyzer = SimpleDeepContext;
let temp_dir = TempDir::new().unwrap();
let file1 = temp_dir.path().join("simple.rs");
fs::write(&file1, "fn simple() { }").unwrap();
let file2 = temp_dir.path().join("complex.rs");
fs::write(
&file2,
"fn complex(x: i32) -> i32 {\n if x > 0 {\n if x > 10 {\n for i in 0..x {\n if i % 2 == 0 { return i; }\n }\n }\n }\n 0\n}\n",
)
.unwrap();
let files = vec![file1, file2];
let (metrics, details) = analyzer.analyze_complexity(&files).await.unwrap();
assert!(metrics.total_functions >= 2);
assert_eq!(details.len(), 2);
}
#[test]
fn test_simple_analysis_report_debug() {
let report = SimpleAnalysisReport {
file_count: 5,
analysis_duration: std::time::Duration::from_millis(250),
complexity_metrics: ComplexityMetrics {
total_functions: 25,
high_complexity_count: 3,
avg_complexity: 4.5,
},
recommendations: vec!["Test recommendation".to_string()],
file_complexity_details: vec![],
};
let debug = format!("{:?}", report);
assert!(debug.contains("file_count"));
assert!(debug.contains("5"));
assert!(debug.contains("complexity_metrics"));
}
#[test]
fn test_file_complexity_metrics_debug() {
use super::FileComplexityMetrics;
let metrics = FileComplexityMetrics {
function_count: 10,
high_complexity_functions: 2,
avg_complexity: 5.5,
function_names: vec!["func1".to_string(), "func2".to_string()],
};
let debug = format!("{:?}", metrics);
assert!(debug.contains("function_count"));
assert!(debug.contains("10"));
assert!(debug.contains("function_names"));
}
#[test]
fn test_estimate_complexity_unknown_language() {
let analyzer = SimpleDeepContext;
let code = "some random code with if and while";
let complexity = analyzer.estimate_complexity(code, "unknown_lang");
assert_eq!(complexity, 1);
}
#[test]
fn test_estimate_complexity_empty_code() {
let analyzer = SimpleDeepContext;
let code = "";
let complexity = analyzer.estimate_complexity(code, "py");
assert_eq!(complexity, 1);
}
}