#![cfg_attr(coverage_nightly, coverage(off))]
use tempfile::TempDir;
use std::fs;
#[tokio::test]
async fn test_context_generation_no_stack_overflow_full_analysis() {
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("moderate.rs");
let code = r#"
fn simple_function() -> i32 {
42
}
fn moderate_function(x: i32) -> i32 {
if x > 0 {
x * 2
} else {
0
}
}
struct TestStruct {
value: i32,
}
impl TestStruct {
fn new() -> Self {
Self { value: 0 }
}
}
"#;
fs::write(&test_file, code).unwrap();
let result = tokio::spawn(async move {
let output_file = temp_dir.path().join("context.md");
crate::cli::handlers::utility_handlers::handle_context(
Some("rust".to_string()),
temp_dir.path().to_path_buf(),
Some(output_file.clone()),
crate::cli::handlers::utility_handlers::ContextFormat::Markdown,
false, false, ).await
}).await;
assert!(result.is_ok(), "Context generation should not stack overflow");
let generation_result = result.unwrap();
assert!(generation_result.is_ok(), "Context generation should succeed: {:?}", generation_result.err());
}
#[tokio::test]
async fn test_context_generation_memory_bounded() {
let temp_dir = TempDir::new().unwrap();
for i in 0..50 {
let test_file = temp_dir.path().join(format!("file_{}.rs", i));
let code = format!(r#"
fn function_{}() -> i32 {{
{}
}}
struct Struct{} {{
field: i32,
}}
"#, i, i, i);
fs::write(&test_file, code).unwrap();
}
let start = std::time::Instant::now();
let output_file = temp_dir.path().join("context.md");
let result = crate::cli::handlers::utility_handlers::handle_context(
Some("rust".to_string()),
temp_dir.path().to_path_buf(),
Some(output_file.clone()),
crate::cli::handlers::utility_handlers::ContextFormat::Markdown,
false, false, ).await;
let duration = start.elapsed();
assert!(result.is_ok(), "Context generation should succeed");
assert!(duration.as_secs() < 30, "Should complete within 30 seconds, took {:?}", duration);
let output = fs::read_to_string(output_file).unwrap();
assert!(output.contains("Enhanced Annotated AST Context"), "Should contain enhanced AST header");
assert!(output.contains("Function"), "Should contain function annotations");
}
#[tokio::test]
async fn test_deep_context_analyzer_stack_safe() {
use crate::services::deep_context::{DeepContextAnalyzer, DeepContextConfig, AnalysisType, CacheStrategy, DagType};
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("complex.rs");
let code = r#"
fn deeply_nested() -> i32 {
if true {
if true {
if true {
if true {
if true {
42
} else {
0
}
} else {
0
}
} else {
0
}
} else {
0
}
} else {
0
}
}
"#;
fs::write(&test_file, code).unwrap();
let config = DeepContextConfig {
include_analyses: vec![
AnalysisType::Ast,
AnalysisType::Complexity,
AnalysisType::Churn,
AnalysisType::TechnicalDebtGradient,
AnalysisType::DeadCode,
AnalysisType::Satd,
AnalysisType::Provability,
AnalysisType::BigO,
],
period_days: 30,
dag_type: DagType::CallGraph,
complexity_thresholds: None,
max_depth: Some(5), include_patterns: vec![],
exclude_patterns: vec![],
cache_strategy: CacheStrategy::Normal,
parallel: 2, file_classifier_config: None,
};
let analyzer = DeepContextAnalyzer::new(config);
let result = analyzer.analyze_project(&temp_dir.path()).await;
assert!(result.is_ok(), "Deep context analysis should not stack overflow: {:?}", result.err());
}