91 lines
4.5 KiB
Rust
91 lines
4.5 KiB
Rust
#[macro_use]
|
|
extern crate proptest;
|
|
extern crate strength_reduce;
|
|
|
|
use proptest::test_runner::Config;
|
|
use strength_reduce::{StrengthReducedU8, StrengthReducedU16, StrengthReducedU32, StrengthReducedU64, StrengthReducedUsize, StrengthReducedU128};
|
|
|
|
|
|
macro_rules! reduction_proptest {
|
|
($test_name:ident, $struct_name:ident, $primitive_type:ident) => (
|
|
mod $test_name {
|
|
use super::*;
|
|
use proptest::sample::select;
|
|
|
|
fn assert_div_rem_equivalence(divisor: $primitive_type, numerator: $primitive_type) {
|
|
let reduced_divisor = $struct_name::new(divisor);
|
|
let expected_div = numerator / divisor;
|
|
let expected_rem = numerator % divisor;
|
|
let reduced_div = numerator / reduced_divisor;
|
|
let reduced_rem = numerator % reduced_divisor;
|
|
assert_eq!(expected_div, reduced_div, "Divide failed with numerator: {}, divisor: {}", numerator, divisor);
|
|
assert_eq!(expected_rem, reduced_rem, "Modulo failed with numerator: {}, divisor: {}", numerator, divisor);
|
|
let (reduced_combined_div, reduced_combined_rem) = $struct_name::div_rem(numerator, reduced_divisor);
|
|
assert_eq!(expected_div, reduced_combined_div, "div_rem divide failed with numerator: {}, divisor: {}", numerator, divisor);
|
|
assert_eq!(expected_rem, reduced_combined_rem, "div_rem modulo failed with numerator: {}, divisor: {}", numerator, divisor);
|
|
}
|
|
|
|
|
|
|
|
proptest! {
|
|
#![proptest_config(Config::with_cases(100_000))]
|
|
|
|
#[test]
|
|
fn fully_generated_inputs_are_div_rem_equivalent(divisor in 1..core::$primitive_type::MAX, numerator in 0..core::$primitive_type::MAX) {
|
|
assert_div_rem_equivalence(divisor, numerator);
|
|
}
|
|
|
|
#[test]
|
|
fn generated_divisors_with_edge_case_numerators_are_div_rem_equivalent(
|
|
divisor in 1..core::$primitive_type::MAX,
|
|
numerator in select(vec![0 as $primitive_type, 1 as $primitive_type, core::$primitive_type::MAX - 1, core::$primitive_type::MAX])) {
|
|
assert_div_rem_equivalence(divisor, numerator);
|
|
}
|
|
|
|
#[test]
|
|
fn generated_numerators_with_edge_case_divisors_are_div_rem_equivalent(
|
|
divisor in select(vec![1 as $primitive_type, 2 as $primitive_type, core::$primitive_type::MAX - 1, core::$primitive_type::MAX]),
|
|
numerator in 0..core::$primitive_type::MAX) {
|
|
assert_div_rem_equivalence(divisor, numerator);
|
|
}
|
|
}
|
|
}
|
|
)
|
|
}
|
|
reduction_proptest!(strength_reduced_u08, StrengthReducedU8, u8);
|
|
reduction_proptest!(strength_reduced_u16, StrengthReducedU16, u16);
|
|
reduction_proptest!(strength_reduced_u32, StrengthReducedU32, u32);
|
|
reduction_proptest!(strength_reduced_u64, StrengthReducedU64, u64);
|
|
reduction_proptest!(strength_reduced_usize, StrengthReducedUsize, usize);
|
|
reduction_proptest!(strength_reduced_u128, StrengthReducedU128, u128);
|
|
|
|
macro_rules! exhaustive_test {
|
|
($test_name:ident, $struct_name:ident, $primitive_type:ident) => (
|
|
#[test]
|
|
#[ignore]
|
|
fn $test_name() {
|
|
for divisor in 1..=std::$primitive_type::MAX {
|
|
let reduced_divisor = $struct_name::new(divisor);
|
|
|
|
for numerator in 0..=std::$primitive_type::MAX {
|
|
let expected_div = numerator / divisor;
|
|
let expected_rem = numerator % divisor;
|
|
|
|
let reduced_div = numerator / reduced_divisor;
|
|
assert_eq!(expected_div, reduced_div, "Divide failed with numerator: {}, divisor: {}", numerator, divisor);
|
|
|
|
let reduced_rem = numerator % reduced_divisor;
|
|
assert_eq!(expected_rem, reduced_rem, "Modulo failed with numerator: {}, divisor: {}", numerator, divisor);
|
|
|
|
let (reduced_combined_div, reduced_combined_rem) = $struct_name::div_rem(numerator, reduced_divisor);
|
|
assert_eq!(expected_div, reduced_combined_div, "div_rem divide failed with numerator: {}, divisor: {}", numerator, divisor);
|
|
assert_eq!(expected_rem, reduced_combined_rem, "div_rem modulo failed with numerator: {}, divisor: {}", numerator, divisor);
|
|
}
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
exhaustive_test!(test_strength_reduced_u08_exhaustive, StrengthReducedU8, u8);
|
|
exhaustive_test!(test_strength_reduced_u16_exhaustive, StrengthReducedU16, u16);
|