1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
use std::{
any::Any,
panic::{catch_unwind, AssertUnwindSafe},
};
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct FileSpan {
pub file: &'static str,
pub line: u32,
}
pub type ThreadError = Box<dyn Any + Send + 'static>;
#[derive(Debug, Clone)]
pub struct ShouldHavePanickedAt {
pub span: FileSpan,
}
#[macro_export]
macro_rules! file_span {
() => {{
use $crate::test_utils::FileSpan;
FileSpan {
file: file!(),
line: line!(),
}
}};
}
pub fn must_panic<F, R>(span: FileSpan, f: F) -> Result<ThreadError, ShouldHavePanickedAt>
where
F: FnOnce() -> R,
{
match catch_unwind(AssertUnwindSafe(f)) {
Ok(_) => Err(ShouldHavePanickedAt { span }),
Err(e) => Ok(e),
}
}
#[test]
fn test_must_panic() {
assert!(must_panic(file_span!(), || panic!()).is_ok());
assert!(must_panic(file_span!(), || ()).is_err());
}