Skip to content

Commit 985fecb

Browse files
committed
Improve tests for some seq APIs
1 parent bd3a806 commit 985fecb

File tree

1 file changed

+65
-14
lines changed

1 file changed

+65
-14
lines changed

src/seq.rs

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,17 @@ pub trait SliceRandom {
132132

133133
/// Extension trait on iterators, providing random sampling methods.
134134
pub trait IteratorRandom: Iterator + Sized {
135-
/// Choose one element at random from the iterator.
135+
/// Choose one element at random from the iterator. If you have a slice,
136+
/// it's significantly faster to call the [`choose`] or [`choose_mut`]
137+
/// functions using the slice instead.
136138
///
137139
/// Returns `None` if and only if the iterator is empty.
138140
///
139141
/// Complexity is `O(n)`, where `n` is the length of the iterator.
140142
/// This likely consumes multiple random numbers, but the exact number
141143
/// is unspecified.
144+
/// [`choose`]: trait.SliceRandom.html#method.choose
145+
/// [`choose_mut`]: trait.SliceRandom.html#method.choose_mut
142146
fn choose<R>(mut self, rng: &mut R) -> Option<Self::Item>
143147
where R: Rng + ?Sized
144148
{
@@ -518,19 +522,47 @@ mod test {
518522
use alloc::Vec;
519523

520524
#[test]
521-
fn test_choose() {
525+
fn test_slice_choose() {
522526
let mut r = ::test::rng(107);
523-
assert_eq!([1, 1, 1].choose(&mut r), Some(&1));
524-
525-
let mut v = [2];
526-
v.choose_mut(&mut r).map(|x| *x = 5);
527-
assert_eq!(v[0], 5);
527+
let chars = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'];
528+
let mut chosen = [0i32; 14];
529+
for _ in 0..1000 {
530+
let picked = *chars.choose(&mut r).unwrap();
531+
chosen[(picked as usize) - ('a' as usize)] += 1;
532+
}
533+
for count in chosen.iter() {
534+
let err = *count - (1000 / (chars.len() as i32));
535+
assert!(-20 <= err && err <= 20);
536+
}
528537

529-
let v = [3, 3, 3, 3];
530-
assert_eq!(v.iter().choose(&mut r), Some(&3));
538+
chosen.iter_mut().for_each(|x| *x = 0);
539+
for _ in 0..1000 {
540+
*chosen.choose_mut(&mut r).unwrap() += 1;
541+
}
542+
for count in chosen.iter() {
543+
let err = *count - (1000 / (chosen.len() as i32));
544+
assert!(-20 <= err && err <= 20);
545+
}
531546

532-
let v: &[isize] = &[];
547+
let mut v: [isize; 0] = [];
533548
assert_eq!(v.choose(&mut r), None);
549+
assert_eq!(v.choose_mut(&mut r), None);
550+
}
551+
552+
#[test]
553+
fn test_iterator_choose() {
554+
let mut r = ::test::rng(109);
555+
let mut chosen = [0i32; 9];
556+
for _ in 0..1000 {
557+
let picked = (0..9).choose(&mut r).unwrap();
558+
chosen[picked] += 1;
559+
}
560+
for count in chosen.iter() {
561+
let err = *count - 1000 / 9;
562+
assert!(-25 <= err && err <= 25);
563+
}
564+
565+
assert_eq!((0..0).choose(&mut r), None);
534566
}
535567

536568
#[test]
@@ -547,10 +579,29 @@ mod test {
547579
two.shuffle(&mut r);
548580
assert!(two == [1, 2] || two == [2, 1]);
549581

550-
let mut x = [1, 1, 1];
551-
x.shuffle(&mut r);
552-
let b: &[_] = &[1, 1, 1];
553-
assert_eq!(x, b);
582+
let mut counts = [0i32; 24];
583+
for _ in 0..10000 {
584+
let mut arr: [usize; 4] = [0, 1, 2, 3];
585+
arr.shuffle(&mut r);
586+
let mut permutation = 0usize;
587+
let mut pos_value = counts.len();
588+
for i in 0..4 {
589+
pos_value /= 4 - i;
590+
let pos = arr.iter().position(|&x| x == i).unwrap();
591+
assert!(pos < (4 - i));
592+
permutation += pos * pos_value;
593+
arr[pos..].rotate_left(1);
594+
assert_eq!(arr[3], i);
595+
}
596+
for i in 0..4 {
597+
assert_eq!(arr[i], i);
598+
}
599+
counts[permutation] += 1;
600+
}
601+
for count in counts.iter() {
602+
let err = *count - 10000i32 / 24;
603+
assert!(-50 <= err && err <= 50);
604+
}
554605
}
555606

556607
#[test]

0 commit comments

Comments
 (0)