expect_json/expect/ops/expect_float/
expect_float.rs

1use crate::expect::ops::expect_float::ExpectFloatSubOp;
2use crate::expect_core::expect_op;
3use crate::expect_core::Context;
4use crate::expect_core::ExpectOp;
5use crate::expect_core::ExpectOpResult;
6use crate::JsonType;
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    /// Expect the float found to be within the given range.
21    ///
22    /// ```rust
23    /// # async fn test() -> Result<(), Box<dyn ::std::error::Error>> {
24    /// #
25    /// # use axum::Router;
26    /// # use axum::extract::Json;
27    /// # use axum::routing::get;
28    /// # use axum_test::TestServer;
29    /// # use serde_json::json;
30    /// #
31    /// # let server = TestServer::new(Router::new())?;
32    /// #
33    /// use axum_test::expect_json;
34    ///
35    /// let server = TestServer::new(Router::new())?;
36    ///
37    /// server.get(&"/user/barrington")
38    ///     .await
39    ///     .assert_json(&json!({
40    ///         "name": "Barrington",
41    ///         "height_in_meters": expect_json::float().in_range(0.5..=2.5),
42    ///     }));
43    /// #
44    /// # Ok(()) }
45    /// ```
46    pub fn in_range<R>(mut self, range: R) -> Self
47    where
48        R: RangeBounds<f64>,
49    {
50        let min = range.start_bound().cloned();
51        let max = range.end_bound().cloned();
52
53        self.sub_ops.push(ExpectFloatSubOp::InRange {
54            min: min.into(),
55            max: max.into(),
56        });
57
58        self
59    }
60
61    pub fn outside_range<R>(mut self, range: R) -> Self
62    where
63        R: RangeBounds<f64>,
64    {
65        let min = range.start_bound().cloned();
66        let max = range.end_bound().cloned();
67
68        self.sub_ops.push(ExpectFloatSubOp::OutsideRange {
69            min: min.into(),
70            max: max.into(),
71        });
72
73        self
74    }
75
76    pub fn zero(mut self) -> Self {
77        self.sub_ops.push(ExpectFloatSubOp::Zero);
78        self
79    }
80
81    pub fn not_zero(mut self) -> Self {
82        self.sub_ops.push(ExpectFloatSubOp::NotZero);
83        self
84    }
85
86    pub fn positive(mut self) -> Self {
87        self.sub_ops.push(ExpectFloatSubOp::Positive);
88        self
89    }
90
91    pub fn negative(mut self) -> Self {
92        self.sub_ops.push(ExpectFloatSubOp::Negative);
93        self
94    }
95}
96
97impl ExpectOp for ExpectFloat {
98    fn on_f64(&self, context: &mut Context, received: f64) -> ExpectOpResult<()> {
99        for sub_op in &self.sub_ops {
100            sub_op.on_f64(self, context, received)?;
101        }
102
103        Ok(())
104    }
105
106    fn debug_supported_types(&self) -> &'static [JsonType] {
107        &[JsonType::Float]
108    }
109}
110
111#[cfg(test)]
112mod test_in_range {
113    use crate::expect;
114    use crate::expect_json_eq;
115    use pretty_assertions::assert_eq;
116    use serde_json::json;
117
118    #[test]
119    fn it_should_be_true_for_all_values_in_total_range() {
120        let left = json!(1.0);
121        let right = json!(expect::float().in_range(..));
122        let output = expect_json_eq(&left, &right);
123        assert!(output.is_ok());
124
125        let left = json!(f64::MIN);
126        let right = json!(expect::float().in_range(..));
127        let output = expect_json_eq(&left, &right);
128        assert!(output.is_ok());
129    }
130
131    #[test]
132    fn it_should_be_true_for_all_values_in_partial_range() {
133        let left = json!(0.5);
134        let right = json!(expect::float().in_range(0.0..1.0));
135        let output = expect_json_eq(&left, &right);
136        assert!(output.is_ok());
137    }
138
139    #[test]
140    fn it_should_be_false_for_all_values_out_of_range() {
141        let left = json!(1.0);
142        let right = json!(expect::float().in_range(0.0..1.0));
143
144        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
145        assert_eq!(
146            output,
147            r#"Json expect::float() error at root:
148    float is not in range
149    expected 0.0..1.0
150    received 1.0"#
151        );
152    }
153
154    #[test]
155    fn it_should_be_true_for_value_in_inclusive_range() {
156        let left = json!(1.0);
157        let right = json!(expect::float().in_range(0.0..=1.0));
158
159        let output = expect_json_eq(&left, &right);
160        assert!(output.is_ok());
161    }
162}
163
164#[cfg(test)]
165mod test_outside_range {
166    use crate::expect;
167    use crate::expect_json_eq;
168    use pretty_assertions::assert_eq;
169    use serde_json::json;
170
171    #[test]
172    fn it_should_be_false_for_all_values_in_total_range() {
173        let left = json!(1.0);
174        let right = json!(expect::float().outside_range(..));
175        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
176        assert_eq!(
177            output,
178            r#"Json expect::float() error at root:
179    float is in range
180    expected ..
181    received 1.0"#
182        );
183
184        let left = json!(f64::MIN);
185        let right = json!(expect::float().outside_range(..));
186        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
187        assert_eq!(
188            output,
189            r#"Json expect::float() error at root:
190    float is in range
191    expected ..
192    received -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0"#
193        );
194    }
195
196    #[test]
197    fn it_should_be_false_for_all_values_in_partial_range() {
198        let left = json!(0.5);
199        let right = json!(expect::float().outside_range(0.0..1.0));
200
201        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
202        assert_eq!(
203            output,
204            r#"Json expect::float() error at root:
205    float is in range
206    expected 0.0..1.0
207    received 0.5"#
208        );
209    }
210
211    #[test]
212    fn it_should_be_true_for_all_values_out_of_range() {
213        let left = json!(1.0);
214        let right = json!(expect::float().outside_range(0.0..1.0));
215
216        let output = expect_json_eq(&left, &right);
217        assert!(output.is_ok());
218    }
219
220    #[test]
221    fn it_should_be_false_for_value_in_inclusive_range() {
222        let left = json!(1.0);
223        let right = json!(expect::float().outside_range(0.0..=1.0));
224
225        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
226        assert_eq!(
227            output,
228            r#"Json expect::float() error at root:
229    float is in range
230    expected 0.0..=1.0
231    received 1.0"#
232        );
233    }
234}
235
236#[cfg(test)]
237mod test_zero {
238    use crate::expect;
239    use crate::expect_json_eq;
240    use pretty_assertions::assert_eq;
241    use serde_json::json;
242
243    #[test]
244    fn it_should_be_true_for_zero() {
245        let left = json!(0.0);
246        let right = json!(expect::float().zero());
247
248        let output = expect_json_eq(&left, &right);
249        assert!(output.is_ok());
250    }
251
252    #[test]
253    fn it_should_be_false_for_negative_value() {
254        let left = json!(-1.0);
255        let right = json!(expect::float().zero());
256
257        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
258        assert_eq!(
259            output,
260            r#"Json expect::float() error at root, is not zero:
261    expected 0.0
262    received -1.0"#
263        );
264    }
265
266    #[test]
267    fn it_should_be_false_for_positive_value() {
268        let left = json!(1.0);
269        let right = json!(expect::float().zero());
270
271        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
272        assert_eq!(
273            output,
274            r#"Json expect::float() error at root, is not zero:
275    expected 0.0
276    received 1.0"#
277        );
278    }
279
280    #[test]
281    fn it_should_be_false_for_min() {
282        let left = json!(f64::MIN);
283        let right = json!(expect::float().zero());
284
285        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
286        assert_eq!(
287            output,
288            r#"Json expect::float() error at root, is not zero:
289    expected 0.0
290    received -179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0"#
291        );
292    }
293
294    #[test]
295    fn it_should_be_false_for_max() {
296        let left = json!(f64::MAX);
297        let right = json!(expect::float().zero());
298
299        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
300        assert_eq!(
301            output,
302            r#"Json expect::float() error at root, is not zero:
303    expected 0.0
304    received 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0"#
305        );
306    }
307}
308
309#[cfg(test)]
310mod test_not_zero {
311    use crate::expect;
312    use crate::expect_json_eq;
313    use pretty_assertions::assert_eq;
314    use serde_json::json;
315
316    #[test]
317    fn it_should_be_false_for_zero() {
318        let left = json!(0.0);
319        let right = json!(expect::float().not_zero());
320
321        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
322        assert_eq!(
323            output,
324            r#"Json expect::float() error at root, is zero:
325    expected non-zero float
326    received 0.0"#
327        );
328    }
329
330    #[test]
331    fn it_should_be_true_for_negative_value() {
332        let left = json!(-1.0);
333        let right = json!(expect::float().not_zero());
334
335        let output = expect_json_eq(&left, &right);
336        assert!(output.is_ok());
337    }
338
339    #[test]
340    fn it_should_be_true_for_positive_value() {
341        let left = json!(1.0);
342        let right = json!(expect::float().not_zero());
343
344        let output = expect_json_eq(&left, &right);
345        assert!(output.is_ok());
346    }
347}
348
349#[cfg(test)]
350mod test_positive {
351    use crate::expect;
352    use crate::expect_json_eq;
353    use pretty_assertions::assert_eq;
354    use serde_json::json;
355
356    #[test]
357    fn it_should_be_false_for_zero() {
358        let left = json!(0.0);
359        let right = json!(expect::float().positive());
360
361        let output = expect_json_eq(&left, &right);
362        assert!(output.is_ok());
363    }
364
365    #[test]
366    fn it_should_be_false_for_negative_value() {
367        let left = json!(-1.0);
368        let right = json!(expect::float().positive());
369
370        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
371        assert_eq!(
372            output,
373            r#"Json expect::float() error at root:
374    float is not positive
375    received -1.0"#
376        );
377    }
378
379    #[test]
380    fn it_should_be_true_for_positive_value() {
381        let left = json!(1.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
389#[cfg(test)]
390mod test_negative {
391    use crate::expect;
392    use crate::expect_json_eq;
393    use pretty_assertions::assert_eq;
394    use serde_json::json;
395
396    #[test]
397    fn it_should_be_false_for_zero() {
398        let left = json!(0.0);
399        let right = json!(expect::float().negative());
400
401        let output = expect_json_eq(&left, &right).unwrap_err().to_string();
402        assert_eq!(
403            output,
404            r#"Json expect::float() error at root:
405    float is not negative
406    received 0.0"#
407        );
408    }
409
410    #[test]
411    fn it_should_be_true_for_negative_value() {
412        let left = json!(-1.0);
413        let right = json!(expect::float().negative());
414
415        let output = expect_json_eq(&left, &right);
416        assert!(output.is_ok());
417    }
418
419    #[test]
420    fn it_should_be_false_for_positive_value() {
421        let left = json!(1.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 1.0"#
430        );
431    }
432}