#[allow(unused_imports)]
use crate::*;
#[macro_export]
macro_rules! DIE {
(($($fmt:tt)*) $(,$($args:expr),*)?) => {{
$crate::TRACE_NOBUG!(($($fmt)*) $(,$($args),*)?);
$crate::CFG_IF! {
if #[cfg(all(not(feature = "abort_on_fail"), not(any(test, debug_assertions))))] {
compile_error!("abort_on_fail is not enabled");
} else if #[cfg(debug_assertions)] {
if $crate::get_testing() {
panic!(concat!(file!(), ":", line!(), ": ", $($fmt)*) $(,$($args),*)?)
}
}
}
$crate::CRITICAL!(($($fmt)*) $(,$($args),*)?);
$crate::CFG_IF! {
if #[cfg(feature = "backtrace_on_abort")] {
eprintln!("{:?}", std::backtrace::Backtrace::force_capture());
}
};
std::process::abort()
}};
($fmt:literal $(,$($args:expr),*)?) => {{
$crate::TRACE_NOBUG!(($fmt) $(,$($args),*)?);
$crate::CFG_IF! {
if #[cfg(all(not(feature = "abort_on_fail"), not(any(test, debug_assertions))))] {
compile_error!("abort_on_fail is not enabled");
} else if #[cfg(debug_assertions)] {
if $crate::get_testing() {
panic!(concat!($fmt) $(,$($args),*)?)
}
}
}
$crate::CRITICAL!(($fmt) $(,$($args),*)?);
$crate::CFG_IF! {
if #[cfg(feature = "backtrace_on_abort")] {
eprintln!("{:?}", std::backtrace::Backtrace::force_capture());
}
};
std::process::abort()
}};
() => {{
$crate::TRACE_NOBUG!("EXPLICIT DIE");
$crate::CFG_IF! {
if #[cfg(all(not(feature = "abort_on_fail"), not(any(test, debug_assertions))))] {
compile_error!("abort_on_fail is not enabled");
} else if #[cfg(debug_assertions)] {
if $crate::get_testing() {
panic!(concat!(file!(), ":", line!(), ": EXPLICIT DIE"))
}
}
}
$crate::CRITICAL!("EXPLICIT DIE");
$crate::CFG_IF! {
if #[cfg(feature = "backtrace_on_abort")] {
eprintln!("{:?}", std::backtrace::Backtrace::force_capture());
}
};
std::process::abort()
}}
}
#[test]
#[cfg(debug_assertions)]
#[should_panic(expected = "this is a test")]
fn test_die() {
DIE!(("this is a test"));
}
#[cfg(test)]
#[cfg(debug_assertions)]
fn testfn() {
DIE!(("this is a test"));
}
#[test]
#[cfg(debug_assertions)]
#[should_panic(expected = "this is a test")]
fn test_diefn() {
testfn();
}
#[test]
#[cfg(debug_assertions)]
#[should_panic(expected = "this is a test 123")]
fn test_die2() {
DIE!("this is a test {}{}{}", 1, 2, 3);
}
#[macro_export]
macro_rules! ONCE {
($($code:tt)*) => {{
static ONCE: std::sync::Once = std::sync::Once::new();
ONCE.call_once(|| {$($code)*});
}};
}
#[macro_export]
macro_rules! MOCK {
(IF {$($pred:tt)*} THEN {$($then:tt)*} $(ELSE {$($else:tt)*})?) => {{
$crate::TRACE_NOBUG!();
$crate::CFG_IF! {
if #[cfg(debug_assertions)] {
if {$($pred)*} {
$crate::NOTICE!(
("MOCK: {{{}}}"),
stringify!($($then)*)
);
{$($then)*}
} $(else {
$crate::NOTICE!(
("MOCK: {{{}}}"),
stringify!($($else)*)
);
{$($else)*}
})?
} else {
compile_error!(
concat!(
"MOCK: {", stringify!($($then)*), "}"
$(, " {", stringify!($($else)*), "}")?
)
)
}
}
}};
($($code:tt)*) => {{
$crate::TRACE_NOBUG!();
$crate::CFG_IF! {
if #[cfg(debug_assertions)] {
$crate::NOTICE!(
("MOCK: {{{}}}"),
stringify!($($code)*)
);
{$($code)*}
} else {
compile_error!(
concat!(
"MOCK: {", stringify!($($code)*), "}"
)
)
}
}
}};
}
#[test]
#[cfg(debug_assertions)]
fn test_mock_simple() {
CHECK!(MOCK! {true});
CHECK!(!MOCK! {false});
}
#[test]
#[cfg(debug_assertions)]
fn test_mock_conditional() {
let mut r: bool = false;
MOCK!(IF {true} THEN {r = true;});
CHECK!(r);
CHECK!(MOCK!(IF {false} THEN {false} ELSE {true}));
}