mod common;
use std::error::Error as _;
use common::{TestError, TestKind};
use uni_error::cause::{Cause, Downcast, FakeError};
use uni_error::convert::{ErrorContext as _, ErrorContextDisplay as _};
use uni_error::{SimpleError, UniError};
#[test]
fn test_cause_with_error_root() {
let err1 = TestError::new("test".to_string(), None);
let err2 = TestError::new("test2".to_string(), Some(Box::new(err1.clone())));
let err3: SimpleError = err2.clone().kind_default_context("context");
let err4: UniError<TestKind> = err3.clone().kind(TestKind::Test);
let err5: SimpleError = err4.clone().kind_default();
let mut chain = err5.chain();
let cause4 = chain.next().unwrap();
let cause3 = chain.next().unwrap();
let cause2 = chain.next().unwrap();
let cause1 = chain.next().unwrap();
assert!(chain.next().is_none());
assert!(matches!(cause4, Cause::UniError(_)));
assert!(matches!(cause3, Cause::UniError(_)));
assert!(matches!(cause2, Cause::UniStdError(_)));
assert!(matches!(cause1, Cause::StdError(_)));
assert_eq!(cause4.to_string(), "context: TestError: test2");
assert_eq!(cause3.to_string(), "context: TestError: test2");
assert_eq!(cause2.to_string(), "TestError: test2");
assert_eq!(cause1.to_string(), "TestError: test");
assert_eq!(
cause4.type_name(),
"uni_error::error::UniError<test_cause::common::TestKind>"
);
assert_eq!(cause3.type_name(), "uni_error::error::UniError<()>");
assert_eq!(cause2.type_name(), "test_cause::common::TestError");
assert_eq!(cause1.type_name(), "dyn core::error::Error");
match cause4.downcast::<(), FakeError, TestKind>() {
Some(Downcast::UniError(err)) => assert_eq!(err, err4),
_ => panic!("Expected downcast to UniError<TestKind>"),
}
match cause3.downcast::<(), FakeError, ()>() {
Some(Downcast::UniError(err)) => assert_eq!(err, err3),
_ => panic!("Expected downcast to SimpleError"),
}
match cause2.downcast::<(), TestError, ()>() {
Some(Downcast::ErrorRef(err)) => assert_eq!(err, &err2),
_ => panic!("Expected downcast to TestError"),
}
match cause1.downcast::<(), TestError, ()>() {
Some(Downcast::ErrorRef(err)) => assert_eq!(err, &err1),
_ => panic!("Expected downcast to TestError"),
}
match cause4.source() {
Some(err) => assert!(err.to_string().contains("context")),
None => panic!("Expected source for cause4 to be present"),
}
match cause3.source().unwrap().downcast_ref::<TestError>() {
Some(err) => assert_eq!(err, &err2),
None => panic!("Expected source for cause3 to be present"),
}
match cause2.source().unwrap().downcast_ref::<TestError>() {
Some(err) => assert_eq!(err, &err1),
None => panic!("Expected source for cause2 to be present"),
}
assert!(cause1.source().is_none());
}
#[test]
fn test_cause_with_display_root() {
let err1 = "special test";
let err2: SimpleError = err1.kind_default_context_disp("special context");
let err3: UniError<TestKind> = err2.clone().kind(TestKind::Test);
let mut chain = err3.chain();
let cause2 = chain.next().unwrap();
let cause1 = chain.next().unwrap();
assert!(chain.next().is_none());
assert!(matches!(cause2, Cause::UniError(_)));
assert!(matches!(cause1, Cause::UniDisplay(_)));
assert_eq!(cause2.to_string(), "special context: special test");
assert_eq!(cause1.to_string(), "special test");
assert_eq!(cause2.type_name(), "uni_error::error::UniError<()>");
assert_eq!(cause1.type_name(), "&str");
match cause2.downcast::<(), FakeError, ()>() {
Some(Downcast::UniError(err)) => assert_eq!(err, err2),
_ => panic!("Expected downcast to SimpleError"),
}
match cause1.downcast::<&str, FakeError, ()>() {
Some(Downcast::DisplayRef(err)) => assert_eq!(err, &err1),
_ => panic!("Expected downcast to &str"),
}
assert!(cause2.source().is_none());
assert!(cause1.source().is_none());
}