use af_core::task;
use af_core::test::prelude::*;
pub fn test(cx: &mut test::Context) {
test!(cx, "::chance()", {
let chance = sample_chance(|| random::chance(0.42)).await;
fail::when!(
!(0.40..=0.44).contains(&chance),
"Expected a chance of 42%, was {}%.",
(chance * 100.0).round_to_places(2),
);
});
test!(cx, "::fill_bytes()", {
let empty = vec![0u8; 256];
let mut a = empty.clone();
let mut b = empty.clone();
random::fill_bytes(&mut a);
random::fill_bytes(&mut b);
fail::when!(a == b);
fail::when!(a == empty);
fail::when!(b == empty);
});
test!(cx, "::range()", {
let (min, max) = sample_range(|| random::range(1..=10)).await;
fail::when!(min != 1);
fail::when!(max != 10);
});
test!(cx, "::ratio()", {
let chance = sample_chance(|| random::ratio(7, 8)).await;
fail::when!(
!(0.85..=0.9).contains(&chance),
"Expected a chance of 87.5%, was {}%.",
(chance * 100.0).round_to_places(2),
);
});
test!(cx, "::shuffle()", {
let initial = (0..=255u8).collect_vec();
let mut a = initial.clone();
let mut b = initial.clone();
random::shuffle(&mut a);
random::shuffle(&mut b);
fail::when!(a == b);
fail::when!(a == initial);
fail::when!(b == initial);
a.sort_unstable();
b.sort_unstable();
fail::when!(a != initial, "`a` has different elements.");
fail::when!(b != initial, "`b` has different elements.");
});
cx.scope("::Rng", |cx| {
test!(cx, "::fill_bytes()", {
let empty = vec![0u8; 256];
let mut a = empty.clone();
let mut b = empty.clone();
let mut rng = random::Rng::new();
rng.fill_bytes(&mut a);
rng.fill_bytes(&mut b);
fail::when!(a == b);
fail::when!(a == empty);
fail::when!(b == empty);
});
test!(cx, "::gen_chance()", {
let mut rng = random::Rng::new();
let chance = sample_chance(|| rng.gen_chance(0.71)).await;
fail::when!(
!(0.69..=0.73).contains(&chance),
"Expected a chance of 71%, was {}%.",
(chance * 100.0).round_to_places(2),
);
});
test!(cx, "::gen_range()", {
let mut rng = random::Rng::new();
let (min, max) = sample_range(|| rng.gen_range(0..8)).await;
fail::when!(min != 0);
fail::when!(max != 7);
});
test!(cx, "::gen_ratio()", {
let mut rng = random::Rng::new();
let chance = sample_chance(|| rng.gen_ratio(4, 9)).await;
fail::when!(
!(0.434..=0.464).contains(&chance),
"Expected a chance of 87.5%, was {}%.",
(chance * 100.0).round_to_places(2),
);
});
test!(cx, "::shuffle()", {
let initial = (0..=255u8).collect_vec();
let mut a = initial.clone();
let mut b = initial.clone();
let mut rng = random::Rng::new();
rng.shuffle(&mut a);
rng.shuffle(&mut b);
fail::when!(a == b);
fail::when!(a == initial);
fail::when!(b == initial);
a.sort_unstable();
b.sort_unstable();
fail::when!(a != initial, "`a` has different elements.");
fail::when!(b != initial, "`b` has different elements.");
});
});
}
async fn sample_chance(mut func: impl FnMut() -> bool) -> f64 {
let mut count = 0;
for _ in 0..128 {
for _ in 0..128 {
if func() {
count += 1;
}
}
task::yield_now().await;
}
count as f64 / 16_384.0
}
async fn sample_range<T>(mut func: impl FnMut() -> T) -> (T, T)
where
T: Copy + Number + Ord,
{
let mut min = func();
let mut max = func();
if min > max {
mem::swap(&mut min, &mut max);
}
for _ in 0..128 {
for _ in 0..128 {
let val = func();
min = cmp::min(min, val);
max = cmp::max(max, val);
}
task::yield_now().await;
}
(min, max)
}