Something went wrong. Try again.
forked from tvlfyi/tvix
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165//! Macros that generate proptest test suites checking laws of stdlib traits
/// Generate a suite of tests to check the laws of the [`Eq`] impl for the given typemacro_rules! eq_laws { ($ty: ty) => { eq_laws!( #[strategy(::proptest::arbitrary::any::<$ty>())] $ty, Default::default() ); }; ($ty: ty, $config: expr) => { eq_laws!( #[strategy(::proptest::arbitrary::any::<$ty>())] $ty, $config ); }; (#[$meta: meta] $ty: ty, $config: expr) => { #[allow(clippy::eq_op)] mod eq { use test_strategy::proptest;
use super::*;
#[proptest($config)] fn reflexive(#[$meta] x: $ty) { assert!(x == x); }
#[proptest($config)] fn symmetric(#[$meta] x: $ty, #[$meta] y: $ty) { assert_eq!(x == y, y == x); }
#[proptest($config)] fn transitive(#[$meta] x: $ty, #[$meta] y: $ty, #[$meta] z: $ty) { if x == y && y == z { assert!(x == z); } } } };}
/// Generate a suite of tests to check the laws of the [`Ord`] impl for the given typemacro_rules! ord_laws { ($ty: ty) => { ord_laws!( #[strategy(::proptest::arbitrary::any::<$ty>())] $ty, Default::default() ); }; ($ty: ty, $config: expr) => { ord_laws!( #[strategy(::proptest::arbitrary::any::<$ty>())] $ty, $config ); }; (#[$meta: meta] $ty: ty, $config: expr) => { mod ord { use test_strategy::proptest;
use super::*;
#[proptest($config)] fn partial_cmp_matches_cmp(#[$meta] x: $ty, #[$meta] y: $ty) { assert_eq!(x.partial_cmp(&y), Some(x.cmp(&y))); }
#[proptest($config)] fn dual(#[$meta] x: $ty, #[$meta] y: $ty) { if x < y { assert!(y > x); } if y < x { assert!(x > y); } }
#[proptest($config)] fn le_transitive(#[$meta] x: $ty, #[$meta] y: $ty, #[$meta] z: $ty) { if x < y && y < z { assert!(x < z) } }
#[proptest($config)] fn gt_transitive(#[$meta] x: $ty, #[$meta] y: $ty, #[$meta] z: $ty) { if x > y && y > z { assert!(x > z) } }
#[proptest($config)] fn trichotomy(#[$meta] x: $ty, #[$meta] y: $ty) { let less = x < y; let greater = x > y; let eq = x == y;
if less { assert!(!greater); assert!(!eq); }
if greater { assert!(!less); assert!(!eq); }
if eq { assert!(!less); assert!(!greater); } } } };}
/// Generate a test to check the laws of the [`Hash`] impl for the given typemacro_rules! hash_laws { ($ty: ty) => { hash_laws!( #[strategy(::proptest::arbitrary::any::<$ty>())] $ty, Default::default() ); }; ($ty: ty, $config: expr) => { hash_laws!( #[strategy(::proptest::arbitrary::any::<$ty>())] $ty, $config ); }; (#[$meta: meta] $ty: ty, $config: expr) => { mod hash { use test_strategy::proptest;
use super::*;
#[proptest($config)] fn matches_eq(#[$meta] x: $ty, #[$meta] y: $ty) { let hash = |x: &$ty| { use std::hash::Hasher;
let mut hasher = ::std::collections::hash_map::DefaultHasher::new(); x.hash(&mut hasher); hasher.finish() };
if x == y { assert_eq!(hash(&x), hash(&y)); } } } };}
pub(crate) use eq_laws;pub(crate) use hash_laws;pub(crate) use ord_laws;