use claude_utils::{ClaudeUtilsError, Result};
use std::io;
#[test]
fn test_error_conversions() {
let io_error = io::Error::new(io::ErrorKind::NotFound, "File not found");
let utils_error: ClaudeUtilsError = io_error.into();
assert!(matches!(utils_error, ClaudeUtilsError::FileOperation(_)));
let img_error = image::ImageError::Unsupported(
image::error::UnsupportedError::from_format_and_kind(
image::error::ImageFormatHint::Unknown,
image::error::UnsupportedErrorKind::GenericFeature("test".to_string()),
)
);
let utils_error: ClaudeUtilsError = img_error.into();
assert!(matches!(utils_error, ClaudeUtilsError::ImageProcessing(_)));
let json_error = serde_json::from_str::<String>("invalid json").unwrap_err();
let utils_error: ClaudeUtilsError = json_error.into();
assert!(matches!(utils_error, ClaudeUtilsError::Serialization(_)));
}
#[test]
fn test_custom_errors() {
let clipboard_error = ClaudeUtilsError::Clipboard("Test clipboard error".to_string());
assert_eq!(clipboard_error.to_string(), "Clipboard error: Test clipboard error");
let auth_error = ClaudeUtilsError::Authentication("Invalid token".to_string());
assert_eq!(auth_error.to_string(), "Authentication error: Invalid token");
let mcp_error = ClaudeUtilsError::McpProtocol("Protocol violation".to_string());
assert_eq!(mcp_error.to_string(), "MCP protocol error: Protocol violation");
let server_error = ClaudeUtilsError::Server("Port in use".to_string());
assert_eq!(server_error.to_string(), "Server error: Port in use");
let turbo_error = ClaudeUtilsError::Turbo("Rollback failed".to_string());
assert_eq!(turbo_error.to_string(), "Turbo mode error: Rollback failed");
}
#[test]
fn test_result_type() {
fn returns_result() -> Result<String> {
Ok("Success".to_string())
}
fn returns_error() -> Result<String> {
Err(ClaudeUtilsError::Clipboard("Failed".to_string()))
}
assert!(returns_result().is_ok());
assert!(returns_error().is_err());
}
#[tokio::test]
async fn test_file_operation_errors() {
let result: Result<()> = async {
tokio::fs::read("/non/existent/path/file.txt").await?;
Ok(())
}.await;
assert!(result.is_err());
match result.unwrap_err() {
ClaudeUtilsError::FileOperation(e) => {
assert_eq!(e.kind(), io::ErrorKind::NotFound);
}
_ => panic!("Expected FileOperation error"),
}
}
#[test]
fn test_error_chain() {
let io_error = io::Error::new(io::ErrorKind::PermissionDenied, "Access denied");
let utils_error: ClaudeUtilsError = io_error.into();
assert!(utils_error.to_string().contains("Access denied") ||
utils_error.to_string().contains("permission denied"));
}
#[test]
fn test_authentication_error_scenarios() {
let scenarios = vec![
("", "Empty token"),
("invalid-token", "Invalid format"),
("expired-token", "Token expired"),
];
for (token, reason) in scenarios {
let error = ClaudeUtilsError::Authentication(format!("{reason}: {token}"));
assert!(error.to_string().contains(reason));
}
}
#[test]
fn test_mcp_protocol_errors() {
let errors = vec![
ClaudeUtilsError::McpProtocol("Invalid JSON-RPC version".to_string()),
ClaudeUtilsError::McpProtocol("Method not found".to_string()),
ClaudeUtilsError::McpProtocol("Invalid parameters".to_string()),
];
for error in errors {
assert!(error.to_string().starts_with("MCP protocol error:"));
}
}
#[tokio::test]
async fn test_concurrent_error_handling() {
use std::sync::Arc;
use tokio::sync::Mutex;
let error_count = Arc::new(Mutex::new(0));
let handles: Vec<_> = (0..10)
.map(|i| {
let count = error_count.clone();
tokio::spawn(async move {
let result: Result<()> = if i % 2 == 0 {
Ok(())
} else {
Err(ClaudeUtilsError::Server(format!("Error {i}")))
};
if result.is_err() {
let mut c = count.lock().await;
*c += 1;
}
})
})
.collect();
for handle in handles {
handle.await.unwrap();
}
assert_eq!(*error_count.lock().await, 5);
}
#[test]
fn test_error_display_formatting() {
let error = ClaudeUtilsError::Turbo("Operation failed: unable to create checkpoint".to_string());
let formatted = format!("{error}");
assert_eq!(formatted, "Turbo mode error: Operation failed: unable to create checkpoint");
let debug_formatted = format!("{error:?}");
assert!(debug_formatted.contains("Turbo"));
assert!(debug_formatted.contains("Operation failed"));
}