use decrust_promac_runtime::types::{
Autocorrection, DiagnosticResult, ErrorCategory, ErrorContext, ErrorLocation,
ErrorReportFormat, ErrorSeverity, ErrorSource, ExtractedParameters, FixDetails, FixType,
ParameterSource,
};
use std::path::PathBuf;
#[test]
fn test_error_category_display_and_debug() {
assert_eq!(format!("{}", ErrorCategory::Io), "IO");
assert_eq!(format!("{}", ErrorCategory::Parsing), "Parsing");
assert_eq!(format!("{}", ErrorCategory::Network), "Network");
assert_eq!(format!("{}", ErrorCategory::Configuration), "Configuration");
assert_eq!(format!("{}", ErrorCategory::Validation), "Validation");
assert_eq!(format!("{}", ErrorCategory::Internal), "Internal");
assert_eq!(format!("{:?}", ErrorCategory::Io), "Io");
assert_eq!(format!("{:?}", ErrorCategory::Parsing), "Parsing");
assert_eq!(format!("{:?}", ErrorCategory::Network), "Network");
assert_eq!(
format!("{:?}", ErrorCategory::Configuration),
"Configuration"
);
assert_eq!(format!("{:?}", ErrorCategory::Validation), "Validation");
assert_eq!(format!("{:?}", ErrorCategory::Internal), "Internal");
}
#[test]
fn test_error_severity_ordering() {
assert!(ErrorSeverity::Critical > ErrorSeverity::Error);
assert!(ErrorSeverity::Error > ErrorSeverity::Warning);
assert!(ErrorSeverity::Warning > ErrorSeverity::Info);
assert!(ErrorSeverity::Info > ErrorSeverity::Debug);
assert_eq!(ErrorSeverity::Critical, ErrorSeverity::Critical);
assert_eq!(ErrorSeverity::Error, ErrorSeverity::Error);
assert_eq!(ErrorSeverity::Warning, ErrorSeverity::Warning);
assert_eq!(ErrorSeverity::Info, ErrorSeverity::Info);
assert_eq!(ErrorSeverity::Debug, ErrorSeverity::Debug);
}
#[test]
fn test_error_report_format_display_and_debug() {
assert_eq!(format!("{}", ErrorReportFormat::Plain), "Plain");
assert_eq!(format!("{}", ErrorReportFormat::Json), "JSON");
assert_eq!(format!("{}", ErrorReportFormat::Markdown), "Markdown");
assert_eq!(format!("{}", ErrorReportFormat::Html), "HTML");
assert_eq!(format!("{:?}", ErrorReportFormat::Plain), "Plain");
assert_eq!(format!("{:?}", ErrorReportFormat::Json), "Json");
assert_eq!(format!("{:?}", ErrorReportFormat::Markdown), "Markdown");
assert_eq!(format!("{:?}", ErrorReportFormat::Html), "Html");
}
#[test]
fn test_autocorrection_building() {
let autocorrection = Autocorrection::new("Fix parse error", FixType::TextReplacement, 0.85);
assert_eq!(autocorrection.description, "Fix parse error");
assert_eq!(autocorrection.fix_type, FixType::TextReplacement);
assert_eq!(autocorrection.confidence, 0.85);
assert!(autocorrection.details.is_none());
assert!(autocorrection.diff_suggestion.is_none());
assert!(autocorrection.commands_to_apply.is_empty());
assert!(autocorrection.targets_error_code.is_none());
let autocorrection = autocorrection.with_details(FixDetails::TextReplace {
file_path: PathBuf::from("src/main.rs"),
line_start: 10,
column_start: 5,
line_end: 10,
column_end: 15,
original_text_snippet: Some("foo(bar)".to_string()),
replacement_text: "foo(baz)".to_string(),
});
assert!(autocorrection.details.is_some());
let autocorrection =
autocorrection.with_diff_suggestion("@@ -10,5 +10,5 @@\n-foo(bar)\n+foo(baz)");
assert!(autocorrection.diff_suggestion.is_some());
assert_eq!(
autocorrection.diff_suggestion.as_ref().unwrap(),
"@@ -10,5 +10,5 @@\n-foo(bar)\n+foo(baz)"
);
let autocorrection = autocorrection.add_command("cargo check");
assert_eq!(autocorrection.commands_to_apply.len(), 1);
assert_eq!(autocorrection.commands_to_apply[0], "cargo check");
let autocorrection = autocorrection.with_target_error_code("E0001");
assert!(autocorrection.targets_error_code.is_some());
assert_eq!(autocorrection.targets_error_code.unwrap(), "E0001");
}
#[test]
fn test_fix_details_variants() {
let text_replace = FixDetails::TextReplace {
file_path: PathBuf::from("src/main.rs"),
line_start: 10,
column_start: 5,
line_end: 10,
column_end: 15,
original_text_snippet: Some("foo(bar)".to_string()),
replacement_text: "foo(baz)".to_string(),
};
let add_import = FixDetails::AddImport {
file_path: "src/main.rs".to_string(),
import: "use std::io::Result;".to_string(),
};
let exec_command = FixDetails::ExecuteCommand {
command: "cargo".to_string(),
args: vec!["fix".to_string(), "--allow-dirty".to_string()],
working_directory: Some(PathBuf::from(".")),
};
let suggest_code = FixDetails::SuggestCodeChange {
file_path: PathBuf::from("src/lib.rs"),
line_hint: 42,
suggested_code_snippet: "impl Clone for MyStruct {}".to_string(),
explanation: "Add Clone implementation".to_string(),
};
assert!(matches!(text_replace, FixDetails::TextReplace { .. }));
assert!(matches!(add_import, FixDetails::AddImport { .. }));
assert!(matches!(exec_command, FixDetails::ExecuteCommand { .. }));
assert!(matches!(suggest_code, FixDetails::SuggestCodeChange { .. }));
}
#[test]
fn test_error_source() {
let source = ErrorSource::new("src/main.rs", 42, "main");
assert_eq!(source.file, "src/main.rs");
assert_eq!(source.line, 42);
assert_eq!(source.module_path, "main");
assert_eq!(source.column, None);
assert_eq!(source.function, None);
let source = source.with_column(10).with_function("process_data");
assert_eq!(source.column, Some(10));
assert_eq!(source.function, Some("process_data".to_string()));
}
#[test]
fn test_error_location() {
let location = ErrorLocation::new("src/main.rs", 42, 10, "process_data");
assert_eq!(location.file, "src/main.rs");
assert_eq!(location.line, 42);
assert_eq!(location.column, 10);
assert_eq!(location.function_context, "process_data");
assert_eq!(location.decrust_variant, None);
let location = location.with_snafu_variant("IoError");
assert_eq!(location.decrust_variant, Some("IoError".to_string()));
}
#[test]
fn test_diagnostic_result() {
let diagnostic = DiagnosticResult {
primary_location: Some(ErrorLocation::new("src/main.rs", 42, 10, "process_data")),
expansion_trace: vec![],
suggested_fixes: vec!["Add semicolon at the end of line".to_string()],
original_message: Some("Expected ';', found '}'".to_string()),
diagnostic_code: Some("E0001".to_string()),
};
assert!(diagnostic.primary_location.is_some());
assert!(diagnostic.expansion_trace.is_empty());
assert_eq!(diagnostic.suggested_fixes.len(), 1);
assert_eq!(
diagnostic.suggested_fixes[0],
"Add semicolon at the end of line"
);
assert_eq!(
diagnostic.original_message,
Some("Expected ';', found '}'".to_string())
);
assert_eq!(diagnostic.diagnostic_code, Some("E0001".to_string()));
}
#[test]
fn test_error_context_building() {
let context = ErrorContext::new("Test error");
assert_eq!(context.message, "Test error");
assert_eq!(context.severity, ErrorSeverity::Error);
assert!(context.source_location.is_none());
assert!(context.recovery_suggestion.is_none());
assert!(context.metadata.is_empty());
assert!(context.timestamp.is_some());
assert!(context.correlation_id.is_none());
assert!(context.component.is_none());
assert!(context.tags.is_empty());
assert!(context.diagnostic_info.is_none());
let context = context
.with_severity(ErrorSeverity::Warning)
.with_recovery_suggestion("Try again")
.with_metadata("request_id", "123456")
.with_correlation_id("corr-789")
.with_component("auth_service")
.add_tag("security");
assert_eq!(context.severity, ErrorSeverity::Warning);
assert_eq!(context.recovery_suggestion, Some("Try again".to_string()));
assert_eq!(
context.metadata.get("request_id"),
Some(&"123456".to_string())
);
assert_eq!(context.correlation_id, Some("corr-789".to_string()));
assert_eq!(context.component, Some("auth_service".to_string()));
assert_eq!(context.tags.len(), 1);
assert_eq!(context.tags[0], "security");
}
#[test]
fn test_extracted_parameters() {
let mut params = ExtractedParameters::new();
assert!(params.values.is_empty());
assert_eq!(params.confidence, 0.0);
assert_eq!(params.source, ParameterSource::Manual);
params.add_parameter("file", "src/main.rs");
params.add_parameter("line", "42");
params.set_confidence(0.8);
params.set_source(ParameterSource::ErrorMessage);
assert_eq!(params.values.len(), 2);
assert_eq!(params.values.get("file"), Some(&"src/main.rs".to_string()));
assert_eq!(params.values.get("line"), Some(&"42".to_string()));
assert_eq!(params.confidence, 0.8);
assert_eq!(params.source, ParameterSource::ErrorMessage);
let mut other_params = ExtractedParameters::with_source(ParameterSource::DiagnosticInfo, 0.9);
other_params.add_parameter("column", "10");
other_params.add_parameter("message", "Missing semicolon");
params.merge(&other_params);
assert_eq!(params.values.len(), 4);
assert_eq!(params.values.get("column"), Some(&"10".to_string()));
assert_eq!(
params.values.get("message"),
Some(&"Missing semicolon".to_string())
);
assert_eq!(params.confidence, 0.9);
assert_eq!(params.source, ParameterSource::DiagnosticInfo);
}