Skip to main content

googletest/matchers/
points_to_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
15use crate::description::Description;
16use crate::matcher::{Matcher, MatcherBase, MatcherResult};
17use 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/// ```
36pub fn points_to<MatcherT>(expected: MatcherT) -> PointsToMatcher<MatcherT> {
37    PointsToMatcher { expected }
38}
39
40#[derive(MatcherBase)]
41pub struct PointsToMatcher<MatcherT> {
42    expected: MatcherT,
43}
44
45impl<'a, ExpectedT, MatcherT> Matcher<&'a ExpectedT> for PointsToMatcher<MatcherT>
46where
47    ExpectedT: Debug + Copy,
48    MatcherT: Matcher<ExpectedT>,
49{
50    fn matches(&self, actual: &'a ExpectedT) -> MatcherResult {
51        self.expected.matches(*actual)
52    }
53
54    fn explain_match(&self, actual: &'a ExpectedT) -> Description {
55        self.expected.explain_match(*actual)
56    }
57
58    fn describe(&self, matcher_result: MatcherResult) -> Description {
59        self.expected.describe(matcher_result)
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    use crate::prelude::*;
66    use crate::Result;
67    use indoc::indoc;
68
69    #[test]
70    fn points_to_matches_ref() -> Result<()> {
71        verify_that!(&123, points_to(eq(123)))
72    }
73
74    #[test]
75    fn match_explanation_references_actual_value() -> Result<()> {
76        let result = verify_that!(&1, points_to(eq(0)));
77
78        verify_that!(
79            result,
80            err(displays_as(contains_substring(indoc!(
81                "
82                    Actual: 1,
83                      which isn't equal to 0
84                "
85            ))))
86        )
87    }
88}