diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/hashlink/tests/linked_hash_map.rs | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/hashlink/tests/linked_hash_map.rs')
-rw-r--r-- | third_party/rust/hashlink/tests/linked_hash_map.rs | 563 |
1 files changed, 563 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); + } +} |