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.assertNull;
21  import static org.junit.jupiter.api.Assertions.assertThrows;
22  
23  import java.util.ArrayList;
24  import java.util.Arrays;
25  import java.util.Collections;
26  import java.util.Iterator;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.NoSuchElementException;
30  import java.util.TreeMap;
31  
32  import org.apache.commons.collections4.BulkTest;
33  import org.apache.commons.collections4.OrderedMap;
34  import org.apache.commons.collections4.OrderedMapIterator;
35  import org.apache.commons.collections4.comparators.NullComparator;
36  import org.apache.commons.collections4.iterators.AbstractOrderedMapIteratorTest;
37  import org.junit.jupiter.api.Test;
38  
39  /**
40   * Tests {@link OrderedMap}.
41   *
42   * @param <K> the type of the keys in the maps tested.
43   * @param <V> the type of the values in the maps tested.
44   */
45  public abstract class AbstractOrderedMapTest<K, V> extends AbstractIterableMapTest<K, V> {
46  
47      public class InnerTestOrderedMapIterator extends AbstractOrderedMapIteratorTest<K, V> {
48  
49          @Override
50          public Map<K, V> getConfirmedMap() {
51              // assumes makeFullMapIterator() called first
52              return getConfirmed();
53          }
54  
55          @Override
56          public OrderedMap<K, V> getMap() {
57              // assumes makeFullMapIterator() called first
58              return AbstractOrderedMapTest.this.getMap();
59          }
60  
61          @Override
62          public boolean isGetStructuralModify() {
63              return AbstractOrderedMapTest.this.isGetStructuralModify();
64          }
65  
66          @Override
67          public OrderedMapIterator<K, V> makeEmptyIterator() {
68              resetEmpty();
69              return AbstractOrderedMapTest.this.getMap().mapIterator();
70          }
71  
72          @Override
73          public OrderedMapIterator<K, V> makeObject() {
74              resetFull();
75              return AbstractOrderedMapTest.this.getMap().mapIterator();
76          }
77  
78          @Override
79          public boolean supportsRemove() {
80              return isRemoveSupported();
81          }
82  
83          @Override
84          public boolean supportsSetValue() {
85              return isSetValueSupported();
86          }
87  
88          @Override
89          public void verify() {
90              super.verify();
91              AbstractOrderedMapTest.this.verify();
92          }
93      }
94  
95      public BulkTest bulkTestOrderedMapIterator() {
96          return new InnerTestOrderedMapIterator();
97      }
98  
99      /**
100      * {@inheritDoc}
101      */
102     @Override
103     public OrderedMap<K, V> getMap() {
104         return (OrderedMap<K, V>) super.getMap();
105     }
106 
107     /**
108      * The only confirmed collection we have that is ordered is the sorted one. Thus, sort the keys.
109      */
110     @Override
111     @SuppressWarnings("unchecked")
112     public K[] getSampleKeys() {
113         final List<K> list = new ArrayList<>(Arrays.asList(super.getSampleKeys()));
114         list.sort(new NullComparator<>());
115         return (K[]) list.toArray();
116     }
117 
118     /**
119      * OrderedMap uses TreeMap as its known comparison.
120      *
121      * @return a map that is known to be valid
122      */
123     @Override
124     public Map<K, V> makeConfirmedMap() {
125         return new TreeMap<>(new NullComparator<>());
126     }
127 
128     /**
129      * {@inheritDoc}
130      */
131     @Override
132     public OrderedMap<K, V> makeFullMap() {
133         return (OrderedMap<K, V>) super.makeFullMap();
134     }
135 
136     /**
137      * {@inheritDoc}
138      */
139     @Override
140     public abstract OrderedMap<K, V> makeObject();
141 
142     @Test
143     public void testFirstKey() {
144         resetEmpty();
145         OrderedMap<K, V> ordered = getMap();
146         final OrderedMap<K, V> finalOrdered = ordered;
147         assertThrows(NoSuchElementException.class, () -> finalOrdered.firstKey());
148 
149         resetFull();
150         ordered = getMap();
151         final K confirmedFirst = confirmed.keySet().iterator().next();
152         assertEquals(confirmedFirst, ordered.firstKey());
153     }
154 
155     @Test
156     public void testLastKey() {
157         resetEmpty();
158         OrderedMap<K, V> ordered = getMap();
159         final OrderedMap<K, V> finalOrdered = ordered;
160         assertThrows(NoSuchElementException.class, () -> finalOrdered.lastKey());
161 
162         resetFull();
163         ordered = getMap();
164         K confirmedLast = null;
165         for (final Iterator<K> it = confirmed.keySet().iterator(); it.hasNext();) {
166             confirmedLast = it.next();
167         }
168         assertEquals(confirmedLast, ordered.lastKey());
169     }
170 
171     @Test
172     public void testNextKey() {
173         resetEmpty();
174         OrderedMap<K, V> ordered = getMap();
175         assertNull(ordered.nextKey(getOtherKeys()[0]));
176         if (!isAllowNullKey()) {
177             try {
178                 assertNull(ordered.nextKey(null)); // this is allowed too
179             } catch (final NullPointerException ex) {
180             }
181         } else {
182             assertNull(ordered.nextKey(null));
183         }
184 
185         resetFull();
186         ordered = getMap();
187         final Iterator<K> it = confirmed.keySet().iterator();
188         K confirmedLast = it.next();
189         while (it.hasNext()) {
190             final K confirmedObject = it.next();
191             assertEquals(confirmedObject, ordered.nextKey(confirmedLast));
192             confirmedLast = confirmedObject;
193         }
194         assertNull(ordered.nextKey(confirmedLast));
195 
196         if (!isAllowNullKey()) {
197             final OrderedMap<K, V> finalOrdered = ordered;
198             assertThrows(NullPointerException.class, () -> finalOrdered.nextKey(null));
199         } else {
200             assertNull(ordered.nextKey(null));
201         }
202     }
203 
204     @Test
205     public void testPreviousKey() {
206         resetEmpty();
207         OrderedMap<K, V> ordered = getMap();
208         assertNull(ordered.previousKey(getOtherKeys()[0]));
209         if (!isAllowNullKey()) {
210             try {
211                 assertNull(ordered.previousKey(null)); // this is allowed too
212             } catch (final NullPointerException ex) {
213             }
214         } else {
215             assertNull(ordered.previousKey(null));
216         }
217 
218         resetFull();
219         ordered = getMap();
220         final List<K> list = new ArrayList<>(confirmed.keySet());
221         Collections.reverse(list);
222         final Iterator<K> it = list.iterator();
223         K confirmedLast = it.next();
224         while (it.hasNext()) {
225             final K confirmedObject = it.next();
226             assertEquals(confirmedObject, ordered.previousKey(confirmedLast));
227             confirmedLast = confirmedObject;
228         }
229         assertNull(ordered.previousKey(confirmedLast));
230 
231         if (!isAllowNullKey()) {
232             final OrderedMap<K, V> finalOrdered = ordered;
233             assertThrows(NullPointerException.class, () -> finalOrdered.previousKey(null));
234         } else if (!isAllowNullKey()) {
235             assertNull(ordered.previousKey(null));
236         }
237     }
238 
239 }