#![cfg(test)] use crate::SmallInt; use crate::SmallUint; use core::fmt::Debug; #[cfg(feature = "num-bigint")] use num_bigint::{BigInt, BigUint, Sign}; macro_rules! conversion_tests { ($t:ty, $i:ident) => { #[test] fn $i() { let i = <$t>::MAX; let s = SmallInt::from(i); assert_eq!(<$t>::try_from(s).unwrap(), i); let i = <$t>::MIN; let s = SmallInt::from(i); assert_eq!(<$t>::try_from(s).unwrap(), i); } }; } conversion_tests!(u8, test_u8); conversion_tests!(i8, test_i8); conversion_tests!(u16, test_u16); conversion_tests!(i16, test_i16); conversion_tests!(u32, test_u32); conversion_tests!(i32, test_i32); conversion_tests!(u64, test_u64); conversion_tests!(i64, test_i64); conversion_tests!(u128, test_u128); conversion_tests!(i128, test_i128); #[cfg(feature = "num-bigint")] fn run_tests_u_inner(test: impl Fn(BigUint)) { for i in 0u8..=7 { test(BigUint::from(i)); } for shift_scale in 1..=16 { for shift_offset in -2..=2 { let shift: i16 = (shift_scale * 32) + shift_offset; test(BigUint::from(1u8) << shift); for offset in 1u8..=7 { test((BigUint::from(1u8) << shift) + BigUint::from(offset)); test((BigUint::from(1u8) << shift) - BigUint::from(offset)); } } } test(BigUint::new(vec![3, 9, 8, 3, 1])); test(BigUint::new(vec![5, 4, 9, 3, 1, 81])); } #[allow(dead_code)] #[cfg(feature = "num-bigint")] fn run_tests_u_1(small: impl Fn(SmallUint) -> T, big: impl Fn(&BigUint) -> T) { run_tests_u_inner(|i| { let small_result = small(SmallUint::from(&i)); let big_result = big(&i); assert_eq!( small_result, big_result, "{:#x}", i ); }); } #[cfg(feature = "num-bigint")] fn run_tests_u_2( small: impl Fn(SmallUint, SmallUint) -> T, big: impl Fn(&BigUint, &BigUint) -> T ) { run_tests_u_inner(|i| run_tests_u_inner(|k| { let small_result = small(SmallUint::from(&i), SmallUint::from(&k)); let big_result = big(&i, &k); assert_eq!( small_result, big_result, "{:#x} {:#x}", i, k ); })); } #[cfg(feature = "num-bigint")] fn run_tests_i_inner(test: impl Fn(BigInt)) { run_tests_u_inner(|value| { test(BigInt::from_biguint(Sign::Plus, value.clone())); test(BigInt::from_biguint(Sign::Minus, value)); }); } #[cfg(feature = "num-bigint")] fn run_tests_i_1(small: impl Fn(SmallInt) -> T, big: impl Fn(&BigInt) -> T) { run_tests_i_inner(|i| { let small_result = small(SmallInt::from(&i)); let big_result = big(&i); assert_eq!( small_result, big_result, "{:#x}", i ); }); } #[cfg(feature = "num-bigint")] fn run_tests_i_2( small: impl Fn(SmallInt, SmallInt) -> T, big: impl Fn(&BigInt, &BigInt) -> T ) { run_tests_i_inner(|i| run_tests_i_inner(|k| { let small_result = small(SmallInt::from(&i), SmallInt::from(&k)); let big_result = big(&i, &k); assert_eq!( small_result, big_result, "{:#x} {:#x}", i, k ); })); } #[test] #[cfg(feature = "num-bigint")] fn test_convert_biguint() { run_tests_u_1(|i| BigUint::from(&i), |i| i.clone()); run_tests_u_1(|i| i, |i| SmallUint::from(i)); } #[test] #[cfg(feature = "num-bigint")] fn test_convert_bigint() { run_tests_i_1(|i| BigInt::from(&i), |i| i.clone()); run_tests_i_1(|i| i, |i| SmallInt::from(i)); } #[test] #[cfg(feature = "num-bigint")] fn test_cmp_u() { run_tests_u_2( |i, k| i.partial_cmp(&k), |i, k| i.partial_cmp(&k), ); } #[test] #[cfg(feature = "num-bigint")] fn test_cmp_i() { run_tests_i_2( |i, k| i.partial_cmp(&k), |i, k| i.partial_cmp(&k), ); } #[test] #[cfg(feature = "num-bigint")] fn test_op_add_u() { run_tests_u_2( |i, k| BigUint::from(&(i + k)), |i, k| i + k, ); } #[test] #[cfg(feature = "num-bigint")] fn test_op_add_i() { run_tests_i_2( |i, k| BigInt::from(&(i + k)), |i, k| i + k, ); } #[test] #[cfg(feature = "num-bigint")] fn test_op_mul_u() { run_tests_u_2( |i, k| BigUint::from(&(i * k)), |i, k| i * k, ); } #[test] #[cfg(feature = "num-bigint")] fn test_op_mul_i() { run_tests_i_2( |i, k| BigInt::from(&(i * k)), |i, k| i * k, ); } #[test] #[cfg(feature = "num-bigint")] fn test_op_sub_u() { run_tests_u_2( |i, k| (i >= k).then(|| BigUint::from(&(i - k))), |i, k| (i >= k).then(|| i - k), ); } #[test] #[cfg(feature = "num-bigint")] fn test_op_sub_i() { run_tests_i_2( |i, k| BigInt::from(&(i - k)), |i, k| i - k, ); } #[test] #[cfg(feature = "num-bigint")] fn test_op_and_u() { run_tests_u_2( |i, k| BigUint::from(&(i & k)), |i, k| i & k, ); } #[test] #[cfg(feature = "num-bigint")] fn test_op_and_i() { run_tests_i_2( |i, k| BigInt::from(&(i & k)), |i, k| i & k, ); } #[test] #[cfg(feature = "num-bigint")] fn test_op_or_u() { run_tests_u_2( |i, k| BigUint::from(&(i | k)), |i, k| i | k, ); } // #[test] // #[cfg(feature = "num-bigint")] // fn test_op_or_i() { // run_tests_i_2( // |i, k| BigInt::from(&(i | k)), // |i, k| i | k, // ); // } #[test] #[cfg(feature = "num-bigint")] fn test_op_xor_u() { run_tests_u_2( |i, k| BigUint::from(&(i ^ k)), |i, k| i ^ k, ); } #[test] #[cfg(feature = "num-bigint")] fn test_op_neg() { run_tests_i_1(|i| BigInt::from(&-i), |i| -i.clone()); } #[test] #[cfg(feature = "num-bigint")] fn test_conversion_sign_drop() { run_tests_i_1( |i| BigUint::from(&SmallUint::from_smallint_unsigned(i)), |i| i.magnitude().clone() ); } #[test] #[cfg(feature = "num-bigint")] fn test_bigint() { let i = BigInt::new(Sign::Plus, vec![5, 4, 8, 3, 2, 9, 3]); let s = SmallInt::from(&i); assert_eq!( BigInt::from(&s).to_u32_digits(), (Sign::Plus, vec![5, 4, 8, 3, 2, 9, 3]) ); }