use debtmap::core::FunctionMetrics;
use debtmap::priority::{
external_api_detector::{
generate_enhanced_dead_code_hints_with_config, is_likely_external_api_with_config,
ExternalApiConfig,
},
FunctionVisibility,
};
use std::path::PathBuf;
fn create_test_function(name: &str, path: &str, visibility: Option<String>) -> FunctionMetrics {
FunctionMetrics {
name: name.to_string(),
file: PathBuf::from(path),
line: 1,
cyclomatic: 5,
cognitive: 8,
nesting: 1,
length: 10,
is_test: false,
visibility,
is_trait_method: false,
in_test_module: false,
entropy_score: None,
is_pure: None,
purity_confidence: None,
detected_patterns: None,
upstream_callers: None,
downstream_callees: None,
mapping_pattern_result: None,
adjusted_complexity: None,
composition_metrics: None,
language_specific: None,
purity_reason: None,
call_dependencies: None,
purity_level: None,
error_swallowing_count: None,
error_swallowing_patterns: None,
entropy_analysis: None,
}
}
fn test_config() -> ExternalApiConfig {
ExternalApiConfig {
detect_external_api: true,
api_functions: vec![],
api_files: vec![],
}
}
#[test]
fn test_workflow_public_api_in_lib_rs() {
let func = create_test_function("new", "src/lib.rs", Some("pub".to_string()));
let visibility = FunctionVisibility::Public;
let (is_api, indicators) =
is_likely_external_api_with_config(&func, &visibility, &test_config());
assert!(is_api, "Constructor in lib.rs should be external API");
assert!(!indicators.is_empty(), "Should have indicators");
let hints = generate_enhanced_dead_code_hints_with_config(&func, &visibility, &test_config());
assert!(
hints.iter().any(|h| h.contains("Likely external API")),
"Hints should indicate external API: {hints:?}"
);
}
#[test]
fn test_workflow_internal_public_function() {
let func = create_test_function(
"helper",
"src/internal/impl/utils.rs",
Some("pub".to_string()),
);
let visibility = FunctionVisibility::Public;
let (is_api, _) = is_likely_external_api_with_config(&func, &visibility, &test_config());
assert!(
!is_api,
"Internal module function should not be external API"
);
let hints = generate_enhanced_dead_code_hints_with_config(&func, &visibility, &test_config());
let has_api_warning = hints.iter().any(|h| h.contains("⚠️ Likely external API"));
assert!(
!has_api_warning,
"Should not have API warning for internal function"
);
}
#[test]
fn test_workflow_private_function() {
let func = create_test_function("internal_helper", "src/utils.rs", None);
let visibility = FunctionVisibility::Private;
let (is_api, indicators) =
is_likely_external_api_with_config(&func, &visibility, &test_config());
assert!(!is_api, "Private functions cannot be external APIs");
assert!(
indicators.is_empty(),
"Private functions should have no API indicators"
);
let hints = generate_enhanced_dead_code_hints_with_config(&func, &visibility, &test_config());
assert!(
!hints.iter().any(|h| h.contains("external API")),
"Private functions should not mention external API"
);
}
#[test]
fn test_workflow_mod_rs_with_api_pattern() {
let func = create_test_function(
"get_configuration",
"src/config/mod.rs",
Some("pub".to_string()),
);
let visibility = FunctionVisibility::Public;
let (is_api, indicators) =
is_likely_external_api_with_config(&func, &visibility, &test_config());
assert!(is_api, "get_* function in mod.rs should be detected as API");
assert!(
indicators.len() >= 2,
"Should have multiple indicators: {indicators:?}"
);
assert!(
indicators.iter().any(|i| i.contains("mod.rs")),
"Should mention mod.rs"
);
assert!(
indicators.iter().any(|i| i.contains("API pattern")),
"Should mention API pattern"
);
}
#[test]
fn test_action_recommendations_based_on_api_detection() {
let api_func = create_test_function("builder", "src/lib.rs", Some("pub".to_string()));
let pub_vis = FunctionVisibility::Public;
let (is_api, _) = is_likely_external_api_with_config(&api_func, &pub_vis, &test_config());
assert!(is_api);
let expected_action = if is_api {
"Verify external usage before removal"
} else {
"Remove unused public function"
};
assert_eq!(expected_action, "Verify external usage before removal");
let non_api_func = create_test_function(
"internal_helper",
"src/internal/utils.rs",
Some("pub".to_string()),
);
let (is_api2, _) = is_likely_external_api_with_config(&non_api_func, &pub_vis, &test_config());
assert!(!is_api2);
let expected_action2 = if is_api2 {
"Verify external usage before removal"
} else {
"Remove unused public function"
};
assert_eq!(expected_action2, "Remove unused public function");
}
#[test]
fn test_complexity_hints_integration() {
let mut func = create_test_function("process", "src/lib.rs", Some("pub".to_string()));
func.cyclomatic = 2;
func.cognitive = 3;
let visibility = FunctionVisibility::Public;
let hints = generate_enhanced_dead_code_hints_with_config(&func, &visibility, &test_config());
assert!(
hints.iter().any(|h| h.contains("Low complexity")),
"Should indicate low complexity"
);
func.cyclomatic = 15;
func.cognitive = 20;
let hints_high =
generate_enhanced_dead_code_hints_with_config(&func, &visibility, &test_config());
assert!(
hints_high.iter().any(|h| h.contains("High complexity")),
"Should indicate high complexity"
);
assert!(
hints.iter().any(|h| h.contains("Likely external API")),
"Low complexity API should still be flagged"
);
assert!(
hints_high.iter().any(|h| h.contains("Likely external API")),
"High complexity API should still be flagged"
);
}