diff options
Diffstat (limited to 'third_party/rust/hashlink/tests')
-rw-r--r-- | third_party/rust/hashlink/tests/linked_hash_map.rs | 563 | ||||
-rw-r--r-- | third_party/rust/hashlink/tests/linked_hash_set.rs | 543 | ||||
-rw-r--r-- | third_party/rust/hashlink/tests/lru_cache.rs | 166 | ||||
-rw-r--r-- | third_party/rust/hashlink/tests/serde.rs | 108 |
4 files changed, 1380 insertions, 0 deletions
diff --git a/third_party/rust/hashlink/tests/linked_hash_map.rs b/third_party/rust/hashlink/tests/linked_hash_map.rs new file mode 100644 index 0000000000..e04629275e --- /dev/null +++ b/third_party/rust/hashlink/tests/linked_hash_map.rs @@ -0,0 +1,563 @@ +use hashlink::{linked_hash_map, LinkedHashMap}; + +#[allow(dead_code)] +fn assert_covariance() { + fn set<'new>(v: LinkedHashMap<&'static str, ()>) -> LinkedHashMap<&'new str, ()> { + v + } + + fn iter<'a, 'new>( + v: linked_hash_map::Iter<'a, &'static str, &'static str>, + ) -> linked_hash_map::Iter<'a, &'new str, &'new str> { + v + } + + fn iter_mut<'a, 'new>( + v: linked_hash_map::Iter<'a, &'static str, ()>, + ) -> linked_hash_map::Iter<'a, &'new str, ()> { + v + } + + fn into_iter<'new>( + v: linked_hash_map::IntoIter<&'static str, &'static str>, + ) -> linked_hash_map::IntoIter<&'new str, &'new str> { + v + } + + fn drain<'new>( + d: linked_hash_map::Drain<'static, &'static str, &'static str>, + ) -> linked_hash_map::Drain<'new, &'new str, &'new str> { + d + } + + fn raw_entry_builder<'a, 'new>( + v: linked_hash_map::RawEntryBuilder<'a, &'static str, &'static str, ()>, + ) -> linked_hash_map::RawEntryBuilder<'a, &'new str, &'new str, ()> { + v + } +} + +#[test] +fn test_index() { + let mut map = LinkedHashMap::new(); + map.insert(1, 10); + map.insert(2, 20); + assert_eq!(10, map[&1]); + map[&2] = 22; + assert_eq!(22, map[&2]); +} + +#[test] +fn test_insert_and_get() { + let mut map = LinkedHashMap::new(); + map.insert(1, 10); + map.insert(2, 20); + assert_eq!(map.get(&1), Some(&10)); + assert_eq!(map.get(&2), Some(&20)); + assert_eq!(map.len(), 2); +} + +#[test] +fn test_insert_update() { + let mut map = LinkedHashMap::new(); + map.insert("1".to_string(), vec![10, 10]); + map.insert("1".to_string(), vec![10, 19]); + assert_eq!(map.get(&"1".to_string()), Some(&vec![10, 19])); + assert_eq!(map.len(), 1); +} + +#[test] +fn test_entry_insert_vacant() { + let mut map = LinkedHashMap::new(); + match map.entry("1".to_string()) { + linked_hash_map::Entry::Vacant(e) => { + assert_eq!(*e.insert(vec![10, 10]), vec![10, 10]); + } + _ => panic!("fail"), + } + assert!(map.contains_key("1")); + assert_eq!(map["1"], vec![10, 10]); + + match map.entry("1".to_string()) { + linked_hash_map::Entry::Occupied(mut e) => { + assert_eq!(*e.get(), vec![10, 10]); + assert_eq!(e.insert(vec![10, 16]), vec![10, 10]); + } + _ => panic!("fail"), + } + + assert!(map.contains_key("1")); + assert_eq!(map["1"], vec![10, 16]); + + match map.entry("1".to_string()) { + linked_hash_map::Entry::Occupied(e) => { + assert_eq!(e.remove(), vec![10, 16]); + } + _ => panic!("fail"), + } +} + +#[test] +fn test_remove() { + let mut map = LinkedHashMap::new(); + map.insert(1, 10); + map.insert(2, 20); + map.insert(3, 30); + map.insert(4, 40); + map.insert(5, 50); + map.remove(&3); + map.remove(&4); + assert!(map.get(&3).is_none()); + assert!(map.get(&4).is_none()); + map.insert(6, 60); + map.insert(7, 70); + map.insert(8, 80); + assert_eq!(map.get(&6), Some(&60)); + assert_eq!(map.get(&7), Some(&70)); + assert_eq!(map.get(&8), Some(&80)); +} + +#[test] +fn test_pop() { + let mut map = LinkedHashMap::new(); + map.insert(1, 10); + map.insert(2, 20); + map.insert(3, 30); + map.insert(4, 40); + map.insert(5, 50); + assert_eq!(map.pop_front(), Some((1, 10))); + assert!(map.get(&1).is_none()); + assert_eq!(map.pop_back(), Some((5, 50))); + assert!(map.get(&5).is_none()); + map.insert(6, 60); + map.insert(7, 70); + map.insert(8, 80); + assert_eq!(map.pop_front(), Some((2, 20))); + assert!(map.get(&2).is_none()); + assert_eq!(map.pop_back(), Some((8, 80))); + assert!(map.get(&8).is_none()); + map.insert(3, 30); + assert_eq!(map.pop_front(), Some((4, 40))); + assert!(map.get(&4).is_none()); + assert_eq!(map.pop_back(), Some((3, 30))); + assert!(map.get(&3).is_none()); +} + +#[test] +fn test_move() { + let to_back = |map: &mut LinkedHashMap<_, _>, key| match map.entry(key) { + linked_hash_map::Entry::Occupied(mut occupied) => occupied.to_back(), + linked_hash_map::Entry::Vacant(_) => panic!(), + }; + + let to_front = |map: &mut LinkedHashMap<_, _>, key| match map.entry(key) { + linked_hash_map::Entry::Occupied(mut occupied) => occupied.to_front(), + linked_hash_map::Entry::Vacant(_) => panic!(), + }; + + let mut map = LinkedHashMap::new(); + map.insert(1, 10); + map.insert(2, 20); + map.insert(3, 30); + map.insert(4, 40); + map.insert(5, 50); + + to_back(&mut map, 1); + assert_eq!(map.keys().copied().collect::<Vec<_>>(), vec![2, 3, 4, 5, 1]); + + to_front(&mut map, 4); + assert_eq!(map.keys().copied().collect::<Vec<_>>(), vec![4, 2, 3, 5, 1]); + + to_back(&mut map, 3); + assert_eq!(map.keys().copied().collect::<Vec<_>>(), vec![4, 2, 5, 1, 3]); + + to_front(&mut map, 2); + assert_eq!(map.keys().copied().collect::<Vec<_>>(), vec![2, 4, 5, 1, 3]); + + to_back(&mut map, 3); + assert_eq!(map.keys().copied().collect::<Vec<_>>(), vec![2, 4, 5, 1, 3]); + + to_front(&mut map, 2); + assert_eq!(map.keys().copied().collect::<Vec<_>>(), vec![2, 4, 5, 1, 3]); +} + +#[test] +fn test_clear() { + let mut map = LinkedHashMap::new(); + map.insert(1, 10); + map.insert(2, 20); + map.clear(); + assert!(map.get(&1).is_none()); + assert!(map.get(&2).is_none()); + assert!(map.is_empty()); +} + +#[test] +fn test_iter() { + let mut map = LinkedHashMap::new(); + + // empty iter + assert_eq!(None, map.iter().next()); + + map.insert("a", 10); + map.insert("b", 20); + map.insert("c", 30); + + // regular iter + let mut iter = map.iter(); + assert_eq!((&"a", &10), iter.next().unwrap()); + assert_eq!((&"b", &20), iter.next().unwrap()); + assert_eq!((&"c", &30), iter.next().unwrap()); + assert_eq!(None, iter.next()); + assert_eq!(None, iter.next()); + + let mut iter = map.iter(); + assert_eq!((&"a", &10), iter.next().unwrap()); + let mut iclone = iter.clone(); + assert_eq!((&"b", &20), iter.next().unwrap()); + assert_eq!((&"b", &20), iclone.next().unwrap()); + assert_eq!((&"c", &30), iter.next().unwrap()); + assert_eq!((&"c", &30), iclone.next().unwrap()); + + // reversed iter + let mut rev_iter = map.iter().rev(); + assert_eq!((&"c", &30), rev_iter.next().unwrap()); + assert_eq!((&"b", &20), rev_iter.next().unwrap()); + assert_eq!((&"a", &10), rev_iter.next().unwrap()); + assert_eq!(None, rev_iter.next()); + assert_eq!(None, rev_iter.next()); + + // mixed + let mut mixed_iter = map.iter(); + assert_eq!((&"a", &10), mixed_iter.next().unwrap()); + assert_eq!((&"c", &30), mixed_iter.next_back().unwrap()); + assert_eq!((&"b", &20), mixed_iter.next().unwrap()); + assert_eq!(None, mixed_iter.next()); + assert_eq!(None, mixed_iter.next_back()); +} + +#[test] +fn test_borrow() { + #[derive(PartialEq, Eq, Hash)] + struct Foo(Bar); + #[derive(PartialEq, Eq, Hash)] + struct Bar(i32); + + impl ::std::borrow::Borrow<Bar> for Foo { + fn borrow(&self) -> &Bar { + &self.0 + } + } + + let mut map = LinkedHashMap::new(); + map.insert(Foo(Bar(1)), "a"); + map.insert(Foo(Bar(2)), "b"); + + assert!(map.contains_key(&Bar(1))); + assert!(map.contains_key(&Bar(2))); + assert!(map.contains_key(&Foo(Bar(1)))); + assert!(map.contains_key(&Foo(Bar(2)))); + + assert_eq!(map.get(&Bar(1)), Some(&"a")); + assert_eq!(map.get(&Bar(2)), Some(&"b")); + assert_eq!(map.get(&Foo(Bar(1))), Some(&"a")); + assert_eq!(map.get(&Foo(Bar(2))), Some(&"b")); + + assert_eq!(map.get_mut(&Bar(1)), Some(&mut "a")); + assert_eq!(map.get_mut(&Bar(2)), Some(&mut "b")); + assert_eq!(map.get_mut(&Foo(Bar(1))), Some(&mut "a")); + assert_eq!(map.get_mut(&Foo(Bar(2))), Some(&mut "b")); + + assert_eq!(map[&Bar(1)], "a"); + assert_eq!(map[&Bar(2)], "b"); + assert_eq!(map[&Foo(Bar(1))], "a"); + assert_eq!(map[&Foo(Bar(2))], "b"); + + assert_eq!(map.remove(&Bar(1)), Some("a")); + assert_eq!(map.remove(&Bar(2)), Some("b")); + assert_eq!(map.remove(&Foo(Bar(1))), None); + assert_eq!(map.remove(&Foo(Bar(2))), None); +} + +#[test] +fn test_iter_mut() { + let mut map = LinkedHashMap::new(); + map.insert("a", 10); + map.insert("c", 30); + map.insert("b", 20); + + { + let mut iter = map.iter_mut(); + let entry = iter.next().unwrap(); + assert_eq!("a", *entry.0); + *entry.1 = 17; + + assert_eq!(format!("{:?}", iter), "[(\"c\", 30), (\"b\", 20)]"); + + // reverse iterator + let mut iter = iter.rev(); + let entry = iter.next().unwrap(); + assert_eq!("b", *entry.0); + *entry.1 = 23; + + let entry = iter.next().unwrap(); + assert_eq!("c", *entry.0); + assert_eq!(None, iter.next()); + assert_eq!(None, iter.next()); + } + + assert_eq!(17, map[&"a"]); + assert_eq!(23, map[&"b"]); +} + +#[test] +fn test_consuming_iter() { + let map = { + let mut map = LinkedHashMap::new(); + map.insert("a", 10); + map.insert("c", 30); + map.insert("b", 20); + map + }; + + let mut iter = map.into_iter(); + assert_eq!(Some(("a", 10)), iter.next()); + assert_eq!(Some(("b", 20)), iter.next_back()); + assert_eq!(iter.len(), 1); + assert_eq!(format!("{:?}", iter), "[(\"c\", 30)]"); + assert_eq!(Some(("c", 30)), iter.next()); + assert_eq!(None, iter.next()); +} + +#[test] +fn test_consuming_iter_empty() { + let map = LinkedHashMap::<&str, i32>::new(); + let mut iter = map.into_iter(); + assert_eq!(None, iter.next()); +} + +#[test] +fn test_consuming_iter_with_free_list() { + let mut map = LinkedHashMap::new(); + map.insert("a", 10); + map.insert("c", 30); + map.insert("b", 20); + map.remove("a"); + map.remove("b"); + + let mut iter = map.into_iter(); + assert_eq!(Some(("c", 30)), iter.next()); + assert_eq!(None, iter.next()); +} + +#[test] +fn test_into_iter_drop() { + struct Counter<'a>(&'a mut usize); + + impl<'a> Drop for Counter<'a> { + fn drop(&mut self) { + *self.0 += 1; + } + } + + let mut a = 0; + let mut b = 0; + let mut c = 0; + + { + let mut map = LinkedHashMap::new(); + map.insert("a", Counter(&mut a)); + map.insert("b", Counter(&mut b)); + map.insert("c", Counter(&mut c)); + + let mut iter = map.into_iter(); + assert_eq!(iter.next().map(|p| p.0), Some("a")); + assert_eq!(iter.next_back().map(|p| p.0), Some("c")); + } + + assert_eq!(a, 1); + assert_eq!(b, 1); + assert_eq!(c, 1); +} + +#[test] +fn test_drain() { + use std::{cell::Cell, rc::Rc}; + + struct Counter(Rc<Cell<u32>>); + + impl<'a> Drop for Counter { + fn drop(&mut self) { + self.0.set(self.0.get() + 1); + } + } + + let mut map = LinkedHashMap::new(); + + let a = Rc::new(Cell::new(0)); + let b = Rc::new(Cell::new(0)); + let c = Rc::new(Cell::new(0)); + + map.insert("a", Counter(a.clone())); + map.insert("b", Counter(b.clone())); + map.insert("c", Counter(c.clone())); + + let mut iter = map.drain(); + assert_eq!(iter.next().map(|p| p.0), Some("a")); + assert_eq!(iter.next_back().map(|p| p.0), Some("c")); + assert_eq!(iter.next_back().map(|p| p.0), Some("b")); + assert!(iter.next().is_none()); + assert!(iter.next_back().is_none()); + + drop(iter); + assert_eq!(map.len(), 0); + + assert_eq!(a.get(), 1); + assert_eq!(b.get(), 1); + assert_eq!(c.get(), 1); + + map.insert("a", Counter(a.clone())); + map.insert("b", Counter(b.clone())); + map.insert("c", Counter(c.clone())); + + let mut iter = map.drain(); + assert_eq!(iter.next().map(|p| p.0), Some("a")); + assert_eq!(iter.next().map(|p| p.0), Some("b")); + assert_eq!(iter.next_back().map(|p| p.0), Some("c")); + assert!(iter.next().is_none()); + assert!(iter.next_back().is_none()); + + drop(iter); + assert_eq!(map.len(), 0); + + assert_eq!(a.get(), 2); + assert_eq!(b.get(), 2); + assert_eq!(c.get(), 2); + + map.insert("a", Counter(a.clone())); + map.insert("b", Counter(b.clone())); + map.insert("c", Counter(c.clone())); + + map.drain(); + assert_eq!(map.len(), 0); + + assert_eq!(a.get(), 3); + assert_eq!(b.get(), 3); + assert_eq!(c.get(), 3); +} + +#[test] +fn test_send_sync() { + fn is_send_sync<T: Send + Sync>() {} + + is_send_sync::<LinkedHashMap<u32, i32>>(); + is_send_sync::<linked_hash_map::Entry<u32, i32, ()>>(); + is_send_sync::<linked_hash_map::RawEntryBuilder<u32, i32, ()>>(); + is_send_sync::<linked_hash_map::RawEntryBuilderMut<u32, i32, ()>>(); + is_send_sync::<linked_hash_map::RawEntryMut<u32, i32, ()>>(); + is_send_sync::<linked_hash_map::Iter<u32, i32>>(); + is_send_sync::<linked_hash_map::IterMut<u32, i32>>(); + is_send_sync::<linked_hash_map::Drain<u32, i32>>(); + is_send_sync::<linked_hash_map::Keys<u32, i32>>(); + is_send_sync::<linked_hash_map::Values<u32, i32>>(); +} + +#[test] +fn test_retain() { + use std::{cell::Cell, rc::Rc}; + + let xs = [1, 2, 3, 4, 5, 6]; + let mut map: LinkedHashMap<String, i32> = xs.iter().map(|i| (i.to_string(), *i)).collect(); + map.retain(|_, v| *v % 2 == 0); + assert_eq!(map.len(), 3); + assert!(map.contains_key("2")); + assert!(map.contains_key("4")); + assert!(map.contains_key("6")); + + struct Counter(Rc<Cell<u32>>); + + impl<'a> Drop for Counter { + fn drop(&mut self) { + self.0.set(self.0.get() + 1); + } + } + + let c = Rc::new(Cell::new(0)); + + let mut map = LinkedHashMap::new(); + map.insert(1, Counter(Rc::clone(&c))); + map.insert(2, Counter(Rc::clone(&c))); + map.insert(3, Counter(Rc::clone(&c))); + map.insert(4, Counter(Rc::clone(&c))); + + map.retain(|k, _| *k % 2 == 0); + + assert!(c.get() == 2); + drop(map); + assert!(c.get() == 4); +} + +#[test] +fn test_order_equality() { + let xs = [1, 2, 3, 4, 5, 6]; + let mut map1: LinkedHashMap<String, i32> = xs.iter().map(|i| (i.to_string(), *i)).collect(); + let mut map2: LinkedHashMap<String, i32> = xs.iter().map(|i| (i.to_string(), *i)).collect(); + + assert_eq!(map1, map2); + + map1.to_front("4"); + assert_ne!(map1, map2); + + map2.to_front("4"); + assert_eq!(map1, map2); +} + +#[test] +fn test_replace() { + let mut map = LinkedHashMap::new(); + + map.insert(1, 1); + map.insert(2, 2); + map.insert(3, 3); + map.insert(4, 4); + + assert!(map + .iter() + .map(|(k, v)| (*k, *v)) + .eq([(1, 1), (2, 2), (3, 3), (4, 4)].iter().copied())); + + map.insert(3, 5); + + assert!(map + .iter() + .map(|(k, v)| (*k, *v)) + .eq([(1, 1), (2, 2), (4, 4), (3, 5)].iter().copied())); + + map.replace(2, 6); + + assert!(map + .iter() + .map(|(k, v)| (*k, *v)) + .eq([(1, 1), (2, 6), (4, 4), (3, 5)].iter().copied())); +} + +#[test] +fn test_shrink_to_fit_resize() { + let mut map = LinkedHashMap::new(); + map.shrink_to_fit(); + + for i in 0..100 { + map.insert(i, i); + } + map.shrink_to_fit(); + + for _ in 0..50 { + map.pop_front(); + map.shrink_to_fit(); + } + + assert_eq!(map.len(), 50); + for i in 50..100 { + assert_eq!(map.get(&i).unwrap(), &i); + } +} diff --git a/third_party/rust/hashlink/tests/linked_hash_set.rs b/third_party/rust/hashlink/tests/linked_hash_set.rs new file mode 100644 index 0000000000..7a9e33f90d --- /dev/null +++ b/third_party/rust/hashlink/tests/linked_hash_set.rs @@ -0,0 +1,543 @@ +use hashbrown::hash_map::DefaultHashBuilder; +use hashlink::linked_hash_set::{self, LinkedHashSet}; + +#[allow(dead_code)] +fn assert_covariance() { + fn set<'new>(v: LinkedHashSet<&'static str>) -> LinkedHashSet<&'new str> { + v + } + + fn iter<'a, 'new>( + v: linked_hash_set::Iter<'a, &'static str>, + ) -> linked_hash_set::Iter<'a, &'new str> { + v + } + + fn into_iter<'new>( + v: linked_hash_set::IntoIter<&'static str>, + ) -> linked_hash_set::IntoIter<&'new str> { + v + } + + fn difference<'a, 'new>( + v: linked_hash_set::Difference<'a, &'static str, DefaultHashBuilder>, + ) -> linked_hash_set::Difference<'a, &'new str, DefaultHashBuilder> { + v + } + + fn symmetric_difference<'a, 'new>( + v: linked_hash_set::SymmetricDifference<'a, &'static str, DefaultHashBuilder>, + ) -> linked_hash_set::SymmetricDifference<'a, &'new str, DefaultHashBuilder> { + v + } + + fn intersection<'a, 'new>( + v: linked_hash_set::Intersection<'a, &'static str, DefaultHashBuilder>, + ) -> linked_hash_set::Intersection<'a, &'new str, DefaultHashBuilder> { + v + } + + fn union<'a, 'new>( + v: linked_hash_set::Union<'a, &'static str, DefaultHashBuilder>, + ) -> linked_hash_set::Union<'a, &'new str, DefaultHashBuilder> { + v + } + + fn drain<'new>( + d: linked_hash_set::Drain<'static, &'static str>, + ) -> linked_hash_set::Drain<'new, &'new str> { + d + } +} + +#[test] +fn test_zero_capacities() { + type HS = LinkedHashSet<i32>; + + let s = HS::new(); + assert_eq!(s.capacity(), 0); + + let s = HS::default(); + assert_eq!(s.capacity(), 0); + + let s = HS::with_hasher(DefaultHashBuilder::default()); + assert_eq!(s.capacity(), 0); + + let s = HS::with_capacity(0); + assert_eq!(s.capacity(), 0); + + let s = HS::with_capacity_and_hasher(0, DefaultHashBuilder::default()); + assert_eq!(s.capacity(), 0); + + let mut s = HS::new(); + s.insert(1); + s.insert(2); + s.remove(&1); + s.remove(&2); + s.shrink_to_fit(); + assert_eq!(s.capacity(), 0); + + let mut s = HS::new(); + s.reserve(0); + assert_eq!(s.capacity(), 0); +} + +#[test] +fn test_disjoint() { + let mut xs = LinkedHashSet::new(); + let mut ys = LinkedHashSet::new(); + assert!(xs.is_disjoint(&ys)); + assert!(ys.is_disjoint(&xs)); + assert!(xs.insert(5)); + assert!(ys.insert(11)); + assert!(xs.is_disjoint(&ys)); + assert!(ys.is_disjoint(&xs)); + assert!(xs.insert(7)); + assert!(xs.insert(19)); + assert!(xs.insert(4)); + assert!(ys.insert(2)); + assert!(ys.insert(-11)); + assert!(xs.is_disjoint(&ys)); + assert!(ys.is_disjoint(&xs)); + assert!(ys.insert(7)); + assert!(!xs.is_disjoint(&ys)); + assert!(!ys.is_disjoint(&xs)); +} + +#[test] +fn test_subset_and_superset() { + let mut a = LinkedHashSet::new(); + assert!(a.insert(0)); + assert!(a.insert(5)); + assert!(a.insert(11)); + assert!(a.insert(7)); + + let mut b = LinkedHashSet::new(); + assert!(b.insert(0)); + assert!(b.insert(7)); + assert!(b.insert(19)); + assert!(b.insert(250)); + assert!(b.insert(11)); + assert!(b.insert(200)); + + assert!(!a.is_subset(&b)); + assert!(!a.is_superset(&b)); + assert!(!b.is_subset(&a)); + assert!(!b.is_superset(&a)); + + assert!(b.insert(5)); + + assert!(a.is_subset(&b)); + assert!(!a.is_superset(&b)); + assert!(!b.is_subset(&a)); + assert!(b.is_superset(&a)); +} + +#[test] +fn test_iterate() { + let mut a = LinkedHashSet::new(); + for i in 0..32 { + assert!(a.insert(i)); + } + let mut observed: u32 = 0; + for k in &a { + observed |= 1 << *k; + } + assert_eq!(observed, 0xFFFF_FFFF); +} + +#[test] +fn test_intersection() { + let mut a = LinkedHashSet::new(); + let mut b = LinkedHashSet::new(); + + assert!(a.insert(11)); + assert!(a.insert(1)); + assert!(a.insert(3)); + assert!(a.insert(77)); + assert!(a.insert(103)); + assert!(a.insert(5)); + assert!(a.insert(-5)); + + assert!(b.insert(2)); + assert!(b.insert(11)); + assert!(b.insert(77)); + assert!(b.insert(-9)); + assert!(b.insert(-42)); + assert!(b.insert(5)); + assert!(b.insert(3)); + + let mut i = 0; + let expected = [3, 5, 11, 77]; + for x in a.intersection(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); +} + +#[test] +fn test_difference() { + let mut a = LinkedHashSet::new(); + let mut b = LinkedHashSet::new(); + + assert!(a.insert(1)); + assert!(a.insert(3)); + assert!(a.insert(5)); + assert!(a.insert(9)); + assert!(a.insert(11)); + + assert!(b.insert(3)); + assert!(b.insert(9)); + + let mut i = 0; + let expected = [1, 5, 11]; + for x in a.difference(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); +} + +#[test] +fn test_symmetric_difference() { + let mut a = LinkedHashSet::new(); + let mut b = LinkedHashSet::new(); + + assert!(a.insert(1)); + assert!(a.insert(3)); + assert!(a.insert(5)); + assert!(a.insert(9)); + assert!(a.insert(11)); + + assert!(b.insert(-2)); + assert!(b.insert(3)); + assert!(b.insert(9)); + assert!(b.insert(14)); + assert!(b.insert(22)); + + let mut i = 0; + let expected = [-2, 1, 5, 11, 14, 22]; + for x in a.symmetric_difference(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); +} + +#[test] +fn test_union() { + let mut a = LinkedHashSet::new(); + let mut b = LinkedHashSet::new(); + + assert!(a.insert(1)); + assert!(a.insert(3)); + assert!(a.insert(5)); + assert!(a.insert(9)); + assert!(a.insert(11)); + assert!(a.insert(16)); + assert!(a.insert(19)); + assert!(a.insert(24)); + + assert!(b.insert(-2)); + assert!(b.insert(1)); + assert!(b.insert(5)); + assert!(b.insert(9)); + assert!(b.insert(13)); + assert!(b.insert(19)); + + let mut i = 0; + let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]; + for x in a.union(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); +} + +#[test] +fn test_from_iter() { + let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + + let set: LinkedHashSet<_> = xs.iter().cloned().collect(); + + for x in &xs { + assert!(set.contains(x)); + } +} + +#[test] +fn test_move_iter() { + let hs = { + let mut hs = LinkedHashSet::new(); + + hs.insert('a'); + hs.insert('b'); + + hs + }; + + let v = hs.into_iter().collect::<Vec<char>>(); + assert!(v == ['a', 'b'] || v == ['b', 'a']); +} + +#[test] +fn test_eq() { + let mut s1 = LinkedHashSet::new(); + + s1.insert(1); + s1.insert(2); + s1.insert(3); + + let mut s2 = LinkedHashSet::new(); + + s2.insert(1); + s2.insert(2); + + assert!(s1 != s2); + + s2.insert(3); + + assert_eq!(s1, s2); +} + +#[test] +fn test_show() { + let mut set = LinkedHashSet::new(); + let empty = LinkedHashSet::<i32>::new(); + + set.insert(1); + set.insert(2); + + let set_str = format!("{:?}", set); + + assert!(set_str == "{1, 2}" || set_str == "{2, 1}"); + assert_eq!(format!("{:?}", empty), "{}"); +} + +#[test] +fn test_trivial_drain() { + let mut s = LinkedHashSet::<i32>::new(); + for _ in s.drain() {} + assert!(s.is_empty()); + drop(s); + + let mut s = LinkedHashSet::<i32>::new(); + drop(s.drain()); + assert!(s.is_empty()); +} + +#[test] +fn test_drain() { + let mut s: LinkedHashSet<_> = (1..100).collect(); + + for _ in 0..20 { + assert_eq!(s.len(), 99); + + { + let mut last_i = 0; + let mut d = s.drain(); + for (i, x) in d.by_ref().take(50).enumerate() { + last_i = i; + assert!(x != 0); + } + assert_eq!(last_i, 49); + } + + for _ in &s { + panic!("s should be empty!"); + } + + s.extend(1..100); + } +} + +#[test] +fn test_replace() { + use core::hash; + + #[derive(Debug)] + struct Foo(&'static str, i32); + + impl PartialEq for Foo { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } + } + + impl Eq for Foo {} + + impl hash::Hash for Foo { + fn hash<H: hash::Hasher>(&self, h: &mut H) { + self.0.hash(h); + } + } + + let mut s = LinkedHashSet::new(); + assert_eq!(s.replace(Foo("a", 1)), None); + assert_eq!(s.len(), 1); + assert_eq!(s.replace(Foo("a", 2)), Some(Foo("a", 1))); + assert_eq!(s.len(), 1); + + let mut it = s.iter(); + assert_eq!(it.next(), Some(&Foo("a", 2))); + assert_eq!(it.next(), None); +} + +#[test] +fn test_extend_ref() { + let mut a = LinkedHashSet::new(); + a.insert(1); + + a.extend(&[2, 3, 4]); + + assert_eq!(a.len(), 4); + assert!(a.contains(&1)); + assert!(a.contains(&2)); + assert!(a.contains(&3)); + assert!(a.contains(&4)); + + let mut b = LinkedHashSet::new(); + b.insert(5); + b.insert(6); + + a.extend(&b); + + assert_eq!(a.len(), 6); + assert!(a.contains(&1)); + assert!(a.contains(&2)); + assert!(a.contains(&3)); + assert!(a.contains(&4)); + assert!(a.contains(&5)); + assert!(a.contains(&6)); +} + +#[test] +fn test_retain() { + let xs = [1, 2, 3, 4, 5, 6]; + let mut set: LinkedHashSet<i32> = xs.iter().cloned().collect(); + set.retain(|&k| k % 2 == 0); + assert_eq!(set.len(), 3); + assert!(set.contains(&2)); + assert!(set.contains(&4)); + assert!(set.contains(&6)); +} + +#[test] +fn test_retain_with_order() { + let xs = [1, 2, 3, 4, 5, 6]; + let mut set: LinkedHashSet<i32> = xs.iter().cloned().collect(); + let mut vec = Vec::new(); + set.retain_with_order(|&k| { + if k % 2 == 0 { + true + } else { + vec.push(k); + false + } + }); + assert_eq!(vec![1, 3, 5], vec); +} + +#[test] +fn insert_order() { + let mut set = LinkedHashSet::new(); + set.insert(1); + set.insert(2); + set.insert(3); + set.insert(4); + assert_eq!( + set.clone().into_iter().collect::<Vec<_>>(), + vec![1, 2, 3, 4] + ); + assert_eq!(set.into_iter().collect::<Vec<_>>(), vec![1, 2, 3, 4]); +} + +#[test] +fn front_back() { + let mut set = LinkedHashSet::new(); + set.insert(1); + set.insert(2); + set.insert(3); + set.insert(4); + assert_eq!(set.front(), Some(&1)); + assert_eq!(set.back(), Some(&4)); + assert_eq!(set.pop_back(), Some(4)); + assert_eq!(set.back(), Some(&3)); + assert_eq!(set.pop_front(), Some(1)); + assert_eq!(set.front(), Some(&2)); +} + +#[test] +fn double_ended_iter() { + let mut set = LinkedHashSet::new(); + set.insert(1); + set.insert(2); + set.insert(3); + set.insert(4); + + let mut iter = set.iter(); + assert_eq!(iter.next(), Some(&1)); + assert_eq!(iter.next(), Some(&2)); + assert_eq!(iter.next_back(), Some(&4)); + assert_eq!(iter.next_back(), Some(&3)); + assert_eq!(iter.next_back(), None); + assert_eq!(iter.next(), None); + assert_eq!(iter.next_back(), None); + drop(iter); + + let mut iter = set.drain(); + assert_eq!(iter.next(), Some(1)); + assert_eq!(iter.next(), Some(2)); + assert_eq!(iter.next_back(), Some(4)); + assert_eq!(iter.next_back(), Some(3)); + assert_eq!(iter.next_back(), None); + assert_eq!(iter.next(), None); + assert_eq!(iter.next_back(), None); + drop(iter); + + set.insert(1); + set.insert(2); + set.insert(3); + set.insert(4); + + let mut iter = set.into_iter(); + assert_eq!(iter.next(), Some(1)); + assert_eq!(iter.next(), Some(2)); + assert_eq!(iter.next_back(), Some(4)); + assert_eq!(iter.next_back(), Some(3)); + assert_eq!(iter.next_back(), None); + assert_eq!(iter.next(), None); + assert_eq!(iter.next_back(), None); +} + +#[test] +fn to_back_front_order() { + let mut set = LinkedHashSet::new(); + set.insert(1); + set.insert(2); + set.insert(3); + set.insert(4); + + assert_eq!(set.back().copied(), Some(4)); + assert_eq!(set.front().copied(), Some(1)); + set.to_back(&2); + assert_eq!(set.back().copied(), Some(2)); + set.to_front(&3); + assert_eq!(set.front().copied(), Some(3)); +} + +#[test] +fn test_order_equality() { + let xs = [1, 2, 3, 4, 5, 6]; + let mut set1: LinkedHashSet<i32> = xs.iter().copied().collect(); + let mut set2: LinkedHashSet<i32> = xs.iter().copied().collect(); + + assert_eq!(set1, set2); + + set1.to_front(&4); + assert_ne!(set1, set2); + + set2.to_front(&4); + assert_eq!(set1, set2); +} diff --git a/third_party/rust/hashlink/tests/lru_cache.rs b/third_party/rust/hashlink/tests/lru_cache.rs new file mode 100644 index 0000000000..f863c70e9c --- /dev/null +++ b/third_party/rust/hashlink/tests/lru_cache.rs @@ -0,0 +1,166 @@ +use hashlink::LruCache; + +#[test] +fn test_put_and_get() { + let mut cache = LruCache::new(2); + cache.insert(1, 10); + cache.insert(2, 20); + assert_eq!(cache.get_mut(&1), Some(&mut 10)); + assert_eq!(cache.get_mut(&2), Some(&mut 20)); + assert_eq!(cache.len(), 2); +} + +#[test] +fn test_put_update() { + let mut cache = LruCache::new(1); + cache.insert("1", 10); + cache.insert("1", 19); + assert_eq!(cache.get_mut("1"), Some(&mut 19)); + assert_eq!(cache.len(), 1); +} + +#[test] +fn test_contains_key() { + let mut cache = LruCache::new(1); + cache.insert("1", 10); + assert_eq!(cache.contains_key("1"), true); +} + +#[test] +fn test_expire_lru() { + let mut cache = LruCache::new(2); + cache.insert("foo1", "bar1"); + cache.insert("foo2", "bar2"); + cache.insert("foo3", "bar3"); + assert!(cache.get_mut("foo1").is_none()); + cache.insert("foo2", "bar2update"); + cache.insert("foo4", "bar4"); + assert!(cache.get_mut("foo3").is_none()); +} + +#[test] +fn test_pop() { + let mut cache = LruCache::new(2); + cache.insert(1, 10); + cache.insert(2, 20); + assert_eq!(cache.len(), 2); + let opt1 = cache.remove(&1); + assert!(opt1.is_some()); + assert_eq!(opt1.unwrap(), 10); + assert!(cache.get_mut(&1).is_none()); + assert_eq!(cache.len(), 1); +} + +#[test] +fn test_change_capacity() { + let mut cache = LruCache::new(2); + assert_eq!(cache.capacity(), 2); + cache.insert(1, 10); + cache.insert(2, 20); + cache.set_capacity(1); + assert!(cache.get_mut(&1).is_none()); + assert_eq!(cache.capacity(), 1); +} + +#[test] +fn test_remove() { + let mut cache = LruCache::new(3); + cache.insert(1, 10); + cache.insert(2, 20); + cache.insert(3, 30); + cache.insert(4, 40); + cache.insert(5, 50); + cache.remove(&3); + cache.remove(&4); + assert!(cache.get_mut(&3).is_none()); + assert!(cache.get_mut(&4).is_none()); + cache.insert(6, 60); + cache.insert(7, 70); + cache.insert(8, 80); + assert!(cache.get_mut(&5).is_none()); + assert_eq!(cache.get_mut(&6), Some(&mut 60)); + assert_eq!(cache.get_mut(&7), Some(&mut 70)); + assert_eq!(cache.get_mut(&8), Some(&mut 80)); +} + +#[test] +fn test_clear() { + let mut cache = LruCache::new(2); + cache.insert(1, 10); + cache.insert(2, 20); + cache.clear(); + assert!(cache.get_mut(&1).is_none()); + assert!(cache.get_mut(&2).is_none()); + assert!(cache.is_empty()) +} + +#[test] +fn test_iter() { + let mut cache = LruCache::new(3); + cache.insert(1, 10); + cache.insert(2, 20); + cache.insert(3, 30); + cache.insert(4, 40); + cache.insert(5, 50); + assert_eq!( + cache.iter().collect::<Vec<_>>(), + [(&3, &30), (&4, &40), (&5, &50)] + ); + assert_eq!( + cache.iter_mut().collect::<Vec<_>>(), + [(&3, &mut 30), (&4, &mut 40), (&5, &mut 50)] + ); + assert_eq!( + cache.iter().rev().collect::<Vec<_>>(), + [(&5, &50), (&4, &40), (&3, &30)] + ); + assert_eq!( + cache.iter_mut().rev().collect::<Vec<_>>(), + [(&5, &mut 50), (&4, &mut 40), (&3, &mut 30)] + ); +} + +#[test] +fn test_peek() { + let mut cache = LruCache::new_unbounded(); + cache.insert(1, 10); + cache.insert(2, 20); + cache.insert(3, 30); + cache.insert(4, 40); + cache.insert(5, 50); + cache.insert(6, 60); + + assert_eq!(cache.remove_lru(), Some((1, 10))); + assert_eq!(cache.peek(&2), Some(&20)); + assert_eq!(cache.remove_lru(), Some((2, 20))); + assert_eq!(cache.peek_mut(&3), Some(&mut 30)); + assert_eq!(cache.remove_lru(), Some((3, 30))); + assert_eq!(cache.get(&4), Some(&40)); + assert_eq!(cache.remove_lru(), Some((5, 50))); +} + +#[test] +fn test_entry() { + let mut cache = LruCache::new(4); + + cache.insert(1, 10); + cache.insert(2, 20); + cache.insert(3, 30); + cache.insert(4, 40); + cache.insert(5, 50); + cache.insert(6, 60); + + assert_eq!(cache.len(), 4); + + cache.entry(7).or_insert(70); + cache.entry(8).or_insert(80); + cache.entry(9).or_insert(90); + + assert!(cache.len() <= 5); + + cache.raw_entry_mut().from_key(&10).or_insert(10, 100); + cache.raw_entry_mut().from_key(&11).or_insert(11, 110); + cache.raw_entry_mut().from_key(&12).or_insert(12, 120); + + assert!(cache.len() <= 5); +} diff --git a/third_party/rust/hashlink/tests/serde.rs b/third_party/rust/hashlink/tests/serde.rs new file mode 100644 index 0000000000..d397a245fa --- /dev/null +++ b/third_party/rust/hashlink/tests/serde.rs @@ -0,0 +1,108 @@ +#![cfg(feature = "serde_impl")] + +use fxhash::FxBuildHasher; +use hashlink::{LinkedHashMap, LinkedHashSet}; +use serde_test::{assert_tokens, Token}; + +#[test] +fn map_serde_tokens_empty() { + let map = LinkedHashMap::<char, u32>::new(); + + assert_tokens(&map, &[Token::Map { len: Some(0) }, Token::MapEnd]); +} + +#[test] +fn map_serde_tokens() { + let mut map = LinkedHashMap::new(); + map.insert('a', 10); + map.insert('b', 20); + map.insert('c', 30); + + assert_tokens( + &map, + &[ + Token::Map { len: Some(3) }, + Token::Char('a'), + Token::I32(10), + Token::Char('b'), + Token::I32(20), + Token::Char('c'), + Token::I32(30), + Token::MapEnd, + ], + ); +} + +#[test] +fn map_serde_tokens_empty_generic() { + let map = LinkedHashMap::<char, u32, FxBuildHasher>::with_hasher(FxBuildHasher::default()); + + assert_tokens(&map, &[Token::Map { len: Some(0) }, Token::MapEnd]); +} + +#[test] +fn map_serde_tokens_generic() { + let mut map = LinkedHashMap::with_hasher(FxBuildHasher::default()); + map.insert('a', 10); + map.insert('b', 20); + map.insert('c', 30); + + assert_tokens( + &map, + &[ + Token::Map { len: Some(3) }, + Token::Char('a'), + Token::I32(10), + Token::Char('b'), + Token::I32(20), + Token::Char('c'), + Token::I32(30), + Token::MapEnd, + ], + ); +} + +#[test] +fn set_serde_tokens_empty() { + let set = LinkedHashSet::<u32>::new(); + + assert_tokens(&set, &[Token::Seq { len: Some(0) }, Token::SeqEnd]); +} + +#[test] +fn set_serde_tokens() { + let mut set = LinkedHashSet::new(); + set.insert(10); + set.insert(20); + set.insert(30); + + assert_tokens( + &set, + &[ + Token::Seq { len: Some(3) }, + Token::I32(10), + Token::I32(20), + Token::I32(30), + Token::SeqEnd, + ], + ); +} + +#[test] +fn set_serde_tokens_generic() { + let mut set = LinkedHashSet::with_hasher(FxBuildHasher::default()); + set.insert('a'); + set.insert('b'); + set.insert('c'); + + assert_tokens( + &set, + &[ + Token::Seq { len: Some(3) }, + Token::Char('a'), + Token::Char('b'), + Token::Char('c'), + Token::SeqEnd, + ], + ); +} |