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