use chrono::{DateTime, TimeZone, Utc};
use proptest::prelude::*;
use super::{
CompactSizeMessage, DateTime32, TrustedPreallocate, ZcashSerialize, MAX_PROTOCOL_MESSAGE_LEN,
};
impl Arbitrary for DateTime32 {
type Parameters = ();
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
any::<u32>().prop_map(Into::into).boxed()
}
type Strategy = BoxedStrategy<Self>;
}
pub fn datetime_full() -> impl Strategy<Value = chrono::DateTime<Utc>> {
(
DateTime::<Utc>::MIN_UTC.timestamp()..=DateTime::<Utc>::MAX_UTC.timestamp(),
0..1_000_000_000_u32,
)
.prop_map(|(secs, nsecs)| {
Utc.timestamp_opt(secs, nsecs)
.single()
.expect("in-range number of seconds and valid nanosecond")
})
}
pub fn datetime_u32() -> impl Strategy<Value = chrono::DateTime<Utc>> {
any::<DateTime32>().prop_map(Into::into)
}
impl Arbitrary for CompactSizeMessage {
type Parameters = ();
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
(0..=MAX_PROTOCOL_MESSAGE_LEN)
.prop_map(|size| {
size.try_into()
.expect("MAX_PROTOCOL_MESSAGE_LEN fits in CompactSizeMessage")
})
.boxed()
}
type Strategy = BoxedStrategy<Self>;
}
pub fn max_allocation_is_big_enough<T>(item: T) -> (usize, usize, usize, usize)
where
T: TrustedPreallocate + ZcashSerialize + Clone,
{
let max_allocation: usize = T::max_allocation().try_into().unwrap();
let mut smallest_disallowed_vec = vec![item; max_allocation + 1];
let smallest_disallowed_serialized = smallest_disallowed_vec
.zcash_serialize_to_vec()
.expect("Serialization to vec must succeed");
let smallest_disallowed_vec_len = smallest_disallowed_vec.len();
smallest_disallowed_vec.pop();
let largest_allowed_vec = smallest_disallowed_vec;
let largest_allowed_serialized = largest_allowed_vec
.zcash_serialize_to_vec()
.expect("Serialization to vec must succeed");
(
smallest_disallowed_vec_len,
smallest_disallowed_serialized.len(),
largest_allowed_vec.len(),
largest_allowed_serialized.len(),
)
}