#![cfg(all(feature = "tier2", feature = "tier3"))]
use mod_rand::tier1::Xoshiro256;
use mod_rand::{tier2, tier3};
#[test]
fn tier1_u8_bounds_and_full_width() {
let mut rng = Xoshiro256::seed_from_u64(1);
for _ in 0..10_000 {
let n = rng.gen_range_u8(0..100);
assert!(n < 100);
}
let mut seen = [false; 256];
for _ in 0..50_000 {
seen[rng.gen_range_inclusive_u8(0..=u8::MAX) as usize] = true;
}
assert!(
seen.iter().filter(|s| **s).count() > 200,
"0..=u8::MAX did not reach diverse byte values"
);
}
#[test]
fn tier1_u16_bounds_and_full_width() {
let mut rng = Xoshiro256::seed_from_u64(2);
for _ in 0..10_000 {
let n = rng.gen_range_u16(100..1000);
assert!((100..1000).contains(&n));
}
for _ in 0..1000 {
let _ = rng.gen_range_inclusive_u16(0..=u16::MAX);
}
}
#[test]
fn tier1_u128_bounds() {
let mut rng = Xoshiro256::seed_from_u64(3);
let lo: u128 = 1_000_000_000_000;
let hi: u128 = u128::MAX / 2;
for _ in 0..1000 {
let n = rng.gen_range_u128(lo..hi);
assert!((lo..hi).contains(&n));
}
}
#[test]
fn tier1_u128_full_width_inclusive() {
let mut rng = Xoshiro256::seed_from_u64(4);
let a = rng.gen_range_inclusive_u128(0..=u128::MAX);
let b = rng.gen_range_inclusive_u128(0..=u128::MAX);
assert_ne!(a, b, "two consecutive full-width u128 draws should differ");
}
#[test]
fn tier1_u128_uniformity_chi_squared() {
let mut rng = Xoshiro256::seed_from_u64(0x1_2345_6789);
let bucket_count: u128 = 100;
let mut counts = [0u32; 100];
let span: u128 = 1_000_000;
for _ in 0..100_000 {
let v = rng.gen_range_u128(0..span);
let b = (v * bucket_count / span) as usize;
counts[b] += 1;
}
let expected = 1_000.0;
let chi: f64 = counts
.iter()
.map(|&c| {
let d = c as f64 - expected;
d * d / expected
})
.sum();
assert!(chi < 250.0, "u128 bounded-range chi-squared {chi} too high");
}
#[test]
fn tier1_usize_bounds_and_full_width() {
let mut rng = Xoshiro256::seed_from_u64(5);
for _ in 0..10_000 {
let n = rng.gen_range_usize(0..1000);
assert!(n < 1000);
}
let _ = rng.gen_range_inclusive_usize(0..=usize::MAX);
}
#[test]
fn tier1_i8_negative_and_mixed_sign() {
let mut rng = Xoshiro256::seed_from_u64(6);
let mut saw_neg = false;
let mut saw_pos = false;
for _ in 0..10_000 {
let n = rng.gen_range_i8(-100..50);
assert!((-100..50).contains(&n));
if n < 0 {
saw_neg = true;
} else {
saw_pos = true;
}
}
assert!(saw_neg && saw_pos);
for _ in 0..1000 {
let _ = rng.gen_range_inclusive_i8(i8::MIN..=i8::MAX);
}
}
#[test]
fn tier1_i16_negative_and_mixed_sign() {
let mut rng = Xoshiro256::seed_from_u64(7);
for _ in 0..10_000 {
let n = rng.gen_range_i16(-1000..1000);
assert!((-1000..1000).contains(&n));
}
for _ in 0..1000 {
let _ = rng.gen_range_inclusive_i16(i16::MIN..=i16::MAX);
}
}
#[test]
fn tier1_i128_mixed_sign_and_full_width() {
let mut rng = Xoshiro256::seed_from_u64(8);
for _ in 0..1000 {
let n = rng.gen_range_i128(-1_000_000..1_000_000);
assert!((-1_000_000..1_000_000).contains(&n));
}
let a = rng.gen_range_inclusive_i128(i128::MIN..=i128::MAX);
let b = rng.gen_range_inclusive_i128(i128::MIN..=i128::MAX);
assert_ne!(a, b, "two consecutive full-width i128 draws should differ");
}
#[test]
fn tier1_isize_bounds_and_full_width() {
let mut rng = Xoshiro256::seed_from_u64(9);
for _ in 0..10_000 {
let n = rng.gen_range_isize(-1000..1000);
assert!((-1000..1000).contains(&n));
}
let _ = rng.gen_range_inclusive_isize(isize::MIN..=isize::MAX);
}
#[test]
fn tier2_u8_u16_u128_bounds() {
for _ in 0..1000 {
assert!(tier2::range_u8(0..100) < 100);
assert!(tier2::range_u16(0..1000) < 1000);
}
for _ in 0..200 {
let n = tier2::range_u128(0..u128::MAX / 2);
assert!(n < u128::MAX / 2);
}
let a = tier2::range_inclusive_u128(0..=u128::MAX);
let b = tier2::range_inclusive_u128(0..=u128::MAX);
assert_ne!(a, b);
}
#[test]
fn tier2_i128_full_width() {
let _ = tier2::range_inclusive_i128(i128::MIN..=i128::MAX);
}
#[test]
fn tier2_usize_isize_full_width() {
let _ = tier2::range_inclusive_usize(0..=usize::MAX);
let _ = tier2::range_inclusive_isize(isize::MIN..=isize::MAX);
}
#[test]
#[should_panic(expected = "empty range")]
fn tier2_range_u128_empty_panics() {
let _ = tier2::range_u128(10..10);
}
#[test]
fn tier3_u8_u16_u128_bounds() {
for _ in 0..200 {
assert!(tier3::random_range_u8(0..100).unwrap() < 100);
assert!(tier3::random_range_u16(0..1000).unwrap() < 1000);
}
for _ in 0..50 {
let n = tier3::random_range_u128(0..u128::MAX / 2).unwrap();
assert!(n < u128::MAX / 2);
}
let a = tier3::random_range_inclusive_u128(0..=u128::MAX).unwrap();
let b = tier3::random_range_inclusive_u128(0..=u128::MAX).unwrap();
assert_ne!(a, b);
}
#[test]
fn tier3_i128_full_width() {
let _ = tier3::random_range_inclusive_i128(i128::MIN..=i128::MAX).unwrap();
}
#[test]
fn tier3_usize_isize_full_width() {
let _ = tier3::random_range_inclusive_usize(0..=usize::MAX).unwrap();
let _ = tier3::random_range_inclusive_isize(isize::MIN..=isize::MAX).unwrap();
}
#[test]
fn tier3_empty_range_returns_invalid_input() {
let err = tier3::random_range_u128(10..10).unwrap_err();
assert_eq!(err.kind(), std::io::ErrorKind::InvalidInput);
let err = tier3::random_range_i128(0..0).unwrap_err();
assert_eq!(err.kind(), std::io::ErrorKind::InvalidInput);
}