View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4.map;
18  
19  import static org.junit.jupiter.api.Assertions.assertAll;
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertFalse;
22  import static org.junit.jupiter.api.Assertions.assertSame;
23  import static org.junit.jupiter.api.Assertions.assertThrows;
24  
25  import java.util.ArrayList;
26  import java.util.HashMap;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.TreeMap;
30  
31  import org.apache.commons.collections4.BulkTest;
32  import org.apache.commons.collections4.MapIterator;
33  import org.apache.commons.collections4.list.AbstractListTest;
34  import org.apache.commons.lang3.StringUtils;
35  import org.junit.jupiter.api.Test;
36  
37  /**
38   * Extension of {@link AbstractOrderedMapTest} for exercising the {@link ListOrderedMap} implementation.
39   */
40  public class ListOrderedMapTest<K, V> extends AbstractOrderedMapTest<K, V> {
41  
42      public class TestKeyListView extends AbstractListTest<K> {
43  
44          TestKeyListView() {
45              super("TestKeyListView");
46          }
47  
48          @Override
49          public K[] getFullElements() {
50              return ListOrderedMapTest.this.getSampleKeys();
51          }
52  
53          @Override
54          public boolean isAddSupported() {
55              return false;
56          }
57  
58          @Override
59          public boolean isNullSupported() {
60              return ListOrderedMapTest.this.isAllowNullKey();
61          }
62  
63          @Override
64          public boolean isRemoveSupported() {
65              return false;
66          }
67  
68          @Override
69          public boolean isSetSupported() {
70              return false;
71          }
72  
73          @Override
74          public boolean isTestSerialization() {
75              return false;
76          }
77  
78          @Override
79          public List<K> makeFullCollection() {
80              return ListOrderedMapTest.this.makeFullMap().keyList();
81          }
82  
83          @Override
84          public List<K> makeObject() {
85              return ListOrderedMapTest.this.makeObject().keyList();
86          }
87  
88      }
89  
90      public class TestValueListView extends AbstractListTest<V> {
91  
92          TestValueListView() {
93              super("TestValueListView");
94          }
95  
96          @Override
97          public V[] getFullElements() {
98              return ListOrderedMapTest.this.getSampleValues();
99          }
100 
101         @Override
102         public boolean isAddSupported() {
103             return false;
104         }
105 
106         @Override
107         public boolean isNullSupported() {
108             return ListOrderedMapTest.this.isAllowNullKey();
109         }
110 
111         @Override
112         public boolean isRemoveSupported() {
113             return true;
114         }
115 
116         @Override
117         public boolean isSetSupported() {
118             return true;
119         }
120 
121         @Override
122         public boolean isTestSerialization() {
123             return false;
124         }
125 
126         @Override
127         public List<V> makeFullCollection() {
128             return ListOrderedMapTest.this.makeFullMap().valueList();
129         }
130 
131         @Override
132         public List<V> makeObject() {
133             return ListOrderedMapTest.this.makeObject().valueList();
134         }
135 
136     }
137 
138     public ListOrderedMapTest() {
139         super(ListOrderedMapTest.class.getSimpleName());
140     }
141 
142     public BulkTest bulkTestKeyListView() {
143         return new TestKeyListView();
144     }
145 
146     public BulkTest bulkTestValueListView() {
147         return new TestValueListView();
148     }
149 
150     @Override
151     public String getCompatibilityVersion() {
152         return "4";
153     }
154 
155     /**
156      * {@inheritDoc}
157      */
158     @Override
159     public ListOrderedMap<K, V> getMap() {
160         return (ListOrderedMap<K, V>) super.getMap();
161     }
162 
163     /**
164      * {@inheritDoc}
165      */
166     @Override
167     public ListOrderedMap<K, V> makeFullMap() {
168         return (ListOrderedMap<K, V>) super.makeFullMap();
169     }
170 
171     @Override
172     public ListOrderedMap<K, V> makeObject() {
173         return ListOrderedMap.listOrderedMap(new HashMap<>());
174     }
175 
176     @Test
177     public void testCOLLECTIONS_474_nonNullValues() {
178         final Object key1 = new Object();
179         final Object key2 = new Object();
180         final HashMap<Object, Object> hmap = new HashMap<>();
181         hmap.put(key1, "1");
182         hmap.put(key2, "2");
183         assertEquals(2, hmap.size(), "Should have two elements");
184         final ListOrderedMap<Object, Object> listMap = new ListOrderedMap<>();
185         listMap.put(key1, "3");
186         listMap.put(key2, "4");
187         assertEquals(2, listMap.size(), "Should have two elements");
188         listMap.putAll(2, hmap);
189     }
190 
191     @Test
192     public void testCOLLECTIONS_474_nullValues() {
193         final Object key1 = new Object();
194         final Object key2 = new Object();
195         final HashMap<Object, Object> hmap = new HashMap<>();
196         hmap.put(key1, null);
197         hmap.put(key2, null);
198         assertEquals(2, hmap.size(), "Should have two elements");
199         final ListOrderedMap<Object, Object> listMap = new ListOrderedMap<>();
200         listMap.put(key1, null);
201         listMap.put(key2, null);
202         assertEquals(2, listMap.size(), "Should have two elements");
203         listMap.putAll(2, hmap);
204     }
205 
206     @Test
207     public void testGetByIndex() {
208         resetEmpty();
209         ListOrderedMap<K, V> lom = getMap();
210         try {
211             lom.get(0);
212         } catch (final IndexOutOfBoundsException ex) {
213         }
214         try {
215             lom.get(-1);
216         } catch (final IndexOutOfBoundsException ex) {
217         }
218 
219         resetFull();
220         lom = getMap();
221         try {
222             lom.get(-1);
223         } catch (final IndexOutOfBoundsException ex) {
224         }
225         try {
226             lom.get(lom.size());
227         } catch (final IndexOutOfBoundsException ex) {
228         }
229 
230         int i = 0;
231         for (final MapIterator<K, V> it = lom.mapIterator(); it.hasNext(); i++) {
232             assertSame(it.next(), lom.get(i));
233         }
234     }
235 
236     @Test
237     public void testGetValueByIndex() {
238         resetEmpty();
239         ListOrderedMap<K, V> lom = getMap();
240         try {
241             lom.getValue(0);
242         } catch (final IndexOutOfBoundsException ex) {
243         }
244         try {
245             lom.getValue(-1);
246         } catch (final IndexOutOfBoundsException ex) {
247         }
248 
249         resetFull();
250         lom = getMap();
251         try {
252             lom.getValue(-1);
253         } catch (final IndexOutOfBoundsException ex) {
254         }
255         try {
256             lom.getValue(lom.size());
257         } catch (final IndexOutOfBoundsException ex) {
258         }
259 
260         int i = 0;
261         for (final MapIterator<K, V> it = lom.mapIterator(); it.hasNext(); i++) {
262             it.next();
263             assertSame(it.getValue(), lom.getValue(i));
264         }
265     }
266 
267     @Test
268     public void testIndexOf() {
269         resetEmpty();
270         ListOrderedMap<K, V> lom = getMap();
271         assertEquals(-1, lom.indexOf(getOtherKeys()));
272 
273         resetFull();
274         lom = getMap();
275         final List<K> list = new ArrayList<>();
276         for (final MapIterator<K, V> it = lom.mapIterator(); it.hasNext();) {
277             list.add(it.next());
278         }
279         for (int i = 0; i < list.size(); i++) {
280             assertEquals(i, lom.indexOf(list.get(i)));
281         }
282     }
283 
284     @Test
285     @SuppressWarnings("unchecked")
286     public void testPut_intObjectObject() {
287         resetEmpty();
288         ListOrderedMap<K, V> lom = getMap();
289 
290         final ListOrderedMap<K, V> finalLom = lom;
291         assertAll(
292                 () -> assertThrows(IndexOutOfBoundsException.class, () -> finalLom.put(1, (K) "testInsert1", (V) "testInsert1v"),
293                         "should not be able to insert at pos 1 in empty Map"),
294                 () -> assertThrows(IndexOutOfBoundsException.class, () -> finalLom.put(-1, (K) "testInsert-1", (V) "testInsert-1v"),
295                         "should not be able to insert at pos -1 in empty Map"));
296 
297         // put where key doesn't exist
298         lom.put(0, (K) "testInsert1", (V) "testInsert1v");
299         assertEquals("testInsert1v", lom.getValue(0));
300 
301         lom.put((K) "testInsertPut", (V) "testInsertPutv");
302         assertEquals("testInsert1v", lom.getValue(0));
303         assertEquals("testInsertPutv", lom.getValue(1));
304 
305         lom.put(0, (K) "testInsert0", (V) "testInsert0v");
306         assertEquals("testInsert0v", lom.getValue(0));
307         assertEquals("testInsert1v", lom.getValue(1));
308         assertEquals("testInsertPutv", lom.getValue(2));
309 
310         lom.put(3, (K) "testInsert3", (V) "testInsert3v");
311         assertEquals("testInsert0v", lom.getValue(0));
312         assertEquals("testInsert1v", lom.getValue(1));
313         assertEquals("testInsertPutv", lom.getValue(2));
314         assertEquals("testInsert3v", lom.getValue(3));
315 
316         // put in a full map
317         resetFull();
318         lom = getMap();
319         final ListOrderedMap<K, V> lom2 = new ListOrderedMap<>();
320         lom2.putAll(lom);
321 
322         lom2.put(0, (K) "testInsert0", (V) "testInsert0v");
323         assertEquals("testInsert0v", lom2.getValue(0));
324         for (int i = 0; i < lom.size(); i++) {
325             assertEquals(lom2.getValue(i + 1), lom.getValue(i));
326         }
327 
328         // put where key does exist
329         final Integer i1 = Integer.valueOf(1);
330         final Integer i1b = Integer.valueOf(1);
331         final Integer i2 = Integer.valueOf(2);
332         final Integer i3 = Integer.valueOf(3);
333 
334         resetEmpty();
335         lom = getMap();
336         lom.put((K) i1, (V) "1");
337         lom.put((K) i2, (V) "2");
338         lom.put((K) i3, (V) "3");
339         lom.put(0, (K) i1, (V) "One");
340         assertEquals(3, lom.size());
341         assertEquals(3, lom.map.size());
342         assertEquals(3, lom.keyList().size());
343         assertEquals("One", lom.getValue(0));
344         assertSame(i1, lom.get(0));
345 
346         resetEmpty();
347         lom = getMap();
348         lom.put((K) i1, (V) "1");
349         lom.put((K) i2, (V) "2");
350         lom.put((K) i3, (V) "3");
351         lom.put(0, (K) i1b, (V) "One");
352         assertEquals(3, lom.size());
353         assertEquals(3, lom.map.size());
354         assertEquals(3, lom.keyList().size());
355         assertEquals("One", lom.getValue(0));
356         assertEquals("2", lom.getValue(1));
357         assertEquals("3", lom.getValue(2));
358         assertSame(i1b, lom.get(0));
359 
360         resetEmpty();
361         lom = getMap();
362         lom.put((K) i1, (V) "1");
363         lom.put((K) i2, (V) "2");
364         lom.put((K) i3, (V) "3");
365         lom.put(1, (K) i1b, (V) "One");
366         assertEquals(3, lom.size());
367         assertEquals(3, lom.map.size());
368         assertEquals(3, lom.keyList().size());
369         assertEquals("One", lom.getValue(0));
370         assertEquals("2", lom.getValue(1));
371         assertEquals("3", lom.getValue(2));
372 
373         resetEmpty();
374         lom = getMap();
375         lom.put((K) i1, (V) "1");
376         lom.put((K) i2, (V) "2");
377         lom.put((K) i3, (V) "3");
378         lom.put(2, (K) i1b, (V) "One");
379         assertEquals(3, lom.size());
380         assertEquals(3, lom.map.size());
381         assertEquals(3, lom.keyList().size());
382         assertEquals("2", lom.getValue(0));
383         assertEquals("One", lom.getValue(1));
384         assertEquals("3", lom.getValue(2));
385 
386         resetEmpty();
387         lom = getMap();
388         lom.put((K) i1, (V) "1");
389         lom.put((K) i2, (V) "2");
390         lom.put((K) i3, (V) "3");
391         lom.put(3, (K) i1b, (V) "One");
392         assertEquals(3, lom.size());
393         assertEquals(3, lom.map.size());
394         assertEquals(3, lom.keyList().size());
395         assertEquals("2", lom.getValue(0));
396         assertEquals("3", lom.getValue(1));
397         assertEquals("One", lom.getValue(2));
398     }
399 
400     @Test
401     public void testPutAllWithIndex() {
402         resetEmpty();
403         @SuppressWarnings("unchecked")
404         final ListOrderedMap<String, String> lom = (ListOrderedMap<String, String>) map;
405 
406         // Create Initial Data
407         lom.put("testInsert0", "testInsert0v");
408         lom.put("testInsert1", "testInsert1v");
409         lom.put("testInsert2", "testInsert2v");
410         assertEquals("testInsert0v", lom.getValue(0));
411         assertEquals("testInsert1v", lom.getValue(1));
412         assertEquals("testInsert2v", lom.getValue(2));
413 
414         // Create New Test Map and Add using putAll(int, Object, Object)
415         final Map<String, String> values = new ListOrderedMap<>();
416         values.put("NewInsert0", "NewInsert0v");
417         values.put("NewInsert1", "NewInsert1v");
418         lom.putAll(1, values);
419 
420         // Perform Asserts
421         assertEquals("testInsert0v", lom.getValue(0));
422         assertEquals("NewInsert0v", lom.getValue(1));
423         assertEquals("NewInsert1v", lom.getValue(2));
424         assertEquals("testInsert1v", lom.getValue(3));
425         assertEquals("testInsert2v", lom.getValue(4));
426     }
427 
428     @Test
429     @SuppressWarnings("unchecked")
430     public void testPutAllWithIndexBug441() {
431         // see COLLECTIONS-441
432         resetEmpty();
433         final ListOrderedMap<K, V> lom = getMap();
434 
435         final int size = 5;
436         for (int i = 0; i < size; i++) {
437             lom.put((K) Integer.valueOf(i), (V) Boolean.TRUE);
438         }
439 
440         final Map<K, V> map = new TreeMap<>();
441         for (int i = 0; i < size; i++) {
442             map.put((K) Integer.valueOf(i), (V) Boolean.FALSE);
443         }
444 
445         lom.putAll(3, map);
446 
447         final List<K> orderedList = lom.asList();
448         for (int i = 0; i < size; i++) {
449             assertEquals(Integer.valueOf(i), orderedList.get(i));
450         }
451     }
452 
453     @Test
454     public void testRemoveByIndex() {
455         resetEmpty();
456         ListOrderedMap<K, V> lom = getMap();
457         try {
458             lom.remove(0);
459         } catch (final IndexOutOfBoundsException ex) {
460         }
461         try {
462             lom.remove(-1);
463         } catch (final IndexOutOfBoundsException ex) {
464         }
465 
466         resetFull();
467         lom = getMap();
468         try {
469             lom.remove(-1);
470         } catch (final IndexOutOfBoundsException ex) {
471         }
472         try {
473             lom.remove(lom.size());
474         } catch (final IndexOutOfBoundsException ex) {
475         }
476 
477         final List<K> list = new ArrayList<>();
478         for (final MapIterator<K, V> it = lom.mapIterator(); it.hasNext();) {
479             list.add(it.next());
480         }
481         for (int i = 0; i < list.size(); i++) {
482             final Object key = list.get(i);
483             final Object value = lom.get(key);
484             assertEquals(value, lom.remove(i));
485             list.remove(i);
486             assertFalse(lom.containsKey(key));
487         }
488     }
489 
490     @Test
491     @SuppressWarnings("unchecked")
492     public void testSetValueByIndex() {
493         resetEmpty();
494         ListOrderedMap<K, V> lom = getMap();
495         try {
496             lom.setValue(0, (V) StringUtils.EMPTY);
497         } catch (final IndexOutOfBoundsException ex) {
498         }
499         try {
500             lom.setValue(-1, (V) StringUtils.EMPTY);
501         } catch (final IndexOutOfBoundsException ex) {
502         }
503 
504         resetFull();
505         lom = getMap();
506         try {
507             lom.setValue(-1, (V) StringUtils.EMPTY);
508         } catch (final IndexOutOfBoundsException ex) {
509         }
510         try {
511             lom.setValue(lom.size(), (V) StringUtils.EMPTY);
512         } catch (final IndexOutOfBoundsException ex) {
513         }
514 
515         for (int i = 0; i < lom.size(); i++) {
516             final V value = lom.getValue(i);
517             final Object input = Integer.valueOf(i);
518             assertEquals(value, lom.setValue(i, (V) input));
519             assertEquals(input, lom.getValue(i));
520         }
521     }
522 
523     @Test
524     public void testValueList_getByIndex() {
525         resetFull();
526         final ListOrderedMap<K, V> lom = getMap();
527         for (int i = 0; i < lom.size(); i++) {
528             final V expected = lom.getValue(i);
529             assertEquals(expected, lom.valueList().get(i));
530         }
531     }
532 
533     @Test
534     public void testValueList_removeByIndex() {
535         resetFull();
536         final ListOrderedMap<K, V> lom = getMap();
537         while (lom.size() > 1) {
538             final V expected = lom.getValue(1);
539             assertEquals(expected, lom.valueList().remove(1));
540         }
541     }
542 
543 //    public void testCreate() throws Exception {
544 //        resetEmpty();
545 //        writeExternalFormToDisk(
546 //            (java.io.Serializable) map,
547 //            "src/test/resources/data/test/ListOrderedMap.emptyCollection.version4.obj");
548 //        resetFull();
549 //        writeExternalFormToDisk(
550 //            (java.io.Serializable) map,
551 //            "src/test/resources/data/test/ListOrderedMap.fullCollection.version4.obj");
552 //    }
553 
554     @Test
555     @SuppressWarnings("unchecked")
556     public void testValueList_setByIndex() {
557         resetFull();
558         final ListOrderedMap<K, V> lom = getMap();
559         for (int i = 0; i < lom.size(); i++) {
560             final Object input = Integer.valueOf(i);
561             final V expected = lom.getValue(i);
562             assertEquals(expected, lom.valueList().set(i, (V) input));
563             assertEquals(input, lom.getValue(i));
564             assertEquals(input, lom.valueList().get(i));
565         }
566     }
567 
568 }