1use crate::core::SourceLocation;
2
3#[derive(Debug)]
5pub enum TestResult {
6 Success,
8 Failure(Failure),
10}
11
12impl TestResult {
13 pub fn new_success() -> Self {
15 TestResult::Success
16 }
17
18 pub fn new_failure(message: String, location: Option<SourceLocation>) -> Self {
21 TestResult::Failure(Failure {
22 should_panic: true,
23 message: message,
24 location: location,
25 })
26 }
27
28 pub fn assert_eq_message(self, message: &str) {
43 if let TestResult::Failure(mut failure) = self {
44 failure.should_panic = false;
45 assert_eq!(failure.message, message);
46 } else {
47 panic!("expected to be TestResult::Failure, got <{:?}>", self);
48 }
49 }
50}
51
52#[derive(Debug)]
59pub struct Failure {
60 should_panic: bool,
61 message: String,
62 location: Option<SourceLocation>,
63}
64
65impl Failure {
66 #[cfg(feature = "nightly")]
67 fn panic(&self) {
68 use rust_core::panicking;
69
70 if let Some(location) = self.location {
71 let file_line = &(location.file, location.line, location.column);
72 panicking::panic_fmt(format_args!("{}", self.message), file_line);
73 } else {
74 panic!("assertion failed: `{}`", self.message);
75 }
76 }
77
78 #[cfg(not(feature = "nightly"))]
79 fn panic(&self) {
80 if let Some(location) = self.location {
81 panic!("assertion failed: `{}`, {}", self.message, location);
82 } else {
83 panic!("assertion failed: `{}`", self.message);
84 }
85 }
86}
87
88impl Drop for Failure {
89 fn drop(&mut self) {
90 if self.should_panic {
91 self.panic();
92 }
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::TestResult;
99
100 #[test]
101 #[should_panic]
102 fn it_panics() {
103 TestResult::new_failure("panics on drop".into(), None);
104 }
105}