pub use super::super::{SAMPLE, apply_unary};
pub use check_monotone::check_monotone;
pub use fake_broken_monotone_inverts::fake_broken_monotone_inverts;
use crate::properties::tests::{pair, primitive, result_u32, unary};
use crate::spec::law::AlgebraicLaw;
#[inline]
pub fn check_monotone(id: &str, f: fn(&[u8]) -> Vec<u8>) {
let mut sorted = SAMPLE;
sorted.sort_unstable();
for window in sorted.windows(2) {
let a = window[0];
let b = window[1];
let fa = apply_unary(f, a);
let fb = apply_unary(f, b);
assert!(
fa <= fb,
"{id} violates Monotone at ({a:#010x} <= {b:#010x}): \
f(a)={fa:#010x} > f(b)={fb:#010x}"
);
}
}
#[inline]
pub fn fake_broken_monotone_inverts(input: &[u8]) -> Vec<u8> {
let a = u32::from_le_bytes([input[0], input[1], input[2], input[3]]);
(u32::MAX - a).to_le_bytes().to_vec()
}
use crate::properties::tests::declared_laws::identity::fake_identity_unary;
#[test]
fn monotone_checker_accepts_identity() {
check_monotone("fake.identity", fake_identity_unary);
}
#[test]
fn monotone_checker_catches_violation() {
let result = std::panic::catch_unwind(|| {
check_monotone("fake.broken_monotone", fake_broken_monotone_inverts);
});
assert!(
result.is_err(),
"Monotone checker failed to catch an order-inverting impl"
);
}