Add assert_scalar_op! for DRYer testing

This commit is contained in:
Josh Stone 2017-07-11 21:59:10 -07:00
parent 6afac825d9
commit e5434dc659
2 changed files with 75 additions and 241 deletions

View File

@ -1,4 +1,4 @@
use {BigDigit, DoubleBigDigit, BigUint, big_digit}; use {BigDigit, BigUint, big_digit};
use {Sign, BigInt, RandBigInt, ToBigInt}; use {Sign, BigInt, RandBigInt, ToBigInt};
use Sign::{Minus, NoSign, Plus}; use Sign::{Minus, NoSign, Plus};
@ -24,6 +24,25 @@ macro_rules! assert_op {
}; };
} }
/// Assert that an op works for scalar left or right
macro_rules! assert_scalar_op {
(($($to:ident),*) $left:ident $op:tt $right:ident == $expected:expr) => {
$(
if let Some(left) = $left.$to() {
assert_op!(left $op $right == $expected);
}
if let Some(right) = $right.$to() {
assert_op!($left $op right == $expected);
}
)*
};
($left:ident $op:tt $right:ident == $expected:expr) => {
assert_scalar_op!((to_u8, to_u16, to_u32, to_u64, to_usize,
to_i8, to_i16, to_i32, to_i64, to_isize)
$left $op $right == $expected);
};
}
#[test] #[test]
fn test_from_biguint() { fn test_from_biguint() {
fn check(inp_s: Sign, inp_n: usize, ans_s: Sign, ans_n: usize) { fn check(inp_s: Sign, inp_n: usize, ans_s: Sign, ans_n: usize) {
@ -532,16 +551,6 @@ const SUM_TRIPLES: &'static [(&'static [BigDigit],
(&[1, 1, 1], &[N1, N1], &[0, 1, 2]), (&[1, 1, 1], &[N1, N1], &[0, 1, 2]),
(&[2, 2, 1], &[N1, N2], &[1, 1, 2])]; (&[2, 2, 1], &[N1, N2], &[1, 1, 2])];
fn get_scalar(vec: &[BigDigit]) -> BigDigit {
vec.get(0).map_or(0, BigDigit::clone)
}
fn get_scalar_double(vec: &[BigDigit]) -> DoubleBigDigit {
let lo = vec.get(0).map_or(0, BigDigit::clone);
let hi = vec.get(1).map_or(0, BigDigit::clone);
big_digit::to_doublebigdigit(hi, lo)
}
#[test] #[test]
fn test_add() { fn test_add() {
for elm in SUM_TRIPLES.iter() { for elm in SUM_TRIPLES.iter() {
@ -571,69 +580,14 @@ fn test_scalar_add() {
let c = BigInt::from_slice(Plus, c_vec); let c = BigInt::from_slice(Plus, c_vec);
let (na, nb, nc) = (-&a, -&b, -&c); let (na, nb, nc) = (-&a, -&b, -&c);
if a_vec.len() <= 1 { assert_scalar_op!(a + b == c);
let a = get_scalar(a_vec); assert_scalar_op!(b + a == c);
assert_op!(a + b == c); assert_scalar_op!(c + na == b);
assert_op!(b + a == c); assert_scalar_op!(c + nb == a);
assert_op!(a + nc == nb); assert_scalar_op!(a + nc == nb);
assert_op!(nc + a == nb); assert_scalar_op!(b + nc == na);
assert_scalar_op!(na + nb == nc);
if a <= i32::max_value() as u32 { assert_scalar_op!(a + na == Zero::zero());
let na = -(a as i32);
assert_op!(na + nb == nc);
assert_op!(nb + na == nc);
assert_op!(na + c == b);
assert_op!(c + na == b);
}
}
if a_vec.len() <= 2 {
let a = get_scalar_double(a_vec);
assert_op!(a + b == c);
assert_op!(b + a == c);
assert_op!(a + nc == nb);
assert_op!(nc + a == nb);
if a <= i64::max_value() as u64 {
let na = -(a as i64);
assert_op!(na + nb == nc);
assert_op!(nb + na == nc);
assert_op!(na + c == b);
assert_op!(c + na == b);
}
}
if b_vec.len() <= 1 {
let b = get_scalar(b_vec);
assert_op!(a + b == c);
assert_op!(b + a == c);
assert_op!(b + nc == na);
assert_op!(nc + b == na);
if b <= i32::max_value() as u32 {
let nb = -(b as i32);
assert_op!(na + nb == nc);
assert_op!(nb + na == nc);
assert_op!(nb + c == a);
assert_op!(c + nb == a);
}
}
if b_vec.len() <= 2 {
let b = get_scalar_double(b_vec);
assert_op!(a + b == c);
assert_op!(b + a == c);
assert_op!(b + nc == na);
assert_op!(nc + b == na);
if b <= i64::max_value() as u64 {
let nb = -(b as i64);
assert_op!(na + nb == nc);
assert_op!(nb + na == nc);
assert_op!(nb + c == a);
assert_op!(c + nb == a);
}
}
} }
} }
@ -666,53 +620,14 @@ fn test_scalar_sub() {
let c = BigInt::from_slice(Plus, c_vec); let c = BigInt::from_slice(Plus, c_vec);
let (na, nb, nc) = (-&a, -&b, -&c); let (na, nb, nc) = (-&a, -&b, -&c);
if a_vec.len() == 1 { assert_scalar_op!(c - a == b);
let a = a_vec[0]; assert_scalar_op!(c - b == a);
assert_op!(c - a == b); assert_scalar_op!(nb - a == nc);
assert_op!(a - c == nb); assert_scalar_op!(na - b == nc);
assert_op!(a - nb == c); assert_scalar_op!(b - na == c);
assert_op!(nb - a == nc); assert_scalar_op!(a - nb == c);
assert_scalar_op!(nc - na == nb);
if a <= i32::max_value() as u32 { assert_scalar_op!(a - a == Zero::zero());
let na = -(a as i32);
assert_op!(nc - na == nb);
assert_op!(na - nc == b);
assert_op!(na - b == nc);
assert_op!(b - na == c);
}
}
if b_vec.len() == 1 {
let b = b_vec[0];
assert_op!(c - b == a);
assert_op!(b - c == na);
assert_op!(b - na == c);
assert_op!(na - b == nc);
if b <= i32::max_value() as u32 {
let nb = -(b as i32);
assert_op!(nc - nb == na);
assert_op!(nb - nc == a);
assert_op!(nb - a == nc);
assert_op!(a - nb == c);
}
}
if c_vec.len() == 1 {
let c = c_vec[0];
assert_op!(c - a == b);
assert_op!(a - c == nb);
assert_op!(c - b == a);
assert_op!(b - c == na);
if c <= i32::max_value() as u32 {
let nc = -(c as i32);
assert_op!(nc - na == nb);
assert_op!(na - nc == b);
assert_op!(nc - nb == na);
assert_op!(nb - nc == a);
}
}
} }
} }
@ -791,37 +706,12 @@ fn test_scalar_mul() {
let c = BigInt::from_slice(Plus, c_vec); let c = BigInt::from_slice(Plus, c_vec);
let (na, nb, nc) = (-&a, -&b, -&c); let (na, nb, nc) = (-&a, -&b, -&c);
if a_vec.len() == 1 { assert_scalar_op!(a * b == c);
let a = a_vec[0]; assert_scalar_op!(b * a == c);
assert_op!(b * a == c); assert_scalar_op!(na * nb == c);
assert_op!(a * b == c);
assert_op!(nb * a == nc);
assert_op!(a * nb == nc);
if a <= i32::max_value() as u32 { assert_scalar_op!(na * b == nc);
let na = -(a as i32); assert_scalar_op!(nb * a == nc);
assert_op!(nb * na == c);
assert_op!(na * nb == c);
assert_op!(b * na == nc);
assert_op!(na * b == nc);
}
}
if b_vec.len() == 1 {
let b = b_vec[0];
assert_op!(a * b == c);
assert_op!(b * a == c);
assert_op!(na * b == nc);
assert_op!(b * na == nc);
if b <= i32::max_value() as u32 {
let nb = -(b as i32);
assert_op!(na * nb == c);
assert_op!(nb * na == c);
assert_op!(a * nb == nc);
assert_op!(nb * a == nc);
}
}
} }
} }

View File

@ -1,5 +1,5 @@
use integer::Integer; use integer::Integer;
use {BigDigit, DoubleBigDigit, BigUint, ToBigUint, big_digit}; use {BigDigit, BigUint, ToBigUint, big_digit};
use {BigInt, RandBigInt, ToBigInt}; use {BigInt, RandBigInt, ToBigInt};
use Sign::Plus; use Sign::Plus;
@ -25,6 +25,24 @@ macro_rules! assert_op {
}; };
} }
/// Assert that an op works for scalar left or right
macro_rules! assert_scalar_op {
(($($to:ident),*) $left:ident $op:tt $right:ident == $expected:expr) => {
$(
if let Some(left) = $left.$to() {
assert_op!(left $op $right == $expected);
}
if let Some(right) = $right.$to() {
assert_op!($left $op right == $expected);
}
)*
};
($left:ident $op:tt $right:ident == $expected:expr) => {
assert_scalar_op!((to_u8, to_u16, to_u32, to_u64, to_usize)
$left $op $right == $expected);
};
}
#[test] #[test]
fn test_from_slice() { fn test_from_slice() {
fn check(slice: &[BigDigit], data: &[BigDigit]) { fn check(slice: &[BigDigit], data: &[BigDigit]) {
@ -677,16 +695,6 @@ const SUM_TRIPLES: &'static [(&'static [BigDigit],
(&[1, 1, 1], &[N1, N1], &[0, 1, 2]), (&[1, 1, 1], &[N1, N1], &[0, 1, 2]),
(&[2, 2, 1], &[N1, N2], &[1, 1, 2])]; (&[2, 2, 1], &[N1, N2], &[1, 1, 2])];
fn get_scalar(vec: &[BigDigit]) -> BigDigit {
vec.get(0).map_or(0, BigDigit::clone)
}
fn get_scalar_double(vec: &[BigDigit]) -> DoubleBigDigit {
let lo = vec.get(0).map_or(0, BigDigit::clone);
let hi = vec.get(1).map_or(0, BigDigit::clone);
big_digit::to_doublebigdigit(hi, lo)
}
#[test] #[test]
fn test_add() { fn test_add() {
for elm in SUM_TRIPLES.iter() { for elm in SUM_TRIPLES.iter() {
@ -708,29 +716,8 @@ fn test_scalar_add() {
let b = BigUint::from_slice(b_vec); let b = BigUint::from_slice(b_vec);
let c = BigUint::from_slice(c_vec); let c = BigUint::from_slice(c_vec);
if a_vec.len() <= 1 { assert_scalar_op!(a + b == c);
let a = get_scalar(a_vec); assert_scalar_op!(b + a == c);
assert_op!(a + b == c);
assert_op!(b + a == c);
}
if a_vec.len() <= 2 {
let a = get_scalar_double(a_vec);
assert_op!(a + b == c);
assert_op!(b + a == c);
}
if b_vec.len() <= 1 {
let b = get_scalar(b_vec);
assert_op!(a + b == c);
assert_op!(b + a == c);
}
if b_vec.len() <= 2 {
let b = get_scalar_double(b_vec);
assert_op!(a + b == c);
assert_op!(b + a == c);
}
} }
} }
@ -755,21 +742,8 @@ fn test_scalar_sub() {
let b = BigUint::from_slice(b_vec); let b = BigUint::from_slice(b_vec);
let c = BigUint::from_slice(c_vec); let c = BigUint::from_slice(c_vec);
if a_vec.len() == 1 { assert_scalar_op!(c - a == b);
let a = a_vec[0]; assert_scalar_op!(c - b == a);
assert_op!(c - a == b);
}
if b_vec.len() == 1 {
let b = b_vec[0];
assert_op!(c - b == a);
}
if c_vec.len() == 1 {
let c = c_vec[0];
assert_op!(c - a == b);
assert_op!(c - b == a);
}
} }
} }
@ -849,17 +823,8 @@ fn test_scalar_mul() {
let b = BigUint::from_slice(b_vec); let b = BigUint::from_slice(b_vec);
let c = BigUint::from_slice(c_vec); let c = BigUint::from_slice(c_vec);
if a_vec.len() == 1 { assert_scalar_op!(a * b == c);
let a = a_vec[0]; assert_scalar_op!(b * a == c);
assert_op!(a * b == c);
assert_op!(b * a == c);
}
if b_vec.len() == 1 {
let b = b_vec[0];
assert_op!(a * b == c);
assert_op!(b * a == c);
}
} }
} }
@ -906,28 +871,14 @@ fn test_scalar_div_rem() {
let b = BigUint::from_slice(b_vec); let b = BigUint::from_slice(b_vec);
let c = BigUint::from_slice(c_vec); let c = BigUint::from_slice(c_vec);
if a_vec.len() == 1 && a_vec[0] != 0 { if !a.is_zero() {
let a = a_vec[0]; assert_scalar_op!(c / a == b);
assert_op!(c / a == b); assert_scalar_op!(c % a == Zero::zero());
assert_op!(c % a == Zero::zero());
} }
if b_vec.len() == 1 && b_vec[0] != 0 { if !b.is_zero() {
let b = b_vec[0]; assert_scalar_op!(c / b == a);
assert_op!(c / b == a); assert_scalar_op!(c % b == Zero::zero());
assert_op!(c % b == Zero::zero());
}
if c_vec.len() == 1 {
let c = c_vec[0];
if !a.is_zero() {
assert_op!(c / a == b);
assert_op!(c % a == Zero::zero());
}
if !b.is_zero() {
assert_op!(c / b == a);
assert_op!(c % b == Zero::zero());
}
} }
} }
@ -938,16 +889,9 @@ fn test_scalar_div_rem() {
let c = BigUint::from_slice(c_vec); let c = BigUint::from_slice(c_vec);
let d = BigUint::from_slice(d_vec); let d = BigUint::from_slice(d_vec);
if b_vec.len() == 1 && b_vec[0] != 0 { if !b.is_zero() {
let b = b_vec[0]; assert_scalar_op!(a / b == c);
assert_op!(a / b == c); assert_scalar_op!(a % b == d);
assert_op!(a % b == d);
}
if a_vec.len() == 1 && !b.is_zero() {
let a = a_vec[0];
assert_op!(a / b == c);
assert_op!(a % b == d);
} }
} }
} }