1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 use crate::{
16     description::Description,
17     matcher::{Matcher, MatcherResult},
18 };
19 use std::{fmt::Debug, marker::PhantomData};
20 
21 /// Matches a `Result` containing `Ok` with a value matched by `inner`.
22 ///
23 /// ```
24 /// # use googletest::prelude::*;
25 /// # fn should_pass() -> googletest::Result<()> {
26 /// verify_that!(Ok::<_, ()>("Some value"), ok(eq("Some value")))?;  // Passes
27 /// #     Ok(())
28 /// # }
29 /// # fn should_fail_1() -> googletest::Result<()> {
30 /// verify_that!(Err::<&str, _>("An error"), ok(eq("An error")))?;   // Fails
31 /// #     Ok(())
32 /// # }
33 /// # fn should_fail_2() -> googletest::Result<()> {
34 /// verify_that!(Ok::<_, ()>("Some value"), ok(eq("Some other value")))?;   // Fails
35 /// #     Ok(())
36 /// # }
37 /// # should_pass().unwrap();
38 /// # should_fail_1().unwrap_err();
39 /// # should_fail_2().unwrap_err();
40 /// ```
ok<T: Debug, E: Debug>( inner: impl Matcher<ActualT = T>, ) -> impl Matcher<ActualT = std::result::Result<T, E>>41 pub fn ok<T: Debug, E: Debug>(
42     inner: impl Matcher<ActualT = T>,
43 ) -> impl Matcher<ActualT = std::result::Result<T, E>> {
44     OkMatcher::<T, E, _> { inner, phantom_t: Default::default(), phantom_e: Default::default() }
45 }
46 
47 struct OkMatcher<T, E, InnerMatcherT> {
48     inner: InnerMatcherT,
49     phantom_t: PhantomData<T>,
50     phantom_e: PhantomData<E>,
51 }
52 
53 impl<T: Debug, E: Debug, InnerMatcherT: Matcher<ActualT = T>> Matcher
54     for OkMatcher<T, E, InnerMatcherT>
55 {
56     type ActualT = std::result::Result<T, E>;
57 
matches(&self, actual: &Self::ActualT) -> MatcherResult58     fn matches(&self, actual: &Self::ActualT) -> MatcherResult {
59         actual.as_ref().map(|v| self.inner.matches(v)).unwrap_or(MatcherResult::NoMatch)
60     }
61 
explain_match(&self, actual: &Self::ActualT) -> Description62     fn explain_match(&self, actual: &Self::ActualT) -> Description {
63         match actual {
64             Ok(o) => {
65                 Description::new().text("which is a success").nested(self.inner.explain_match(o))
66             }
67             Err(_) => "which is an error".into(),
68         }
69     }
70 
describe(&self, matcher_result: MatcherResult) -> Description71     fn describe(&self, matcher_result: MatcherResult) -> Description {
72         match matcher_result {
73             MatcherResult::Match => format!(
74                 "is a success containing a value, which {}",
75                 self.inner.describe(MatcherResult::Match)
76             )
77             .into(),
78             MatcherResult::NoMatch => format!(
79                 "is an error or a success containing a value, which {}",
80                 self.inner.describe(MatcherResult::NoMatch)
81             )
82             .into(),
83         }
84     }
85 }
86 
87 #[cfg(test)]
88 mod tests {
89     use super::ok;
90     use crate::matcher::{Matcher, MatcherResult};
91     use crate::prelude::*;
92     use indoc::indoc;
93 
94     #[test]
ok_matches_result_with_value() -> Result<()>95     fn ok_matches_result_with_value() -> Result<()> {
96         let matcher = ok(eq(1));
97         let value: std::result::Result<i32, i32> = Ok(1);
98 
99         let result = matcher.matches(&value);
100 
101         verify_that!(result, eq(MatcherResult::Match))
102     }
103 
104     #[test]
ok_does_not_match_result_with_wrong_value() -> Result<()>105     fn ok_does_not_match_result_with_wrong_value() -> Result<()> {
106         let matcher = ok(eq(1));
107         let value: std::result::Result<i32, i32> = Ok(0);
108 
109         let result = matcher.matches(&value);
110 
111         verify_that!(result, eq(MatcherResult::NoMatch))
112     }
113 
114     #[test]
ok_does_not_match_result_with_err() -> Result<()>115     fn ok_does_not_match_result_with_err() -> Result<()> {
116         let matcher = ok(eq(1));
117         let value: std::result::Result<i32, i32> = Err(1);
118 
119         let result = matcher.matches(&value);
120 
121         verify_that!(result, eq(MatcherResult::NoMatch))
122     }
123 
124     #[test]
ok_full_error_message() -> Result<()>125     fn ok_full_error_message() -> Result<()> {
126         let result = verify_that!(Ok::<i32, i32>(1), ok(eq(2)));
127 
128         verify_that!(
129             result,
130             err(displays_as(contains_substring(indoc!(
131                 "
132                     Value of: Ok::<i32, i32>(1)
133                     Expected: is a success containing a value, which is equal to 2
134                     Actual: Ok(1),
135                       which is a success
136                         which isn't equal to 2
137                 "
138             ))))
139         )
140     }
141 
142     #[test]
ok_describe_matches() -> Result<()>143     fn ok_describe_matches() -> Result<()> {
144         let matcher = super::OkMatcher::<i32, i32, _> {
145             inner: eq(1),
146             phantom_t: Default::default(),
147             phantom_e: Default::default(),
148         };
149         verify_that!(
150             matcher.describe(MatcherResult::Match),
151             displays_as(eq("is a success containing a value, which is equal to 1"))
152         )
153     }
154 }
155