clearcheck/assertions/float/
mod.rs1use std::fmt::Debug;
2use std::ops::{Range, RangeInclusive};
3
4use crate::matchers::float::{be_nan, be_negative, be_positive, be_zero};
5use crate::matchers::range::{be_in_exclusive_range, be_in_inclusive_range};
6use crate::matchers::{Should, ShouldNot};
7
8pub trait FloatAssertion<T: num::Float + Default + PartialEq> {
23 fn should_be_nan(&self) -> &Self;
34
35 fn should_not_be_nan(&self) -> &Self;
46
47 fn should_be_zero(&self) -> &Self;
58
59 fn should_not_be_zero(&self) -> &Self;
70
71 fn should_be_positive(&self) -> &Self;
82
83 fn should_be_negative(&self) -> &Self;
94
95 fn should_be_in_inclusive_range_with_tolerance(
106 &self,
107 range: RangeInclusive<T>,
108 tolerance: T,
109 ) -> &Self;
110
111 fn should_not_be_in_inclusive_range_with_tolerance(
122 &self,
123 range: RangeInclusive<T>,
124 tolerance: T,
125 ) -> &Self;
126
127 fn should_be_in_exclusive_range_with_tolerance(&self, range: Range<T>, tolerance: T) -> &Self;
138
139 fn should_not_be_in_exclusive_range_with_tolerance(
150 &self,
151 range: Range<T>,
152 tolerance: T,
153 ) -> &Self;
154}
155
156impl<T: num::Float + Debug + Default + PartialEq> FloatAssertion<T> for T {
157 fn should_be_nan(&self) -> &Self {
158 self.should(&be_nan());
159 self
160 }
161
162 fn should_not_be_nan(&self) -> &Self {
163 self.should_not(&be_nan());
164 self
165 }
166
167 fn should_be_zero(&self) -> &Self {
168 self.should(&be_zero());
169 self
170 }
171
172 fn should_not_be_zero(&self) -> &Self {
173 self.should_not(&be_zero());
174 self
175 }
176
177 fn should_be_positive(&self) -> &Self {
178 self.should(&be_positive());
179 self
180 }
181
182 fn should_be_negative(&self) -> &Self {
183 self.should(&be_negative());
184 self
185 }
186
187 fn should_be_in_inclusive_range_with_tolerance(
188 &self,
189 range: RangeInclusive<T>,
190 tolerance: T,
191 ) -> &Self {
192 self.should(&be_in_inclusive_range(RangeInclusive::new(
193 range.start().add(tolerance),
194 range.end().add(tolerance),
195 )));
196 self
197 }
198
199 fn should_not_be_in_inclusive_range_with_tolerance(
200 &self,
201 range: RangeInclusive<T>,
202 tolerance: T,
203 ) -> &Self {
204 self.should_not(&be_in_inclusive_range(RangeInclusive::new(
205 range.start().add(tolerance),
206 range.end().add(tolerance),
207 )));
208 self
209 }
210
211 fn should_be_in_exclusive_range_with_tolerance(&self, range: Range<T>, tolerance: T) -> &Self {
212 let range_with_tolerance = range.start.add(tolerance)..range.end.add(tolerance);
213 self.should(&be_in_exclusive_range(range_with_tolerance));
214 self
215 }
216
217 fn should_not_be_in_exclusive_range_with_tolerance(
218 &self,
219 range: Range<T>,
220 tolerance: T,
221 ) -> &Self {
222 let range_with_tolerance = range.start.add(tolerance)..range.end.add(tolerance);
223 self.should_not(&be_in_exclusive_range(range_with_tolerance));
224 self
225 }
226}
227
228#[cfg(all(test, feature = "num"))]
229mod tests {
230 use crate::assertions::float::FloatAssertion;
231
232 #[test]
233 fn should_be_nan() {
234 let value: f64 = num::Float::nan();
235 value.should_be_nan();
236 }
237
238 #[test]
239 #[should_panic]
240 fn should_be_nan_but_was_not() {
241 let value: f64 = 1.23;
242 value.should_be_nan();
243 }
244
245 #[test]
246 fn should_not_be_nan() {
247 let value: f64 = 1.23;
248 value.should_not_be_nan();
249 }
250
251 #[test]
252 #[should_panic]
253 fn should_not_be_nan_but_was() {
254 let value: f64 = num::Float::nan();
255 value.should_not_be_nan();
256 }
257
258 #[test]
259 fn should_be_zero() {
260 let value: f64 = 0.0;
261 value.should_be_zero();
262 }
263
264 #[test]
265 #[should_panic]
266 fn should_not_be_zero_but_was() {
267 let value: f64 = 0.0;
268 value.should_not_be_zero();
269 }
270
271 #[test]
272 fn should_be_positive() {
273 let value: f64 = 0.123;
274 value.should_be_positive();
275 }
276
277 #[test]
278 fn should_be_negative() {
279 let value: f64 = -1.23;
280 value.should_be_negative();
281 }
282
283 #[test]
284 fn should_be_in_inclusive_range_with_tolerance() {
285 let value: f64 = 8.123;
286 value.should_be_in_inclusive_range_with_tolerance(6.10..=8.10, 0.123);
287 }
288
289 #[test]
290 #[should_panic]
291 fn should_be_in_inclusive_range_with_tolerance_but_was_not() {
292 let value: f64 = 8.423;
293 value.should_be_in_inclusive_range_with_tolerance(6.10..=8.10, 0.123);
294 }
295
296 #[test]
297 fn should_not_be_in_inclusive_range_with_tolerance() {
298 let value: f64 = 8.123;
299 value.should_not_be_in_inclusive_range_with_tolerance(6.10..=7.10, 0.123);
300 }
301
302 #[test]
303 #[should_panic]
304 fn should_not_be_in_inclusive_range_with_tolerance_but_was() {
305 let value: f64 = 8.123;
306 value.should_not_be_in_inclusive_range_with_tolerance(6.10..=8.10, 0.123);
307 }
308
309 #[test]
310 fn should_be_in_exclusive_range_with_tolerance() {
311 let value: f64 = 8.123;
312 value.should_be_in_exclusive_range_with_tolerance(6.10..8.10, 0.123);
313 }
314
315 #[test]
316 #[should_panic]
317 fn should_be_in_exclusive_range_with_tolerance_but_was_not() {
318 let value: f64 = 8.423;
319 value.should_be_in_exclusive_range_with_tolerance(6.10..8.10, 0.123);
320 }
321
322 #[test]
323 fn should_not_be_in_exclusive_range_with_tolerance() {
324 let value: f64 = 8.423;
325 value.should_not_be_in_exclusive_range_with_tolerance(6.10..8.10, 0.123);
326 }
327
328 #[test]
329 #[should_panic]
330 fn should_not_be_in_exclusive_range_with_tolerance_but_was_not() {
331 let value: f64 = 8.123;
332 value.should_not_be_in_exclusive_range_with_tolerance(6.10..8.20, 0.123);
333 }
334}