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.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  
24  import java.util.ArrayList;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.Map;
28  
29  import org.apache.commons.collections4.BulkTest;
30  import org.apache.commons.collections4.MapIterator;
31  import org.apache.commons.collections4.OrderedMap;
32  import org.apache.commons.collections4.ResettableIterator;
33  import org.apache.commons.collections4.list.AbstractListTest;
34  import org.junit.jupiter.api.Test;
35  
36  /**
37   * JUnit tests.
38   *
39   * @param <K> the key type.
40   * @param <V> the value type.
41   */
42  public class LinkedMapTest<K, V> extends AbstractOrderedMapTest<K, V> {
43  
44      public class TestListView extends AbstractListTest<K> {
45  
46          @Override
47          public K[] getFullElements() {
48              return getSampleKeys();
49          }
50  
51          @Override
52          public boolean isAddSupported() {
53              return false;
54          }
55  
56          @Override
57          public boolean isNullSupported() {
58              return isAllowNullKey();
59          }
60  
61          @Override
62          public boolean isRemoveSupported() {
63              return false;
64          }
65  
66          @Override
67          public boolean isSetSupported() {
68              return false;
69          }
70  
71          @Override
72          public boolean isTestSerialization() {
73              return false;
74          }
75  
76          @Override
77          public List<K> makeFullCollection() {
78              return LinkedMapTest.this.makeFullMap().asList();
79          }
80  
81          @Override
82          public List<K> makeObject() {
83              return LinkedMapTest.this.makeObject().asList();
84          }
85      }
86  
87      public BulkTest bulkTestListView() {
88          return new TestListView();
89      }
90  
91      @Override
92      public String getCompatibilityVersion() {
93          return "4";
94      }
95  
96      /**
97       * {@inheritDoc}
98       */
99      @Override
100     public LinkedMap<K, V> getMap() {
101         return (LinkedMap<K, V>) super.getMap();
102     }
103 
104     /**
105      * {@inheritDoc}
106      */
107     @Override
108     public LinkedMap<K, V> makeFullMap() {
109         return (LinkedMap<K, V>) super.makeFullMap();
110     }
111 
112     @Override
113     public LinkedMap<K, V> makeObject() {
114         return new LinkedMap<>();
115     }
116 
117     @Test
118     @SuppressWarnings("unchecked")
119     public void testClone() {
120         final LinkedMap<K, V> map = new LinkedMap<>(10);
121         map.put((K) "1", (V) "1");
122         final Map<K, V> cloned = map.clone();
123         assertEquals(map.size(), cloned.size());
124         assertSame(map.get("1"), cloned.get("1"));
125     }
126 
127     @Test
128     public void testGetByIndex() {
129         resetEmpty();
130         assertThrows(IndexOutOfBoundsException.class, () -> getMap().get(0));
131         assertThrows(IndexOutOfBoundsException.class, () -> getMap().get(-1));
132         resetFull();
133         final LinkedMap<K, V> lm = getMap();
134         assertThrows(IndexOutOfBoundsException.class, () -> lm.get(-1));
135         assertThrows(IndexOutOfBoundsException.class, () -> lm.get(lm.size()));
136         int i = 0;
137         for (final MapIterator<K, V> it = lm.mapIterator(); it.hasNext(); i++) {
138             assertSame(it.next(), lm.get(i));
139         }
140     }
141 
142     @Test
143     public void testGetValueByIndex() {
144         resetEmpty();
145         assertThrows(IndexOutOfBoundsException.class, () -> getMap().getValue(0));
146         assertThrows(IndexOutOfBoundsException.class, () -> getMap().getValue(-1));
147         resetFull();
148         final LinkedMap<K, V> lm = getMap();
149         assertThrows(IndexOutOfBoundsException.class, () -> lm.getValue(-1));
150         assertThrows(IndexOutOfBoundsException.class, () -> lm.getValue(lm.size()));
151         int i = 0;
152         for (final MapIterator<K, V> it = lm.mapIterator(); it.hasNext(); i++) {
153             it.next();
154             assertSame(it.getValue(), lm.getValue(i));
155         }
156     }
157 
158     @Test
159     public void testIndexOf() {
160         resetEmpty();
161         LinkedMap<K, V> lm = getMap();
162         assertEquals(-1, lm.indexOf(getOtherKeys()));
163 
164         resetFull();
165         lm = getMap();
166         final List<K> list = new ArrayList<>();
167         for (final MapIterator<K, V> it = lm.mapIterator(); it.hasNext();) {
168             list.add(it.next());
169         }
170         for (int i = 0; i < list.size(); i++) {
171             assertEquals(i, lm.indexOf(list.get(i)));
172         }
173     }
174 
175     /**
176      * Test for <a href="https://issues.apache.org/jira/browse/COLLECTIONS-323">COLLECTIONS-323</a>.
177      */
178     @Test
179     public void testInitialCapacityZero() {
180         final LinkedMap<String, String> map = new LinkedMap<>(0);
181         assertEquals(1, map.data.length);
182     }
183 
184     @Test
185     public void testInsertionOrder() {
186         if (!isPutAddSupported() || !isPutChangeSupported()) {
187             return;
188         }
189         final K[] keys = getSampleKeys();
190         final V[] values = getSampleValues();
191         Iterator<K> keyIter;
192         Iterator<V> valueIter;
193 
194         resetEmpty();
195         map.put(keys[0], values[0]);
196         map.put(keys[1], values[1]);
197         keyIter = map.keySet().iterator();
198         assertSame(keys[0], keyIter.next());
199         assertSame(keys[1], keyIter.next());
200         valueIter = map.values().iterator();
201         assertSame(values[0], valueIter.next());
202         assertSame(values[1], valueIter.next());
203 
204         // no change to order
205         map.put(keys[1], values[1]);
206         keyIter = map.keySet().iterator();
207         assertSame(keys[0], keyIter.next());
208         assertSame(keys[1], keyIter.next());
209         valueIter = map.values().iterator();
210         assertSame(values[0], valueIter.next());
211         assertSame(values[1], valueIter.next());
212 
213         // no change to order
214         map.put(keys[1], values[2]);
215         keyIter = map.keySet().iterator();
216         assertSame(keys[0], keyIter.next());
217         assertSame(keys[1], keyIter.next());
218         valueIter = map.values().iterator();
219         assertSame(values[0], valueIter.next());
220         assertSame(values[2], valueIter.next());
221 
222         // no change to order
223         map.put(keys[0], values[3]);
224         keyIter = map.keySet().iterator();
225         assertSame(keys[0], keyIter.next());
226         assertSame(keys[1], keyIter.next());
227         valueIter = map.values().iterator();
228         assertSame(values[3], valueIter.next());
229         assertSame(values[2], valueIter.next());
230     }
231 
232 //    public void testCreate() throws Exception {
233 //        resetEmpty();
234 //        writeExternalFormToDisk((java.io.Serializable) map, "src/test/resources/data/test/LinkedMap.emptyCollection.version4.obj");
235 //        resetFull();
236 //        writeExternalFormToDisk((java.io.Serializable) map, "src/test/resources/data/test/LinkedMap.fullCollection.version4.obj");
237 //    }
238 
239     @Test
240     public void testRemoveByIndex() {
241         resetEmpty();
242         assertThrows(IndexOutOfBoundsException.class, () -> getMap().remove(0));
243         assertThrows(IndexOutOfBoundsException.class, () -> getMap().remove(-1));
244         resetFull();
245         final LinkedMap<K, V> lm = getMap();
246         assertThrows(IndexOutOfBoundsException.class, () -> lm.remove(-1));
247         assertThrows(IndexOutOfBoundsException.class, () -> lm.remove(lm.size()));
248         final List<K> list = new ArrayList<>();
249         for (final MapIterator<K, V> it = lm.mapIterator(); it.hasNext();) {
250             list.add(it.next());
251         }
252         for (int i = 0; i < list.size(); i++) {
253             final Object key = list.get(i);
254             final Object value = lm.get(key);
255             assertEquals(value, lm.remove(i));
256             list.remove(i);
257             assertFalse(lm.containsKey(key));
258         }
259     }
260 
261     @Test
262     @SuppressWarnings("unchecked")
263     public void testReset() {
264         resetEmpty();
265         OrderedMap<K, V> ordered = getMap();
266         ((ResettableIterator<K>) ordered.mapIterator()).reset();
267 
268         resetFull();
269         ordered = getMap();
270         final List<K> list = new ArrayList<>(ordered.keySet());
271         final ResettableIterator<K> it = (ResettableIterator<K>) ordered.mapIterator();
272         assertSame(list.get(0), it.next());
273         assertSame(list.get(1), it.next());
274         it.reset();
275         assertSame(list.get(0), it.next());
276     }
277 }