googletest/matchers/
not_matcher.rs1use crate::{
16 description::Description,
17 matcher::{Matcher, MatcherBase, MatcherResult},
18};
19use std::fmt::Debug;
20
21pub fn not<InnerMatcherT>(inner: InnerMatcherT) -> NotMatcher<InnerMatcherT> {
37 NotMatcher { inner }
38}
39
40#[derive(MatcherBase)]
41pub struct NotMatcher<InnerMatcherT> {
42 inner: InnerMatcherT,
43}
44
45impl<T: Debug + Copy, InnerMatcherT: Matcher<T>> Matcher<T> for NotMatcher<InnerMatcherT> {
46 fn matches(&self, actual: T) -> MatcherResult {
47 match self.inner.matches(actual) {
48 MatcherResult::Match => MatcherResult::NoMatch,
49 MatcherResult::NoMatch => MatcherResult::Match,
50 }
51 }
52
53 fn explain_match(&self, actual: T) -> Description {
54 self.inner.explain_match(actual)
55 }
56
57 fn describe(&self, matcher_result: MatcherResult) -> Description {
58 self.inner.describe(if matcher_result.into() {
59 MatcherResult::NoMatch
60 } else {
61 MatcherResult::Match
62 })
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use crate::matcher::MatcherResult;
69 use crate::prelude::*;
70 use crate::Result;
71 use indoc::indoc;
72
73 #[test]
74 fn matches_when_inner_matcher_does_not_match() -> Result<()> {
75 let matcher = not(eq(1));
76
77 let result = matcher.matches(0);
78
79 verify_that!(result, eq(MatcherResult::Match))
80 }
81
82 #[test]
83 fn does_not_match_when_inner_matcher_matches() -> Result<()> {
84 let matcher = not(eq(1));
85
86 let result = matcher.matches(1);
87
88 verify_that!(result, eq(MatcherResult::NoMatch))
89 }
90
91 #[test]
92 fn match_explanation_references_actual_value() -> Result<()> {
93 let result = verify_that!(&[1], not(container_eq([1])));
94
95 verify_that!(
96 result,
97 err(displays_as(contains_substring(indoc!(
98 "
99 Actual: [1],
100 which contains all the elements
101 "
102 ))))
103 )
104 }
105}