googletest/matchers/
len_matcher.rs1use crate::description::Description;
16use crate::matcher::{Matcher, MatcherBase, MatcherResult};
17use crate::matcher_support::count_elements::count_elements;
18use std::fmt::Debug;
19
20pub fn len<E>(expected: E) -> LenMatcher<E> {
52 LenMatcher { expected }
53}
54
55#[derive(MatcherBase)]
56pub struct LenMatcher<E> {
57 expected: E,
58}
59
60impl<T: Debug + Copy, E: Matcher<usize>> Matcher<T> for LenMatcher<E>
61where
62 T: IntoIterator,
63{
64 fn matches(&self, actual: T) -> MatcherResult {
65 self.expected.matches(count_elements(actual))
66 }
67
68 fn describe(&self, matcher_result: MatcherResult) -> Description {
69 match matcher_result {
70 MatcherResult::Match => {
71 format!("has length, which {}", self.expected.describe(MatcherResult::Match)).into()
72 }
73 MatcherResult::NoMatch => {
74 format!("has length, which {}", self.expected.describe(MatcherResult::NoMatch))
75 .into()
76 }
77 }
78 }
79
80 fn explain_match(&self, actual: T) -> Description {
81 let actual_size = count_elements(actual);
82 format!("which has length {}, {}", actual_size, self.expected.explain_match(actual_size))
83 .into()
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use crate::description::Description;
90 use crate::matcher::MatcherResult;
91 use crate::prelude::*;
92 use crate::Result;
93 use indoc::indoc;
94 use std::collections::{
95 BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque,
96 };
97 use std::fmt::Debug;
98
99 #[test]
100 fn len_matcher_match_vec() -> Result<()> {
101 let value = vec![1, 2, 3];
102 verify_that!(value, len(eq(3)))
103 }
104
105 #[test]
106 fn len_matcher_match_array_reference() -> Result<()> {
107 let value = &[1, 2, 3];
108 verify_that!(value, len(eq(3)))
109 }
110
111 #[test]
112 fn len_matcher_match_slice_of_array() -> Result<()> {
113 let value = &[1, 2, 3];
114 verify_that!(value[0..1], len(eq(1)))
115 }
116
117 #[test]
118 fn len_matcher_match_slice_of_vec() -> Result<()> {
119 let value = vec![1, 2, 3];
120 let slice = value.as_slice();
121 verify_that!(slice, len(eq(3)))
122 }
123
124 #[test]
125 fn len_matcher_match_sized_slice() -> Result<()> {
126 let value = [1, 2, 3];
127 verify_that!(value, len(eq(3)))
128 }
129
130 #[test]
131 fn len_matcher_match_btreemap() -> Result<()> {
132 let value = BTreeMap::from([(1, 2), (2, 3), (3, 4)]);
133 verify_that!(value, len(eq(3)))
134 }
135
136 #[test]
137 fn len_matcher_match_btreeset() -> Result<()> {
138 let value = BTreeSet::from([1, 2, 3]);
139 verify_that!(value, len(eq(3)))
140 }
141
142 #[test]
143 fn len_matcher_match_binaryheap() -> Result<()> {
144 let value = BinaryHeap::from([1, 2, 3]);
145 verify_that!(value, len(eq(3)))
146 }
147
148 #[test]
149 fn len_matcher_match_hashmap() -> Result<()> {
150 let value = HashMap::from([(1, 2), (2, 3), (3, 4)]);
151 verify_that!(value, len(eq(3)))
152 }
153
154 #[test]
155 fn len_matcher_match_hashset() -> Result<()> {
156 let value = HashSet::from([1, 2, 3]);
157 verify_that!(value, len(eq(3)))
158 }
159
160 #[test]
161 fn len_matcher_match_linkedlist() -> Result<()> {
162 let value = LinkedList::from([1, 2, 3]);
163 verify_that!(value, len(eq(3)))
164 }
165
166 #[test]
167 fn len_matcher_match_vecdeque() -> Result<()> {
168 let value = VecDeque::from([1, 2, 3]);
169 verify_that!(value, len(eq(3)))
170 }
171
172 #[test]
173 fn len_matcher_explain_match() -> Result<()> {
174 #[derive(MatcherBase)]
175 struct TestMatcher;
176 impl<T: Debug + Copy> Matcher<T> for TestMatcher {
177 fn matches(&self, _: T) -> MatcherResult {
178 false.into()
179 }
180
181 fn describe(&self, _: MatcherResult) -> Description {
182 "called described".into()
183 }
184
185 fn explain_match(&self, _: T) -> Description {
186 "called explain_match".into()
187 }
188 }
189 verify_that!(
190 len(TestMatcher).explain_match([1, 2, 3]),
191 displays_as(eq("which has length 3, called explain_match"))
192 )
193 }
194
195 #[test]
196 fn len_matcher_error_message() -> Result<()> {
197 let result = verify_that!(vec![1, 2, 3, 4], len(eq(3)));
198 verify_that!(
199 result,
200 err(displays_as(contains_substring(indoc!(
201 "
202 Value of: vec![1, 2, 3, 4]
203 Expected: has length, which is equal to 3
204 Actual: [1, 2, 3, 4],
205 which has length 4, which isn't equal to 3"
206 ))))
207 )
208 }
209}