#[test]
fn test_convert_dag_type_call_graph() {
let result = convert_deep_context_dag_type(DeepContextDagType::CallGraph);
assert!(matches!(result, DagType::CallGraph));
}
#[test]
fn test_convert_dag_type_import_graph() {
let result = convert_deep_context_dag_type(DeepContextDagType::ImportGraph);
assert!(matches!(result, DagType::ImportGraph));
}
#[test]
fn test_convert_dag_type_inheritance() {
let result = convert_deep_context_dag_type(DeepContextDagType::Inheritance);
assert!(matches!(result, DagType::Inheritance));
}
#[test]
fn test_convert_dag_type_full_dependency() {
let result = convert_deep_context_dag_type(DeepContextDagType::FullDependency);
assert!(matches!(result, DagType::FullDependency));
}
#[test]
fn test_convert_cache_strategy_normal() {
let result = convert_cache_strategy(DeepContextCacheStrategy::Normal);
assert_eq!(result, "normal");
}
#[test]
fn test_convert_cache_strategy_force_refresh() {
let result = convert_cache_strategy(DeepContextCacheStrategy::ForceRefresh);
assert_eq!(result, "force-refresh");
}
#[test]
fn test_convert_cache_strategy_offline() {
let result = convert_cache_strategy(DeepContextCacheStrategy::Offline);
assert_eq!(result, "offline");
}
#[test]
fn test_get_top_violations_empty() {
let violations: Vec<crate::entropy::violation_detector::ActionableViolation> = vec![];
let result = get_top_violations(&violations, 5);
assert!(result.is_empty());
}
#[test]
fn test_get_top_violations_zero_limit() {
let violations: Vec<crate::entropy::violation_detector::ActionableViolation> = vec![];
let result = get_top_violations(&violations, 0);
assert!(result.is_empty());
}
#[test]
fn test_format_violation_list_empty() {
let violations: Vec<crate::entropy::violation_detector::ActionableViolation> = vec![];
let result = format_violation_list(&violations);
assert!(result.is_empty());
}
#[test]
fn test_format_markdown_violations_empty() {
let violations: Vec<crate::entropy::violation_detector::ActionableViolation> = vec![];
let result = format_markdown_violations(&violations, 10);
assert!(result.is_empty());
}
#[test]
fn test_format_markdown_violations_zero_max() {
let violations: Vec<crate::entropy::violation_detector::ActionableViolation> = vec![];
let result = format_markdown_violations(&violations, 0);
assert!(result.is_empty());
}
#[test]
fn test_output_entropy_results_stdout() {
let result = output_entropy_results(None, "test content");
assert!(result.is_ok());
}
#[test]
fn test_output_entropy_results_to_file() {
let temp_dir = tempfile::tempdir().unwrap();
let output_path = temp_dir.path().join("test_output.txt");
let result = output_entropy_results(Some(output_path.clone()), "test content");
assert!(result.is_ok());
assert!(output_path.exists());
let content = std::fs::read_to_string(output_path).unwrap();
assert_eq!(content, "test content");
}
#[test]
fn test_create_entropy_config_low_severity() {
use crate::cli::EntropySeverity;
use crate::entropy::violation_detector::Severity;
let config = create_entropy_config(EntropySeverity::Low, true);
assert!(matches!(config.min_severity, Severity::Low));
assert_eq!(config.exclude_paths.len(), 2);
}
#[test]
fn test_create_entropy_config_medium_severity() {
use crate::cli::EntropySeverity;
use crate::entropy::violation_detector::Severity;
let config = create_entropy_config(EntropySeverity::Medium, true);
assert!(matches!(config.min_severity, Severity::Medium));
}
#[test]
fn test_create_entropy_config_high_severity() {
use crate::cli::EntropySeverity;
use crate::entropy::violation_detector::Severity;
let config = create_entropy_config(EntropySeverity::High, true);
assert!(matches!(config.min_severity, Severity::High));
}
#[test]
fn test_create_entropy_config_exclude_tests() {
use crate::cli::EntropySeverity;
let config = create_entropy_config(EntropySeverity::Low, false);
assert!(config.exclude_paths.len() >= 2);
assert!(config.exclude_paths.contains(&"**/*test*.rs".to_string()));
assert!(config.exclude_paths.contains(&"tests/**".to_string()));
}
fn strip_ansi(s: &str) -> String {
let re = regex::Regex::new(r"\x1b\[[0-9;]*m").unwrap();
re.replace_all(s, "").to_string()
}
fn create_test_violation(
message: &str,
loc_reduction: usize,
) -> crate::entropy::violation_detector::ActionableViolation {
use crate::entropy::pattern_extractor::PatternType;
use crate::entropy::violation_detector::{ActionableViolation, PatternSummary, Severity};
use std::path::PathBuf;
ActionableViolation {
severity: Severity::High,
pattern: PatternSummary {
pattern_type: PatternType::ErrorHandling,
repetitions: 5,
variation_score: 0.1,
example_code: "fn example() {}".to_string(),
},
message: message.to_string(),
fix_suggestion: "Extract into function".to_string(),
estimated_loc_reduction: loc_reduction,
affected_files: vec![PathBuf::from("src/test.rs")],
priority_score: 0.9,
}
}
#[test]
fn test_get_top_violations_with_real_data() {
let v1 = create_test_violation("First", 10);
let v2 = create_test_violation("Second", 20);
let v3 = create_test_violation("Third", 30);
let violations = vec![v1, v2, v3];
let result = get_top_violations(&violations, 2);
assert_eq!(result.len(), 2);
assert_eq!(result[0].message, "First");
assert_eq!(result[1].message, "Second");
}
#[test]
fn test_get_top_violations_limit_exceeds_size() {
let v1 = create_test_violation("Only one", 10);
let violations = vec![v1];
let result = get_top_violations(&violations, 10);
assert_eq!(result.len(), 1);
}
#[test]
fn test_format_violation_list_with_real_data() {
let violations = vec![
create_test_violation("Repeated pattern found", 15),
create_test_violation("Similar code detected", 25),
];
let result = format_violation_list(&violations);
let stripped = strip_ansi(&result);
assert!(stripped.contains("1. "));
assert!(stripped.contains("Repeated pattern found"));
assert!(stripped.contains("15"));
assert!(stripped.contains("2. "));
assert!(stripped.contains("Similar code detected"));
assert!(stripped.contains("25"));
assert!(stripped.contains("Extract into function"));
}
#[test]
fn test_format_markdown_violations_with_real_data() {
let violations = vec![
create_test_violation("Pattern A", 20),
create_test_violation("Pattern B", 30),
];
let result = format_markdown_violations(&violations, 2);
assert!(result.contains("### Pattern A"));
assert!(result.contains("### Pattern B"));
assert!(result.contains("**Fix**: Extract into function"));
assert!(result.contains("**LOC Reduction**: 20 lines"));
assert!(result.contains("**Pattern**: ErrorHandling"));
}
#[test]
fn test_format_markdown_violations_max_count() {
let violations = vec![
create_test_violation("First", 10),
create_test_violation("Second", 20),
create_test_violation("Third", 30),
];
let result = format_markdown_violations(&violations, 1);
assert!(result.contains("### First"));
assert!(!result.contains("### Second"));
assert!(!result.contains("### Third"));
}
#[test]
fn test_format_violation_list_single_item() {
let violations = vec![create_test_violation("Single violation", 50)];
let result = format_violation_list(&violations);
let stripped = strip_ansi(&result);
assert!(stripped.contains("1. "));
assert!(stripped.contains("Single violation"));
assert!(stripped.contains("50"));
}
#[test]
fn test_format_markdown_violations_take_zero() {
let violations = vec![
create_test_violation("First", 10),
create_test_violation("Second", 20),
];
let result = format_markdown_violations(&violations, 0);
assert!(result.is_empty());
}
#[test]
fn test_output_entropy_results_empty_content() {
let result = output_entropy_results(None, "");
assert!(result.is_ok());
}
#[test]
fn test_output_entropy_results_unicode_content() {
let result = output_entropy_results(None, "测试内容 🎉");
assert!(result.is_ok());
}
#[test]
fn test_output_entropy_results_multiline() {
let result = output_entropy_results(None, "Line 1\nLine 2\nLine 3");
assert!(result.is_ok());
}
#[test]
fn test_output_entropy_results_to_nested_directory() {
let temp_dir = tempfile::tempdir().unwrap();
let output_path = temp_dir.path().join("nested").join("output.txt");
std::fs::create_dir_all(output_path.parent().unwrap()).unwrap();
let result = output_entropy_results(Some(output_path.clone()), "test");
assert!(result.is_ok());
}
#[test]
fn test_all_deep_context_dag_type_variants() {
let variants = [
(DeepContextDagType::CallGraph, DagType::CallGraph),
(DeepContextDagType::ImportGraph, DagType::ImportGraph),
(DeepContextDagType::Inheritance, DagType::Inheritance),
(DeepContextDagType::FullDependency, DagType::FullDependency),
];
for (input, expected) in variants {
let result = convert_deep_context_dag_type(input);
assert!(
matches!(result, ref e if std::mem::discriminant(&result) == std::mem::discriminant(e))
);
let _ = expected; }
}
#[test]
fn test_cache_strategy_all_variants() {
assert_eq!(
convert_cache_strategy(DeepContextCacheStrategy::Normal),
"normal"
);
assert_eq!(
convert_cache_strategy(DeepContextCacheStrategy::ForceRefresh),
"force-refresh"
);
assert_eq!(
convert_cache_strategy(DeepContextCacheStrategy::Offline),
"offline"
);
}
#[test]
fn test_create_entropy_config_boundary_include_tests_true() {
use crate::cli::EntropySeverity;
let config = create_entropy_config(EntropySeverity::Low, true);
assert!(config.exclude_paths.len() >= 2);
}
#[test]
fn test_create_entropy_config_boundary_include_tests_false() {
use crate::cli::EntropySeverity;
let config = create_entropy_config(EntropySeverity::High, false);
assert!(config.exclude_paths.iter().any(|p| p.contains("test")));
}