1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
pub mod array_like; pub mod empty_types; pub mod specifics; #[cfg(test)] mod tests; pub mod wrapper_types; use once_cell::sync::Lazy; use std::borrow::Borrow; use std::fmt::Debug; use std::ops::Deref; pub struct Should<'a, T> { inner: &'a T, } impl<'a, T> Should<'a, T> where T: Shoulda, { pub fn eq<K: Borrow<T>>(self, other: K) -> Self { let other = other.borrow(); assert!( self.inner.test_eq(other), "a = {:?}, b = {:?}", &self.inner, other ); self } pub fn equal<K: Borrow<T>>(self, other: K) -> Self { self.eq(other) } pub fn not(self) -> ShouldNot<'a, T> { ShouldNot { inner: self.inner } } pub fn be(self) -> Self { self } pub fn and(self) -> Self { self } } pub struct ShouldNot<'a, T> { inner: &'a T, } impl<'a, T> ShouldNot<'a, T> where T: Shoulda, { pub fn eq<K: Borrow<T>>(self, other: K) -> Should<'a, T> { let other = other.borrow(); assert!( !self.inner.test_eq(other), "a = {:?}, b = {:?}", &self.inner, other ); self.not() } pub fn equal<K: Borrow<T>>(self, other: K) -> Should<'a, T> { self.eq(other) } pub fn not(self) -> Should<'a, T> { Should { inner: self.inner } } pub fn be(self) -> Self { self } pub fn and(self) -> Self { self } } pub trait Shoulda: Debug { fn test_eq(&self, other: &Self) -> bool; fn should(&self) -> Should<Self> where Self: Sized, { Should { inner: self } } } macro_rules! eq_assertable_impl { ($x:ty) => { impl Shoulda for $x { fn test_eq(&self, other: &Self) -> bool { self.eq(other) } } }; } static SHOULDA_FLOAT_DIFF_MODE: Lazy<f64> = Lazy::new(|| { option_env!("SHOULDA_FLOAT_DIFF_MODE") .map(|x| x.parse().unwrap()) .unwrap_or(0.0001) }); macro_rules! float_assertable_impl { ($x:ty) => { impl Shoulda for $x { fn test_eq(&self, other: &Self) -> bool { (self - other).abs() < (*SHOULDA_FLOAT_DIFF_MODE.deref() as $x) } } }; } eq_assertable_impl!(String); eq_assertable_impl!(str); eq_assertable_impl!(bool); eq_assertable_impl!(u8); eq_assertable_impl!(i8); eq_assertable_impl!(u16); eq_assertable_impl!(i16); eq_assertable_impl!(u32); eq_assertable_impl!(i32); eq_assertable_impl!(u64); eq_assertable_impl!(i64); eq_assertable_impl!(u128); eq_assertable_impl!(i128); eq_assertable_impl!(usize); eq_assertable_impl!(isize); float_assertable_impl!(f32); float_assertable_impl!(f64); impl<T> Shoulda for &T where T: Shoulda, { fn test_eq(&self, other: &Self) -> bool { T::test_eq(self, other) } }