1//! Tests for the VecMap collection.
2//!
3//! This is in a sibling module so that the tests are guaranteed to only cover
4//! states that can be created by the public API.
5
6use crate::vecmap::*;
7
8#[test]
9fn test_entry_vacant_or_insert() {
10 let mut map: VecMap<&str, i32> = VecMap::new();
11 let value = map.entry("a").or_insert(1);
12 assert_eq!(*value, 1);
13 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&"a", &1)]);
14}
15
16#[test]
17fn test_entry_occupied_or_insert_keeps_existing() {
18 let mut map: VecMap<&str, i32> = VecMap::new();
19 map.entry("a").or_insert(1);
20 let value = map.entry("a").or_insert(99);
21 assert_eq!(*value, 1);
22 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&"a", &1)]);
23}
24
25#[test]
26fn test_entry_or_insert_with() {
27 let mut map: VecMap<&str, i32> = VecMap::new();
28 map.entry("a").or_insert_with(|| 42);
29 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&"a", &42)]);
30}
31
32#[test]
33fn test_entry_or_insert_with_not_called_when_occupied() {
34 let mut map: VecMap<&str, i32> = VecMap::new();
35 map.entry("a").or_insert(1);
36 map.entry("a")
37 .or_insert_with(|| panic!("should not be called"));
38 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&"a", &1)]);
39}
40
41#[test]
42fn test_entry_or_insert_with_key() {
43 let mut map: VecMap<&str, String> = VecMap::new();
44 map.entry("hello").or_insert_with_key(|k| k.to_uppercase());
45 assert_eq!(
46 map.iter().collect::<Vec<_>>(),
47 vec![(&"hello", &"HELLO".to_string())]
48 );
49}
50
51#[test]
52fn test_entry_or_insert_default() {
53 let mut map: VecMap<&str, i32> = VecMap::new();
54 map.entry("a").or_insert_default();
55 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&"a", &0)]);
56}
57
58#[test]
59fn test_entry_key() {
60 let mut map: VecMap<&str, i32> = VecMap::new();
61 assert_eq!(*map.entry("a").key(), "a");
62 map.entry("a").or_insert(1);
63 assert_eq!(*map.entry("a").key(), "a");
64}
65
66#[test]
67fn test_entry_mut_ref_can_be_updated() {
68 let mut map: VecMap<&str, i32> = VecMap::new();
69 let value = map.entry("a").or_insert(0);
70 *value = 5;
71 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&"a", &5)]);
72}
73
74#[test]
75fn test_insertion_order_preserved() {
76 let mut map: VecMap<&str, i32> = VecMap::new();
77 map.entry("b").or_insert(2);
78 map.entry("a").or_insert(1);
79 map.entry("c").or_insert(3);
80 assert_eq!(
81 map.iter().collect::<Vec<_>>(),
82 vec![(&"b", &2), (&"a", &1), (&"c", &3)]
83 );
84}
85
86#[test]
87fn test_multiple_entries_independent() {
88 let mut map: VecMap<i32, i32> = VecMap::new();
89 map.entry(1).or_insert(10);
90 map.entry(2).or_insert(20);
91 map.entry(3).or_insert(30);
92 assert_eq!(map.iter().count(), 3);
93 // Re-inserting does not duplicate keys
94 map.entry(1).or_insert(99);
95 assert_eq!(map.iter().count(), 3);
96}
97
98// entry_ref tests
99
100use std::cell::Cell;
101use std::rc::Rc;
102
103#[derive(PartialEq, Eq)]
104struct CountedKey {
105 value: String,
106 clone_count: Rc<Cell<usize>>,
107}
108
109impl Clone for CountedKey {
110 fn clone(&self) -> Self {
111 self.clone_count.set(self.clone_count.get() + 1);
112 CountedKey {
113 value: self.value.clone(),
114 clone_count: self.clone_count.clone(),
115 }
116 }
117}
118
119#[test]
120fn test_entry_ref_vacant_or_insert() {
121 let mut map: VecMap<String, i32> = VecMap::new();
122 let key = "a".to_string();
123 let value = map.entry_ref(&key).or_insert(1);
124 assert_eq!(*value, 1);
125 assert_eq!(map.iter().count(), 1);
126}
127
128#[test]
129fn test_entry_ref_occupied_or_insert_keeps_existing() {
130 let mut map: VecMap<String, i32> = VecMap::new();
131 map.entry_ref(&"a".to_string()).or_insert(1);
132 let value = map.entry_ref(&"a".to_string()).or_insert(99);
133 assert_eq!(*value, 1);
134 assert_eq!(map.iter().count(), 1);
135}
136
137#[test]
138fn test_entry_ref_key_not_cloned_when_occupied() {
139 let clone_count = Rc::new(Cell::new(0));
140 let key = CountedKey {
141 value: "a".to_string(),
142 clone_count: clone_count.clone(),
143 };
144
145 let mut map: VecMap<CountedKey, i32> = VecMap::new();
146 map.entry_ref(&key).or_insert(1);
147 let clones_after_insert = clone_count.get();
148
149 // Looking up an existing key must not clone it.
150 map.entry_ref(&key).or_insert(99);
151 assert_eq!(clone_count.get(), clones_after_insert);
152}
153
154#[test]
155fn test_entry_ref_key_cloned_exactly_once_on_vacant_insert() {
156 let clone_count = Rc::new(Cell::new(0));
157 let key = CountedKey {
158 value: "a".to_string(),
159 clone_count: clone_count.clone(),
160 };
161
162 let mut map: VecMap<CountedKey, i32> = VecMap::new();
163 map.entry_ref(&key).or_insert(1);
164 assert_eq!(clone_count.get(), 1);
165}
166
167#[test]
168fn test_entry_ref_or_insert_with_key() {
169 let mut map: VecMap<String, String> = VecMap::new();
170 let key = "hello".to_string();
171 map.entry_ref(&key).or_insert_with_key(|k| k.to_uppercase());
172 assert_eq!(
173 map.iter().collect::<Vec<_>>(),
174 vec![(&"hello".to_string(), &"HELLO".to_string())]
175 );
176}
177
178#[test]
179fn test_entry_ref_or_insert_with_not_called_when_occupied() {
180 let mut map: VecMap<String, i32> = VecMap::new();
181 let key = "a".to_string();
182 map.entry_ref(&key).or_insert(1);
183 map.entry_ref(&key)
184 .or_insert_with(|| panic!("should not be called"));
185 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&key, &1)]);
186}
187
188#[test]
189fn test_entry_ref_or_insert_default() {
190 let mut map: VecMap<String, i32> = VecMap::new();
191 map.entry_ref(&"a".to_string()).or_insert_default();
192 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&"a".to_string(), &0)]);
193}
194
195#[test]
196fn test_entry_ref_key() {
197 let mut map: VecMap<String, i32> = VecMap::new();
198 let key = "a".to_string();
199 assert_eq!(*map.entry_ref(&key).key(), key);
200 map.entry_ref(&key).or_insert(1);
201 assert_eq!(*map.entry_ref(&key).key(), key);
202}
203
204#[test]
205fn test_entry_ref_mut_ref_can_be_updated() {
206 let mut map: VecMap<String, i32> = VecMap::new();
207 let key = "a".to_string();
208 let value = map.entry_ref(&key).or_insert(0);
209 *value = 5;
210 assert_eq!(map.iter().collect::<Vec<_>>(), vec![(&key, &5)]);
211}