Skip to content

Commit

Permalink
Add tests for Quantity<D, U, V> operations generated by system! m…
Browse files Browse the repository at this point in the history
…acro.

Includes mathematical operations (`+`, `+=`, `-`, `-=`, ...) and fixes bug with
`-` using `+`. Part of #22.
  • Loading branch information
iliekturtles committed Apr 13, 2017
1 parent ffcf47d commit 4287da0
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 4 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ typenum = "1.6.0"
clippy = {version = "^0", optional = true}
compiletest_rs = {version = "^0", optional = true}

[dev-dependencies]
quickcheck = "0.4.1"

[features]
default = ["f32", "f64", "si"]
f32 = []
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@

#[doc(hidden)]
pub extern crate typenum;
#[cfg(test)]
#[macro_use]
extern crate quickcheck;

#[doc(hidden)]
pub mod stdlib {
Expand Down
6 changes: 3 additions & 3 deletions src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ macro_rules! system {
impl_ops!(Add, add, +, AddAssign, add_assign, +=,
Mul, mul, *, MulAssign, mul_assign, *=,
$V);
impl_ops!(Sub, sub, +, SubAssign, sub_assign, -=,
impl_ops!(Sub, sub, -, SubAssign, sub_assign, -=,
Div, div, /, DivAssign, div_assign, /=,
$V);

Expand Down Expand Up @@ -737,8 +737,8 @@ macro_rules! quantity {
pub fn get<N>(self, _unit: N) -> $V
where N: Unit<$V>,
{
self.value * <U as super::Units<Dimension, $V>>::conversion()
/ <N as super::Conversion<$V>>::conversion()
self.value / (<N as super::Conversion<$V>>::conversion()
/ <U as super::Units<Dimension, $V>>::conversion())
}
}

Expand Down
156 changes: 155 additions & 1 deletion src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ mod f32 {
Q!(tests, f32);
}

mod quantity {
mod quantity_macro {
use super::*;
use super::f32::*;
use super::length::{kilometer, meter};
Expand Down Expand Up @@ -100,3 +100,157 @@ mod quantity {
assert_eq!(1.0, kilogram::conversion());
}
}

mod system_macro {
use super::*;
use super::f32::*;
use super::length::{kilometer, meter};
use super::mass::kilogram;

quickcheck! {
#[allow(trivial_casts)]
fn add(l: f32, r: f32) -> bool {
(l + r) == (TLength::new::<meter>(l) + TLength::new::<meter>(r)).get(meter)
}
}

quickcheck! {
#[allow(trivial_casts)]
fn add_assign(l: f32, r: f32) -> bool {
let mut f = l;
let mut v = TLength::new::<meter>(l);

f += r;
v += TLength::new::<meter>(r);

f == v.get(meter)
}
}

quickcheck! {
#[allow(trivial_casts)]
fn sub(l: f32, r: f32) -> bool {
(l - r) == (TLength::new::<meter>(l) - TLength::new::<meter>(r)).get(meter)
}
}

quickcheck! {
#[allow(trivial_casts)]
fn sub_assign(l: f32, r: f32) -> bool {
let mut f = l;
let mut v = TLength::new::<meter>(l);

f -= r;
v -= TLength::new::<meter>(r);

f == v.get(meter)
}
}

quickcheck! {
#[allow(trivial_casts)]
fn mul_quantity(l: f32, r: f32) -> bool {
// TODO Use `.get(square_meter)`
(l * r) == (TLength::new::<meter>(l) * TLength::new::<meter>(r)).value
}
}

quickcheck! {
#[allow(trivial_casts)]
fn mul_float(l: f32, r: f32) -> bool {
(l * r) == (TLength::new::<meter>(l) * r).get(meter)
&& (l * r) == (l * TLength::new::<meter>(r)).get(meter)
}
}

quickcheck! {
#[allow(trivial_casts)]
fn mul_assign(l: f32, r: f32) -> bool {
let mut f = l;
let mut v = TLength::new::<meter>(l);

f *= r;
v *= r;

f == v.get(meter)
}
}

quickcheck! {
#[allow(trivial_casts)]
fn div_quantity(l: f32, r: f32) -> bool {
// TODO Use `.get(?)`
(l / r) == (TLength::new::<meter>(l) / TLength::new::<meter>(r)).value
}
}

quickcheck! {
#[allow(trivial_casts)]
fn div_float(l: f32, r: f32) -> bool {
// TODO Use `get(meter^-1)`
(l / r) == (TLength::new::<meter>(l) / r).get(meter)
&& (l / r) == (l / TLength::new::<meter>(r)).value
}
}

quickcheck! {
#[allow(trivial_casts)]
fn div_assign(l: f32, r: f32) -> bool {
let mut f = l;
let mut v = TLength::new::<meter>(l);

f /= r;
v /= r;

f == v.get(meter)
}
}

quickcheck! {
#[allow(trivial_casts)]
fn neg(l: f32) -> bool {
-l == -TLength::new::<meter>(l).get(meter)
}
}

quickcheck! {
#[allow(trivial_casts)]
fn rem(l: f32, r: f32) -> bool {
(l % r) == (TLength::new::<meter>(l) % TLength::new::<meter>(r)).get(meter)
}
}

quickcheck! {
#[allow(trivial_casts)]
fn rem_assign(l: f32, r: f32) -> bool {
let mut f = l;
let mut v = TLength::new::<meter>(l);

f %= r;
v %= TLength::new::<meter>(r);

f == v.get(meter)
}
}

#[test]
fn conversion() {
use typenum::{N1, P1, Z0};

type U1 = BaseUnits<meter, kilogram, f32>;
type U2 = BaseUnits<kilometer, kilogram, f32>;

assert_eq!(1.0, <U1 as Units<Q<Z0, Z0>, f32>>::conversion());
assert_eq!(1.0, <U1 as Units<Q<Z0, P1>, f32>>::conversion());
assert_eq!(1.0, <U1 as Units<Q<P1, Z0>, f32>>::conversion());
assert_eq!(1.0, <U1 as Units<Q<P1, P1>, f32>>::conversion());
assert_eq!(1.0, <U1 as Units<Q<Z0, N1>, f32>>::conversion());
assert_eq!(1.0, <U1 as Units<Q<N1, Z0>, f32>>::conversion());
assert_eq!(1.0, <U2 as Units<Q<Z0, Z0>, f32>>::conversion());
assert_eq!(1.0, <U2 as Units<Q<Z0, P1>, f32>>::conversion());
assert_eq!(1.0_E3, <U2 as Units<Q<P1, Z0>, f32>>::conversion());
assert_eq!(1.0_E3, <U2 as Units<Q<P1, P1>, f32>>::conversion());
assert_eq!(1.0, <U2 as Units<Q<Z0, N1>, f32>>::conversion());
assert_eq!(1.0_E-3, <U2 as Units<Q<N1, Z0>, f32>>::conversion());
}
}

0 comments on commit 4287da0

Please sign in to comment.