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.iterators;
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  import static org.junit.jupiter.api.Assertions.assertTrue;
24  
25  import java.util.ArrayList;
26  import java.util.HashSet;
27  import java.util.Iterator;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.NoSuchElementException;
31  import java.util.Set;
32  
33  import org.apache.commons.collections4.OrderedMapIterator;
34  import org.junit.jupiter.api.Test;
35  
36  /**
37   * Abstract class for testing the OrderedMapIterator interface.
38   * <p>
39   * This class provides a framework for testing an implementation of MapIterator.
40   * Concrete subclasses must provide the list iterator to be tested.
41   * They must also specify certain details of how the list iterator operates by
42   * overriding the supportsXxx() methods if necessary.
43   */
44  public abstract class AbstractOrderedMapIteratorTest<K, V> extends AbstractMapIteratorTest<K, V> {
45  
46      /**
47       * JUnit constructor.
48       *
49       * @param testName  the test class name
50       */
51      public AbstractOrderedMapIteratorTest(final String testName) {
52          super(testName);
53      }
54  
55      @Override
56      public abstract OrderedMapIterator<K, V> makeEmptyIterator();
57  
58      @Override
59      public abstract OrderedMapIterator<K, V> makeObject();
60  
61      /**
62       * Test that the empty list iterator contract is correct.
63       */
64      @Test
65      @Override
66      public void testEmptyMapIterator() {
67          if (!supportsEmptyIterator()) {
68              return;
69          }
70  
71          super.testEmptyMapIterator();
72  
73          final OrderedMapIterator<K, V> it = makeEmptyIterator();
74          assertFalse(it.hasPrevious());
75  
76          assertThrows(NoSuchElementException.class, () -> it.previous());
77      }
78  
79      /**
80       * Test that the full list iterator contract is correct.
81       */
82      @Test
83      @Override
84      public void testFullMapIterator() {
85          if (!supportsFullIterator()) {
86              return;
87          }
88  
89          super.testFullMapIterator();
90  
91          final OrderedMapIterator<K, V> it = makeObject();
92          final Map<K, V> map = getMap();
93  
94          assertTrue(it.hasNext());
95          assertFalse(it.hasPrevious());
96          final Set<K> set = new HashSet<>();
97          while (it.hasNext()) {
98              // getKey
99              final K key = it.next();
100             assertSame(key, it.getKey(), "it.next() should equals getKey()");
101             assertTrue(map.containsKey(key),  "Key must be in map");
102             assertTrue(set.add(key), "Key must be unique");
103 
104             // getValue
105             final V value = it.getValue();
106             if (!isGetStructuralModify()) {
107                 assertSame(map.get(key), value, "Value must be mapped to key");
108             }
109             assertTrue(map.containsValue(value),  "Value must be in map");
110 
111             assertTrue(it.hasPrevious());
112 
113             verify();
114         }
115         while (it.hasPrevious()) {
116             // getKey
117             final Object key = it.previous();
118             assertSame(key, it.getKey(), "it.previous() should equals getKey()");
119             assertTrue(map.containsKey(key),  "Key must be in map");
120             assertTrue(set.remove(key), "Key must be unique");
121 
122             // getValue
123             final Object value = it.getValue();
124             if (!isGetStructuralModify()) {
125                 assertSame(map.get(key), value, "Value must be mapped to key");
126             }
127             assertTrue(map.containsValue(value),  "Value must be in map");
128 
129             assertTrue(it.hasNext());
130 
131             verify();
132         }
133     }
134 
135     /**
136      * Test that the iterator order matches the keySet order.
137      */
138     @Test
139     public void testMapIteratorOrder() {
140         if (!supportsFullIterator()) {
141             return;
142         }
143 
144         final OrderedMapIterator<K, V> it = makeObject();
145         final Map<K, V> map = getMap();
146 
147         assertEquals(new ArrayList<>(map.keySet()), new ArrayList<>(map.keySet()), "keySet() not consistent");
148 
149         final Iterator<K> it2 = map.keySet().iterator();
150         assertTrue(it.hasNext());
151         assertTrue(it2.hasNext());
152         final List<K> list = new ArrayList<>();
153         while (it.hasNext()) {
154             final K key = it.next();
155             assertEquals(it2.next(), key);
156             list.add(key);
157         }
158         assertEquals(map.size(), list.size());
159         while (it.hasPrevious()) {
160             final K key = it.previous();
161             assertEquals(list.get(list.size() - 1), key);
162             list.remove(list.size() - 1);
163         }
164         assertEquals(0, list.size());
165     }
166 
167 }