use std::cmp::max;
use std::cmp::min;
use crate::BoxGen;
use crate::BoxIter;
use rand::distr::Uniform;
use rand::Rng;
use rand::SeedableRng;
#[deprecated = "To be removed without replacement due to high complexity and lack of obvious use case"]
#[allow(deprecated)]
pub fn default() -> BoxGen<usize> {
progressively_increasing(0, 30, 100_000)
}
#[deprecated = "To be removed without replacement due to high complexity and lack of obvious use case"]
pub fn progressively_increasing(
start_size: usize,
percent_increase: usize,
max_size: usize,
) -> BoxGen<usize> {
crate::gens::from_fn(move |seed, _size| {
let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(seed);
max_iterator(start_size, percent_increase, max_size).map(move |max| {
rng.sample(Uniform::new_inclusive(0usize, max).unwrap())
})
})
.with_shrinker(crate::shrinks::int_to_zero())
}
fn max_iterator(
start_size: usize,
percent_increase: usize,
max_size: usize,
) -> BoxIter<usize> {
Box::new(std::iter::successors(
Some(min(start_size, max_size)),
move |last| {
let inc = max(last * percent_increase / 100, 1);
Some(min(max_size, last + inc))
},
))
}
#[cfg(test)]
mod test {
use assert_approx_eq::assert_approx_eq;
use crate::testing::assert_iter_eq;
#[test]
pub fn max_iterator_should_clamp_at_max_size() {
let max_size = 7;
let extra_large = 7_000;
assert_iter_eq(
super::max_iterator(extra_large, extra_large, max_size).take(6),
vec![max_size, max_size, max_size, max_size, max_size, max_size],
"stay flat when at max size",
);
}
#[test]
pub fn max_iterator_should_grow_with_at_least_one() {
let percent_increase = 10;
assert_iter_eq(
super::max_iterator(3, percent_increase, 1337).take(30),
vec![
3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
22, 24, 26, 28, 30,
33, 36, 39, 42,
46, 50,
55,
],
"max iterator should increase with largest value of percent, \
but at least with 1 to get growth at all",
);
}
#[test]
pub fn max_iterator_should_normally_grow_with_percent_increase() {
let percent_increase = 100;
assert_iter_eq(
super::max_iterator(16, percent_increase, 1337).take(10),
vec![16, 32, 64, 128, 256, 512, 1024, 1337, 1337, 1337],
"size should grow with increase 100% up to max value 1337",
);
}
#[test]
#[allow(deprecated)]
pub fn generator_should_never_exceed_max_size() {
let max_size = 7;
let extra_large = 7_000;
let max_value_generated =
super::progressively_increasing(extra_large, extra_large, max_size)
.examples(1337, 0..=1000)
.take(1_000)
.max();
assert_eq!(max_value_generated, Some(max_size));
}
#[test]
#[allow(deprecated)]
pub fn generator_should_behave_reasonably() {
let always_increase_with_one = 0;
let n = 10_000;
let sum_of_examples = super::progressively_increasing(
0,
always_increase_with_one,
usize::MAX,
)
.examples(1337, 0..=1000)
.take(n)
.sum::<usize>() as f64;
let expected_sum = n as f64 * n as f64 / 4.0;
let diff = expected_sum * 0.010;
assert_approx_eq!(sum_of_examples, expected_sum, diff);
}
}