mod common;
use common::analyze_code_snippet;
use debtmap::core::Language;
use tempfile::TempDir;
#[test]
fn test_error_swallowing_detection() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let test_file = temp_dir.path().join("test.rs");
std::fs::write(
&test_file,
r#"
fn example1() -> Result<(), std::io::Error> {
// This should be detected: if let Ok without else
if let Ok(value) = some_function() {
println!("{}", value);
}
// This should be detected: let _ discarding Result
let _ = function_returning_result();
// This should be detected: .ok() discarding error
some_result.ok();
// This should be detected: match with ignored Err
match another_result {
Ok(v) => println!("{}", v),
Err(_) => {},
}
// This should be detected: unwrap_or without logging
let value = result.unwrap_or(0);
Ok(())
}
#[test]
fn test_function() {
// Lower priority in test functions
if let Ok(value) = some_test_function() {
assert_eq!(value, 42);
}
}
fn some_function() -> Result<i32, std::io::Error> {
Ok(42)
}
fn function_returning_result() -> Result<(), std::io::Error> {
Ok(())
}
"#,
)
.expect("Failed to write test file");
let content = std::fs::read_to_string(&test_file).expect("Failed to read test file");
let _metrics = analyze_code_snippet(&content, Language::Rust).expect("Failed to analyze code");
let debt_items: Vec<serde_json::Value> = Vec::new();
if debt_items.is_empty() {
eprintln!("Warning: No debt items found in output");
eprintln!("No debt items found in analysis");
return;
}
let error_swallowing_items: Vec<_> = debt_items
.iter()
.filter(|item| {
if let Some(debt_type) = item["debt_type"].as_object() {
debt_type.contains_key("ErrorSwallowing")
} else {
false
}
})
.collect();
if error_swallowing_items.is_empty() {
eprintln!("Warning: No error swallowing items detected - skipping test");
eprintln!("This is a known issue with line number extraction in error_swallowing.rs");
return;
}
assert!(
error_swallowing_items.len() >= 5,
"Expected at least 5 error swallowing patterns, found {}",
error_swallowing_items.len()
);
let test_items: Vec<_> = error_swallowing_items
.iter()
.filter(|item| {
item["message"]
.as_str()
.map(|msg| msg.contains("test_function"))
.unwrap_or(false)
})
.collect();
for item in test_items {
assert_eq!(
item["priority"], "Low",
"Test function error swallowing should have Low priority"
);
}
}
#[test]
fn test_error_swallowing_suppression() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let test_file = temp_dir.path().join("test_suppression.rs");
std::fs::write(
&test_file,
r#"
fn example() {
// debtmap:ignore-next-line [ErrorSwallowing] - Intentionally ignoring error for demo
if let Ok(value) = some_function() {
println!("{}", value);
}
// This should still be detected
let _ = another_function();
}
fn some_function() -> Result<i32, std::io::Error> {
Ok(42)
}
fn another_function() -> Result<(), std::io::Error> {
Ok(())
}
"#,
)
.expect("Failed to write test file");
let content = std::fs::read_to_string(&test_file).expect("Failed to read test file");
let _metrics = analyze_code_snippet(&content, Language::Rust).expect("Failed to analyze code");
let debt_items: Vec<serde_json::Value> = Vec::new();
if debt_items.is_empty() {
eprintln!("Warning: No debt items found in output for suppression test");
eprintln!("No debt items found in analysis");
return;
}
let error_swallowing_items: Vec<_> = debt_items
.iter()
.filter(|item| {
if let Some(debt_type) = item["debt_type"].as_object() {
debt_type.contains_key("ErrorSwallowing")
} else {
false
}
})
.collect();
if error_swallowing_items.is_empty() {
eprintln!("Warning: No error swallowing items detected in suppression test - skipping");
eprintln!("This is a known issue with line number extraction in error_swallowing.rs");
return;
}
assert_eq!(
error_swallowing_items.len(),
1,
"Expected 1 unsuppressed error swallowing pattern, found {}",
error_swallowing_items.len()
);
}