Skip to content

Commit

Permalink
Tests for complex numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
TobTobXX committed May 15, 2022
1 parent f0ca0a5 commit d6d39e1
Show file tree
Hide file tree
Showing 4 changed files with 330 additions and 96 deletions.
21 changes: 21 additions & 0 deletions src/tests/asserts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,24 @@ storage_types! {
assert_not_impl_any!(QuantityArguments<Q<Z0, Z0, Z0>, U<V>, V, meter>:
Copy, Eq, Hash, LowerExp, Ord, PartialEq, PartialOrd, UpperExp);
}

storage_types! {
types: Complex;

use super::*;

assert_impl_all!(Quantity<Q<Z0, Z0, Z0>, U<V>, V>:
Clone, Copy, Debug, PartialEq, Send, Sync, Unpin);
#[cfg(feature = "std")]
assert_impl_all!(Quantity<Q<Z0, Z0, Z0>, U<V>, V>:
RefUnwindSafe, UnwindSafe);
assert_not_impl_any!(Quantity<Q<Z0, Z0, Z0>, U<V>, V>:
Binary, Display, Eq, Hash, LowerExp, LowerHex, Octal, Ord, PartialOrd, UpperExp, UpperHex);
assert_impl_all!(QuantityArguments<Q<Z0, Z0, Z0>, U<V>, V, meter>:
Clone, Copy, Debug, Display, LowerExp, Send, Sync, Unpin, UpperExp);
#[cfg(feature = "std")]
assert_impl_all!(QuantityArguments<Q<Z0, Z0, Z0>, U<V>, V, meter>:
RefUnwindSafe, UnwindSafe);
assert_not_impl_any!(QuantityArguments<Q<Z0, Z0, Z0>, U<V>, V, meter>:
Binary, Eq, Hash, LowerHex, Octal, Ord, PartialEq, PartialOrd, UpperHex);
}
66 changes: 66 additions & 0 deletions src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,56 @@ mod test_trait {

impl super::super::Test for V {}
}

storage_types! {
types: Complex;

use crate::num::Float;

// const EPSILON: VV = 64.0 * VV::epsilon(); //error[E0015]; calls in constants are limited...
const EPS_FACTOR: VV = 0.5;
const ULPS: u32 = 3;

impl super::super::Test for V {
/// Assert that `lhs` and `rhs` are exactly equal.
fn assert_eq(lhs: &Self, rhs: &Self) {
match (lhs.is_nan(), rhs.is_nan()) {
(true, true) => {}
_ => { assert_eq!(lhs, rhs); }
}
}

/// Assert that `lhs` and `rhs` are approximately equal for floating point types or
/// exactly equal for other types.
fn assert_approx_eq(lhs: &Self, rhs: &Self) {
match (lhs.is_nan(), rhs.is_nan()) {
(true, true) => {}
_ => {
assert_ulps_eq!(lhs.re, rhs.re, epsilon = EPS_FACTOR * VV::epsilon(),
max_ulps = ULPS);
assert_ulps_eq!(lhs.im, rhs.im, epsilon = EPS_FACTOR * VV::epsilon(),
max_ulps = ULPS);
}
}
}

/// Exactly compare `lhs` and `rhs` and return the result.
fn eq(lhs: &Self, rhs: &Self) -> bool {
(lhs.is_nan() && rhs.is_nan())
|| lhs == rhs
}

/// Approximately compare `lhs` and `rhs` for floating point types or exactly compare
/// for other types and return the result.
fn approx_eq(lhs: &Self, rhs: &Self) -> bool {
(lhs.is_nan() && rhs.is_nan())
|| ulps_eq!(lhs.re, rhs.re,
epsilon = EPS_FACTOR * VV::epsilon(), max_ulps = ULPS)
|| ulps_eq!(lhs.im, rhs.im,
epsilon = EPS_FACTOR * VV::epsilon(), max_ulps = ULPS)
}
}
}
}

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -194,6 +244,22 @@ mod a_struct {
}
}
}

storage_types! {
types: Complex;

use super::super::A;

impl quickcheck::Arbitrary for A<V> {
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
A {
v: V::new(
<VV as quickcheck::Arbitrary>::arbitrary(g),
<VV as quickcheck::Arbitrary>::arbitrary(g)),
}
}
}
}
}

mod asserts;
Expand Down
145 changes: 80 additions & 65 deletions src/tests/quantity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,71 +173,6 @@ storage_types! {

a == x && b == y
}

#[allow(trivial_casts)]
fn partial_cmp(l: A<V>, r: A<V>) -> bool {
let km: V = <kilometer as crate::Conversion<V>>::coefficient().value();
let a = (*l).partial_cmp(&(((*r).clone() / &km) * &km));
let b = ((*l).clone() / &km).partial_cmp(&((*r).clone() / &km));
let x = f::Length::new::<meter>((*l).clone()).partial_cmp(
&k::Length::new::<meter>((*r).clone()));
let y = k::Length::new::<meter>((*l).clone()).partial_cmp(
&f::Length::new::<meter>((*r).clone()));

a == x && b == y
}

#[allow(trivial_casts)]
fn lt(l: A<V>, r: A<V>) -> bool {
let km: V = <kilometer as crate::Conversion<V>>::coefficient().value();
let a = (*l).lt(&(((*r).clone() / &km) * &km));
let b = ((*l).clone() / &km).lt(&((*r).clone() / &km));
let x = f::Length::new::<meter>((*l).clone()).lt(
&k::Length::new::<meter>((*r).clone()));
let y = k::Length::new::<meter>((*l).clone()).lt(
&f::Length::new::<meter>((*r).clone()));

a == x && b == y
}

#[allow(trivial_casts)]
fn le(l: A<V>, r: A<V>) -> bool {
let km: V = <kilometer as crate::Conversion<V>>::coefficient().value();
let a = (*l).le(&(((*r).clone() / &km) * &km));
let b = ((*l).clone() / &km).le(&((*r).clone() / &km));
let x = f::Length::new::<meter>((*l).clone()).le(
&k::Length::new::<meter>((*r).clone()));
let y = k::Length::new::<meter>((*l).clone()).le(
&f::Length::new::<meter>((*r).clone()));

a == x && b == y
}

#[allow(trivial_casts)]
fn gt(l: A<V>, r: A<V>) -> bool {
let km: V = <kilometer as crate::Conversion<V>>::coefficient().value();
let a = (*l).gt(&(((*r).clone() / &km) * &km));
let b = ((*l).clone() / &km).gt(&((*r).clone() / &km));
let x = f::Length::new::<meter>((*l).clone()).gt(
&k::Length::new::<meter>((*r).clone()));
let y = k::Length::new::<meter>((*l).clone()).gt(
&f::Length::new::<meter>((*r).clone()));

a == x && b == y
}

#[allow(trivial_casts)]
fn ge(l: A<V>, r: A<V>) -> bool {
let km: V = <kilometer as crate::Conversion<V>>::coefficient().value();
let a = (*l).ge(&(((*r).clone() / &km) * &km));
let b = ((*l).clone() / &km).ge(&((*r).clone() / &km));
let x = f::Length::new::<meter>((*l).clone()).ge(
&k::Length::new::<meter>((*r).clone()));
let y = k::Length::new::<meter>((*l).clone()).ge(
&f::Length::new::<meter>((*r).clone()));

a == x && b == y
}
}
}

Expand Down Expand Up @@ -556,3 +491,83 @@ mod float {
}
}
}

#[cfg(feature = "autoconvert")]
mod non_complex {
storage_types! {
// Everything BUT complex
types: PrimInt, Ratio, Float, BigInt, BigUint;

use crate::tests::*;

mod f { Q!(crate::tests, super::V); }
mod k { Q!(crate::tests, super::V, (kilometer, kilogram, kelvin)); }

quickcheck! {
#[allow(trivial_casts)]
fn partial_cmp(l: A<V>, r: A<V>) -> bool {
let km: V = <kilometer as crate::Conversion<V>>::coefficient().value();
let a = (*l).partial_cmp(&(((*r).clone() / &km) * &km));
let b = ((*l).clone() / &km).partial_cmp(&((*r).clone() / &km));
let x = f::Length::new::<meter>((*l).clone()).partial_cmp(
&k::Length::new::<meter>((*r).clone()));
let y = k::Length::new::<meter>((*l).clone()).partial_cmp(
&f::Length::new::<meter>((*r).clone()));

a == x && b == y
}

#[allow(trivial_casts)]
fn lt(l: A<V>, r: A<V>) -> bool {
let km: V = <kilometer as crate::Conversion<V>>::coefficient().value();
let a = (*l).lt(&(((*r).clone() / &km) * &km));
let b = ((*l).clone() / &km).lt(&((*r).clone() / &km));
let x = f::Length::new::<meter>((*l).clone()).lt(
&k::Length::new::<meter>((*r).clone()));
let y = k::Length::new::<meter>((*l).clone()).lt(
&f::Length::new::<meter>((*r).clone()));

a == x && b == y
}

#[allow(trivial_casts)]
fn le(l: A<V>, r: A<V>) -> bool {
let km: V = <kilometer as crate::Conversion<V>>::coefficient().value();
let a = (*l).le(&(((*r).clone() / &km) * &km));
let b = ((*l).clone() / &km).le(&((*r).clone() / &km));
let x = f::Length::new::<meter>((*l).clone()).le(
&k::Length::new::<meter>((*r).clone()));
let y = k::Length::new::<meter>((*l).clone()).le(
&f::Length::new::<meter>((*r).clone()));

a == x && b == y
}

#[allow(trivial_casts)]
fn gt(l: A<V>, r: A<V>) -> bool {
let km: V = <kilometer as crate::Conversion<V>>::coefficient().value();
let a = (*l).gt(&(((*r).clone() / &km) * &km));
let b = ((*l).clone() / &km).gt(&((*r).clone() / &km));
let x = f::Length::new::<meter>((*l).clone()).gt(
&k::Length::new::<meter>((*r).clone()));
let y = k::Length::new::<meter>((*l).clone()).gt(
&f::Length::new::<meter>((*r).clone()));

a == x && b == y
}

#[allow(trivial_casts)]
fn ge(l: A<V>, r: A<V>) -> bool {
let km: V = <kilometer as crate::Conversion<V>>::coefficient().value();
let a = (*l).ge(&(((*r).clone() / &km) * &km));
let b = ((*l).clone() / &km).ge(&((*r).clone() / &km));
let x = f::Length::new::<meter>((*l).clone()).ge(
&k::Length::new::<meter>((*r).clone()));
let y = k::Length::new::<meter>((*l).clone()).ge(
&f::Length::new::<meter>((*r).clone()));

a == x && b == y
}
}
}
}
Loading

0 comments on commit d6d39e1

Please sign in to comment.