googletest/matchers/
err_matcher.rs1use crate::{
16 description::Description,
17 matcher::{Matcher, MatcherBase, MatcherResult},
18};
19use std::fmt::Debug;
20
21pub fn err<Inner>(inner: Inner) -> ErrMatcher<Inner> {
42 ErrMatcher { inner }
43}
44
45#[derive(MatcherBase)]
46pub struct ErrMatcher<InnerMatcherT> {
47 inner: InnerMatcherT,
48}
49
50impl<T: Debug + Copy, E: Debug + Copy, InnerMatcherT: Matcher<E>> Matcher<std::result::Result<T, E>>
51 for ErrMatcher<InnerMatcherT>
52{
53 fn matches(&self, actual: std::result::Result<T, E>) -> MatcherResult {
54 actual.err().map(|v| self.inner.matches(v)).unwrap_or(MatcherResult::NoMatch)
55 }
56
57 fn explain_match(&self, actual: std::result::Result<T, E>) -> Description {
58 match actual {
59 Err(e) => {
60 Description::new().text("which is an error").nested(self.inner.explain_match(e))
61 }
62 Ok(_) => "which is a success".into(),
63 }
64 }
65
66 fn describe(&self, matcher_result: MatcherResult) -> Description {
67 match matcher_result {
68 MatcherResult::Match => {
69 format!("is an error which {}", self.inner.describe(MatcherResult::Match)).into()
70 }
71 MatcherResult::NoMatch => format!(
72 "is a success or is an error containing a value which {}",
73 self.inner.describe(MatcherResult::NoMatch)
74 )
75 .into(),
76 }
77 }
78}
79
80impl<'a, T: Debug, E: Debug, InnerMatcherT: Matcher<&'a E>> Matcher<&'a std::result::Result<T, E>>
81 for ErrMatcher<InnerMatcherT>
82{
83 fn matches(&self, actual: &'a std::result::Result<T, E>) -> MatcherResult {
84 actual.as_ref().err().map(|v| self.inner.matches(v)).unwrap_or(MatcherResult::NoMatch)
85 }
86
87 fn explain_match(&self, actual: &'a std::result::Result<T, E>) -> Description {
88 match actual {
89 Err(e) => {
90 Description::new().text("which is an error").nested(self.inner.explain_match(e))
91 }
92 Ok(_) => "which is a success".into(),
93 }
94 }
95
96 fn describe(&self, matcher_result: MatcherResult) -> Description {
97 match matcher_result {
98 MatcherResult::Match => {
99 format!("is an error which {}", self.inner.describe(MatcherResult::Match)).into()
100 }
101 MatcherResult::NoMatch => format!(
102 "is a success or is an error containing a value which {}",
103 self.inner.describe(MatcherResult::NoMatch)
104 )
105 .into(),
106 }
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use crate::matcher::MatcherResult;
113 use crate::prelude::*;
114 use crate::Result;
115 use indoc::indoc;
116
117 #[test]
118 fn err_matches_result_with_err_value() -> Result<()> {
119 let matcher = err(eq(1));
120 let value: std::result::Result<i32, i32> = Err(1);
121
122 let result = matcher.matches(value);
123
124 verify_that!(result, eq(MatcherResult::Match))
125 }
126
127 #[test]
128 fn err_does_not_match_result_with_wrong_err_value() -> Result<()> {
129 let matcher = err(eq(1));
130 let value: std::result::Result<i32, i32> = Err(0);
131
132 let result = matcher.matches(value);
133
134 verify_that!(result, eq(MatcherResult::NoMatch))
135 }
136
137 #[test]
138 fn err_does_not_match_result_with_ok() -> Result<()> {
139 let matcher = err(eq(1));
140 let value: std::result::Result<i32, i32> = Ok(1);
141
142 let result = matcher.matches(value);
143
144 verify_that!(result, eq(MatcherResult::NoMatch))
145 }
146
147 #[test]
148 fn err_matches_result_with_err_value_by_ref() -> Result<()> {
149 let value: std::result::Result<String, String> = Err("123".to_string());
150 verify_that!(value, err(eq("123")))
151 }
152
153 #[test]
154 fn err_does_not_match_result_with_wrong_err_value_by_ref() -> Result<()> {
155 let value: std::result::Result<String, String> = Err("321".to_string());
156 verify_that!(value, not(err(eq("123"))))
157 }
158
159 #[test]
160 fn err_does_not_match_result_with_ok_by_ref() -> Result<()> {
161 let value: std::result::Result<String, String> = Ok("123".to_string());
162 verify_that!(value, not(err(eq("123"))))
163 }
164
165 #[test]
166 fn err_full_error_message() -> Result<()> {
167 let result = verify_that!(Err::<i32, i32>(1), err(eq(2)));
168
169 verify_that!(
170 result,
171 err(displays_as(contains_substring(indoc!(
172 "
173 Value of: Err::<i32, i32>(1)
174 Expected: is an error which is equal to 2
175 Actual: Err(1),
176 which is an error
177 which isn't equal to 2
178 "
179 ))))
180 )
181 }
182
183 #[test]
184 fn err_describe_match() -> Result<()> {
185 let matcher = err(eq(1));
186 verify_that!(
187 Matcher::<std::result::Result<i32, i32>>::describe(&matcher, MatcherResult::Match),
188 displays_as(eq("is an error which is equal to 1"))
189 )
190 }
191
192 #[test]
193 fn err_describe_no_match() -> Result<()> {
194 let matcher = err(eq(1));
195 verify_that!(
196 Matcher::<std::result::Result<i32, i32>>::describe(&matcher, MatcherResult::NoMatch),
197 displays_as(eq(
198 "is a success or is an error containing a value which isn't equal to 1"
199 ))
200 )
201 }
202
203 #[test]
204 fn err_describe_match_by_ref() -> Result<()> {
205 let matcher = err(eq("123"));
206 verify_that!(
207 Matcher::<&std::result::Result<String, String>>::describe(
208 &matcher,
209 MatcherResult::Match
210 ),
211 displays_as(eq("is an error which is equal to \"123\""))
212 )
213 }
214
215 #[test]
216 fn err_describe_no_match_by_ref() -> Result<()> {
217 let matcher = err(eq("123"));
218 verify_that!(
219 Matcher::<&std::result::Result<String, String>>::describe(
220 &matcher,
221 MatcherResult::NoMatch
222 ),
223 displays_as(eq(
224 "is a success or is an error containing a value which isn't equal to \"123\""
225 ))
226 )
227 }
228
229 #[test]
230 fn err_explain_match_success() -> Result<()> {
231 let actual: std::result::Result<i32, i32> = Err(1);
232 let matcher = err(eq(1));
233 verify_that!(
234 matcher.explain_match(actual),
235 displays_as(eq("which is an error\n which is equal to 1"))
236 )
237 }
238
239 #[test]
240 fn err_explain_match_fail() -> Result<()> {
241 let actual: std::result::Result<i32, i32> = Err(2);
242 let matcher = err(eq(1));
243 verify_that!(
244 matcher.explain_match(actual),
245 displays_as(eq("which is an error\n which isn't equal to 1"))
246 )
247 }
248
249 #[test]
250 fn err_explain_match_ok() -> Result<()> {
251 let actual: std::result::Result<i32, i32> = Ok(1);
252 let matcher = err(eq(1));
253 verify_that!(matcher.explain_match(actual), displays_as(eq("which is a success")))
254 }
255
256 #[test]
257 fn err_explain_match_success_by_ref() -> Result<()> {
258 let actual: std::result::Result<String, String> = Err("123".to_string());
259 let matcher = err(eq("123"));
260 verify_that!(
261 matcher.explain_match(&actual),
262 displays_as(eq("which is an error\n which is equal to \"123\""))
263 )
264 }
265
266 #[test]
267 fn err_explain_match_fail_by_ref() -> Result<()> {
268 let actual: std::result::Result<String, String> = Err("321".to_string());
269 let matcher = err(eq("123"));
270 verify_that!(
271 matcher.explain_match(&actual),
272 displays_as(eq("which is an error\n which isn't equal to \"123\""))
273 )
274 }
275
276 #[test]
277 fn err_explain_match_ok_by_ref() -> Result<()> {
278 let actual: std::result::Result<String, String> = Ok("123".to_string());
279 let matcher = err(eq("123"));
280 verify_that!(matcher.explain_match(&actual), displays_as(eq("which is a success")))
281 }
282}