use brlapi::BrlApiError;
use std::ffi::CString;
#[test]
fn test_error_enum_completeness() {
use brlapi_sys::brlapi_error;
assert!(matches!(
BrlApiError::from_c_error(brlapi_error::BRLAPI_ERROR_SUCCESS as i32),
BrlApiError::Success
));
assert!(matches!(
BrlApiError::from_c_error(brlapi_error::BRLAPI_ERROR_NOMEM as i32),
BrlApiError::NoMem
));
assert!(matches!(
BrlApiError::from_c_error(brlapi_error::BRLAPI_ERROR_TTYBUSY as i32),
BrlApiError::TTYBusy
));
assert!(matches!(
BrlApiError::from_c_error(brlapi_error::BRLAPI_ERROR_DEVICEBUSY as i32),
BrlApiError::DeviceBusy
));
assert!(matches!(
BrlApiError::from_c_error(brlapi_error::BRLAPI_ERROR_UNKNOWN_INSTRUCTION as i32),
BrlApiError::UnknownInstruction
));
assert!(matches!(
BrlApiError::from_c_error(brlapi_error::BRLAPI_ERROR_ILLEGAL_INSTRUCTION as i32),
BrlApiError::IllegalInstruction
));
assert!(matches!(
BrlApiError::from_c_error(brlapi_error::BRLAPI_ERROR_INVALID_PARAMETER as i32),
BrlApiError::InvalidParameter
));
assert!(matches!(
BrlApiError::from_c_error(brlapi_error::BRLAPI_ERROR_INVALID_PACKET as i32),
BrlApiError::InvalidPacket
));
assert!(matches!(
BrlApiError::from_c_error(brlapi_error::BRLAPI_ERROR_CONNREFUSED as i32),
BrlApiError::ConnectionRefused
));
assert!(matches!(
BrlApiError::from_c_error(brlapi_error::BRLAPI_ERROR_OPNOTSUPP as i32),
BrlApiError::OperationNotSupported
));
assert!(matches!(
BrlApiError::from_c_error(brlapi_error::BRLAPI_ERROR_AUTHENTICATION as i32),
BrlApiError::AuthenticationFailed
));
assert!(matches!(
BrlApiError::from_c_error(brlapi_error::BRLAPI_ERROR_READONLY_PARAMETER as i32),
BrlApiError::ParameterCannotBeChanged
));
let error = BrlApiError::ConnectionRefused;
let message = format!("{error}");
assert_eq!(
message,
"Failed to connect to BrlAPI server. Is BRLTTY running? Try 'sudo systemctl start brltty'"
);
let debug_output = format!("{error:?}");
assert!(debug_output.contains("ConnectionRefused"));
}
#[test]
fn test_error_display_and_debug() {
let errors = [
BrlApiError::Success,
BrlApiError::NoMem,
BrlApiError::ConnectionRefused,
BrlApiError::AuthenticationFailed,
BrlApiError::OperationNotSupported,
];
for error in &errors {
let display_msg = format!("{error}");
assert!(!display_msg.is_empty(), "Error message should not be empty");
println!("Display: {display_msg}");
let debug_msg = format!("{error:?}");
assert!(!debug_msg.is_empty(), "Debug output should not be empty");
println!("Debug: {debug_msg}");
let error_msg = error.to_string();
assert_eq!(display_msg, error_msg, "Display and to_string should match");
}
}
#[test]
fn test_error_categorization() {
let connection_errors = [
BrlApiError::ConnectionRefused,
BrlApiError::AuthenticationFailed,
BrlApiError::GetAddrInfoError,
BrlApiError::ConnectionTimeout,
];
let resource_busy_errors = [
BrlApiError::TTYBusy,
BrlApiError::DeviceBusy,
BrlApiError::NoMem,
];
let operation_errors = [
BrlApiError::OperationNotSupported,
BrlApiError::InvalidParameter,
BrlApiError::InvalidPacket,
BrlApiError::ParameterCannotBeChanged,
];
for error in &connection_errors {
assert!(
error.is_connection_error(),
"Should be a connection error: {:?}",
error
);
let msg = format!("{error}");
println!("Connection error: {msg}");
assert!(!msg.is_empty());
}
for error in &resource_busy_errors {
assert!(
error.is_resource_busy(),
"Should be a resource busy error: {:?}",
error
);
let msg = format!("{error}");
println!("Resource busy error: {msg}");
assert!(!msg.is_empty());
}
for error in &operation_errors {
assert!(
error.is_operation_error(),
"Should be an operation error: {:?}",
error
);
let msg = format!("{error}");
println!("Operation error: {msg}");
assert!(!msg.is_empty());
}
}
#[test]
fn test_conversion_errors() {
use std::ffi::CString;
let null_byte_result = CString::new("hello\0world");
assert!(null_byte_result.is_err());
let brlapi_error: BrlApiError = null_byte_result.unwrap_err().into();
assert!(brlapi_error.is_conversion_error());
assert!(matches!(brlapi_error, BrlApiError::NullByteInString(_)));
let invalid_utf8 = vec![0xFF, 0xFE, 0xFD];
let utf8_result = String::from_utf8(invalid_utf8);
assert!(utf8_result.is_err());
let brlapi_error: BrlApiError = utf8_result.unwrap_err().into();
assert!(brlapi_error.is_conversion_error());
assert!(matches!(brlapi_error, BrlApiError::StringConversion(_)));
}
#[test]
fn test_custom_errors() {
let custom_error = BrlApiError::custom("This is a test error");
assert!(matches!(custom_error, BrlApiError::Custom { .. }));
let message = format!("{custom_error}");
assert_eq!(message, "This is a test error");
let unexpected_error = BrlApiError::unexpected_return_value(42);
assert!(matches!(
unexpected_error,
BrlApiError::UnexpectedReturnValue { value: 42 }
));
assert!(unexpected_error.is_operation_error());
}
#[test]
fn test_error_suggestions() {
let connection_error = BrlApiError::ConnectionRefused;
let suggestions = connection_error.suggestions();
assert!(!suggestions.is_empty());
assert!(suggestions.iter().any(|s| s.contains("brltty")));
let auth_error = BrlApiError::AuthenticationFailed;
let auth_suggestions = auth_error.suggestions();
assert!(!auth_suggestions.is_empty());
assert!(auth_suggestions.iter().any(|s| s.contains("brlapi")));
let conversion_error = BrlApiError::NullByteInString(CString::new("test\0").unwrap_err());
let conversion_suggestions = conversion_error.suggestions();
assert!(!conversion_suggestions.is_empty());
assert!(conversion_suggestions.iter().any(|s| s.contains("null")));
}