#![cfg_attr(
feature = "unstable-error-generic-member-access",
feature(error_generic_member_access)
)]
use std::error::Error as _;
use oopsie::prelude::*;
#[test]
fn welp_propagates_foreign_io_error_through_question_mark() {
fn read() -> Result<String, Welp> {
let raw = std::fs::read_to_string("/nonexistent/oopsie-welp-test").welp()?;
Ok(raw)
}
let err = read().unwrap_err();
assert!(err.message().is_none());
assert!(err.source().is_some());
}
#[test]
fn welp_delegates_display_to_source() {
let result: Result<(), std::io::Error> = Err(std::io::Error::other("disk full"));
let err = result.welp().unwrap_err();
assert_eq!(err.to_string(), "disk full");
assert_eq!(err.source().expect("source").to_string(), "disk full");
}
#[test]
fn welp_source_chain_is_one_link() {
let result: Result<(), std::io::Error> = Err(std::io::Error::other("boom"));
let err = result.welp().unwrap_err();
let first = err.source().expect("first source is the io error");
assert_eq!(first.to_string(), "boom");
assert!(
first.source().is_none(),
"the io error is the chain's root cause"
);
}
#[test]
fn welp_source_downcasts_to_original_error() {
let result: Result<(), std::io::Error> = Err(std::io::Error::new(
std::io::ErrorKind::PermissionDenied,
"nope",
));
let err = result.welp().unwrap_err();
let io = err
.source()
.and_then(|s| s.downcast_ref::<std::io::Error>())
.expect("source downcasts back to the original io::Error");
assert_eq!(io.kind(), std::io::ErrorKind::PermissionDenied);
}
#[test]
fn from_error_matches_welp_behavior() {
let err = Welp::from_error(std::io::Error::other("manual"));
assert!(err.message().is_none());
assert_eq!(err.to_string(), "manual");
assert_eq!(err.source().expect("source").to_string(), "manual");
}
#[test]
fn welp_surfaces_a_trace() {
use oopsie::Diagnostic as _;
oopsie_core::test_utils::force_backtrace();
let result: Result<(), Welp> = Err(Welp::new("origin"));
let err = result.welp().unwrap_err();
assert!(err.oopsie_backtrace().is_some());
}