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 use googletest::matcher::{Matcher, MatcherResult};
16 use googletest::prelude::*;
17
18 #[derive(Debug)]
19 struct SomeStruct {
20 a_property: u32,
21 }
22
23 impl SomeStruct {
get_property(&self) -> u3224 fn get_property(&self) -> u32 {
25 self.a_property
26 }
27
get_property_ref(&self) -> &u3228 fn get_property_ref(&self) -> &u32 {
29 &self.a_property
30 }
31
add_product_to_field(&self, a: u32, b: u32) -> u3232 fn add_product_to_field(&self, a: u32, b: u32) -> u32 {
33 self.a_property + a * b
34 }
35
get_property_ref_with_params(&self, _a: u32, _b: u32) -> &u3236 fn get_property_ref_with_params(&self, _a: u32, _b: u32) -> &u32 {
37 &self.a_property
38 }
39 }
40
41 #[test]
matches_struct_with_matching_property() -> Result<()>42 fn matches_struct_with_matching_property() -> Result<()> {
43 let value = SomeStruct { a_property: 10 };
44 verify_that!(value, property!(SomeStruct.get_property(), eq(10)))
45 }
46
47 #[test]
matches_struct_with_matching_property_with_parameters() -> Result<()>48 fn matches_struct_with_matching_property_with_parameters() -> Result<()> {
49 let value = SomeStruct { a_property: 10 };
50 verify_that!(value, property!(SomeStruct.add_product_to_field(2, 3), eq(16)))
51 }
52
53 #[test]
matches_struct_with_matching_property_with_captured_arguments() -> Result<()>54 fn matches_struct_with_matching_property_with_captured_arguments() -> Result<()> {
55 let value = SomeStruct { a_property: 10 };
56 let arg1 = 2;
57 let arg2 = 3;
58 verify_that!(value, property!(SomeStruct.add_product_to_field(arg1, arg2), eq(16)))
59 }
60
61 #[test]
matches_struct_with_matching_property_with_parameters_with_trailing_comma() -> Result<()>62 fn matches_struct_with_matching_property_with_parameters_with_trailing_comma() -> Result<()> {
63 let value = SomeStruct { a_property: 10 };
64 verify_that!(value, property!(SomeStruct.add_product_to_field(2, 3,), eq(16)))
65 }
66
67 #[test]
matches_struct_with_matching_property_ref() -> Result<()>68 fn matches_struct_with_matching_property_ref() -> Result<()> {
69 let value = SomeStruct { a_property: 10 };
70 verify_that!(value, property!(*SomeStruct.get_property_ref(), eq(10)))
71 }
72
73 #[test]
matches_struct_with_matching_string_reference_property() -> Result<()>74 fn matches_struct_with_matching_string_reference_property() -> Result<()> {
75 #[derive(Debug)]
76 struct StructWithString {
77 property: String,
78 }
79 impl StructWithString {
80 fn get_property_ref(&self) -> &String {
81 &self.property
82 }
83 }
84 let value = StructWithString { property: "Something".into() };
85 verify_that!(value, property!(*StructWithString.get_property_ref(), eq("Something")))
86 }
87
88 #[test]
matches_struct_with_matching_slice_property() -> Result<()>89 fn matches_struct_with_matching_slice_property() -> Result<()> {
90 #[derive(Debug)]
91 struct StructWithVec {
92 property: Vec<u32>,
93 }
94 impl StructWithVec {
95 fn get_property_ref(&self) -> &[u32] {
96 &self.property
97 }
98 }
99 let value = StructWithVec { property: vec![1, 2, 3] };
100 verify_that!(value, property!(*StructWithVec.get_property_ref(), eq([1, 2, 3])))
101 }
102
103 #[test]
matches_struct_with_matching_property_ref_with_parameters() -> Result<()>104 fn matches_struct_with_matching_property_ref_with_parameters() -> Result<()> {
105 let value = SomeStruct { a_property: 10 };
106 verify_that!(value, property!(*SomeStruct.get_property_ref_with_params(2, 3), eq(10)))
107 }
108
109 #[test]
matches_struct_with_matching_property_ref_with_parameters_and_trailing_comma() -> Result<()>110 fn matches_struct_with_matching_property_ref_with_parameters_and_trailing_comma() -> Result<()> {
111 let value = SomeStruct { a_property: 10 };
112 verify_that!(value, property!(*SomeStruct.get_property_ref_with_params(2, 3,), eq(10)))
113 }
114
115 #[test]
does_not_match_struct_with_non_matching_property() -> Result<()>116 fn does_not_match_struct_with_non_matching_property() -> Result<()> {
117 let value = SomeStruct { a_property: 2 };
118 verify_that!(value, not(property!(SomeStruct.get_property(), eq(1))))
119 }
120
121 #[test]
describes_itself_in_matching_case() -> Result<()>122 fn describes_itself_in_matching_case() -> Result<()> {
123 verify_that!(
124 property!(SomeStruct.get_property(), eq(1)).describe(MatcherResult::Match),
125 displays_as(eq("has property `get_property()`, which is equal to 1"))
126 )
127 }
128
129 #[test]
describes_itself_in_not_matching_case() -> Result<()>130 fn describes_itself_in_not_matching_case() -> Result<()> {
131 verify_that!(
132 property!(SomeStruct.get_property(), eq(1)).describe(MatcherResult::NoMatch),
133 displays_as(eq("has property `get_property()`, which isn't equal to 1"))
134 )
135 }
136
137 #[test]
explains_mismatch_referencing_explanation_of_inner_matcher() -> Result<()>138 fn explains_mismatch_referencing_explanation_of_inner_matcher() -> Result<()> {
139 impl SomeStruct {
140 fn get_a_collection(&self) -> Vec<u32> {
141 vec![]
142 }
143 }
144 let value = SomeStruct { a_property: 2 };
145 let result = verify_that!(value, property!(SomeStruct.get_a_collection(), container_eq([1])));
146
147 verify_that!(
148 result,
149 err(displays_as(contains_substring(
150 "whose property `get_a_collection()` is `[]`, which is missing the element 1"
151 )))
152 )
153 }
154
155 #[test]
describes_itself_in_matching_case_for_ref() -> Result<()>156 fn describes_itself_in_matching_case_for_ref() -> Result<()> {
157 verify_that!(
158 property!(*SomeStruct.get_property_ref(), eq(1)).describe(MatcherResult::Match),
159 displays_as(eq("has property `get_property_ref()`, which is equal to 1"))
160 )
161 }
162
163 #[test]
describes_itself_in_not_matching_case_for_ref() -> Result<()>164 fn describes_itself_in_not_matching_case_for_ref() -> Result<()> {
165 verify_that!(
166 property!(*SomeStruct.get_property_ref(), eq(1)).describe(MatcherResult::NoMatch),
167 displays_as(eq("has property `get_property_ref()`, which isn't equal to 1"))
168 )
169 }
170
171 #[test]
explains_mismatch_referencing_explanation_of_inner_matcher_for_ref() -> Result<()>172 fn explains_mismatch_referencing_explanation_of_inner_matcher_for_ref() -> Result<()> {
173 static EMPTY_COLLECTION: Vec<u32> = vec![];
174 impl SomeStruct {
175 fn get_a_collection_ref(&self) -> &[u32] {
176 &EMPTY_COLLECTION
177 }
178 }
179 let value = SomeStruct { a_property: 2 };
180 let result =
181 verify_that!(value, property!(*SomeStruct.get_a_collection_ref(), container_eq([1])));
182
183 verify_that!(
184 result,
185 err(displays_as(contains_substring(
186 "whose property `get_a_collection_ref()` is `[]`, which is missing the element 1"
187 )))
188 )
189 }
190