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