use super::*;
#[test]
fn display_config_not_found() {
let err = TwcError::ConfigNotFound("/tmp/test.toml".to_string());
assert_eq!(err.to_string(), "config not found: /tmp/test.toml");
}
#[test]
fn display_config_parse() {
let err = TwcError::ConfigParse("bad toml".to_string());
assert_eq!(err.to_string(), "failed to parse config: bad toml");
}
#[test]
fn display_config_write() {
let err = TwcError::ConfigWrite("disk full".to_string());
assert_eq!(err.to_string(), "failed to write config: disk full");
}
#[test]
fn display_token_missing() {
let err = TwcError::TokenMissing;
assert_eq!(
err.to_string(),
"no API token configured; run `twc-rs config set-token`"
);
}
#[test]
fn display_api() {
let err = TwcError::Api("timeout".to_string());
assert_eq!(err.to_string(), "API error: timeout");
}
#[test]
fn display_io() {
let err = TwcError::Io("permission denied".to_string());
assert_eq!(err.to_string(), "I/O error: permission denied");
}
#[test]
fn from_io_error() {
let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file missing");
let twc_err: TwcError = io_err.into();
assert!(twc_err.to_string().contains("file missing"));
}
#[test]
fn from_toml_de_error() {
let toml_err = toml::from_str::<super::super::config::AppConfig>("not valid = [").unwrap_err();
let twc_err: TwcError = toml_err.into();
assert!(twc_err.to_string().contains("failed to parse config"));
}
#[test]
fn from_toml_de_error_invalid_syntax() {
let toml_err = toml::from_str::<super::super::config::AppConfig>("= = =").unwrap_err();
let twc_err: TwcError = toml_err.into();
assert!(twc_err.to_string().contains("failed to parse config"));
}
#[test]
fn from_toml_ser_error() {
use serde::Serialize;
#[derive(Serialize)]
struct NanHolder(f64);
let holder = NanHolder(f64::NAN);
let ser_err = toml::to_string(&holder).unwrap_err();
let twc_err: TwcError = ser_err.into();
assert!(twc_err.to_string().contains("failed to write config"));
}
#[test]
fn from_timeweb_serde_error() {
let serde_err = serde_json::from_str::<serde_json::Value>("not json").unwrap_err();
let api_err: timeweb_rs::apis::Error<String> = timeweb_rs::apis::Error::Serde(serde_err);
let twc_err: TwcError = api_err.into();
assert!(twc_err.to_string().contains("API error"));
}
#[test]
fn from_timeweb_io_error() {
let io_err = std::io::Error::other("timeweb io");
let api_err: timeweb_rs::apis::Error<String> = timeweb_rs::apis::Error::Io(io_err);
let twc_err: TwcError = api_err.into();
assert!(twc_err.to_string().contains("I/O error"));
}
#[test]
fn from_timeweb_response_error_with_entity() {
use timeweb_rs::apis::ResponseContent;
let content = ResponseContent::<String> {
status: reqwest::StatusCode::UNAUTHORIZED,
content: String::new(),
entity: Some("unauthorized".to_string())
};
let api_err: timeweb_rs::apis::Error<String> = timeweb_rs::apis::Error::ResponseError(content);
let twc_err: TwcError = api_err.into();
assert!(twc_err.to_string().contains("API error"));
assert!(twc_err.to_string().contains("unauthorized"));
}
#[test]
fn from_timeweb_response_error_without_entity() {
use timeweb_rs::apis::ResponseContent;
let content = ResponseContent::<String> {
status: reqwest::StatusCode::NOT_FOUND,
content: String::new(),
entity: None
};
let api_err: timeweb_rs::apis::Error<String> = timeweb_rs::apis::Error::ResponseError(content);
let twc_err: TwcError = api_err.into();
assert!(twc_err.to_string().contains("API error"));
assert!(twc_err.to_string().contains("404"));
}
#[test]
fn error_trait_is_implemented() {
let err = TwcError::TokenMissing;
#[allow(clippy::no_effect_underscore_binding)]
let _dyn_err: &dyn std::error::Error = &err;
}
#[test]
fn error_source_is_none_for_response_error() {
use timeweb_rs::apis::ResponseContent;
let content = ResponseContent::<String> {
status: reqwest::StatusCode::BAD_REQUEST,
content: String::new(),
entity: None
};
let api_err: timeweb_rs::apis::Error<String> = timeweb_rs::apis::Error::ResponseError(content);
let twc_err: TwcError = api_err.into();
let dyn_err: &dyn std::error::Error = &twc_err;
assert!(dyn_err.source().is_none());
}