#![cfg_attr(coverage_nightly, coverage(off))]
#[macro_export]
macro_rules! assert_error_message {
($error:expr, $expected:expr) => {{ $crate::test_util::assert_error_message_impl(&$error.to_string(), $expected) }};
}
#[doc(hidden)]
#[track_caller]
pub fn assert_error_message_impl(error_string: &str, expected: &str) {
let matches = error_string == expected
|| error_string.strip_prefix(expected).is_some_and(|remainder| {
remainder.starts_with("\n\nBacktrace:\n") || remainder.starts_with("\ncaused by: ") || remainder.starts_with("\n> ")
});
assert!(matches, "left : {expected}\nright: {error_string}");
}
#[cfg(test)]
mod tests {
use crate::OhnoCore;
use crate::backtrace::Backtrace;
#[derive(crate::Error)]
struct MyTestError {
inner: OhnoCore,
}
#[test]
fn test_assert_error_message_exact_match() {
let error = MyTestError::caused_by("test message");
assert_error_message!(error, "test message");
}
#[test]
fn test_assert_error_message_with_backtrace() {
let mut error = MyTestError::caused_by("test message");
error.inner.data.backtrace = Backtrace::disabled();
assert_error_message!(error, "test message");
}
#[test]
#[should_panic(expected = "left : expected message\nright: actual message")]
fn test_assert_error_message_mismatch() {
let error = MyTestError::caused_by("actual message");
assert_error_message!(error, "expected message");
}
#[test]
fn impl_accepts_backtrace_continuation() {
super::assert_error_message_impl("base\n\nBacktrace:\n at ...", "base");
}
#[test]
fn impl_accepts_caused_by_continuation() {
super::assert_error_message_impl("base\ncaused by: inner", "base");
}
#[test]
fn impl_accepts_error_trace_continuation() {
super::assert_error_message_impl("base\n> trace entry", "base");
}
#[test]
#[should_panic(expected = "left : base\nright: base mismatch")]
fn impl_rejects_unrelated_continuation() {
super::assert_error_message_impl("base mismatch", "base");
}
}