fluent_test/backend/matchers/
numeric.rs1use crate::backend::Assertion;
2use crate::backend::assertions::sentence::AssertionSentence;
3use std::fmt::Debug;
4use std::ops::Range;
5
6pub trait NumericMatchers<T> {
8 fn to_be_positive(self) -> Self;
9 fn to_be_negative(self) -> Self;
10 fn to_be_zero(self) -> Self;
11 fn to_be_greater_than(self, expected: T) -> Self;
12 fn to_be_greater_than_or_equal(self, expected: T) -> Self;
13 fn to_be_less_than(self, expected: T) -> Self;
14 fn to_be_less_than_or_equal(self, expected: T) -> Self;
15 fn to_be_in_range(self, range: Range<T>) -> Self;
16 fn to_be_even(self) -> Self;
17 fn to_be_odd(self) -> Self;
18}
19
20trait AsNumeric {
22 fn is_positive(&self) -> bool;
23 fn is_negative(&self) -> bool;
24 fn is_zero(&self) -> bool;
25 fn is_greater_than(&self, expected: i32) -> bool;
26 fn is_greater_than_or_equal(&self, expected: i32) -> bool;
27 fn is_less_than(&self, expected: i32) -> bool;
28 fn is_less_than_or_equal(&self, expected: i32) -> bool;
29 fn is_in_range(&self, range: Range<i32>) -> bool;
30 fn is_even(&self) -> bool;
31 fn is_odd(&self) -> bool;
32}
33
34impl AsNumeric for i32 {
36 fn is_positive(&self) -> bool {
37 *self > 0
38 }
39
40 fn is_negative(&self) -> bool {
41 *self < 0
42 }
43
44 fn is_zero(&self) -> bool {
45 *self == 0
46 }
47
48 fn is_greater_than(&self, expected: i32) -> bool {
49 *self > expected
50 }
51
52 fn is_greater_than_or_equal(&self, expected: i32) -> bool {
53 *self >= expected
54 }
55
56 fn is_less_than(&self, expected: i32) -> bool {
57 *self < expected
58 }
59
60 fn is_less_than_or_equal(&self, expected: i32) -> bool {
61 *self <= expected
62 }
63
64 fn is_in_range(&self, range: Range<i32>) -> bool {
65 range.contains(self)
66 }
67
68 fn is_even(&self) -> bool {
69 *self % 2 == 0
70 }
71
72 fn is_odd(&self) -> bool {
73 *self % 2 != 0
74 }
75}
76
77impl AsNumeric for &i32 {
79 fn is_positive(&self) -> bool {
80 **self > 0
81 }
82
83 fn is_negative(&self) -> bool {
84 **self < 0
85 }
86
87 fn is_zero(&self) -> bool {
88 **self == 0
89 }
90
91 fn is_greater_than(&self, expected: i32) -> bool {
92 **self > expected
93 }
94
95 fn is_greater_than_or_equal(&self, expected: i32) -> bool {
96 **self >= expected
97 }
98
99 fn is_less_than(&self, expected: i32) -> bool {
100 **self < expected
101 }
102
103 fn is_less_than_or_equal(&self, expected: i32) -> bool {
104 **self <= expected
105 }
106
107 fn is_in_range(&self, range: Range<i32>) -> bool {
108 range.contains(*self)
109 }
110
111 fn is_even(&self) -> bool {
112 **self % 2 == 0
113 }
114
115 fn is_odd(&self) -> bool {
116 **self % 2 != 0
117 }
118}
119
120impl<V> NumericMatchers<i32> for Assertion<V>
122where
123 V: AsNumeric + Debug + Clone,
124{
125 fn to_be_positive(self) -> Self {
126 let result = self.value.is_positive();
127 let sentence = AssertionSentence::new("be", "positive");
128
129 return self.add_step(sentence, result);
130 }
131
132 fn to_be_negative(self) -> Self {
133 let result = self.value.is_negative();
134 let sentence = AssertionSentence::new("be", "negative");
135
136 return self.add_step(sentence, result);
137 }
138
139 fn to_be_zero(self) -> Self {
140 let result = self.value.is_zero();
141 let sentence = AssertionSentence::new("be", "zero");
142
143 return self.add_step(sentence, result);
144 }
145
146 fn to_be_greater_than(self, expected: i32) -> Self {
147 let result = self.value.is_greater_than(expected);
148 let sentence = AssertionSentence::new("be", format!("greater than {}", expected));
149
150 return self.add_step(sentence, result);
151 }
152
153 fn to_be_greater_than_or_equal(self, expected: i32) -> Self {
154 let result = self.value.is_greater_than_or_equal(expected);
155 let sentence = AssertionSentence::new("be", format!("greater than or equal to {}", expected));
156
157 return self.add_step(sentence, result);
158 }
159
160 fn to_be_less_than(self, expected: i32) -> Self {
161 let result = self.value.is_less_than(expected);
162 let sentence = AssertionSentence::new("be", format!("less than {}", expected));
163
164 return self.add_step(sentence, result);
165 }
166
167 fn to_be_less_than_or_equal(self, expected: i32) -> Self {
168 let result = self.value.is_less_than_or_equal(expected);
169 let sentence = AssertionSentence::new("be", format!("less than or equal to {}", expected));
170
171 return self.add_step(sentence, result);
172 }
173
174 fn to_be_in_range(self, range: Range<i32>) -> Self {
175 let result = self.value.is_in_range(range.clone());
176 let sentence = AssertionSentence::new("be", format!("in range {}..{}", range.start, range.end));
177
178 return self.add_step(sentence, result);
179 }
180
181 fn to_be_even(self) -> Self {
182 let result = self.value.is_even();
183 let sentence = AssertionSentence::new("be", "even");
184
185 return self.add_step(sentence, result);
186 }
187
188 fn to_be_odd(self) -> Self {
189 let result = self.value.is_odd();
190 let sentence = AssertionSentence::new("be", "odd");
191
192 return self.add_step(sentence, result);
193 }
194}
195
196#[cfg(test)]
197mod tests {
198 use crate::prelude::*;
199
200 #[test]
201 fn test_numeric_matchers() {
202 crate::Reporter::disable_deduplication();
204
205 expect!(5).to_be_positive();
207 expect!(-5).to_be_negative();
208 expect!(0).to_be_zero();
209 expect!(5).to_be_greater_than(2);
210 expect!(5).to_be_greater_than_or_equal(5);
211 expect!(5).to_be_less_than(10);
212 expect!(5).to_be_less_than_or_equal(5);
213 expect!(5).to_be_in_range(0..10);
214 expect!(6).to_be_even();
215 expect!(7).to_be_odd();
216
217 expect!(5).not().to_be_negative();
219 expect!(-5).not().to_be_positive();
220 expect!(5).not().to_be_zero();
221 expect!(2).not().to_be_greater_than(5);
222 expect!(4).not().to_be_greater_than_or_equal(5);
223 expect!(10).not().to_be_less_than(5);
224 expect!(6).not().to_be_less_than_or_equal(5);
225 expect!(15).not().to_be_in_range(0..10);
226 expect!(7).not().to_be_even();
227 expect!(6).not().to_be_odd();
228 }
229
230 #[test]
231 #[should_panic(expected = "be positive")]
232 fn test_not_positive_fails() {
233 expect!(-5).to_be_positive();
234 }
235
236 #[test]
237 #[should_panic(expected = "be negative")]
238 fn test_not_negative_fails() {
239 expect!(5).to_be_negative();
240 }
241
242 #[test]
243 #[should_panic(expected = "be zero")]
244 fn test_not_zero_fails() {
245 expect!(5).to_be_zero();
246 }
247
248 #[test]
249 #[should_panic(expected = "be greater than")]
250 fn test_not_greater_fails() {
251 expect!(2).to_be_greater_than(5);
252 }
253
254 #[test]
255 #[should_panic(expected = "be greater than or equal to")]
256 fn test_not_greater_equal_fails() {
257 expect!(4).to_be_greater_than_or_equal(5);
258 }
259
260 #[test]
261 #[should_panic(expected = "be less than")]
262 fn test_not_less_fails() {
263 expect!(10).to_be_less_than(5);
264 }
265
266 #[test]
267 #[should_panic(expected = "be less than or equal to")]
268 fn test_not_less_equal_fails() {
269 expect!(6).to_be_less_than_or_equal(5);
270 }
271
272 #[test]
273 #[should_panic(expected = "be in range")]
274 fn test_not_in_range_fails() {
275 expect!(15).to_be_in_range(0..10);
276 }
277
278 #[test]
279 #[should_panic(expected = "be even")]
280 fn test_not_even_fails() {
281 expect!(7).to_be_even();
282 }
283
284 #[test]
285 #[should_panic(expected = "be odd")]
286 fn test_not_odd_fails() {
287 expect!(6).to_be_odd();
288 }
289}