summaryrefslogtreecommitdiffstats
path: root/third_party/rust/slab/tests/slab.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/slab/tests/slab.rs')
-rw-r--r--third_party/rust/slab/tests/slab.rs712
1 files changed, 712 insertions, 0 deletions
diff --git a/third_party/rust/slab/tests/slab.rs b/third_party/rust/slab/tests/slab.rs
new file mode 100644
index 0000000000..900eed3989
--- /dev/null
+++ b/third_party/rust/slab/tests/slab.rs
@@ -0,0 +1,712 @@
+#![warn(rust_2018_idioms)]
+
+use slab::*;
+
+use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe};
+
+#[test]
+fn insert_get_remove_one() {
+ let mut slab = Slab::new();
+ assert!(slab.is_empty());
+
+ let key = slab.insert(10);
+
+ assert_eq!(slab[key], 10);
+ assert_eq!(slab.get(key), Some(&10));
+ assert!(!slab.is_empty());
+ assert!(slab.contains(key));
+
+ assert_eq!(slab.remove(key), 10);
+ assert!(!slab.contains(key));
+ assert!(slab.get(key).is_none());
+}
+
+#[test]
+fn insert_get_many() {
+ let mut slab = Slab::with_capacity(10);
+
+ for i in 0..10 {
+ let key = slab.insert(i + 10);
+ assert_eq!(slab[key], i + 10);
+ }
+
+ assert_eq!(slab.capacity(), 10);
+
+ // Storing another one grows the slab
+ let key = slab.insert(20);
+ assert_eq!(slab[key], 20);
+
+ // Capacity grows by 2x
+ assert_eq!(slab.capacity(), 20);
+}
+
+#[test]
+fn insert_get_remove_many() {
+ let mut slab = Slab::with_capacity(10);
+ let mut keys = vec![];
+
+ for i in 0..10 {
+ for j in 0..10 {
+ let val = (i * 10) + j;
+
+ let key = slab.insert(val);
+ keys.push((key, val));
+ assert_eq!(slab[key], val);
+ }
+
+ for (key, val) in keys.drain(..) {
+ assert_eq!(val, slab.remove(key));
+ }
+ }
+
+ assert_eq!(10, slab.capacity());
+}
+
+#[test]
+fn insert_with_vacant_entry() {
+ let mut slab = Slab::with_capacity(1);
+ let key;
+
+ {
+ let entry = slab.vacant_entry();
+ key = entry.key();
+ entry.insert(123);
+ }
+
+ assert_eq!(123, slab[key]);
+}
+
+#[test]
+fn get_vacant_entry_without_using() {
+ let mut slab = Slab::<usize>::with_capacity(1);
+ let key = slab.vacant_entry().key();
+ assert_eq!(key, slab.vacant_entry().key());
+}
+
+#[test]
+#[should_panic(expected = "invalid key")]
+fn invalid_get_panics() {
+ let slab = Slab::<usize>::with_capacity(1);
+ let _ = &slab[0];
+}
+
+#[test]
+#[should_panic(expected = "invalid key")]
+fn invalid_get_mut_panics() {
+ let mut slab = Slab::<usize>::new();
+ let _ = &mut slab[0];
+}
+
+#[test]
+#[should_panic(expected = "invalid key")]
+fn double_remove_panics() {
+ let mut slab = Slab::<usize>::with_capacity(1);
+ let key = slab.insert(123);
+ slab.remove(key);
+ slab.remove(key);
+}
+
+#[test]
+#[should_panic(expected = "invalid key")]
+fn invalid_remove_panics() {
+ let mut slab = Slab::<usize>::with_capacity(1);
+ slab.remove(0);
+}
+
+#[test]
+fn slab_get_mut() {
+ let mut slab = Slab::new();
+ let key = slab.insert(1);
+
+ slab[key] = 2;
+ assert_eq!(slab[key], 2);
+
+ *slab.get_mut(key).unwrap() = 3;
+ assert_eq!(slab[key], 3);
+}
+
+#[test]
+fn key_of_tagged() {
+ let mut slab = Slab::new();
+ slab.insert(0);
+ assert_eq!(slab.key_of(&slab[0]), 0);
+}
+
+#[test]
+fn key_of_layout_optimizable() {
+ // Entry<&str> doesn't need a discriminant tag because it can use the
+ // nonzero-ness of ptr and store Vacant's next at the same offset as len
+ let mut slab = Slab::new();
+ slab.insert("foo");
+ slab.insert("bar");
+ let third = slab.insert("baz");
+ slab.insert("quux");
+ assert_eq!(slab.key_of(&slab[third]), third);
+}
+
+#[test]
+fn key_of_zst() {
+ let mut slab = Slab::new();
+ slab.insert(());
+ let second = slab.insert(());
+ slab.insert(());
+ assert_eq!(slab.key_of(&slab[second]), second);
+}
+
+#[test]
+fn reserve_does_not_allocate_if_available() {
+ let mut slab = Slab::with_capacity(10);
+ let mut keys = vec![];
+
+ for i in 0..6 {
+ keys.push(slab.insert(i));
+ }
+
+ for key in 0..4 {
+ slab.remove(key);
+ }
+
+ assert!(slab.capacity() - slab.len() == 8);
+
+ slab.reserve(8);
+ assert_eq!(10, slab.capacity());
+}
+
+#[test]
+fn reserve_exact_does_not_allocate_if_available() {
+ let mut slab = Slab::with_capacity(10);
+ let mut keys = vec![];
+
+ for i in 0..6 {
+ keys.push(slab.insert(i));
+ }
+
+ for key in 0..4 {
+ slab.remove(key);
+ }
+
+ assert!(slab.capacity() - slab.len() == 8);
+
+ slab.reserve_exact(8);
+ assert_eq!(10, slab.capacity());
+}
+
+#[test]
+#[should_panic(expected = "capacity overflow")]
+fn reserve_does_panic_with_capacity_overflow() {
+ let mut slab = Slab::with_capacity(10);
+ slab.insert(true);
+ slab.reserve(std::isize::MAX as usize);
+}
+
+#[test]
+#[should_panic(expected = "capacity overflow")]
+fn reserve_does_panic_with_capacity_overflow_bytes() {
+ let mut slab = Slab::with_capacity(10);
+ slab.insert(1u16);
+ slab.reserve((std::isize::MAX as usize) / 2);
+}
+
+#[test]
+#[should_panic(expected = "capacity overflow")]
+fn reserve_exact_does_panic_with_capacity_overflow() {
+ let mut slab = Slab::with_capacity(10);
+ slab.insert(true);
+ slab.reserve_exact(std::isize::MAX as usize);
+}
+
+#[test]
+fn retain() {
+ let mut slab = Slab::with_capacity(2);
+
+ let key1 = slab.insert(0);
+ let key2 = slab.insert(1);
+
+ slab.retain(|key, x| {
+ assert_eq!(key, *x);
+ *x % 2 == 0
+ });
+
+ assert_eq!(slab.len(), 1);
+ assert_eq!(slab[key1], 0);
+ assert!(!slab.contains(key2));
+
+ // Ensure consistency is retained
+ let key = slab.insert(123);
+ assert_eq!(key, key2);
+
+ assert_eq!(2, slab.len());
+ assert_eq!(2, slab.capacity());
+
+ // Inserting another element grows
+ let key = slab.insert(345);
+ assert_eq!(key, 2);
+
+ assert_eq!(4, slab.capacity());
+}
+
+#[test]
+fn into_iter() {
+ let mut slab = Slab::new();
+
+ for i in 0..8 {
+ slab.insert(i);
+ }
+ slab.remove(0);
+ slab.remove(4);
+ slab.remove(5);
+ slab.remove(7);
+
+ let vals: Vec<_> = slab
+ .into_iter()
+ .inspect(|&(key, val)| assert_eq!(key, val))
+ .map(|(_, val)| val)
+ .collect();
+ assert_eq!(vals, vec![1, 2, 3, 6]);
+}
+
+#[test]
+fn into_iter_rev() {
+ let mut slab = Slab::new();
+
+ for i in 0..4 {
+ slab.insert(i);
+ }
+
+ let mut iter = slab.into_iter();
+ assert_eq!(iter.next_back(), Some((3, 3)));
+ assert_eq!(iter.next_back(), Some((2, 2)));
+ assert_eq!(iter.next(), Some((0, 0)));
+ assert_eq!(iter.next_back(), Some((1, 1)));
+ assert_eq!(iter.next_back(), None);
+ assert_eq!(iter.next(), None);
+}
+
+#[test]
+fn iter() {
+ let mut slab = Slab::new();
+
+ for i in 0..4 {
+ slab.insert(i);
+ }
+
+ let vals: Vec<_> = slab
+ .iter()
+ .enumerate()
+ .map(|(i, (key, val))| {
+ assert_eq!(i, key);
+ *val
+ })
+ .collect();
+ assert_eq!(vals, vec![0, 1, 2, 3]);
+
+ slab.remove(1);
+
+ let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect();
+ assert_eq!(vals, vec![0, 2, 3]);
+}
+
+#[test]
+fn iter_rev() {
+ let mut slab = Slab::new();
+
+ for i in 0..4 {
+ slab.insert(i);
+ }
+ slab.remove(0);
+
+ let vals = slab.iter().rev().collect::<Vec<_>>();
+ assert_eq!(vals, vec![(3, &3), (2, &2), (1, &1)]);
+}
+
+#[test]
+fn iter_mut() {
+ let mut slab = Slab::new();
+
+ for i in 0..4 {
+ slab.insert(i);
+ }
+
+ for (i, (key, e)) in slab.iter_mut().enumerate() {
+ assert_eq!(i, key);
+ *e += 1;
+ }
+
+ let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect();
+ assert_eq!(vals, vec![1, 2, 3, 4]);
+
+ slab.remove(2);
+
+ for (_, e) in slab.iter_mut() {
+ *e += 1;
+ }
+
+ let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect();
+ assert_eq!(vals, vec![2, 3, 5]);
+}
+
+#[test]
+fn iter_mut_rev() {
+ let mut slab = Slab::new();
+
+ for i in 0..4 {
+ slab.insert(i);
+ }
+ slab.remove(2);
+
+ {
+ let mut iter = slab.iter_mut();
+ assert_eq!(iter.next(), Some((0, &mut 0)));
+ let mut prev_key = !0;
+ for (key, e) in iter.rev() {
+ *e += 10;
+ assert!(prev_key > key);
+ prev_key = key;
+ }
+ }
+
+ assert_eq!(slab[0], 0);
+ assert_eq!(slab[1], 11);
+ assert_eq!(slab[3], 13);
+ assert!(!slab.contains(2));
+}
+
+#[test]
+fn from_iterator_sorted() {
+ let mut slab = (0..5).map(|i| (i, i)).collect::<Slab<_>>();
+ assert_eq!(slab.len(), 5);
+ assert_eq!(slab[0], 0);
+ assert_eq!(slab[2], 2);
+ assert_eq!(slab[4], 4);
+ assert_eq!(slab.vacant_entry().key(), 5);
+}
+
+#[test]
+fn from_iterator_new_in_order() {
+ // all new keys come in increasing order, but existing keys are overwritten
+ let mut slab = [(0, 'a'), (1, 'a'), (1, 'b'), (0, 'b'), (9, 'a'), (0, 'c')]
+ .iter()
+ .cloned()
+ .collect::<Slab<_>>();
+ assert_eq!(slab.len(), 3);
+ assert_eq!(slab[0], 'c');
+ assert_eq!(slab[1], 'b');
+ assert_eq!(slab[9], 'a');
+ assert_eq!(slab.get(5), None);
+ assert_eq!(slab.vacant_entry().key(), 8);
+}
+
+#[test]
+fn from_iterator_unordered() {
+ let mut slab = vec![(1, "one"), (50, "fifty"), (3, "three"), (20, "twenty")]
+ .into_iter()
+ .collect::<Slab<_>>();
+ assert_eq!(slab.len(), 4);
+ assert_eq!(slab.vacant_entry().key(), 0);
+ let mut iter = slab.iter();
+ assert_eq!(iter.next(), Some((1, &"one")));
+ assert_eq!(iter.next(), Some((3, &"three")));
+ assert_eq!(iter.next(), Some((20, &"twenty")));
+ assert_eq!(iter.next(), Some((50, &"fifty")));
+ assert_eq!(iter.next(), None);
+}
+
+// https://github.com/tokio-rs/slab/issues/100
+#[test]
+fn from_iterator_issue_100() {
+ let mut slab: slab::Slab<()> = vec![(1, ())].into_iter().collect();
+ assert_eq!(slab.len(), 1);
+ assert_eq!(slab.insert(()), 0);
+ assert_eq!(slab.insert(()), 2);
+ assert_eq!(slab.insert(()), 3);
+
+ let mut slab: slab::Slab<()> = vec![(1, ()), (2, ())].into_iter().collect();
+ assert_eq!(slab.len(), 2);
+ assert_eq!(slab.insert(()), 0);
+ assert_eq!(slab.insert(()), 3);
+ assert_eq!(slab.insert(()), 4);
+
+ let mut slab: slab::Slab<()> = vec![(1, ()), (3, ())].into_iter().collect();
+ assert_eq!(slab.len(), 2);
+ assert_eq!(slab.insert(()), 2);
+ assert_eq!(slab.insert(()), 0);
+ assert_eq!(slab.insert(()), 4);
+
+ let mut slab: slab::Slab<()> = vec![(0, ()), (2, ()), (3, ()), (5, ())]
+ .into_iter()
+ .collect();
+ assert_eq!(slab.len(), 4);
+ assert_eq!(slab.insert(()), 4);
+ assert_eq!(slab.insert(()), 1);
+ assert_eq!(slab.insert(()), 6);
+}
+
+#[test]
+fn clear() {
+ let mut slab = Slab::new();
+
+ for i in 0..4 {
+ slab.insert(i);
+ }
+
+ // clear full
+ slab.clear();
+ assert!(slab.is_empty());
+
+ assert_eq!(0, slab.len());
+ assert_eq!(4, slab.capacity());
+
+ for i in 0..2 {
+ slab.insert(i);
+ }
+
+ let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect();
+ assert_eq!(vals, vec![0, 1]);
+
+ // clear half-filled
+ slab.clear();
+ assert!(slab.is_empty());
+}
+
+#[test]
+fn shrink_to_fit_empty() {
+ let mut slab = Slab::<bool>::with_capacity(20);
+ slab.shrink_to_fit();
+ assert_eq!(slab.capacity(), 0);
+}
+
+#[test]
+fn shrink_to_fit_no_vacant() {
+ let mut slab = Slab::with_capacity(20);
+ slab.insert(String::new());
+ slab.shrink_to_fit();
+ assert!(slab.capacity() < 10);
+}
+
+#[test]
+fn shrink_to_fit_doesnt_move() {
+ let mut slab = Slab::with_capacity(8);
+ slab.insert("foo");
+ let bar = slab.insert("bar");
+ slab.insert("baz");
+ let quux = slab.insert("quux");
+ slab.remove(quux);
+ slab.remove(bar);
+ slab.shrink_to_fit();
+ assert_eq!(slab.len(), 2);
+ assert!(slab.capacity() >= 3);
+ assert_eq!(slab.get(0), Some(&"foo"));
+ assert_eq!(slab.get(2), Some(&"baz"));
+ assert_eq!(slab.vacant_entry().key(), bar);
+}
+
+#[test]
+fn shrink_to_fit_doesnt_recreate_list_when_nothing_can_be_done() {
+ let mut slab = Slab::with_capacity(16);
+ for i in 0..4 {
+ slab.insert(Box::new(i));
+ }
+ slab.remove(0);
+ slab.remove(2);
+ slab.remove(1);
+ assert_eq!(slab.vacant_entry().key(), 1);
+ slab.shrink_to_fit();
+ assert_eq!(slab.len(), 1);
+ assert!(slab.capacity() >= 4);
+ assert_eq!(slab.vacant_entry().key(), 1);
+}
+
+#[test]
+fn compact_empty() {
+ let mut slab = Slab::new();
+ slab.compact(|_, _, _| panic!());
+ assert_eq!(slab.len(), 0);
+ assert_eq!(slab.capacity(), 0);
+ slab.reserve(20);
+ slab.compact(|_, _, _| panic!());
+ assert_eq!(slab.len(), 0);
+ assert_eq!(slab.capacity(), 0);
+ slab.insert(0);
+ slab.insert(1);
+ slab.insert(2);
+ slab.remove(1);
+ slab.remove(2);
+ slab.remove(0);
+ slab.compact(|_, _, _| panic!());
+ assert_eq!(slab.len(), 0);
+ assert_eq!(slab.capacity(), 0);
+}
+
+#[test]
+fn compact_no_moves_needed() {
+ let mut slab = Slab::new();
+ for i in 0..10 {
+ slab.insert(i);
+ }
+ slab.remove(8);
+ slab.remove(9);
+ slab.remove(6);
+ slab.remove(7);
+ slab.compact(|_, _, _| panic!());
+ assert_eq!(slab.len(), 6);
+ for ((index, &value), want) in slab.iter().zip(0..6) {
+ assert!(index == value);
+ assert_eq!(index, want);
+ }
+ assert!(slab.capacity() >= 6 && slab.capacity() < 10);
+}
+
+#[test]
+fn compact_moves_successfully() {
+ let mut slab = Slab::with_capacity(20);
+ for i in 0..10 {
+ slab.insert(i);
+ }
+ for &i in &[0, 5, 9, 6, 3] {
+ slab.remove(i);
+ }
+ let mut moved = 0;
+ slab.compact(|&mut v, from, to| {
+ assert!(from > to);
+ assert!(from >= 5);
+ assert!(to < 5);
+ assert_eq!(from, v);
+ moved += 1;
+ true
+ });
+ assert_eq!(slab.len(), 5);
+ assert_eq!(moved, 2);
+ assert_eq!(slab.vacant_entry().key(), 5);
+ assert!(slab.capacity() >= 5 && slab.capacity() < 20);
+ let mut iter = slab.iter();
+ assert_eq!(iter.next(), Some((0, &8)));
+ assert_eq!(iter.next(), Some((1, &1)));
+ assert_eq!(iter.next(), Some((2, &2)));
+ assert_eq!(iter.next(), Some((3, &7)));
+ assert_eq!(iter.next(), Some((4, &4)));
+ assert_eq!(iter.next(), None);
+}
+
+#[test]
+fn compact_doesnt_move_if_closure_errors() {
+ let mut slab = Slab::with_capacity(20);
+ for i in 0..10 {
+ slab.insert(i);
+ }
+ for &i in &[9, 3, 1, 4, 0] {
+ slab.remove(i);
+ }
+ slab.compact(|&mut v, from, to| {
+ assert!(from > to);
+ assert_eq!(from, v);
+ v != 6
+ });
+ assert_eq!(slab.len(), 5);
+ assert!(slab.capacity() >= 7 && slab.capacity() < 20);
+ assert_eq!(slab.vacant_entry().key(), 3);
+ let mut iter = slab.iter();
+ assert_eq!(iter.next(), Some((0, &8)));
+ assert_eq!(iter.next(), Some((1, &7)));
+ assert_eq!(iter.next(), Some((2, &2)));
+ assert_eq!(iter.next(), Some((5, &5)));
+ assert_eq!(iter.next(), Some((6, &6)));
+ assert_eq!(iter.next(), None);
+}
+
+#[test]
+fn compact_handles_closure_panic() {
+ let mut slab = Slab::new();
+ for i in 0..10 {
+ slab.insert(i);
+ }
+ for i in 1..6 {
+ slab.remove(i);
+ }
+ let result = catch_unwind(AssertUnwindSafe(|| {
+ slab.compact(|&mut v, from, to| {
+ assert!(from > to);
+ assert_eq!(from, v);
+ if v == 7 {
+ panic!("test");
+ }
+ true
+ })
+ }));
+ match result {
+ Err(ref payload) if payload.downcast_ref() == Some(&"test") => {}
+ Err(bug) => resume_unwind(bug),
+ Ok(()) => unreachable!(),
+ }
+ assert_eq!(slab.len(), 5 - 1);
+ assert_eq!(slab.vacant_entry().key(), 3);
+ let mut iter = slab.iter();
+ assert_eq!(iter.next(), Some((0, &0)));
+ assert_eq!(iter.next(), Some((1, &9)));
+ assert_eq!(iter.next(), Some((2, &8)));
+ assert_eq!(iter.next(), Some((6, &6)));
+ assert_eq!(iter.next(), None);
+}
+
+#[test]
+fn fully_consumed_drain() {
+ let mut slab = Slab::new();
+
+ for i in 0..3 {
+ slab.insert(i);
+ }
+
+ {
+ let mut drain = slab.drain();
+ assert_eq!(Some(0), drain.next());
+ assert_eq!(Some(1), drain.next());
+ assert_eq!(Some(2), drain.next());
+ assert_eq!(None, drain.next());
+ }
+
+ assert!(slab.is_empty());
+}
+
+#[test]
+fn partially_consumed_drain() {
+ let mut slab = Slab::new();
+
+ for i in 0..3 {
+ slab.insert(i);
+ }
+
+ {
+ let mut drain = slab.drain();
+ assert_eq!(Some(0), drain.next());
+ }
+
+ assert!(slab.is_empty())
+}
+
+#[test]
+fn drain_rev() {
+ let mut slab = Slab::new();
+ for i in 0..10 {
+ slab.insert(i);
+ }
+ slab.remove(9);
+
+ let vals: Vec<u64> = slab.drain().rev().collect();
+ assert_eq!(vals, (0..9).rev().collect::<Vec<u64>>());
+}
+
+#[test]
+fn try_remove() {
+ let mut slab = Slab::new();
+
+ let key = slab.insert(1);
+
+ assert_eq!(slab.try_remove(key), Some(1));
+ assert_eq!(slab.try_remove(key), None);
+ assert_eq!(slab.get(key), None);
+}
+
+#[rustversion::since(1.39)]
+#[test]
+fn const_new() {
+ static _SLAB: Slab<()> = Slab::new();
+}