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::description::Description;
16 use crate::matcher::{Matcher, MatcherBase, MatcherResult};
17 use std::fmt::Debug;
18
19 /// Matches a reference pointing to a value matched by the [`Matcher`]
20 /// `expected`.
21 ///
22 /// This is useful for combining matchers, especially when working with
23 /// iterators.
24 ///
25 /// For example:
26 ///
27 /// ```
28 /// # use googletest::prelude::*;
29 /// # fn should_pass() -> Result<()> {
30 /// verify_that!(&123, points_to(eq(123)))?;
31 /// verify_that!(vec![1,2,3], each(points_to(gt(0))))?;
32 /// # Ok(())
33 /// # }
34 /// # should_pass().unwrap();
35 /// ```
points_to<MatcherT>(expected: MatcherT) -> PointsToMatcher<MatcherT>36 pub fn points_to<MatcherT>(expected: MatcherT) -> PointsToMatcher<MatcherT> {
37 PointsToMatcher { expected }
38 }
39
40 #[derive(MatcherBase)]
41 pub struct PointsToMatcher<MatcherT> {
42 expected: MatcherT,
43 }
44
45 impl<'a, ExpectedT, MatcherT> Matcher<&'a ExpectedT> for PointsToMatcher<MatcherT>
46 where
47 ExpectedT: Debug + Copy,
48 MatcherT: Matcher<ExpectedT>,
49 {
matches(&self, actual: &'a ExpectedT) -> MatcherResult50 fn matches(&self, actual: &'a ExpectedT) -> MatcherResult {
51 self.expected.matches(*actual)
52 }
53
explain_match(&self, actual: &'a ExpectedT) -> Description54 fn explain_match(&self, actual: &'a ExpectedT) -> Description {
55 self.expected.explain_match(*actual)
56 }
57
describe(&self, matcher_result: MatcherResult) -> Description58 fn describe(&self, matcher_result: MatcherResult) -> Description {
59 self.expected.describe(matcher_result)
60 }
61 }
62
63 #[cfg(test)]
64 mod tests {
65 use crate::prelude::*;
66 use indoc::indoc;
67
68 #[test]
points_to_matches_ref() -> Result<()>69 fn points_to_matches_ref() -> Result<()> {
70 verify_that!(&123, points_to(eq(123)))
71 }
72
73 #[test]
match_explanation_references_actual_value() -> Result<()>74 fn match_explanation_references_actual_value() -> Result<()> {
75 let result = verify_that!(&1, points_to(eq(0)));
76
77 verify_that!(
78 result,
79 err(displays_as(contains_substring(indoc!(
80 "
81 Actual: 1,
82 which isn't equal to 0
83 "
84 ))))
85 )
86 }
87 }
88