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