1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.commons.collections;
18
19 import static org.apache.juneau.junit.bct.BctAssertions.*;
20 import static org.junit.jupiter.api.Assertions.*;
21
22 import java.util.*;
23
24 import org.apache.juneau.*;
25 import org.junit.jupiter.api.*;
26
27 class BidiMap_Test extends TestBase {
28
29
30
31
32
33 @Test void a01_basicForwardLookup() {
34 var map = BidiMap.<String,Integer>create()
35 .add("one", 1)
36 .add("two", 2)
37 .add("three", 3)
38 .build();
39
40 assertEquals(1, map.get("one"));
41 assertEquals(2, map.get("two"));
42 assertEquals(3, map.get("three"));
43 assertNull(map.get("four"));
44 }
45
46 @Test void a02_basicReverseLookup() {
47 var map = BidiMap.<String,Integer>create()
48 .add("one", 1)
49 .add("two", 2)
50 .add("three", 3)
51 .build();
52
53 assertEquals("one", map.getKey(1));
54 assertEquals("two", map.getKey(2));
55 assertEquals("three", map.getKey(3));
56 assertNull(map.getKey(4));
57 }
58
59
60
61
62
63 @Test void a03_nullKeysAndValuesFilteredOut() {
64 var map = BidiMap.<String,Integer>create()
65 .add("one", 1)
66 .add(null, 2)
67 .add("three", null)
68 .add(null, null)
69 .build();
70
71 assertSize(1, map);
72 assertEquals(1, map.get("one"));
73 assertNull(map.get(null));
74 assertNull(map.getKey(null));
75 }
76
77 @Test void a04_nullLookups() {
78 var map = BidiMap.<String,Integer>create()
79 .add("one", 1)
80 .build();
81
82 assertNull(map.get(null));
83 assertNull(map.getKey(null));
84 }
85
86
87
88
89
90 @Test void a05_emptyMap() {
91 var map = BidiMap.<String,Integer>create().build();
92
93 assertEmpty(map);
94 assertEmpty(map);
95 assertNull(map.get("anything"));
96 assertNull(map.getKey(123));
97 }
98
99 @Test void a06_builderChaining() {
100 var map = BidiMap.<String,Integer>create()
101 .add("a", 1)
102 .add("b", 2)
103 .add("c", 3)
104 .build();
105
106 assertSize(3, map);
107 assertEquals(1, map.get("a"));
108 assertEquals("b", map.getKey(2));
109 }
110
111
112
113
114
115 @Test void a07_containsKey() {
116 var map = BidiMap.<String,Integer>create()
117 .add("one", 1)
118 .add("two", 2)
119 .build();
120
121 assertTrue(map.containsKey("one"));
122 assertTrue(map.containsKey("two"));
123 assertFalse(map.containsKey("three"));
124 assertFalse(map.containsKey(null));
125 }
126
127 @Test void a08_containsValue() {
128 var map = BidiMap.<String,Integer>create()
129 .add("one", 1)
130 .add("two", 2)
131 .build();
132
133 assertTrue(map.containsValue(1));
134 assertTrue(map.containsValue(2));
135 assertFalse(map.containsValue(3));
136 assertFalse(map.containsValue(null));
137 }
138
139
140
141
142
143 @Test void a09_put() {
144 var map = BidiMap.<String,Integer>create().build();
145
146 assertNull(map.put("one", 1));
147 assertEquals(1, map.get("one"));
148 assertEquals("one", map.getKey(1));
149
150 assertEquals(1, map.put("one", 10));
151 assertEquals(10, map.get("one"));
152 assertEquals("one", map.getKey(10));
153 }
154
155 @Test void a10_putAll() {
156 var map = BidiMap.<String,Integer>create()
157 .add("one", 1)
158 .build();
159
160 var toAdd = new HashMap<String,Integer>();
161 toAdd.put("two", 2);
162 toAdd.put("three", 3);
163
164 map.putAll(toAdd);
165
166 assertSize(3, map);
167 assertEquals(2, map.get("two"));
168 assertEquals("three", map.getKey(3));
169 }
170
171 @Test void a11_remove() {
172 var map = BidiMap.<String,Integer>create()
173 .add("one", 1)
174 .add("two", 2)
175 .build();
176
177 assertEquals(1, map.remove("one"));
178 assertFalse(map.containsKey("one"));
179 assertFalse(map.containsValue(1));
180 assertNull(map.getKey(1));
181
182 assertNull(map.remove("three"));
183 }
184
185 @Test void a12_clear() {
186 var map = BidiMap.<String,Integer>create()
187 .add("one", 1)
188 .add("two", 2)
189 .build();
190
191 map.clear();
192
193 assertEmpty(map);
194 assertEmpty(map);
195 assertNull(map.get("one"));
196 assertNull(map.getKey(1));
197 }
198
199
200
201
202
203 @Test void a13_keySet() {
204 var map = BidiMap.<String,Integer>create()
205 .add("one", 1)
206 .add("two", 2)
207 .add("three", 3)
208 .build();
209
210 var keys = map.keySet();
211
212 assertSize(3, keys);
213 assertTrue(keys.contains("one"));
214 assertTrue(keys.contains("two"));
215 assertTrue(keys.contains("three"));
216 }
217
218 @Test void a14_values() {
219 var map = BidiMap.<String,Integer>create()
220 .add("one", 1)
221 .add("two", 2)
222 .add("three", 3)
223 .build();
224
225 var values = map.values();
226
227 assertSize(3, values);
228 assertTrue(values.contains(1));
229 assertTrue(values.contains(2));
230 assertTrue(values.contains(3));
231 }
232
233 @Test void a15_entrySet() {
234 var map = BidiMap.<String,Integer>create()
235 .add("one", 1)
236 .add("two", 2)
237 .build();
238
239 var entries = map.entrySet();
240
241 assertSize(2, entries);
242
243 boolean foundOne = false;
244 boolean foundTwo = false;
245
246 for (var entry : entries) {
247 if ("one".equals(entry.getKey()) && Integer.valueOf(1).equals(entry.getValue())) {
248 foundOne = true;
249 }
250 if ("two".equals(entry.getKey()) && Integer.valueOf(2).equals(entry.getValue())) {
251 foundTwo = true;
252 }
253 }
254
255 assertTrue(foundOne);
256 assertTrue(foundTwo);
257 }
258
259
260
261
262
263 @Test void a16_unmodifiable_put() {
264 var map = BidiMap.<String,Integer>create()
265 .add("one", 1)
266 .unmodifiable()
267 .build();
268
269 assertThrows(UnsupportedOperationException.class, () -> map.put("two", 2));
270 }
271
272 @Test void a17_unmodifiable_putAll() {
273 var map = BidiMap.<String,Integer>create()
274 .add("one", 1)
275 .unmodifiable()
276 .build();
277
278 var toAdd = new HashMap<String,Integer>();
279 toAdd.put("two", 2);
280
281 assertThrows(UnsupportedOperationException.class, () -> map.putAll(toAdd));
282 }
283
284 @Test void a18_unmodifiable_remove() {
285 var map = BidiMap.<String,Integer>create()
286 .add("one", 1)
287 .unmodifiable()
288 .build();
289
290 assertThrows(UnsupportedOperationException.class, () -> map.remove("one"));
291 }
292
293 @Test void a19_unmodifiable_clear() {
294 var map = BidiMap.<String,Integer>create()
295 .add("one", 1)
296 .unmodifiable()
297 .build();
298
299 assertThrows(UnsupportedOperationException.class, () -> map.clear());
300 }
301
302 @Test void a20_unmodifiable_readOperationsWork() {
303 var map = BidiMap.<String,Integer>create()
304 .add("one", 1)
305 .add("two", 2)
306 .unmodifiable()
307 .build();
308
309 assertEquals(1, map.get("one"));
310 assertEquals("two", map.getKey(2));
311 assertSize(2, map);
312 assertTrue(map.containsKey("one"));
313 assertTrue(map.containsValue(2));
314 }
315
316
317
318
319
320 @Test void a21_insertionOrderPreserved() {
321 var map = BidiMap.<String,Integer>create()
322 .add("c", 3)
323 .add("a", 1)
324 .add("b", 2)
325 .build();
326
327 var keys = new ArrayList<>(map.keySet());
328 assertEquals("c", keys.get(0));
329 assertEquals("a", keys.get(1));
330 assertEquals("b", keys.get(2));
331 }
332
333
334
335
336
337 @Test void a22_overwriteInBuilder() {
338 var map = BidiMap.<String,Integer>create()
339 .add("one", 1)
340 .add("one", 10)
341 .build();
342
343 assertSize(1, map);
344 assertEquals(10, map.get("one"));
345 assertEquals("one", map.getKey(10));
346 assertNull(map.getKey(1));
347 }
348
349 @Test void a22b_overwriteInBuilder_differentValue() {
350
351
352 var map = BidiMap.<String,Integer>create()
353 .add("key1", 100)
354 .add("key2", 200)
355 .add("key1", 300)
356 .build();
357
358 assertSize(2, map);
359 assertEquals(300, map.get("key1"));
360 assertEquals(200, map.get("key2"));
361 assertEquals("key1", map.getKey(300));
362 assertNull(map.getKey(100));
363 }
364
365 @Test void a23_duplicateValuesInBuilder() {
366
367 assertThrows(IllegalArgumentException.class, () ->
368 BidiMap.<String,Integer>create()
369 .add("one", 1)
370 .add("uno", 1)
371 .build()
372 );
373 }
374
375 @Test void a23b_duplicateValuesInBuilder_overwritingKey() {
376
377
378
379
380 assertThrows(IllegalArgumentException.class, () ->
381 BidiMap.<String,Integer>create()
382 .add("key1", 100)
383 .add("key2", 200)
384 .add("key1", 200)
385 .build()
386 );
387 }
388
389 @Test void a23c_overwriteKeyWithSameValue() {
390
391
392
393 var map = BidiMap.<String,Integer>create()
394 .add("key1", 100)
395 .add("key2", 200)
396 .add("key1", 100)
397 .build();
398
399 assertSize(2, map);
400 assertEquals(100, map.get("key1"));
401 assertEquals(200, map.get("key2"));
402 }
403
404 @Test void a23d_overwriteKeyWithNewValue_notInValues() {
405
406
407
408 var map = BidiMap.<String,Integer>create()
409 .add("key1", 100)
410 .add("key2", 200)
411 .add("key1", 300)
412 .build();
413
414 assertSize(2, map);
415 assertEquals(300, map.get("key1"));
416 assertEquals(200, map.get("key2"));
417 }
418
419
420
421
422
423 @Test void a24_constructorMergeFunction_duplicateKeysInBuilder() {
424
425
426
427
428
429 var map = BidiMap.<String,Integer>create()
430 .add("key1", 100)
431 .add("key1", 200)
432 .add("key1", 300)
433 .build();
434
435
436 assertSize(1, map);
437 assertEquals(300, map.get("key1"));
438 assertEquals("key1", map.getKey(300));
439 }
440
441 @Test void a25_constructorMergeFunction_duplicateValuesInBuilder() {
442
443
444
445
446 var map = BidiMap.<String,Integer>create()
447 .add("key1", 100)
448 .add("key2", 200)
449 .add("key1", 300)
450 .build();
451
452
453 assertSize(2, map);
454 assertEquals(300, map.get("key1"));
455 assertEquals(200, map.get("key2"));
456 assertEquals("key1", map.getKey(300));
457 assertEquals("key2", map.getKey(200));
458 assertNull(map.getKey(100));
459 }
460
461 @Test void a26_constructorWithNullEntries_filteredCorrectly() {
462
463
464 var map = BidiMap.<String,Integer>create()
465 .add("key1", 1)
466 .add(null, 2)
467 .add("key3", null)
468 .add(null, null)
469 .add("key5", 5)
470 .build();
471
472
473 assertSize(2, map);
474 assertEquals(1, map.get("key1"));
475 assertEquals(5, map.get("key5"));
476 assertEquals("key1", map.getKey(1));
477 assertEquals("key5", map.getKey(5));
478 assertNull(map.get(null));
479 assertNull(map.getKey(null));
480 }
481
482 @Test void a24_sizeAfterOperations() {
483 var map = BidiMap.<String,Integer>create().build();
484
485 assertEmpty(map);
486
487 map.put("one", 1);
488 assertSize(1, map);
489
490 map.put("two", 2);
491 assertSize(2, map);
492
493 map.remove("one");
494 assertSize(1, map);
495
496 map.clear();
497 assertEmpty(map);
498 }
499
500 @Test void a25_differentKeyValueTypes() {
501 var map = BidiMap.<Integer,String>create()
502 .add(1, "one")
503 .add(2, "two")
504 .build();
505
506 assertEquals("one", map.get(1));
507 assertEquals(Integer.valueOf(2), map.getKey("two"));
508 }
509
510 @Test void a26_put_duplicateValueThrowsException() {
511 var map = BidiMap.<String,Integer>create()
512 .add("one", 1)
513 .build();
514
515
516 assertThrows(IllegalArgumentException.class, () -> map.put("uno", 1));
517 }
518
519 @Test void a27_put_sameKeyDifferentValueAllowed() {
520 var map = BidiMap.<String,Integer>create()
521 .add("one", 1)
522 .build();
523
524
525 assertEquals(1, map.put("one", 10));
526 assertEquals(10, map.get("one"));
527 assertEquals("one", map.getKey(10));
528 assertNull(map.getKey(1));
529 }
530
531 @Test void a28_putAll_duplicateValueThrowsException() {
532 var map = BidiMap.<String,Integer>create()
533 .add("one", 1)
534 .build();
535
536 var toAdd = new HashMap<String,Integer>();
537 toAdd.put("uno", 1);
538
539
540 assertThrows(IllegalArgumentException.class, () -> map.putAll(toAdd));
541 }
542
543
544
545
546
547 @Test void a29_isEmpty_emptyMap() {
548 var map = BidiMap.<String,Integer>create().build();
549
550 assertTrue(map.isEmpty());
551 assertSize(0, map);
552 }
553
554 @Test void a30_isEmpty_nonEmptyMap() {
555 var map = BidiMap.<String,Integer>create()
556 .add("one", 1)
557 .build();
558
559 assertFalse(map.isEmpty());
560 assertSize(1, map);
561 }
562
563 @Test void a31_isEmpty_afterClear() {
564 var map = BidiMap.<String,Integer>create()
565 .add("one", 1)
566 .add("two", 2)
567 .build();
568
569 assertFalse(map.isEmpty());
570 map.clear();
571 assertTrue(map.isEmpty());
572 }
573
574 @Test void a32_isEmpty_afterRemove() {
575 var map = BidiMap.<String,Integer>create()
576 .add("one", 1)
577 .build();
578
579 assertFalse(map.isEmpty());
580 map.remove("one");
581 assertTrue(map.isEmpty());
582 }
583
584
585
586
587
588 @Test
589 void w01_toString_delegatesToForwardMap() {
590 var map = BidiMap.<String,Integer>create()
591 .add("one", 1)
592 .add("two", 2)
593 .build();
594
595 var forwardMap = new LinkedHashMap<String, Integer>();
596 forwardMap.put("one", 1);
597 forwardMap.put("two", 2);
598
599 assertEquals(forwardMap.toString(), map.toString());
600 }
601
602 @Test
603 void w02_equals_sameContents() {
604 var map1 = BidiMap.<String,Integer>create()
605 .add("one", 1)
606 .add("two", 2)
607 .build();
608
609 var map2 = BidiMap.<String,Integer>create()
610 .add("one", 1)
611 .add("two", 2)
612 .build();
613
614 assertTrue(map1.equals(map2));
615 assertTrue(map2.equals(map1));
616 }
617
618 @Test
619 void w03_equals_differentContents() {
620 var map1 = BidiMap.<String,Integer>create()
621 .add("one", 1)
622 .build();
623
624 var map2 = BidiMap.<String,Integer>create()
625 .add("one", 2)
626 .build();
627
628 assertFalse(map1.equals(map2));
629 assertFalse(map2.equals(map1));
630 }
631
632 @Test
633 void w04_equals_regularMap() {
634 var map = BidiMap.<String,Integer>create()
635 .add("one", 1)
636 .add("two", 2)
637 .build();
638
639 var regularMap = new LinkedHashMap<String, Integer>();
640 regularMap.put("one", 1);
641 regularMap.put("two", 2);
642
643 assertTrue(map.equals(regularMap));
644 assertTrue(regularMap.equals(map));
645 }
646
647 @Test
648 void w05_equals_notAMap() {
649 var map = BidiMap.<String,Integer>create()
650 .add("one", 1)
651 .build();
652
653 assertFalse(map.equals(null));
654 }
655
656 @Test
657 void w06_hashCode_sameContents() {
658 var map1 = BidiMap.<String,Integer>create()
659 .add("one", 1)
660 .add("two", 2)
661 .build();
662
663 var map2 = BidiMap.<String,Integer>create()
664 .add("one", 1)
665 .add("two", 2)
666 .build();
667
668 assertEquals(map1.hashCode(), map2.hashCode());
669 }
670
671 @Test
672 void w07_hashCode_regularMap() {
673 var map = BidiMap.<String,Integer>create()
674 .add("one", 1)
675 .add("two", 2)
676 .build();
677
678 var regularMap = new LinkedHashMap<String, Integer>();
679 regularMap.put("one", 1);
680 regularMap.put("two", 2);
681
682 assertEquals(map.hashCode(), regularMap.hashCode());
683 }
684 }