#![cfg_attr(coverage_nightly, coverage(off))]
use crate::services::context::{AstItem, ProjectContext, ProjectSummary};
use anyhow::Result;
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use tracing::{info, warn};
pub struct AdvancedUnifiedContextBuilder {
project_path: PathBuf,
output: String,
pub enable_big_o: bool,
pub enable_entropy: bool,
pub enable_provability: bool,
pub enable_graph_metrics: bool,
pub enable_tdg: bool,
pub enable_dead_code: bool,
pub enable_satd: bool,
}
include!("unified_context_advanced_builder.rs");
include!("unified_context_advanced_analysis.rs");
struct EntropyData {
pattern_entropy: f64,
duplication_percentage: f64,
structural_entropy: f64,
actionable_items: Vec<String>,
}
struct ProvabilityData {
invariants: Vec<String>,
preconditions: Vec<String>,
postconditions: Vec<String>,
verified: bool,
}
struct GraphMetricsData {
betweenness: f64,
closeness: f64,
degree: f64,
node_count: usize,
edge_count: usize,
density: f64,
critical_paths: Vec<String>,
}
struct TdgData {
overall_score: f64,
file_scores: HashMap<String, f64>,
hotspots: Vec<TdgHotspot>,
priorities: Vec<String>,
}
struct TdgHotspot {
location: String,
score: f64,
}
struct DeadCodeData {
unreachable_functions: Vec<String>,
unused_variables: Vec<String>,
unused_imports: Vec<String>,
}
impl DeadCodeData {
fn total_dead_items(&self) -> usize {
self.unreachable_functions.len() + self.unused_variables.len() + self.unused_imports.len()
}
}
struct SatdData {
todos: Vec<SatdComment>,
fixmes: Vec<SatdComment>,
hacks: Vec<SatdComment>,
design_debt: usize,
code_debt: usize,
test_debt: usize,
doc_debt: usize,
}
impl SatdData {
fn total_satd_count(&self) -> usize {
self.todos.len() + self.fixmes.len() + self.hacks.len()
}
}
struct SatdComment {
location: String,
comment: String,
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use tempfile::TempDir;
#[tokio::test]
async fn test_unified_context_includes_all_sections() {
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("test.rs");
fs::write(&test_file, "fn main() { println!(\"test\"); }").unwrap();
let mut builder = AdvancedUnifiedContextBuilder::new(temp_dir.path());
let result = builder.build_complete_context().await.unwrap();
assert!(result.contains("# Project Context"));
assert!(result.contains("## Project Structure"));
assert!(result.contains("## Key Components"));
assert!(result.contains("## Big-O Complexity Analysis"));
assert!(result.contains("## Entropy Analysis"));
assert!(result.contains("## Provability Analysis"));
assert!(result.contains("## Graph Metrics"));
assert!(result.contains("## Technical Debt Gradient"));
assert!(result.contains("## Dead Code Analysis"));
assert!(result.contains("## Self-Admitted Technical Debt"));
assert!(result.contains("## Quality Insights"));
assert!(result.contains("## Recommendations"));
}
#[tokio::test]
async fn test_context_with_disabled_features() {
let temp_dir = TempDir::new().unwrap();
let mut builder = AdvancedUnifiedContextBuilder::new(temp_dir.path());
builder.enable_provability = false;
builder.enable_graph_metrics = false;
let result = builder.build_complete_context().await.unwrap();
assert!(result.contains("## Big-O Complexity Analysis"));
assert!(result.contains("## Entropy Analysis"));
assert!(!result.contains("## Provability Analysis"));
assert!(!result.contains("## Graph Metrics"));
}
#[test]
fn test_dead_code_total_calculation() {
let dead_code = DeadCodeData {
unreachable_functions: vec!["func1".to_string(), "func2".to_string()],
unused_variables: vec!["var1".to_string()],
unused_imports: vec!["import1".to_string(), "import2".to_string()],
};
assert_eq!(dead_code.total_dead_items(), 5);
}
#[test]
fn test_satd_total_calculation() {
let satd = SatdData {
todos: vec![
SatdComment {
location: "file1".to_string(),
comment: "TODO: fix".to_string(),
},
SatdComment {
location: "file2".to_string(),
comment: "TODO: improve".to_string(),
},
],
fixmes: vec![SatdComment {
location: "file3".to_string(),
comment: "FIXME: bug".to_string(),
}],
hacks: vec![],
design_debt: 0,
code_debt: 0,
test_debt: 0,
doc_debt: 0,
};
assert_eq!(satd.total_satd_count(), 3);
}
}