use debtmap::priority::caller_classification::{
classify_caller, classify_callers, CallerType, ClassifiedCallers,
};
#[test]
fn test_production_blast_radius_lower_than_total() {
let callers = vec![
"test_parse_empty_array".to_string(),
"test_parse_nested_array".to_string(),
"should_handle_overflow".to_string(),
"verify_array_bounds".to_string(),
"test_unicode_elements".to_string(),
"spec_array_reflow".to_string(),
"mock_parser_setup".to_string(),
"fixture_array_data".to_string(),
"process_file".to_string(),
"main".to_string(),
];
let classified = classify_callers(callers.iter(), None);
assert_eq!(
classified.test_count, 8,
"Expected 8 test callers, got {}",
classified.test_count
);
assert_eq!(
classified.production_count, 2,
"Expected 2 production callers, got {}",
classified.production_count
);
let production_blast_radius = classified.production_count;
let total_blast_radius = classified.total_count();
assert!(
production_blast_radius < total_blast_radius,
"Production blast radius ({}) should be less than total ({})",
production_blast_radius,
total_blast_radius
);
let reduction_percentage =
((total_blast_radius - production_blast_radius) as f64 / total_blast_radius as f64) * 100.0;
assert!(
reduction_percentage >= 50.0,
"Expected at least 50% reduction in blast radius, got {:.1}%",
reduction_percentage
);
}
#[test]
fn test_scoring_uses_production_count_only() {
let callers = vec![
"test_case_1".to_string(),
"test_case_2".to_string(),
"test_case_3".to_string(),
"test_case_4".to_string(),
"test_case_5".to_string(),
"should_work".to_string(),
"verify_output".to_string(),
"fixture_setup".to_string(),
"mock_dependency".to_string(),
"handle_request".to_string(),
];
let classified = classify_callers(callers.iter(), None);
let scoring_dependency_count = classified.production_count;
assert_eq!(
scoring_dependency_count,
1,
"Scoring should use production count (1), not total count ({})",
classified.total_count()
);
assert_eq!(classified.test_count, 9);
assert_eq!(classified.total_count(), 10);
}
#[test]
fn test_real_world_caller_patterns() {
let production_patterns = vec![
"analyze_file",
"process_tokens",
"calculate_complexity",
"build_call_graph",
"format_output",
"parse_config",
"create_report",
"main",
"run",
"execute",
"handle_error",
"validate_input",
];
for pattern in &production_patterns {
let caller_type = classify_caller(pattern, None);
assert_eq!(
caller_type,
CallerType::Production,
"'{}' should be classified as Production",
pattern
);
}
let test_patterns = vec![
"test_analyze_file",
"test_process_tokens",
"should_calculate_complexity",
"verify_call_graph",
"spec_format_output",
"it_parses_config",
"when_creating_report",
"given_valid_input",
"mock_file_system",
"stub_api_client",
"fixture_test_data",
"crate::tests::helper_function", "module::tests::setup", ];
for pattern in &test_patterns {
let caller_type = classify_caller(pattern, None);
assert_eq!(
caller_type,
CallerType::Test,
"'{}' should be classified as Test",
pattern
);
}
}
#[test]
fn test_edge_case_caller_patterns() {
let false_positive_risks = vec![
"attest_signature", "contest_results", "latest_version", "testing_mode_check", ];
for pattern in &false_positive_risks {
let caller_type = classify_caller(pattern, None);
assert_eq!(
caller_type,
CallerType::Production,
"'{}' should NOT be classified as Test (false positive)",
pattern
);
}
let test_infrastructure = vec![
"get_test_config", "load_test_data", "is_test_file", ];
for pattern in &test_infrastructure {
let caller_type = classify_caller(pattern, None);
assert_eq!(
caller_type,
CallerType::Test,
"'{}' should be classified as Test (test infrastructure with _test_)",
pattern
);
}
let false_negative_risks = vec![
"test_", "integration_test_suite",
"unit_test_helper",
"e2e_test_runner",
];
for pattern in &false_negative_risks {
let caller_type = classify_caller(pattern, None);
assert_eq!(
caller_type,
CallerType::Test,
"'{}' SHOULD be classified as Test (avoid false negative)",
pattern
);
}
}
#[test]
fn test_path_based_classification() {
let test_paths = vec![
"src/tests/helpers::create_mock_data",
"crate::tests::test_utils::setup",
"module::test::fixtures::user_data",
"/tests/integration/helper::prepare",
"path/to/tests/common::initialize",
];
for path in &test_paths {
let caller_type = classify_caller(path, None);
assert_eq!(
caller_type,
CallerType::Test,
"Path '{}' should be classified as Test due to path pattern",
path
);
}
let prod_paths = vec![
"src/lib::process_file",
"crate::core::analyze",
"module::utils::format",
];
for path in &prod_paths {
let caller_type = classify_caller(path, None);
assert_eq!(
caller_type,
CallerType::Production,
"Path '{}' should be classified as Production",
path
);
}
}
#[test]
fn test_classified_callers_structure() {
let mut classified = ClassifiedCallers::new();
assert_eq!(classified.total_count(), 0);
assert_eq!(classified.production_count, 0);
assert_eq!(classified.test_count, 0);
assert!(classified.production.is_empty());
assert!(classified.test.is_empty());
classified.production.push("main".to_string());
classified.production_count = 1;
classified.test.push("test_main".to_string());
classified.test.push("verify_main".to_string());
classified.test_count = 2;
assert_eq!(classified.total_count(), 3);
assert_eq!(classified.production_count, 1);
assert_eq!(classified.test_count, 2);
}
#[test]
fn test_heavily_tested_core_function() {
let callers = vec![
"compile_module".to_string(),
"evaluate_script".to_string(),
"analyze_ast".to_string(),
"process_template".to_string(),
"execute_query".to_string(),
"test_parse_simple_expression".to_string(),
"test_parse_binary_operator".to_string(),
"test_parse_unary_operator".to_string(),
"test_parse_parentheses".to_string(),
"test_parse_function_call".to_string(),
"test_parse_method_chain".to_string(),
"test_parse_array_access".to_string(),
"test_parse_object_literal".to_string(),
"test_parse_lambda".to_string(),
"test_parse_ternary".to_string(),
"test_integration_with_lexer".to_string(),
"test_integration_with_ast".to_string(),
"test_performance_large_input".to_string(),
"test_performance_deep_nesting".to_string(),
"test_memory_usage".to_string(),
"should_handle_empty_input".to_string(),
"should_handle_whitespace".to_string(),
"should_handle_comments".to_string(),
"should_handle_unicode".to_string(),
"should_handle_escapes".to_string(),
"verify_operator_precedence".to_string(),
"verify_associativity_left".to_string(),
"verify_associativity_right".to_string(),
"verify_error_recovery".to_string(),
"verify_error_messages".to_string(),
"spec_arithmetic_operators".to_string(),
"spec_comparison_operators".to_string(),
"spec_logical_operators".to_string(),
"spec_assignment_operators".to_string(),
"spec_bitwise_operators".to_string(),
"fixture_complex_expression".to_string(),
"fixture_nested_expression".to_string(),
"fixture_edge_case_expression".to_string(),
"mock_parser_context".to_string(),
"mock_token_stream".to_string(),
"when_input_is_empty".to_string(),
"when_input_is_invalid".to_string(),
"when_input_is_partial".to_string(),
"given_valid_expression".to_string(),
"given_malformed_expression".to_string(),
];
let classified = classify_callers(callers.iter(), None);
assert_eq!(classified.production_count, 5);
assert_eq!(classified.test_count, 40);
assert_eq!(classified.total_count(), 45);
let production_blast_radius = classified.production_count;
let total_blast_radius = classified.total_count();
let test_percentage = (classified.test_count as f64 / total_blast_radius as f64) * 100.0;
assert!(
test_percentage >= 85.0,
"Expected at least 85% test callers, got {:.1}%",
test_percentage
);
let production_percentage =
(production_blast_radius as f64 / total_blast_radius as f64) * 100.0;
assert!(
production_percentage <= 15.0,
"Expected <=15% production callers, got {:.1}%",
production_percentage
);
}
#[test]
fn test_bdd_pattern_classification() {
let bdd_patterns = vec![
"given_user_is_authenticated",
"when_user_clicks_button",
"should_display_error_message",
"it_returns_empty_list",
"spec_validates_input_format",
"verify_state_transition",
];
for pattern in &bdd_patterns {
let caller_type = classify_caller(pattern, None);
assert_eq!(
caller_type,
CallerType::Test,
"BDD pattern '{}' should be classified as Test",
pattern
);
}
}
#[test]
fn test_word_boundary_patterns() {
let mid_test_patterns = vec![
"user_test_helper",
"setup_test_data",
"create_test_fixture",
"run_test_suite",
];
for pattern in &mid_test_patterns {
let caller_type = classify_caller(pattern, None);
assert_eq!(
caller_type,
CallerType::Test,
"'{}' should be classified as Test (word boundary)",
pattern
);
}
let no_boundary_patterns = vec![
"contest", "detest", "attestation", "fastest_route", ];
for pattern in &no_boundary_patterns {
let caller_type = classify_caller(pattern, None);
assert_eq!(
caller_type,
CallerType::Production,
"'{}' should be classified as Production (no word boundary)",
pattern
);
}
}