#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use tempfile::TempDir;
#[tokio::test]
async fn test_ast_context_generation() {
let temp_dir = TempDir::new().unwrap();
let temp_path = temp_dir.path();
let rust_file = temp_path.join("lib.rs");
fs::write(
&rust_file,
r#"
/// Hello.
pub fn hello() -> String {
"Hello, World!".to_string()
}
/// Configuration for config.
pub struct Config {
pub name: String,
}
/// Trait defining Display behavior.
pub trait Display {
fn display(&self) -> String;
}
"#,
)
.unwrap();
let engine = DogfoodingEngine::new();
let context = engine
.generate_ast_context(temp_path, "2025-05-31")
.await
.unwrap();
assert!(context.contains("# AST Context Analysis - 2025-05-31"));
assert!(context.contains("## Project Structure"));
assert!(context.contains("## Summary Statistics"));
assert!(context.contains("**Total Files**: 0")); }
#[tokio::test]
async fn test_combined_metrics_generation() {
let temp_dir = TempDir::new().unwrap();
let temp_path = temp_dir.path();
let rust_file = temp_path.join("lib.rs");
fs::write(&rust_file, "pub fn test() {}").unwrap();
let engine = DogfoodingEngine::new();
let metrics = engine
.generate_combined_metrics(temp_path, "2025-05-31")
.await
.unwrap();
assert_eq!(metrics["timestamp"].as_str().unwrap(), "2025-05-31");
assert_eq!(metrics["ast"]["total_files"].as_u64().unwrap(), 0);
assert!(metrics.get("generation_time").is_some());
assert!(metrics.get("hash").is_some());
}
#[test]
fn test_server_info_generation() {
let engine = DogfoodingEngine::new();
let info = engine.generate_server_info("2025-05-31").unwrap();
assert!(info.contains("# Server Information - 2025-05-31"));
assert!(info.contains("Binary Metadata"));
assert!(info.contains("Runtime Information"));
assert!(info.contains("Performance Characteristics"));
}
#[test]
fn test_dogfooding_engine_new() {
let _engine = DogfoodingEngine::new();
}
#[test]
fn test_dogfooding_engine_default() {
let _engine = DogfoodingEngine::default();
}
#[test]
fn test_file_context_struct() {
let ctx = FileContext {
path: PathBuf::from("src/main.rs"),
functions: 10,
structs: 5,
traits: 2,
max_complexity: 15,
lines: 200,
};
assert_eq!(ctx.functions, 10);
assert_eq!(ctx.structs, 5);
assert_eq!(ctx.traits, 2);
assert_eq!(ctx.max_complexity, 15);
assert_eq!(ctx.lines, 200);
}
#[test]
fn test_file_context_clone() {
let ctx = FileContext {
path: PathBuf::from("test.rs"),
functions: 3,
structs: 1,
traits: 0,
max_complexity: 5,
lines: 50,
};
let cloned = ctx.clone();
assert_eq!(cloned.functions, ctx.functions);
assert_eq!(cloned.path, ctx.path);
}
#[test]
fn test_file_context_debug() {
let ctx = FileContext {
path: PathBuf::from("test.rs"),
functions: 1,
structs: 0,
traits: 0,
max_complexity: 1,
lines: 10,
};
let debug = format!("{:?}", ctx);
assert!(debug.contains("FileContext"));
assert!(debug.contains("test.rs"));
}
#[test]
fn test_churn_metrics_struct() {
let metrics = ChurnMetrics {
files_changed: 50,
commit_count: 100,
total_additions: 5000,
total_deletions: 2000,
hotspots: vec![],
};
assert_eq!(metrics.files_changed, 50);
assert_eq!(metrics.commit_count, 100);
assert_eq!(metrics.total_additions, 5000);
assert_eq!(metrics.total_deletions, 2000);
assert!(metrics.hotspots.is_empty());
}
#[test]
fn test_churn_metrics_with_hotspots() {
let hotspot = FileHotspot {
path: PathBuf::from("hot.rs"),
change_count: 20,
complexity_score: 30,
risk_score: 0.8,
};
let metrics = ChurnMetrics {
files_changed: 1,
commit_count: 20,
total_additions: 100,
total_deletions: 50,
hotspots: vec![hotspot],
};
assert_eq!(metrics.hotspots.len(), 1);
assert_eq!(metrics.hotspots[0].change_count, 20);
}
#[test]
fn test_file_hotspot_struct() {
let hotspot = FileHotspot {
path: PathBuf::from("hotspot.rs"),
change_count: 50,
complexity_score: 25,
risk_score: 0.95,
};
assert_eq!(hotspot.change_count, 50);
assert_eq!(hotspot.complexity_score, 25);
assert!((hotspot.risk_score - 0.95).abs() < f64::EPSILON);
}
#[test]
fn test_file_hotspot_clone() {
let hotspot = FileHotspot {
path: PathBuf::from("test.rs"),
change_count: 10,
complexity_score: 5,
risk_score: 0.5,
};
let cloned = hotspot.clone();
assert_eq!(cloned.path, hotspot.path);
assert_eq!(cloned.change_count, hotspot.change_count);
}
#[test]
fn test_dag_metrics_struct() {
let dag = DagMetrics {
node_count: 100,
edge_count: 200,
density: 0.04,
diameter: 5,
clustering: 0.3,
strongly_connected_components: 3,
};
assert_eq!(dag.node_count, 100);
assert_eq!(dag.edge_count, 200);
assert!((dag.density - 0.04).abs() < f64::EPSILON);
assert_eq!(dag.diameter, 5);
}
#[test]
fn test_dag_metrics_clone() {
let dag = DagMetrics {
node_count: 50,
edge_count: 100,
density: 0.08,
diameter: 3,
clustering: 0.25,
strongly_connected_components: 1,
};
let cloned = dag.clone();
assert_eq!(cloned.node_count, dag.node_count);
assert_eq!(cloned.edge_count, dag.edge_count);
}
#[test]
fn test_dag_metrics_debug() {
let dag = DagMetrics {
node_count: 10,
edge_count: 15,
density: 0.3,
diameter: 2,
clustering: 0.5,
strongly_connected_components: 1,
};
let debug = format!("{:?}", dag);
assert!(debug.contains("DagMetrics"));
assert!(debug.contains("node_count"));
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod property_tests {
use proptest::prelude::*;
proptest! {
#[test]
fn basic_property_stability(_input in ".*") {
prop_assert!(true);
}
#[test]
fn module_consistency_check(_x in 0u32..1000) {
prop_assert!(_x < 1001);
}
}
}