expectest/matchers/
floats.rs1use crate::core::{Join, Matcher};
2use num_traits::{self, Float};
3use std::fmt;
4
5pub struct BeCloseTo<E> {
7 expected: E,
8 delta: E,
9}
10
11pub fn be_close_to<E>(expected: E) -> BeCloseTo<E>
13where
14 E: Float,
15{
16 BeCloseTo {
17 expected: expected,
18 delta: num_traits::cast(0.001).unwrap(),
19 }
20}
21
22impl<E> BeCloseTo<E> {
23 pub fn delta(mut self, v: E) -> BeCloseTo<E> {
25 self.delta = v;
26 self
27 }
28}
29
30impl<E> Matcher<E, E> for BeCloseTo<E>
31where
32 E: Float + fmt::Debug,
33{
34 fn failure_message(&self, join: Join, actual: &E) -> String {
35 format!(
36 "expected {} be close to <{:?}> ±{:?}, got <{:?}>",
37 join, self.expected, self.delta, actual
38 )
39 }
40
41 fn matches(&self, actual: &E) -> bool {
42 if *actual == self.expected {
43 true
44 } else {
45 (self.expected - *actual).abs() - self.delta <= E::zero()
46 }
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::be_close_to;
53 use crate::core::expect;
54
55 #[test]
56 fn close_to_one_and_half_failure_message() {
57 expect(0.5)
58 .to(be_close_to(1.5))
59 .assert_eq_message("expected to be close to <1.5> ±0.001, got <0.5>");
60 }
61
62 #[test]
63 fn to_not_be_close_to_one_and_half_failure_message() {
64 expect(1.4991)
65 .not_to(be_close_to(1.5))
66 .assert_eq_message("expected not to be close to <1.5> ±0.001, got <1.4991>");
67 }
68
69 #[test]
70 fn close_to_one_and_half_delta_failure_message() {
71 expect(0.5)
72 .to(be_close_to(1.5).delta(0.1))
73 .assert_eq_message("expected to be close to <1.5> ±0.1, got <0.5>");
74 }
75}