use anyhow::Result;
use debtmap::comparison::types::{ComparisonResult, DebtTrend, TargetStatus};
use debtmap::comparison::{Comparator, PlanParser};
use debtmap::priority::UnifiedAnalysis;
use std::fs;
use std::path::PathBuf;
#[test]
fn test_compare_with_improvement() -> Result<()> {
let before_path = PathBuf::from("tests/data/fixtures/before.json");
let after_path = PathBuf::from("tests/data/fixtures/after_improved.json");
let plan_path = PathBuf::from("tests/data/fixtures/IMPLEMENTATION_PLAN.md");
let before_content = fs::read_to_string(&before_path)?;
let before_analysis: UnifiedAnalysis = serde_json::from_str(&before_content)?;
let after_content = fs::read_to_string(&after_path)?;
let after_analysis: UnifiedAnalysis = serde_json::from_str(&after_content)?;
let target_location = PlanParser::extract_target_location(&plan_path)?;
let comparator = Comparator::new(
before_analysis,
after_analysis,
Some(target_location.clone()),
);
let result = comparator.compare()?;
assert_eq!(result.metadata.target_location, Some(target_location));
assert!(result.target_item.is_some());
let target = result.target_item.as_ref().unwrap();
assert_eq!(target.status, TargetStatus::Resolved);
assert!(result.summary.target_improved);
assert_eq!(result.summary.new_critical_count, 0);
assert_eq!(result.summary.resolved_count, 1);
assert_eq!(result.summary.overall_debt_trend, DebtTrend::Improving);
assert!(result.project_health.changes.debt_score_change < 0.0); assert!(result.project_health.changes.critical_items_change < 0);
Ok(())
}
#[test]
fn test_compare_with_regression() -> Result<()> {
let before_path = PathBuf::from("tests/data/fixtures/before.json");
let after_path = PathBuf::from("tests/data/fixtures/after_regression.json");
let plan_path = PathBuf::from("tests/data/fixtures/IMPLEMENTATION_PLAN.md");
let before_content = fs::read_to_string(&before_path)?;
let before_analysis: UnifiedAnalysis = serde_json::from_str(&before_content)?;
let after_content = fs::read_to_string(&after_path)?;
let after_analysis: UnifiedAnalysis = serde_json::from_str(&after_content)?;
let target_location = PlanParser::extract_target_location(&plan_path)?;
let comparator = Comparator::new(before_analysis, after_analysis, Some(target_location));
let result = comparator.compare()?;
assert!(result.target_item.is_some());
let target = result.target_item.as_ref().unwrap();
assert_eq!(target.status, TargetStatus::Regressed);
assert!(!result.summary.target_improved);
assert!(result.summary.new_critical_count > 0);
assert_eq!(result.summary.overall_debt_trend, DebtTrend::Regressing);
assert!(result.project_health.changes.debt_score_change > 0.0); assert!(result.project_health.changes.critical_items_change > 0);
Ok(())
}
#[test]
fn test_compare_without_plan() -> Result<()> {
let before_path = PathBuf::from("tests/data/fixtures/before.json");
let after_path = PathBuf::from("tests/data/fixtures/after_improved.json");
let before_content = fs::read_to_string(&before_path)?;
let before_analysis: UnifiedAnalysis = serde_json::from_str(&before_content)?;
let after_content = fs::read_to_string(&after_path)?;
let after_analysis: UnifiedAnalysis = serde_json::from_str(&after_content)?;
let comparator = Comparator::new(before_analysis, after_analysis, None);
let result = comparator.compare()?;
assert_eq!(result.metadata.target_location, None);
assert!(result.target_item.is_none());
assert!(result.project_health.changes.debt_score_change < 0.0);
assert_eq!(result.summary.resolved_count, 1);
Ok(())
}
#[test]
fn test_compare_result_serialization() -> Result<()> {
let before_path = PathBuf::from("tests/data/fixtures/before.json");
let after_path = PathBuf::from("tests/data/fixtures/after_improved.json");
let plan_path = PathBuf::from("tests/data/fixtures/IMPLEMENTATION_PLAN.md");
let before_content = fs::read_to_string(&before_path)?;
let before_analysis: UnifiedAnalysis = serde_json::from_str(&before_content)?;
let after_content = fs::read_to_string(&after_path)?;
let after_analysis: UnifiedAnalysis = serde_json::from_str(&after_content)?;
let target_location = PlanParser::extract_target_location(&plan_path)?;
let comparator = Comparator::new(before_analysis, after_analysis, Some(target_location));
let result = comparator.compare()?;
let json = serde_json::to_string_pretty(&result)?;
assert!(json.contains("\"metadata\""));
assert!(json.contains("\"target_item\""));
assert!(json.contains("\"project_health\""));
assert!(json.contains("\"summary\""));
assert!(json.contains("\"regressions\""));
assert!(json.contains("\"improvements\""));
let deserialized: ComparisonResult = serde_json::from_str(&json)?;
assert_eq!(
deserialized.summary.target_improved,
result.summary.target_improved
);
assert_eq!(
deserialized.summary.resolved_count,
result.summary.resolved_count
);
Ok(())
}
#[test]
fn test_compare_command_compiles() {
let _status = TargetStatus::Improved;
let _trend = DebtTrend::Improving;
}
#[test]
fn test_plan_parser_api() -> Result<()> {
let plan_path = PathBuf::from("tests/data/fixtures/IMPLEMENTATION_PLAN.md");
let location = PlanParser::extract_target_location(&plan_path)?;
assert_eq!(location, "src/example.rs:complex_function:45");
Ok(())
}
#[test]
fn test_comparison_types_serialization() -> Result<()> {
use debtmap::comparison::types::{
ComparisonMetadata, ComparisonSummary, DebtTrend, TargetStatus,
};
use serde_json;
let metadata = ComparisonMetadata {
comparison_date: "2025-10-01T10:00:00Z".to_string(),
before_file: "before.json".to_string(),
after_file: "after.json".to_string(),
target_location: Some("src/test.rs:10".to_string()),
};
let json = serde_json::to_string(&metadata)?;
let _deserialized: ComparisonMetadata = serde_json::from_str(&json)?;
let status = TargetStatus::Improved;
let json = serde_json::to_string(&status)?;
let _deserialized: TargetStatus = serde_json::from_str(&json)?;
let trend = DebtTrend::Improving;
let json = serde_json::to_string(&trend)?;
let _deserialized: DebtTrend = serde_json::from_str(&json)?;
let summary = ComparisonSummary {
target_improved: true,
new_critical_count: 0,
resolved_count: 5,
overall_debt_trend: DebtTrend::Improving,
};
let json = serde_json::to_string(&summary)?;
let _deserialized: ComparisonSummary = serde_json::from_str(&json)?;
Ok(())
}