1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections4.iterators;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertSame;
22 import static org.junit.jupiter.api.Assertions.assertThrows;
23 import static org.junit.jupiter.api.Assertions.assertTrue;
24 import static org.junit.jupiter.api.Assertions.fail;
25
26 import java.util.HashSet;
27 import java.util.Map;
28 import java.util.NoSuchElementException;
29 import java.util.Set;
30
31 import org.apache.commons.collections4.MapIterator;
32 import org.junit.jupiter.api.Test;
33
34
35
36
37
38
39
40
41
42
43
44
45
46 public abstract class AbstractMapIteratorTest<K, V> extends AbstractIteratorTest<K> {
47
48
49
50
51
52 @SuppressWarnings("unchecked")
53 public V[] addSetValues() {
54 return (V[]) new Object[] { "A", "B" };
55 }
56
57
58
59
60
61
62
63 public abstract Map<K, V> getConfirmedMap();
64
65
66
67
68
69
70
71 public abstract Map<K, V> getMap();
72
73
74
75
76
77
78
79 public boolean isGetStructuralModify() {
80 return false;
81 }
82
83
84
85
86
87
88 @Override
89 public abstract MapIterator<K, V> makeEmptyIterator();
90
91
92
93
94
95
96 @Override
97 public abstract MapIterator<K, V> makeObject();
98
99
100
101
102
103
104
105 public boolean supportsSetValue() {
106 return true;
107 }
108
109
110
111
112 @Test
113 public void testEmptyMapIterator() {
114 if (!supportsEmptyIterator()) {
115 return;
116 }
117
118 final MapIterator<K, V> it = makeEmptyIterator();
119 assertFalse(it.hasNext());
120
121
122 assertThrows(NoSuchElementException.class, () -> it.next());
123
124
125 assertThrows(IllegalStateException.class, () -> it.getKey());
126
127
128 assertThrows(IllegalStateException.class, () -> it.getValue());
129
130 if (!supportsSetValue()) {
131
132 try {
133 it.setValue(addSetValues()[0]);
134 fail();
135 } catch (final UnsupportedOperationException | IllegalStateException ex) {
136
137 }
138 } else {
139
140 assertThrows(IllegalStateException.class, () -> it.setValue(addSetValues()[0]));
141 }
142 }
143
144
145
146
147 @Test
148 public void testFullMapIterator() {
149 if (!supportsFullIterator()) {
150 return;
151 }
152
153 final MapIterator<K, V> it = makeObject();
154 final Map<K, V> map = getMap();
155 assertTrue(it.hasNext());
156
157 assertTrue(it.hasNext());
158 final Set<K> set = new HashSet<>();
159 while (it.hasNext()) {
160
161 final K key = it.next();
162 assertSame(key, it.getKey(), "it.next() should equals getKey()");
163 assertTrue(map.containsKey(key), "Key must be in map");
164 assertTrue(set.add(key), "Key must be unique");
165
166
167 final V value = it.getValue();
168 if (!isGetStructuralModify()) {
169 assertSame(map.get(key), value, "Value must be mapped to key");
170 }
171 assertTrue(map.containsValue(value), "Value must be in map");
172
173 verify();
174 }
175 }
176
177 @Test
178 public void testMapIteratorRemoveGetKey() {
179 if (!supportsRemove()) {
180 return;
181 }
182 final MapIterator<K, V> it = makeObject();
183 final Map<K, V> confirmed = getConfirmedMap();
184
185 assertTrue(it.hasNext());
186 final K key = it.next();
187
188 it.remove();
189 confirmed.remove(key);
190 verify();
191
192 assertThrows(IllegalStateException.class, () -> it.getKey());
193 verify();
194 }
195
196 @Test
197 public void testMapIteratorRemoveGetValue() {
198 if (!supportsRemove()) {
199 return;
200 }
201 final MapIterator<K, V> it = makeObject();
202 final Map<K, V> confirmed = getConfirmedMap();
203
204 assertTrue(it.hasNext());
205 final K key = it.next();
206
207 it.remove();
208 confirmed.remove(key);
209 verify();
210
211 assertThrows(IllegalStateException.class, () -> it.getValue());
212 verify();
213 }
214
215 @Test
216 public void testMapIteratorSet() {
217 if (!supportsFullIterator()) {
218 return;
219 }
220
221 final V newValue = addSetValues()[0];
222 final V newValue2 = addSetValues().length == 1 ? addSetValues()[0] : addSetValues()[1];
223 final MapIterator<K, V> it = makeObject();
224 final Map<K, V> map = getMap();
225 final Map<K, V> confirmed = getConfirmedMap();
226 assertTrue(it.hasNext());
227 final K key = it.next();
228 final V value = it.getValue();
229
230 if (!supportsSetValue()) {
231 assertThrows(UnsupportedOperationException.class, () -> it.setValue(newValue));
232 return;
233 }
234 final V old = it.setValue(newValue);
235 confirmed.put(key, newValue);
236 assertSame(key, it.getKey(), "Key must not change after setValue");
237 assertSame(newValue, it.getValue(), "Value must be changed after setValue");
238 assertSame(value, old, "setValue must return old value");
239 assertTrue(map.containsKey(key), "Map must contain key");
240
241 assertEquals(confirmed.containsValue(old), map.containsValue(old),
242 "Map must not contain old value");
243 assertTrue(map.containsValue(newValue), "Map must contain new value");
244 verify();
245
246 it.setValue(newValue);
247 confirmed.put(key, newValue);
248 assertSame(key, it.getKey(), "Key must not change after setValue");
249 assertSame(newValue, it.getValue(), "Value must be changed after setValue");
250 verify();
251
252 it.setValue(newValue2);
253 confirmed.put(key, newValue2);
254 assertSame(key, it.getKey(), "Key must not change after setValue");
255 assertSame(newValue2, it.getValue(), "Value must be changed after setValue");
256 verify();
257 }
258
259 @Test
260 public void testMapIteratorSetRemoveSet() {
261 if (!supportsSetValue() || !supportsRemove()) {
262 return;
263 }
264 final V newValue = addSetValues()[0];
265 final MapIterator<K, V> it = makeObject();
266 final Map<K, V> confirmed = getConfirmedMap();
267
268 assertTrue(it.hasNext());
269 final K key = it.next();
270
271 it.setValue(newValue);
272 it.remove();
273 confirmed.remove(key);
274 verify();
275
276 assertThrows(IllegalStateException.class, () -> it.setValue(newValue));
277 verify();
278 }
279
280 @Test
281 @Override
282 public void testRemove() {
283 final MapIterator<K, V> it = makeObject();
284 final Map<K, V> map = getMap();
285 final Map<K, V> confirmed = getConfirmedMap();
286 assertTrue(it.hasNext());
287 final K key = it.next();
288
289 if (!supportsRemove()) {
290 assertThrows(UnsupportedOperationException.class, () -> it.remove());
291 return;
292 }
293 it.remove();
294 confirmed.remove(key);
295 assertFalse(map.containsKey(key));
296 verify();
297
298 assertThrows(NoSuchElementException.class, it::remove, "Full iterators must have at least one element");
299 verify();
300 }
301
302 }