expect_json/expect/ops/expect_float/
expect_float.rs

1use crate::JsonType;
2use crate::expect::ops::expect_float::ExpectFloatSubOp;
3use crate::expect_core::Context;
4use crate::expect_core::ExpectOp;
5use crate::expect_core::ExpectOpResult;
6use crate::expect_core::expect_op;
7use core::ops::RangeBounds;
8
9#[expect_op(internal, name = "float")]
10#[derive(Debug, Clone, Default, PartialEq)]
11pub struct ExpectFloat {
12    sub_ops: Vec<ExpectFloatSubOp>,
13}
14
15impl ExpectFloat {
16    pub(crate) fn new() -> Self {
17        Self { sub_ops: vec![] }
18    }
19
20    pub fn greater_than(mut self, expected: f64) -> Self {
21        self.sub_ops
22            .push(ExpectFloatSubOp::GreaterThan { expected });
23        self
24    }
25
26    pub fn greater_than_equal(mut self, expected: f64) -> Self {
27        self.sub_ops
28            .push(ExpectFloatSubOp::GreaterThanEqual { expected });
29        self
30    }
31
32    pub fn less_than(mut self, expected: f64) -> Self {
33        self.sub_ops.push(ExpectFloatSubOp::LessThan { expected });
34        self
35    }
36
37    pub fn less_than_equal(mut self, expected: f64) -> Self {
38        self.sub_ops
39            .push(ExpectFloatSubOp::LessThanEqual { expected });
40        self
41    }
42
43    /// Expect the float found to be within the given range.
44    ///
45    /// ```rust
46    /// # async fn test() -> Result<(), Box<dyn ::std::error::Error>> {
47    /// #
48    /// # use axum::Router;
49    /// # use axum::extract::Json;
50    /// # use axum::routing::get;
51    /// # use axum_test::TestServer;
52    /// # use serde_json::json;
53    /// #
54    /// # let server = TestServer::new(Router::new())?;
55    /// #
56    /// use axum_test::expect_json;
57    ///
58    /// let server = TestServer::new(Router::new())?;
59    ///
60    /// server.get(&"/user/barrington")
61    ///     .await
62    ///     .assert_json(&json!({
63    ///         "name": "Barrington",
64    ///         "height_in_meters": expect_json::float().in_range(0.5..=2.5),
65    ///     }));
66    /// #
67    /// # Ok(()) }
68    /// ```
69    pub fn in_range<R>(mut self, range: R) -> Self
70    where
71        R: RangeBounds<f64>,
72    {
73        let min = range.start_bound().cloned();
74        let max = range.end_bound().cloned();
75
76        self.sub_ops.push(ExpectFloatSubOp::InRange {
77            min: min.into(),
78            max: max.into(),
79        });
80
81        self
82    }
83
84    pub fn outside_range<R>(mut self, range: R) -> Self
85    where
86        R: RangeBounds<f64>,
87    {
88        let min = range.start_bound().cloned();
89        let max = range.end_bound().cloned();
90
91        self.sub_ops.push(ExpectFloatSubOp::OutsideRange {
92            min: min.into(),
93            max: max.into(),
94        });
95
96        self
97    }
98
99    pub fn zero(mut self) -> Self {
100        self.sub_ops.push(ExpectFloatSubOp::Zero);
101        self
102    }
103
104    pub fn not_zero(mut self) -> Self {
105        self.sub_ops.push(ExpectFloatSubOp::NotZero);
106        self
107    }
108
109    pub fn positive(mut self) -> Self {
110        self.sub_ops.push(ExpectFloatSubOp::Positive);
111        self
112    }
113
114    pub fn negative(mut self) -> Self {
115        self.sub_ops.push(ExpectFloatSubOp::Negative);
116        self
117    }
118}
119
120impl ExpectOp for ExpectFloat {
121    fn on_f64(&self, context: &mut Context, received: f64) -> ExpectOpResult<()> {
122        for sub_op in &self.sub_ops {
123            sub_op.on_f64(self, context, received)?;
124        }
125
126        Ok(())
127    }
128
129    fn debug_supported_types(&self) -> &'static [JsonType] {
130        &[JsonType::Float]
131    }
132}
133
134#[cfg(test)]
135mod test_in_range {
136    use crate::expect;
137    use crate::expect_json_eq;
138    use pretty_assertions::assert_eq;
139    use serde_json::json;
140
141    #[test]
142    fn it_should_be_true_for_all_values_in_total_range() {
143        let left = json!(1.0);
144        let right = json!(expect::float().in_range(..));
145        let output = expect_json_eq(&left, &right);
146        assert!(output.is_ok());
147
148        let left = json!(f64::MIN);
149        let right = json!(expect::float().in_range(..));
150        let output = expect_json_eq(&left, &right);
151        assert!(output.is_ok());
152    }
153
154    #[test]
155    fn it_should_be_true_for_all_values_in_partial_range() {
156        let left = json!(0.5);
157        let right = json!(expect::float().in_range(0.0..1.0));
158        let output = expect_json_eq(&left, &right);
159        assert!(output.is_ok());
160    }
161
162    #[test]
163    fn it_should_be_false_for_all_values_out_of_range() {
164        let left = json!(1.0);
165        let right = json!(expect::float().in_range(0.0..1.0));
166
167        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
168        assert_eq!(
169            output,
170            r#"Json expect::float() error at root:
171    float is not in range
172    expected 0.0..1.0
173    received 1.0"#
174        );
175    }
176
177    #[test]
178    fn it_should_be_true_for_value_in_inclusive_range() {
179        let left = json!(1.0);
180        let right = json!(expect::float().in_range(0.0..=1.0));
181
182        let output = expect_json_eq(&left, &right);
183        assert!(output.is_ok());
184    }
185}
186
187#[cfg(test)]
188mod test_outside_range {
189    use crate::expect;
190    use crate::expect_json_eq;
191    use pretty_assertions::assert_eq;
192    use serde_json::json;
193
194    #[test]
195    fn it_should_be_false_for_all_values_in_total_range() {
196        let left = json!(1.0);
197        let right = json!(expect::float().outside_range(..));
198        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
199        assert_eq!(
200            output,
201            r#"Json expect::float() error at root:
202    float is in range
203    expected ..
204    received 1.0"#
205        );
206
207        let left = json!(f64::MIN);
208        let right = json!(expect::float().outside_range(..));
209        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
210        assert_eq!(
211            output,
212            r#"Json expect::float() error at root:
213    float is in range
214    expected ..
215    received -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0"#
216        );
217    }
218
219    #[test]
220    fn it_should_be_false_for_all_values_in_partial_range() {
221        let left = json!(0.5);
222        let right = json!(expect::float().outside_range(0.0..1.0));
223
224        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
225        assert_eq!(
226            output,
227            r#"Json expect::float() error at root:
228    float is in range
229    expected 0.0..1.0
230    received 0.5"#
231        );
232    }
233
234    #[test]
235    fn it_should_be_true_for_all_values_out_of_range() {
236        let left = json!(1.0);
237        let right = json!(expect::float().outside_range(0.0..1.0));
238
239        let output = expect_json_eq(&left, &right);
240        assert!(output.is_ok());
241    }
242
243    #[test]
244    fn it_should_be_false_for_value_in_inclusive_range() {
245        let left = json!(1.0);
246        let right = json!(expect::float().outside_range(0.0..=1.0));
247
248        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
249        assert_eq!(
250            output,
251            r#"Json expect::float() error at root:
252    float is in range
253    expected 0.0..=1.0
254    received 1.0"#
255        );
256    }
257}
258
259#[cfg(test)]
260mod test_zero {
261    use crate::expect;
262    use crate::expect_json_eq;
263    use pretty_assertions::assert_eq;
264    use serde_json::json;
265
266    #[test]
267    fn it_should_be_true_for_zero() {
268        let left = json!(0.0);
269        let right = json!(expect::float().zero());
270
271        let output = expect_json_eq(&left, &right);
272        assert!(output.is_ok());
273    }
274
275    #[test]
276    fn it_should_be_false_for_negative_value() {
277        let left = json!(-1.0);
278        let right = json!(expect::float().zero());
279
280        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
281        assert_eq!(
282            output,
283            r#"Json expect::float() error at root, is not zero:
284    expected 0.0
285    received -1.0"#
286        );
287    }
288
289    #[test]
290    fn it_should_be_false_for_positive_value() {
291        let left = json!(1.0);
292        let right = json!(expect::float().zero());
293
294        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
295        assert_eq!(
296            output,
297            r#"Json expect::float() error at root, is not zero:
298    expected 0.0
299    received 1.0"#
300        );
301    }
302
303    #[test]
304    fn it_should_be_false_for_min() {
305        let left = json!(f64::MIN);
306        let right = json!(expect::float().zero());
307
308        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
309        assert_eq!(
310            output,
311            r#"Json expect::float() error at root, is not zero:
312    expected 0.0
313    received -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0"#
314        );
315    }
316
317    #[test]
318    fn it_should_be_false_for_max() {
319        let left = json!(f64::MAX);
320        let right = json!(expect::float().zero());
321
322        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
323        assert_eq!(
324            output,
325            r#"Json expect::float() error at root, is not zero:
326    expected 0.0
327    received 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0"#
328        );
329    }
330}
331
332#[cfg(test)]
333mod test_not_zero {
334    use crate::expect;
335    use crate::expect_json_eq;
336    use pretty_assertions::assert_eq;
337    use serde_json::json;
338
339    #[test]
340    fn it_should_be_false_for_zero() {
341        let left = json!(0.0);
342        let right = json!(expect::float().not_zero());
343
344        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
345        assert_eq!(
346            output,
347            r#"Json expect::float() error at root, is zero:
348    expected non-zero float
349    received 0.0"#
350        );
351    }
352
353    #[test]
354    fn it_should_be_true_for_negative_value() {
355        let left = json!(-1.0);
356        let right = json!(expect::float().not_zero());
357
358        let output = expect_json_eq(&left, &right);
359        assert!(output.is_ok());
360    }
361
362    #[test]
363    fn it_should_be_true_for_positive_value() {
364        let left = json!(1.0);
365        let right = json!(expect::float().not_zero());
366
367        let output = expect_json_eq(&left, &right);
368        assert!(output.is_ok());
369    }
370}
371
372#[cfg(test)]
373mod test_positive {
374    use crate::expect;
375    use crate::expect_json_eq;
376    use pretty_assertions::assert_eq;
377    use serde_json::json;
378
379    #[test]
380    fn it_should_be_false_for_zero() {
381        let left = json!(0.0);
382        let right = json!(expect::float().positive());
383
384        let output = expect_json_eq(&left, &right);
385        assert!(output.is_ok());
386    }
387
388    #[test]
389    fn it_should_be_false_for_negative_value() {
390        let left = json!(-1.0);
391        let right = json!(expect::float().positive());
392
393        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
394        assert_eq!(
395            output,
396            r#"Json expect::float() error at root:
397    float is not positive
398    received -1.0"#
399        );
400    }
401
402    #[test]
403    fn it_should_be_true_for_positive_value() {
404        let left = json!(1.0);
405        let right = json!(expect::float().positive());
406
407        let output = expect_json_eq(&left, &right);
408        assert!(output.is_ok());
409    }
410}
411
412#[cfg(test)]
413mod test_negative {
414    use crate::expect;
415    use crate::expect_json_eq;
416    use pretty_assertions::assert_eq;
417    use serde_json::json;
418
419    #[test]
420    fn it_should_be_false_for_zero() {
421        let left = json!(0.0);
422        let right = json!(expect::float().negative());
423
424        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
425        assert_eq!(
426            output,
427            r#"Json expect::float() error at root:
428    float is not negative
429    received 0.0"#
430        );
431    }
432
433    #[test]
434    fn it_should_be_true_for_negative_value() {
435        let left = json!(-1.0);
436        let right = json!(expect::float().negative());
437
438        let output = expect_json_eq(&left, &right);
439        assert!(output.is_ok());
440    }
441
442    #[test]
443    fn it_should_be_false_for_positive_value() {
444        let left = json!(1.0);
445        let right = json!(expect::float().negative());
446
447        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
448        assert_eq!(
449            output,
450            r#"Json expect::float() error at root:
451    float is not negative
452    received 1.0"#
453        );
454    }
455}
456
457#[cfg(test)]
458mod test_less_than {
459    use crate::expect;
460    use crate::expect_json_eq;
461    use pretty_assertions::assert_eq;
462    use serde_json::json;
463
464    #[test]
465    fn it_should_be_true_for_correct_positive_comparison() {
466        let left = json!(100.0);
467        let right = json!(expect::float().less_than(123.456));
468        let output = expect_json_eq(&left, &right);
469        assert!(output.is_ok(), "{output:#?}");
470    }
471
472    #[test]
473    fn it_should_be_false_when_equal() {
474        let left = json!(123.456);
475        let right = json!(expect::float().less_than(123.456));
476        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
477        assert_eq!(
478            output,
479            "Json expect::float() error at root:
480    float is out of bounds,
481    expected less than 123.456
482    received 123.456"
483        );
484    }
485
486    #[test]
487    fn it_should_be_false_for_incorrect_positive_comparison() {
488        let left = json!(123.456);
489        let right = json!(expect::float().less_than(100.0));
490        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
491        assert_eq!(
492            output,
493            "Json expect::float() error at root:
494    float is out of bounds,
495    expected less than 100.0
496    received 123.456"
497        );
498    }
499
500    #[test]
501    fn it_should_be_true_for_correct_negative_positive_mix() {
502        let left = json!(-1.0);
503        let right = json!(expect::float().less_than(0.0));
504        let output = expect_json_eq(&left, &right);
505        assert!(output.is_ok(), "{output:#?}");
506    }
507
508    #[test]
509    fn it_should_be_true_for_correct_negative_comparison() {
510        let left = json!(-123.456);
511        let right = json!(expect::float().less_than(-99.999));
512        let output = expect_json_eq(&left, &right);
513        assert!(output.is_ok(), "{output:#?}");
514    }
515}
516
517#[cfg(test)]
518mod test_less_than_equal {
519    use crate::expect;
520    use crate::expect_json_eq;
521    use pretty_assertions::assert_eq;
522    use serde_json::json;
523
524    #[test]
525    fn it_should_be_true_for_correct_positive_comparison() {
526        let left = json!(100.0);
527        let right = json!(expect::float().less_than_equal(123.456));
528        let output = expect_json_eq(&left, &right);
529        assert!(output.is_ok(), "{output:#?}");
530    }
531
532    #[test]
533    fn it_should_be_true_when_equal() {
534        let left = json!(123.456);
535        let right = json!(expect::float().less_than_equal(123.456));
536        let output = expect_json_eq(&left, &right);
537        assert!(output.is_ok(), "{output:#?}");
538    }
539
540    #[test]
541    fn it_should_be_false_for_incorrect_positive_comparison() {
542        let left = json!(123.456);
543        let right = json!(expect::float().less_than_equal(100.0));
544        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
545        assert_eq!(
546            output,
547            "Json expect::float() error at root:
548    float is out of bounds,
549    expected less than equal 100.0
550    received 123.456"
551        );
552    }
553
554    #[test]
555    fn it_should_be_true_for_correct_negative_positive_mix() {
556        let left = json!(-1.0);
557        let right = json!(expect::float().less_than_equal(0.0));
558        let output = expect_json_eq(&left, &right);
559        assert!(output.is_ok(), "{output:#?}");
560    }
561
562    #[test]
563    fn it_should_be_true_for_correct_negative_comparison() {
564        let left = json!(-123.456);
565        let right = json!(expect::float().less_than_equal(-99.999));
566        let output = expect_json_eq(&left, &right);
567        assert!(output.is_ok(), "{output:#?}");
568    }
569}
570
571#[cfg(test)]
572mod test_greater_than {
573    use crate::expect;
574    use crate::expect_json_eq;
575    use pretty_assertions::assert_eq;
576    use serde_json::json;
577
578    #[test]
579    fn it_should_be_true_for_correct_positive_comparison() {
580        let left = json!(123.456);
581        let right = json!(expect::float().greater_than(100.0));
582        let output = expect_json_eq(&left, &right);
583        assert!(output.is_ok(), "{output:#?}");
584    }
585
586    #[test]
587    fn it_should_be_false_when_equal() {
588        let left = json!(123.456);
589        let right = json!(expect::float().greater_than(123.456));
590        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
591        assert_eq!(
592            output,
593            "Json expect::float() error at root:
594    float is out of bounds,
595    expected greater than 123.456
596    received 123.456"
597        );
598    }
599
600    #[test]
601    fn it_should_be_false_for_incorrect_positive_comparison() {
602        let left = json!(100.0);
603        let right = json!(expect::float().greater_than(123.456));
604        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
605        assert_eq!(
606            output,
607            "Json expect::float() error at root:
608    float is out of bounds,
609    expected greater than 123.456
610    received 100.0"
611        );
612    }
613
614    #[test]
615    fn it_should_be_true_for_correct_negative_positive_mix() {
616        let left = json!(0.0);
617        let right = json!(expect::float().greater_than(-1.0));
618        let output = expect_json_eq(&left, &right);
619        assert!(output.is_ok(), "{output:#?}");
620    }
621
622    #[test]
623    fn it_should_be_true_for_correct_negative_comparison() {
624        let left = json!(-99.999);
625        let right = json!(expect::float().greater_than(-123.456));
626        let output = expect_json_eq(&left, &right);
627        assert!(output.is_ok(), "{output:#?}");
628    }
629}
630
631#[cfg(test)]
632mod test_greater_than_equal {
633    use crate::expect;
634    use crate::expect_json_eq;
635    use pretty_assertions::assert_eq;
636    use serde_json::json;
637
638    #[test]
639    fn it_should_be_true_for_correct_positive_comparison() {
640        let left = json!(123.456);
641        let right = json!(expect::float().greater_than_equal(100.0));
642        let output = expect_json_eq(&left, &right);
643        assert!(output.is_ok(), "{output:#?}");
644    }
645
646    #[test]
647    fn it_should_be_true_when_equal() {
648        let left = json!(123.456);
649        let right = json!(expect::float().greater_than_equal(123.456));
650        let output = expect_json_eq(&left, &right);
651        assert!(output.is_ok(), "{output:#?}");
652    }
653
654    #[test]
655    fn it_should_be_false_for_incorrect_positive_comparison() {
656        let left = json!(100.0);
657        let right = json!(expect::float().greater_than_equal(123.456));
658        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
659        assert_eq!(
660            output,
661            "Json expect::float() error at root:
662    float is out of bounds,
663    expected greater than equal 123.456
664    received 100.0"
665        );
666    }
667
668    #[test]
669    fn it_should_be_true_for_correct_negative_positive_mix() {
670        let left = json!(0.0);
671        let right = json!(expect::float().greater_than_equal(-1.0));
672        let output = expect_json_eq(&left, &right);
673        assert!(output.is_ok(), "{output:#?}");
674    }
675
676    #[test]
677    fn it_should_be_true_for_correct_negative_comparison() {
678        let left = json!(-99.999);
679        let right = json!(expect::float().greater_than_equal(-123.456));
680        let output = expect_json_eq(&left, &right);
681        assert!(output.is_ok(), "{output:#?}");
682    }
683}