Skip to main content

googletest/matchers/
all_matcher.rs

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// There are no visible documentation elements in this module; the declarative
16// macro is documented in the matcher module.
17#![doc(hidden)]
18
19/// Matches a value which all of the given matchers match.
20///
21/// Each argument is a [`Matcher`][crate::matcher::Matcher] which matches
22/// against the actual value.
23///
24/// For example:
25///
26/// ```
27/// # use googletest::prelude::*;
28/// # fn should_pass() -> Result<()> {
29/// verify_that!("A string", all!(starts_with("A"), ends_with("string")))?; // Passes
30/// #     Ok(())
31/// # }
32/// # fn should_fail() -> Result<()> {
33/// verify_that!("A string", all!(starts_with("A"), ends_with("not a string")))?; // Fails
34/// #     Ok(())
35/// # }
36/// # should_pass().unwrap();
37/// # should_fail().unwrap_err();
38/// ```
39///
40/// Using this macro is equivalent to using the
41/// [`and`][crate::matcher::MatcherBase::and] method:
42///
43/// ```
44/// # use googletest::prelude::*;
45/// # fn should_pass() -> Result<()> {
46/// verify_that!(10, gt(9).and(lt(11)))?; // Also passes
47/// #     Ok(())
48/// # }
49/// # should_pass().unwrap();
50/// ```
51///
52/// Assertion failure messages are not guaranteed to be identical, however.
53///
54///  If an inner matcher is `eq(...)`, it can be omitted:
55///
56/// ```
57/// # use googletest::prelude::*;
58///
59/// verify_that!(123, all![123, lt(1000), gt(100)])
60/// #     .unwrap();
61/// ```
62#[macro_export]
63#[doc(hidden)]
64macro_rules! __all {
65    ($(,)?) => {{
66        $crate::matchers::anything()
67    }} ;
68    ($matcher:expr $(,)?) => {{
69        use $crate::matcher_support::__internal_unstable_do_not_depend_on_these::auto_eq;
70        auto_eq!($matcher)
71    }};
72    ($head:expr, $head2:expr $(,)?) => {{
73        use $crate::matcher_support::__internal_unstable_do_not_depend_on_these::auto_eq;
74        $crate::matchers::__internal_unstable_do_not_depend_on_these::ConjunctionMatcher::new(auto_eq!($head), auto_eq!($head2))
75    }};
76    ($head:expr, $head2:expr, $($tail:expr),+ $(,)?) => {{
77        use $crate::matcher_support::__internal_unstable_do_not_depend_on_these::auto_eq;
78        $crate::__all![
79            $crate::matchers::__internal_unstable_do_not_depend_on_these::ConjunctionMatcher::new(auto_eq!($head), auto_eq!($head2)),
80            $($tail),+
81        ]
82    }}
83}
84
85#[cfg(test)]
86mod tests {
87    use crate::matcher::MatcherResult;
88    use crate::prelude::*;
89    use crate::Result;
90    use indoc::indoc;
91
92    #[test]
93    fn description_shows_more_than_one_matcher() -> Result<()> {
94        let first_matcher = starts_with("A");
95        let second_matcher = ends_with("string");
96        let matcher = all!(first_matcher, second_matcher);
97
98        verify_that!(
99            Matcher::<&String>::describe(&matcher, MatcherResult::Match),
100            displays_as(eq(indoc!(
101                "
102                has all the following properties:
103                  * starts with prefix \"A\"
104                  * ends with suffix \"string\""
105            )))
106        )
107    }
108
109    #[test]
110    fn description_shows_one_matcher_directly() -> Result<()> {
111        let first_matcher = starts_with("A");
112        let matcher = all!(first_matcher);
113
114        verify_that!(
115            Matcher::<&String>::describe(&matcher, MatcherResult::Match),
116            displays_as(eq("starts with prefix \"A\""))
117        )
118    }
119
120    #[test]
121    fn mismatch_description_shows_which_matcher_failed_if_more_than_one_constituent() -> Result<()>
122    {
123        let first_matcher = starts_with("Another");
124        let second_matcher = ends_with("string");
125        let matcher = all!(first_matcher, second_matcher);
126
127        verify_that!(
128            matcher.explain_match("A string"),
129            displays_as(eq("which does not start with \"Another\""))
130        )
131    }
132
133    #[test]
134    fn mismatch_description_is_simple_when_only_one_consistuent() -> Result<()> {
135        let first_matcher = starts_with("Another");
136        let matcher = all!(first_matcher);
137
138        verify_that!(
139            matcher.explain_match("A string"),
140            displays_as(eq("which does not start with \"Another\""))
141        )
142    }
143
144    #[test]
145    fn all_with_auto_eq() -> Result<()> {
146        verify_that!(42, all![eq(42), 42, lt(100)])
147    }
148}