blob: 4b25e34a11159c87c66fb775026cd444a82afe6e [file] [log] [blame]
Sergey Vasilinets62bb8a12017-01-25 15:24:19 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Yigit Boyar64db0cc2017-04-17 13:18:56 -070017package android.arch.core.internal;
Sergey Vasilinets62bb8a12017-01-25 15:24:19 -080018
19import static org.hamcrest.CoreMatchers.is;
Sergey Vasilinetsb546e972017-07-21 12:40:50 -070020import static org.hamcrest.CoreMatchers.nullValue;
Sergey Vasilinets62bb8a12017-01-25 15:24:19 -080021import static org.hamcrest.MatcherAssert.assertThat;
22
23import org.junit.Test;
24import org.junit.runner.RunWith;
25import org.junit.runners.JUnit4;
26
27import java.util.ArrayList;
28import java.util.Iterator;
Sergey Vasilinetsb546e972017-07-21 12:40:50 -070029import java.util.Map.Entry;
Sergey Vasilinets62bb8a12017-01-25 15:24:19 -080030
31@RunWith(JUnit4.class)
32public class SafeIterableMapTest {
33
34 @Test
35 public void testToString() {
36 SafeIterableMap<Integer, String> map = from(1, 2, 3, 4).to("a", "b", "c", "d");
37 assertThat(map.toString(), is("[1=a, 2=b, 3=c, 4=d]"));
38 }
39
40 @Test
41 public void testEmptyToString() {
42 SafeIterableMap<Integer, Boolean> map = mapOf();
43 assertThat(map.toString(), is("[]"));
44 }
45
46 @Test
47 public void testOneElementToString() {
48 SafeIterableMap<Integer, Boolean> map = mapOf(1);
49 assertThat(map.toString(), is("[1=true]"));
50 }
51
52
53 @Test
54 public void testEquality1() {
55 SafeIterableMap<Integer, Integer> map1 = from(1, 2, 3, 4).to(10, 20, 30, 40);
56 SafeIterableMap<Integer, Integer> map2 = from(1, 2, 3, 4).to(10, 20, 30, 40);
57 assertThat(map1.equals(map2), is(true));
58 }
59
60 @Test
61 public void testEquality2() {
62 SafeIterableMap<Integer, Boolean> map = mapOf(1, 2, 3, 4);
63 //noinspection ObjectEqualsNull
64 assertThat(map.equals(null), is(false));
65 }
66
67 @Test
68 public void testEquality3() {
69 SafeIterableMap<Integer, Boolean> map = mapOf(1, 2, 3, 4);
70 //noinspection EqualsBetweenInconvertibleTypes
71 assertThat(map.equals(new ArrayList<>()), is(false));
72 }
73
74 @Test
75 public void testEquality4() {
76 SafeIterableMap<Integer, Boolean> map = mapOf(1, 2, 3, 4);
77 assertThat(map.equals(new SafeIterableMap<Integer, Boolean>()), is(false));
78 }
79
80 @Test
81 public void testEquality5() {
82 SafeIterableMap<Integer, Boolean> map1 = mapOf(1, 2, 3, 4);
83 SafeIterableMap<Integer, Boolean> map2 = mapOf(1);
84 assertThat(map1.equals(map2), is(false));
85 }
86
87 @Test
88 public void testEquality6() {
89 SafeIterableMap<Integer, Boolean> map1 = mapOf(1, 2, 3, 4);
90 SafeIterableMap<Integer, Boolean> map2 = mapOf(1, 2, 3, 5);
91 assertThat(map1.equals(map2), is(false));
92 }
93
94 @Test
95 public void testEquality7() {
96 SafeIterableMap<Integer, Integer> map1 = from(1, 2, 3, 4).to(1, 2, 3, 4);
97 SafeIterableMap<Integer, Integer> map2 = from(1, 2, 3, 4).to(1, 2, 3, 5);
98 assertThat(map1.equals(map2), is(false));
99 }
100
101
102 @Test
103 public void testEquality8() {
104 SafeIterableMap<Integer, Boolean> map1 = mapOf();
105 SafeIterableMap<Integer, Boolean> map2 = mapOf();
106 assertThat(map1.equals(map2), is(true));
107 }
108
109 @Test
110 public void testEqualityRespectsOrder() {
111 SafeIterableMap<Integer, Boolean> map1 = mapOf(1, 2, 3, 4);
112 SafeIterableMap<Integer, Boolean> map2 = mapOf(1, 3, 2, 4);
113 assertThat(map1.equals(map2), is(false));
114 }
115
116 @Test
117 public void testPut() {
118 SafeIterableMap<Integer, Integer> map = from(1, 2, 3, 4).to(10, 20, 30, 40);
119 assertThat(map.putIfAbsent(5, 10), is((Integer) null));
120 assertThat(map, is(from(1, 2, 3, 4, 5).to(10, 20, 30, 40, 10)));
121 }
122
123 @Test
124 public void testAddExisted() {
125 SafeIterableMap<Integer, Integer> map = from(1, 2, 3, 4).to(10, 20, 261, 40);
126 assertThat(map.putIfAbsent(3, 239), is(261));
127 assertThat(map, is(from(1, 2, 3, 4).to(10, 20, 261, 40)));
128 }
129
130 @Test
131 public void testRemoveLast() {
132 SafeIterableMap<Integer, Integer> map = from(1, 2, 3, 4).to(10, 20, 30, 40);
133 assertThat(map.remove(4), is(40));
134 assertThat(map, is(from(1, 2, 3).to(10, 20, 30)));
135 }
136
137 @Test
138 public void testRemoveFirst() {
139 SafeIterableMap<Integer, Boolean> map = mapOf(1, 2, 3, 4);
140 assertThat(map.remove(1), is(true));
141 assertThat(map, is(mapOf(2, 3, 4)));
142 }
143
144 @Test
145 public void testRemoveMiddle() {
146 SafeIterableMap<Integer, Integer> map = from(1, 2, 3, 4).to(10, 20, 30, 40);
147 assertThat(map.remove(2), is(20));
148 assertThat(map.remove(3), is(30));
149 assertThat(map, is(from(1, 4).to(10, 40)));
150 }
151
152 @Test
153 public void testRemoveNotExisted() {
154 SafeIterableMap<Integer, Boolean> map = mapOf(1, 2, 3, 4);
155 assertThat(map.remove(5), is((Boolean) null));
156 assertThat(map, is(mapOf(1, 2, 3, 4)));
157 }
158
159 @Test
160 public void testRemoveSole() {
161 SafeIterableMap<Integer, Integer> map = from(1).to(261);
162 assertThat(map.remove(1), is(261));
163 assertThat(map, is(new SafeIterableMap<Integer, Integer>()));
164 }
165
166 @Test
167 public void testRemoveDuringIteration1() {
168 SafeIterableMap<Integer, Integer> map = from(1, 2, 3, 4).to(10, 20, 30, 40);
169 int index = 0;
170 int[] expected = new int[]{1, 4};
Sergey Vasilinetsb546e972017-07-21 12:40:50 -0700171 for (Entry<Integer, Integer> i : map) {
Sergey Vasilinets62bb8a12017-01-25 15:24:19 -0800172 assertThat(i.getKey(), is(expected[index++]));
173 if (index == 1) {
174 assertThat(map.remove(2), is(20));
175 assertThat(map.remove(3), is(30));
176 }
177 }
178 }
179
180 @Test
181 public void testRemoveDuringIteration2() {
182 SafeIterableMap<Integer, Integer> map = from(1, 2).to(10, 20);
Sergey Vasilinetsb546e972017-07-21 12:40:50 -0700183 Iterator<Entry<Integer, Integer>> iter = map.iterator();
Sergey Vasilinets62bb8a12017-01-25 15:24:19 -0800184 assertThat(map.remove(2), is(20));
185 assertThat(map.remove(1), is(10));
186 assertThat(iter.hasNext(), is(false));
187 }
188
189 @Test
190 public void testRemoveDuringIteration3() {
191 SafeIterableMap<Integer, Integer> map = from(1, 2, 3, 4).to(10, 20, 30, 40);
192 int index = 0;
Sergey Vasilinetsb546e972017-07-21 12:40:50 -0700193 Iterator<Entry<Integer, Integer>> iter = map.iterator();
Sergey Vasilinets62bb8a12017-01-25 15:24:19 -0800194 assertThat(map.remove(1), is(10));
195 assertThat(map.remove(2), is(20));
196 int[] expected = new int[]{3, 4};
197 while (iter.hasNext()) {
198 assertThat(iter.next().getKey(), is(expected[index++]));
199 }
200 }
201
202 @Test
203 public void testAdditionDuringIteration() {
204 SafeIterableMap<Integer, Boolean> map = mapOf(1, 2, 3, 4);
205 int[] expected = new int[]{1, 2, 3, 4};
206 int index = 0;
Sergey Vasilinetsb546e972017-07-21 12:40:50 -0700207 for (Entry<Integer, Boolean> entry : map) {
Sergey Vasilinets62bb8a12017-01-25 15:24:19 -0800208 assertThat(entry.getKey(), is(expected[index++]));
209 if (index == 1) {
210 map.putIfAbsent(5, true);
211 }
212 }
213 }
214
215 @Test
216 public void testReAdditionDuringIteration() {
217 SafeIterableMap<Integer, Boolean> map = mapOf(1, 2, 3, 4);
218 int[] expected = new int[]{1, 2, 4};
219 int index = 0;
Sergey Vasilinetsb546e972017-07-21 12:40:50 -0700220 for (Entry<Integer, Boolean> entry : map) {
Sergey Vasilinets62bb8a12017-01-25 15:24:19 -0800221 assertThat(entry.getKey(), is(expected[index++]));
222 if (index == 1) {
223 map.remove(3);
224 map.putIfAbsent(3, true);
225 }
226 }
227 }
228
229 @Test
230 public void testSize() {
231 SafeIterableMap<Integer, Boolean> map = mapOf(1, 2, 3, 4);
232 assertThat(map.size(), is(4));
233 map.putIfAbsent(5, true);
234 map.putIfAbsent(6, true);
235 assertThat(map.size(), is(6));
236 map.remove(5);
237 map.remove(5);
238 assertThat(map.size(), is(5));
239 map.remove(1);
240 map.remove(2);
241 map.remove(4);
242 map.remove(3);
243 map.remove(6);
244 assertThat(map.size(), is(0));
245 map.putIfAbsent(4, true);
246 assertThat(map.size(), is(1));
247 assertThat(mapOf().size(), is(0));
248 }
249
Sergey Vasilinetsc43ce902017-02-15 18:45:00 -0800250 @Test
Sergey Vasilinetsb546e972017-07-21 12:40:50 -0700251 public void testIteratorWithAdditions1() {
Sergey Vasilinetsc43ce902017-02-15 18:45:00 -0800252 SafeIterableMap<Integer, Boolean> map = mapOf(1, 2, 3, 4);
253 int[] expected = new int[]{1, 2, 3, 5};
254 int index = 0;
Sergey Vasilinetsb546e972017-07-21 12:40:50 -0700255 Iterator<Entry<Integer, Boolean>> iterator = map.iteratorWithAdditions();
Sergey Vasilinetsc43ce902017-02-15 18:45:00 -0800256 while (iterator.hasNext()) {
Sergey Vasilinetsb546e972017-07-21 12:40:50 -0700257 Entry<Integer, Boolean> entry = iterator.next();
Sergey Vasilinetsc43ce902017-02-15 18:45:00 -0800258 assertThat(entry.getKey(), is(expected[index++]));
259 if (index == 3) {
260 map.remove(4);
261 map.putIfAbsent(5, true);
262 }
263 }
264 }
265
Sergey Vasilinetsb546e972017-07-21 12:40:50 -0700266 @Test
267 public void testIteratorWithAdditions2() {
268 SafeIterableMap<Integer, Boolean> map = mapOf(1);
269 int[] expected = new int[]{1, 2, 3};
270 int index = 0;
271 Iterator<Entry<Integer, Boolean>> iterator = map.iteratorWithAdditions();
272 while (iterator.hasNext()) {
273 Entry<Integer, Boolean> entry = iterator.next();
274 assertThat(entry.getKey(), is(expected[index++]));
275 if (index == 1) {
276 map.putIfAbsent(2, true);
277 map.putIfAbsent(3, true);
278 }
279 }
280 assertThat(index, is(3));
281 }
282
283
284 @Test
285 public void testIteratorWithAdditions3() {
286 SafeIterableMap<Integer, Boolean> map = mapOf(1, 2, 3);
287 int[] expected = new int[]{1};
288 int index = 0;
289 Iterator<Entry<Integer, Boolean>> iterator = map.iteratorWithAdditions();
290 while (iterator.hasNext()) {
291 Entry<Integer, Boolean> entry = iterator.next();
292 assertThat(entry.getKey(), is(expected[index++]));
293 map.remove(2);
294 map.remove(3);
295 }
296 assertThat(index, is(1));
297 }
298
299 @Test
300 public void testIteratorWithAdditions4() {
301 SafeIterableMap<Integer, Boolean> map = mapOf();
302 int[] expected = new int[]{1, 2, 3};
303 int index = 0;
304 Iterator<Entry<Integer, Boolean>> iterator = map.iteratorWithAdditions();
305 map.putIfAbsent(1, true);
306 while (iterator.hasNext()) {
307 Entry<Integer, Boolean> entry = iterator.next();
308 assertThat(entry.getKey(), is(expected[index++]));
309 if (index == 1) {
310 map.putIfAbsent(2, false);
311 }
312 if (index == 2) {
313 map.putIfAbsent(3, false);
314 }
315 }
316 assertThat(index, is(3));
317 }
318
319 @Test
320 public void testDescendingIteration() {
321 SafeIterableMap<Integer, Boolean> map = mapOf(1, 2, 3, 4);
322 int[] expected = new int[]{4, 3, 2, 1};
323 int index = 0;
324 for (Iterator<Entry<Integer, Boolean>> iter = map.descendingIterator(); iter.hasNext(); ) {
325 assertThat(iter.next().getKey(), is(expected[index++]));
326 }
327 assertThat(index, is(4));
328 }
329
330 @Test
331 public void testDescendingIterationRemove1() {
332 SafeIterableMap<Integer, Boolean> map = mapOf(1, 2, 3, 4);
333 int[] expected = new int[]{4, 3, 2};
334 int index = 0;
335 for (Iterator<Entry<Integer, Boolean>> iter = map.descendingIterator(); iter.hasNext(); ) {
336 if (index == 1) {
337 map.remove(1);
338 }
339 assertThat(iter.next().getKey(), is(expected[index++]));
340 }
341 assertThat(index, is(3));
342 assertThat(map.size(), is(3));
343 }
344
345 @Test
346 public void testDescendingIterationRemove2() {
347 SafeIterableMap<Integer, Boolean> map = mapOf(1, 2, 3, 4);
348 int[] expected = new int[]{3, 2, 1};
349 int index = 0;
350 for (Iterator<Entry<Integer, Boolean>> iter = map.descendingIterator(); iter.hasNext(); ) {
351 if (index == 0) {
352 map.remove(4);
353 }
354 assertThat(iter.next().getKey(), is(expected[index++]));
355 }
356 assertThat(index, is(3));
357 assertThat(map.size(), is(3));
358 }
359
360 @Test
361 public void testDescendingIterationRemove3() {
362 SafeIterableMap<Integer, Boolean> map = mapOf(1, 2, 3, 4);
363 int[] expected = new int[]{4, 1};
364 int index = 0;
365 for (Iterator<Entry<Integer, Boolean>> iter = map.descendingIterator(); iter.hasNext(); ) {
366 if (index == 1) {
367 map.remove(3);
368 map.remove(2);
369 }
370 assertThat(iter.next().getKey(), is(expected[index++]));
371 }
372 assertThat(index, is(2));
373 assertThat(map.size(), is(2));
374 }
375
376 @Test
377 public void testDescendingIterationAddition() {
378 SafeIterableMap<Integer, Boolean> map = mapOf(1, 2, 3, 4);
379 int[] expected = new int[]{4, 3, 2, 1};
380 int index = 0;
381 for (Iterator<Entry<Integer, Boolean>> iter = map.descendingIterator(); iter.hasNext(); ) {
382 if (index == 0) {
383 map.putIfAbsent(5, false);
384 }
385 assertThat(iter.next().getKey(), is(expected[index++]));
386 }
387 assertThat(index, is(4));
388 assertThat(map.size(), is(5));
389 }
390
391 @Test
392 public void testDescendingIteratorEmpty() {
393 SafeIterableMap<Integer, Boolean> map = mapOf();
394 Iterator<Entry<Integer, Boolean>> iterator = map.descendingIterator();
395 assertThat(iterator.hasNext(), is(false));
396 }
397
398 @Test
399 public void testIteratorEmpty() {
400 SafeIterableMap<Integer, Boolean> map = mapOf();
401 Iterator<Entry<Integer, Boolean>> iterator = map.iterator();
402 assertThat(iterator.hasNext(), is(false));
403 }
404
405 @Test
406 public void testIteratorWithAdditionEmpty() {
407 SafeIterableMap<Integer, Boolean> map = mapOf();
408 Iterator<Entry<Integer, Boolean>> iterator = map.iteratorWithAdditions();
409 assertThat(iterator.hasNext(), is(false));
410 }
411
412 @Test
413 public void testEldest() {
414 SafeIterableMap<Integer, Boolean> map = mapOf();
415 assertThat(map.eldest(), nullValue());
416 map.putIfAbsent(1, false);
417 assertThat(map.eldest().getKey(), is(1));
418 map.putIfAbsent(2, false);
419 assertThat(map.eldest().getKey(), is(1));
420 map.remove(1);
421 assertThat(map.eldest().getKey(), is(2));
422 map.remove(2);
423 assertThat(map.eldest(), nullValue());
424 }
425
426 @Test
427 public void testNewest() {
428 SafeIterableMap<Integer, Boolean> map = mapOf();
429 assertThat(map.newest(), nullValue());
430 map.putIfAbsent(1, false);
431 assertThat(map.newest().getKey(), is(1));
432 map.putIfAbsent(2, false);
433 assertThat(map.newest().getKey(), is(2));
434 map.remove(2);
435 assertThat(map.eldest().getKey(), is(1));
436 map.remove(1);
437 assertThat(map.newest(), nullValue());
438 }
439
440
Sergey Vasilinets62bb8a12017-01-25 15:24:19 -0800441 // for most operations we don't care about values, so we create map from key to true
442 @SafeVarargs
443 private static <K> SafeIterableMap<K, Boolean> mapOf(K... keys) {
444 SafeIterableMap<K, Boolean> map = new SafeIterableMap<>();
445 for (K key : keys) {
446 map.putIfAbsent(key, true);
447 }
448 return map;
449 }
450
451 @SafeVarargs
452 private static <K> MapBuilder<K> from(K... keys) {
453 return new MapBuilder<>(keys);
454 }
455
456 private static class MapBuilder<K> {
457 final K[] mKeys;
458
459 MapBuilder(K[] keys) {
460 this.mKeys = keys;
461 }
462
463 @SafeVarargs
464 public final <V> SafeIterableMap<K, V> to(V... values) {
465 assertThat("Failed to build Map", mKeys.length, is(values.length));
466 SafeIterableMap<K, V> map = new SafeIterableMap<>();
467 for (int i = 0; i < mKeys.length; i++) {
468 map.putIfAbsent(mKeys[i], values[i]);
469 }
470 return map;
471 }
472 }
473}
474
475