use core::fmt::Debug;
use std::ops::RangeBounds;
use osom_lib_prng::traits::{PRNConcreteBoundedGenerator, PRNConcreteGenerator, PRNGSerialize, PRNGenerator};
pub fn test_prng_serialization<TGen>(expected: &[u8], gene: TGen)
where
TGen: PRNGenerator + PRNGSerialize + Debug,
TGen::SerializeError: Debug,
{
assert!(TGen::MAX_SERIALIZED_SIZE <= 1024);
let mut buffer = [0u8; 1024];
let written = gene.serialize(&mut buffer).unwrap();
let slice: &[u8] = &buffer;
let slice = &slice[0..written];
assert_eq!(slice, expected);
}
pub fn test_prng_deserialization<TGen>(given: &[u8], nexts: &[u64])
where
TGen: PRNGenerator + PRNGSerialize + Debug,
TGen::DeserializeError: Debug,
u64: PRNConcreteGenerator<TGen>,
{
assert!(given.len() >= TGen::MAX_SERIALIZED_SIZE);
assert!(!nexts.is_empty());
let gene_result = TGen::deserialize(given).unwrap();
assert!(gene_result.read_bytes <= given.len());
let mut gene = gene_result.value;
for item in nexts {
assert_eq!(gene.generate::<u64>(), *item);
}
}
fn test_in_range<TValue, TBounds, TGen>(gene: &mut TGen, range: TBounds, msg: &str)
where
TValue: PRNConcreteBoundedGenerator<TGen> + PartialOrd + Debug,
TBounds: RangeBounds<TValue> + Debug + Clone,
TGen: PRNGenerator + Debug,
{
let value = gene.generate_in_range(range.clone());
assert!(
range.contains(&value),
"{}: Value {:?} is not in range {:?}",
msg,
value,
range
);
}
pub fn test_in_range_u64<TGen, TBuilder>(mut builder: TBuilder)
where
TGen: PRNGenerator + Debug,
TBuilder: FnMut() -> TGen,
u64: PRNConcreteBoundedGenerator<TGen>,
{
#[cfg(not(miri))]
const ITERATIONS: usize = 10000;
#[cfg(miri)]
const ITERATIONS: usize = 10;
let mut gene = builder();
let range1 = 10u64..17u64;
let range2 = 25u64..;
let range3 = ..6431u64;
let range4 = 10u64..=17u64;
for _ in 0..ITERATIONS {
test_in_range(&mut gene, range1.clone(), "u64");
test_in_range(&mut gene, range2.clone(), "u64");
test_in_range(&mut gene, range3, "u64");
test_in_range(&mut gene, range4.clone(), "u64");
}
}
pub fn test_in_range_u32<TGen, TBuilder>(mut builder: TBuilder)
where
TGen: PRNGenerator + Debug,
TBuilder: FnMut() -> TGen,
u32: PRNConcreteBoundedGenerator<TGen>,
{
#[cfg(not(miri))]
const ITERATIONS: usize = 10000;
#[cfg(miri)]
const ITERATIONS: usize = 10;
let mut gene = builder();
let range1 = 643121u32..643133u32;
let range2 = 743254u32..;
let range3 = ..643211u32;
let range4 = 643121u32..=643133u32;
for _ in 0..ITERATIONS {
test_in_range(&mut gene, range1.clone(), "u32");
test_in_range(&mut gene, range2.clone(), "u32");
test_in_range(&mut gene, range3, "u32");
test_in_range(&mut gene, range4.clone(), "u32");
}
}
pub fn test_in_range_i64<TGen, TBuilder>(mut builder: TBuilder)
where
TGen: PRNGenerator + Debug,
TBuilder: FnMut() -> TGen,
i64: PRNConcreteBoundedGenerator<TGen>,
{
#[cfg(not(miri))]
const ITERATIONS: usize = 10000;
#[cfg(miri)]
const ITERATIONS: usize = 10;
let mut gene = builder();
let range1 = -17i64..10i64;
let range2 = 25i64..;
let range3 = ..-6431i64;
let range4 = -17i64..=10i64;
let range5 = -17i64..=-10i64;
for _ in 0..ITERATIONS {
test_in_range(&mut gene, range1.clone(), "i64");
test_in_range(&mut gene, range2.clone(), "i64");
test_in_range(&mut gene, range3, "i64");
test_in_range(&mut gene, range4.clone(), "i64");
test_in_range(&mut gene, range5.clone(), "i64");
}
}
pub fn test_in_range_i32<TGen, TBuilder>(mut builder: TBuilder)
where
TGen: PRNGenerator + Debug,
TBuilder: FnMut() -> TGen,
i32: PRNConcreteBoundedGenerator<TGen>,
{
#[cfg(not(miri))]
const ITERATIONS: usize = 10000;
#[cfg(miri)]
const ITERATIONS: usize = 10;
let mut gene = builder();
let range1 = -643151i32..-643133i32;
let range2 = 743254i32..;
let range3 = ..-643211i32;
let range4 = -643151i32..=-643133i32;
let range5 = -17i32..=10i32;
let range6 = -17i32..=-10i32;
for _ in 0..ITERATIONS {
test_in_range(&mut gene, range1.clone(), "i32");
test_in_range(&mut gene, range2.clone(), "i32");
test_in_range(&mut gene, range3, "i32");
test_in_range(&mut gene, range4.clone(), "i32");
test_in_range(&mut gene, range5.clone(), "i32");
test_in_range(&mut gene, range6.clone(), "i32");
}
}
pub fn test_in_range_f32<TGen, TBuilder>(mut builder: TBuilder)
where
TGen: PRNGenerator + Debug,
TBuilder: FnMut() -> TGen,
f32: PRNConcreteBoundedGenerator<TGen>,
{
#[cfg(not(miri))]
const ITERATIONS: usize = 10000;
#[cfg(miri)]
const ITERATIONS: usize = 10;
let mut gene = builder();
let range1 = 0.0f32..1.0f32;
let range2 = 0.0f32..=1.0f32;
let range3 = ..0.0f32;
let range4 = -100f32..-90f32;
let range5 = -50f32..50f32;
let range6 = 1300f32..7500f32;
let range7 = 10.0f32..;
for _ in 0..ITERATIONS {
test_in_range(&mut gene, range1.clone(), "f32");
test_in_range(&mut gene, range2.clone(), "f32");
test_in_range(&mut gene, range3, "f32");
test_in_range(&mut gene, range4.clone(), "f32");
test_in_range(&mut gene, range5.clone(), "f32");
test_in_range(&mut gene, range6.clone(), "f32");
test_in_range(&mut gene, range7.clone(), "f32");
}
}
pub fn test_in_range_f64<TGen, TBuilder>(mut builder: TBuilder)
where
TGen: PRNGenerator + Debug,
TBuilder: FnMut() -> TGen,
f64: PRNConcreteBoundedGenerator<TGen>,
{
#[cfg(not(miri))]
const ITERATIONS: usize = 10000;
#[cfg(miri)]
const ITERATIONS: usize = 10;
let mut gene = builder();
let range1 = 0.0f64..1.0f64;
let range2 = 0.0f64..=1.0f64;
let range3 = ..0.0f64;
let range4 = -100f64..-90f64;
let range5 = -50f64..50f64;
let range6 = 1300f64..7500f64;
let range7 = 10.0f64..;
for _ in 0..ITERATIONS {
test_in_range(&mut gene, range1.clone(), "f64");
test_in_range(&mut gene, range2.clone(), "f64");
test_in_range(&mut gene, range3, "f64");
test_in_range(&mut gene, range4.clone(), "f64");
test_in_range(&mut gene, range5.clone(), "f64");
test_in_range(&mut gene, range6.clone(), "f64");
test_in_range(&mut gene, range7.clone(), "f64");
}
}