Skip to main content

rspec/report/
example.rs

1use std::convert::From;
2
3use time::Duration;
4
5use report::Report;
6
7#[cfg(feature = "expectest_compat")]
8use expectest::core::TestResult as ExpectestResult;
9
10#[derive(Clone, PartialEq, Eq, Debug)]
11pub enum ExampleResult {
12    Success,
13    Failure(Option<String>),
14    Ignored,
15}
16
17impl ExampleResult {
18    fn is_success(&self) -> bool {
19        &ExampleResult::Success == self
20    }
21
22    fn is_failure(&self) -> bool {
23        matches!(self, &ExampleResult::Failure(_))
24    }
25
26    fn get_passed(&self) -> u32 {
27        if &ExampleResult::Success == self {
28            1
29        } else {
30            0
31        }
32    }
33
34    fn get_failed(&self) -> u32 {
35        if let ExampleResult::Failure(_) = self {
36            1
37        } else {
38            0
39        }
40    }
41
42    fn get_ignored(&self) -> u32 {
43        if &ExampleResult::Ignored == self {
44            1
45        } else {
46            0
47        }
48    }
49}
50
51/// rspec considers examples returning `()` a success.
52impl From<()> for ExampleResult {
53    fn from(_other: ()) -> ExampleResult {
54        ExampleResult::Success
55    }
56}
57
58/// rspec considers examples returning `true` a success, `false` a failure.
59impl From<bool> for ExampleResult {
60    fn from(other: bool) -> ExampleResult {
61        if other {
62            ExampleResult::Success
63        } else {
64            ExampleResult::Failure(Some(
65                "assertion failed: `expected condition to be true`".to_owned(),
66            ))
67        }
68    }
69}
70
71/// rspec considers examples returning `Result::Ok(…)` a success, `Result::Err(…)` a failure.
72impl<T1, T2> From<Result<T1, T2>> for ExampleResult
73where
74    T2: ::std::fmt::Debug,
75{
76    fn from(other: Result<T1, T2>) -> ExampleResult {
77        match other {
78            Ok(_) => ExampleResult::Success,
79            Err(error) => ExampleResult::Failure(Some(format!("{:?}", error))),
80        }
81    }
82}
83
84/// rspec considers examples returning `ExpectestResult::Ok(…)` a success, `ExpectestResult::Err(…)` a failure.
85#[cfg(feature = "expectest_compat")]
86impl From<ExpectestResult> for ExampleResult {
87    fn from(other: ExpectestResult) -> ExampleResult {
88        match other {
89            ExpectestResult::Success => ExampleResult::Success,
90            ExpectestResult::Failure(failure) => {
91                ExampleResult::Failure(Some(format!("{:?}", failure)))
92            }
93        }
94    }
95}
96
97/// `ExampleReport` holds the results of a context example's test execution.
98#[derive(Clone, PartialEq, Eq, Debug, new)]
99pub struct ExampleReport {
100    result: ExampleResult,
101    duration: Duration,
102}
103
104impl ExampleReport {
105    pub fn get_result(&self) -> &ExampleResult {
106        &self.result
107    }
108}
109
110impl Report for ExampleReport {
111    fn is_success(&self) -> bool {
112        self.result.is_success()
113    }
114
115    fn is_failure(&self) -> bool {
116        self.result.is_failure()
117    }
118
119    fn get_passed(&self) -> u32 {
120        self.result.get_passed()
121    }
122
123    fn get_failed(&self) -> u32 {
124        self.result.get_failed()
125    }
126
127    fn get_ignored(&self) -> u32 {
128        self.result.get_ignored()
129    }
130
131    fn get_duration(&self) -> Duration {
132        self.duration
133    }
134}
135
136#[cfg(test)]
137mod tests {
138    use super::*;
139
140    #[test]
141    fn from_void() {
142        assert!(ExampleResult::from(()).is_success());
143    }
144
145    #[test]
146    fn from_bool() {
147        assert!(ExampleResult::from(true).is_success());
148        assert!(ExampleResult::from(false).is_failure());
149    }
150
151    #[test]
152    fn from_result() {
153        let ok_result: Result<(), ()> = Ok(());
154        let err_result: Result<(), ()> = Err(());
155        assert!(ExampleResult::from(ok_result).is_success());
156        assert!(ExampleResult::from(err_result).is_failure());
157    }
158
159    #[cfg(feature = "expectest_compat")]
160    #[test]
161    #[should_panic]
162    fn from_expectest_result() {
163        let ok_result = ExpectestResult::new_success();
164        // A failure ExpectestResult panics on drop, hence the `#[should_panic]`.
165        let err_result = ExpectestResult::new_failure("dummy".to_owned(), None);
166        assert!(ExampleResult::from(ok_result).is_success());
167        assert!(ExampleResult::from(err_result).is_failure());
168    }
169}