use std::sync::{
Arc, Mutex,
atomic::{AtomicBool, Ordering},
};
use super::*;
static HOOK_LOCK: Mutex<()> = Mutex::new(());
#[test]
fn chained_hook_runs_both_the_framework_hook_and_the_previously_installed_one() {
let _guard = HOOK_LOCK
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
let saved_hook = std::panic::take_hook();
let marker_fired = Arc::new(AtomicBool::new(false));
let marker_for_previous = Arc::clone(&marker_fired);
std::panic::set_hook(Box::new(move |_| {
marker_for_previous.store(true, Ordering::SeqCst);
}));
let previous_hook = std::panic::take_hook();
let own_fired = Arc::new(AtomicBool::new(false));
let own_for_hook = Arc::clone(&own_fired);
std::panic::set_hook(chained_panic_hook(
move |_| own_for_hook.store(true, Ordering::SeqCst),
previous_hook,
));
let panicked = std::panic::catch_unwind(|| panic!("chained_panic_hook test panic"));
std::panic::set_hook(saved_hook);
assert!(
panicked.is_err(),
"the panic should have unwound and been caught"
);
assert!(
own_fired.load(Ordering::SeqCst),
"framework's own hook did not run"
);
assert!(
marker_fired.load(Ordering::SeqCst),
"previously installed hook was replaced instead of chained onto"
);
}