Skip to content

Commit

Permalink
Add assert_approx_eq! macro
Browse files Browse the repository at this point in the history
This patch adds the assert_approx_eq! macro that is functionally
identical to assert!(approx_eq!(...)) but provides a better error
message containing both values, similar to the error message produced by
assert_eq!.

Fixes #27.
  • Loading branch information
robinkrahl committed Jun 17, 2021
1 parent 22dad5c commit fb24170
Showing 1 changed file with 112 additions and 0 deletions.
112 changes: 112 additions & 0 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,58 @@ macro_rules! approx_eq {
};
}

#[macro_export]
macro_rules! assert_approx_eq {
($typ:ty, $lhs:expr, $rhs:expr) => {
{
match (&$lhs, &$rhs) {
(left_val, right_val) => {
if !$crate::approx_eq!($typ, *left_val, *right_val) {
panic!(
r#"assertion failed: `(left approx_eq right)`
left: `{:?}`,
right: `{:?}`"#,
left_val, right_val,
)
}
}
}
}
};
($typ:ty, $lhs:expr, $rhs:expr $(, $set:ident = $val:expr)*) => {
{
match (&$lhs, &$rhs) {
(left_val, right_val) => {
if !$crate::approx_eq!($typ, *left_val, *right_val $(, $set = $val)*) {
panic!(
r#"assertion failed: `(left approx_eq right)`
left: `{:?}`,
right: `{:?}`"#,
left_val, right_val,
)
}
}
}
}
};
($typ:ty, $lhs:expr, $rhs:expr, $marg:expr) => {
{
match (&$lhs, &$rhs) {
(left_val, right_val) => {
if !$crate::approx_eq!($typ, *left_val, *right_val, $marg) {
panic!(
r#"assertion failed: `(left approx_eq right)`
left: `{:?}`,
right: `{:?}`"#,
left_val, right_val,
)
}
}
}
}
};
}

// Until saturating_abs() comes out of nightly, we have to code it ourselves.
macro_rules! saturating_abs_i32 {
($val:expr) => {
Expand Down Expand Up @@ -55,6 +107,12 @@ fn test_macro() {
assert!( approx_eq!(f32, a, b, epsilon = 0.00000003) );
assert!( approx_eq!(f32, a, b, epsilon = 0.00000003, ulps = 2) );
assert!( approx_eq!(f32, a, b, (0.0, 2)) );

assert_approx_eq!(f32, a, b); // uses the default
assert_approx_eq!(f32, a, b, ulps = 2);
assert_approx_eq!(f32, a, b, epsilon = 0.00000003);
assert_approx_eq!(f32, a, b, epsilon = 0.00000003, ulps = 2);
assert_approx_eq!(f32, a, b, (0.0, 2));
}

#[test]
Expand All @@ -64,6 +122,12 @@ fn test_macro_2() {
assert!( approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, epsilon=0.0000000004) );
assert!( approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, (0.0000000004, 0)) );
assert!( approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, (0.0, 3)) );

assert_approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64);
assert_approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, ulps=3);
assert_approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, epsilon=0.0000000004);
assert_approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, (0.0000000004, 0));
assert_approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, (0.0, 3));
}

#[test]
Expand All @@ -74,4 +138,52 @@ fn test_macro_3() {
let b: f32 = 0.1 + 0.1 + 0.25;
assert!( approx_eq!(f32, a, b, F32Margin { epsilon: 0.0, ulps: 2 }) );
assert!( approx_eq!(f32, a, b, F32Margin::default()) );

assert_approx_eq!(f32, a, b, F32Margin { epsilon: 0.0, ulps: 2 });
assert_approx_eq!(f32, a, b, F32Margin::default());
}

#[test]
#[should_panic]
fn test_macro_4() {
let a: f32 = 0.15 + 0.15 + 0.15;
let b: f32 = 1.0;

assert_approx_eq!(f32, a, b);
}

#[test]
#[should_panic]
fn test_macro_5() {
let a: f32 = 0.15 + 0.15 + 0.15;
let b: f32 = 1.0;

assert_approx_eq!(f32, a, b, ulps = 2);
}

#[test]
#[should_panic]
fn test_macro_6() {
let a: f32 = 0.15 + 0.15 + 0.15;
let b: f32 = 1.0;

assert_approx_eq!(f32, a, b, epsilon = 0.00000003);
}

#[test]
#[should_panic]
fn test_macro_7() {
let a: f32 = 0.15 + 0.15 + 0.15;
let b: f32 = 1.0;

assert_approx_eq!(f32, a, b, epsilon = 0.00000003, ulps = 2);
}

#[test]
#[should_panic]
fn test_macro_8() {
let a: f32 = 0.15 + 0.15 + 0.15;
let b: f32 = 1.0;

assert_approx_eq!(f32, a, b, (0.0, 2));
}

0 comments on commit fb24170

Please sign in to comment.