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   * @param <K> the type of the keys in the maps tested.
45   * @param <V> the type of the values in the maps tested.
46   */
47  public abstract class AbstractOrderedMapIteratorTest<K, V> extends AbstractMapIteratorTest<K, V> {
48  
49      @Override
50      public abstract OrderedMapIterator<K, V> makeEmptyIterator();
51  
52      @Override
53      public abstract OrderedMapIterator<K, V> makeObject();
54  
55      /**
56       * Test that the empty list iterator contract is correct.
57       */
58      @Test
59      @Override
60      public void testEmptyMapIterator() {
61          if (!supportsEmptyIterator()) {
62              return;
63          }
64  
65          super.testEmptyMapIterator();
66  
67          final OrderedMapIterator<K, V> it = makeEmptyIterator();
68          assertFalse(it.hasPrevious());
69  
70          assertThrows(NoSuchElementException.class, () -> it.previous());
71      }
72  
73      /**
74       * Test that the full list iterator contract is correct.
75       */
76      @Test
77      @Override
78      public void testFullMapIterator() {
79          if (!supportsFullIterator()) {
80              return;
81          }
82  
83          super.testFullMapIterator();
84  
85          final OrderedMapIterator<K, V> it = makeObject();
86          final Map<K, V> map = getMap();
87  
88          assertTrue(it.hasNext());
89          assertFalse(it.hasPrevious());
90          final Set<K> set = new HashSet<>();
91          while (it.hasNext()) {
92              // getKey
93              final K key = it.next();
94              assertSame(key, it.getKey(), "it.next() should equals getKey()");
95              assertTrue(map.containsKey(key),  "Key must be in map");
96              assertTrue(set.add(key), "Key must be unique");
97  
98              // getValue
99              final V value = it.getValue();
100             if (!isGetStructuralModify()) {
101                 assertSame(map.get(key), value, "Value must be mapped to key");
102             }
103             assertTrue(map.containsValue(value),  "Value must be in map");
104 
105             assertTrue(it.hasPrevious());
106 
107             verify();
108         }
109         while (it.hasPrevious()) {
110             // getKey
111             final Object key = it.previous();
112             assertSame(key, it.getKey(), "it.previous() should equals getKey()");
113             assertTrue(map.containsKey(key),  "Key must be in map");
114             assertTrue(set.remove(key), "Key must be unique");
115 
116             // getValue
117             final Object value = it.getValue();
118             if (!isGetStructuralModify()) {
119                 assertSame(map.get(key), value, "Value must be mapped to key");
120             }
121             assertTrue(map.containsValue(value),  "Value must be in map");
122 
123             assertTrue(it.hasNext());
124 
125             verify();
126         }
127     }
128 
129     /**
130      * Test that the iterator order matches the keySet order.
131      */
132     @Test
133     public void testMapIteratorOrder() {
134         if (!supportsFullIterator()) {
135             return;
136         }
137 
138         final OrderedMapIterator<K, V> it = makeObject();
139         final Map<K, V> map = getMap();
140 
141         assertEquals(new ArrayList<>(map.keySet()), new ArrayList<>(map.keySet()), "keySet() not consistent");
142 
143         final Iterator<K> it2 = map.keySet().iterator();
144         assertTrue(it.hasNext());
145         assertTrue(it2.hasNext());
146         final List<K> list = new ArrayList<>();
147         while (it.hasNext()) {
148             final K key = it.next();
149             assertEquals(it2.next(), key);
150             list.add(key);
151         }
152         assertEquals(map.size(), list.size());
153         while (it.hasPrevious()) {
154             final K key = it.previous();
155             assertEquals(list.get(list.size() - 1), key);
156             list.remove(list.size() - 1);
157         }
158         assertEquals(0, list.size());
159     }
160 
161 }