use std::time::Duration;
use crate::ApiClientError;
#[derive(Debug, derive_more::Error, derive_more::Display, derive_more::From)]
pub enum TestAppError {
#[display("I/O error: {_0}")]
IoError(std::io::Error),
#[display("API client error: {_0}")]
ClientError(ApiClientError),
#[display("JSON error: {_0}")]
JsonError(serde_json::Error),
#[display("YAML serialization error: {error}")]
YamlError {
error: String,
},
#[from(ignore)]
#[display("Server failed to become healthy within {timeout:?}")]
UnhealthyServer {
timeout: Duration,
},
#[display("Server error: {_0}")]
ServerError(Box<dyn std::error::Error + Send + Sync + 'static>),
}
#[cfg(test)]
mod tests {
use super::*;
use std::time::Duration;
#[test]
fn test_test_app_error_display() {
let yaml_error = TestAppError::YamlError {
error: "Invalid YAML format".to_string(),
};
assert_eq!(
format!("{yaml_error}"),
"YAML serialization error: Invalid YAML format"
);
let unhealthy_error = TestAppError::UnhealthyServer {
timeout: Duration::from_secs(5),
};
assert_eq!(
format!("{unhealthy_error}"),
"Server failed to become healthy within 5s"
);
}
#[test]
fn test_test_app_error_debug() {
let yaml_error = TestAppError::YamlError {
error: "Invalid YAML format".to_string(),
};
let debug_str = format!("{yaml_error:?}");
assert!(debug_str.contains("YamlError"));
assert!(debug_str.contains("Invalid YAML format"));
let unhealthy_error = TestAppError::UnhealthyServer {
timeout: Duration::from_secs(10),
};
let debug_str = format!("{unhealthy_error:?}");
assert!(debug_str.contains("UnhealthyServer"));
assert!(debug_str.contains("10s"));
}
#[test]
fn test_test_app_error_from_io_error() {
let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "File not found");
let tokio_error = io_error;
let test_error: TestAppError = tokio_error.into();
match test_error {
TestAppError::IoError(_) => {} other => panic!("Expected IoError, got: {other:?}"),
}
}
#[test]
fn test_test_app_error_from_json_error() {
let json_str = r#"{"invalid": json"#;
let json_error = serde_json::from_str::<serde_json::Value>(json_str).unwrap_err();
let test_error: TestAppError = json_error.into();
match test_error {
TestAppError::JsonError(_) => {} other => panic!("Expected JsonError, got: {other:?}"),
}
}
#[test]
fn test_test_app_error_from_api_client_error() {
use crate::ApiClient;
let build_result = ApiClient::builder()
.with_scheme(http::uri::Scheme::HTTPS)
.with_host("invalid\0host") .build();
match build_result {
Err(api_error) => {
let test_error: TestAppError = api_error.into();
match test_error {
TestAppError::ClientError(_) => {} other => panic!("Expected ClientError, got: {other:?}"),
}
}
Ok(_) => {
use crate::ApiClientError;
let api_error = ApiClientError::InvalidBasePath {
error: "invalid".to_string(),
};
let test_error: TestAppError = api_error.into();
match test_error {
TestAppError::ClientError(_) => {} other => panic!("Expected ClientError, got: {other:?}"),
}
}
}
}
#[test]
fn test_yaml_error_creation() {
let error_msg = "YAML serialization failed";
let yaml_error = TestAppError::YamlError {
error: error_msg.to_string(),
};
match yaml_error {
TestAppError::YamlError { error } => {
assert_eq!(error, error_msg);
}
other => panic!("Expected YamlError, got: {other:?}"),
}
}
#[test]
fn test_unhealthy_server_error_creation() {
let timeout = Duration::from_millis(2500);
let unhealthy_error = TestAppError::UnhealthyServer { timeout };
match unhealthy_error {
TestAppError::UnhealthyServer {
timeout: actual_timeout,
} => {
assert_eq!(actual_timeout, timeout);
}
other => panic!("Expected UnhealthyServer, got: {other:?}"),
}
}
#[test]
fn test_server_error_creation() {
let server_error = std::io::Error::new(std::io::ErrorKind::AddrInUse, "Port in use");
let test_error = TestAppError::ServerError(Box::new(server_error));
match test_error {
TestAppError::ServerError(_) => {} other => panic!("Expected ServerError, got: {other:?}"),
}
}
#[test]
fn test_error_trait_bounds() {
fn assert_error_traits<T>(_: T)
where
T: std::error::Error + std::fmt::Debug + std::fmt::Display + Send + Sync + 'static,
{
}
let yaml_error = TestAppError::YamlError {
error: "test".to_string(),
};
assert_error_traits(yaml_error);
}
#[test]
fn test_error_source_chain() {
let original_io_error =
std::io::Error::new(std::io::ErrorKind::PermissionDenied, "Access denied");
let tokio_error = original_io_error;
let test_error: TestAppError = tokio_error.into();
match test_error {
TestAppError::IoError(ref io_err) => {
assert_eq!(io_err.kind(), std::io::ErrorKind::PermissionDenied);
}
other => panic!("Expected IoError, got: {other:?}"),
}
}
}