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.assertThrows;
22  
23  import java.util.ArrayList;
24  import java.util.List;
25  import java.util.ListIterator;
26  import java.util.NoSuchElementException;
27  
28  import org.apache.commons.collections4.ResettableListIterator;
29  import org.junit.jupiter.api.BeforeEach;
30  import org.junit.jupiter.api.Test;
31  
32  /**
33   * Tests the ListIteratorWrapper to ensure that it simulates
34   * a ListIterator correctly.
35   *
36   * @param <E> the type of elements tested by this iterator.
37   */
38  public class ListIteratorWrapperTest<E> extends AbstractIteratorTest<E> {
39  
40      protected String[] testArray = {
41          "One", "Two", "Three", "Four", "Five", "Six"
42      };
43  
44      protected List<E> list1;
45  
46      @Override
47      public ResettableListIterator<E> makeEmptyIterator() {
48          final ArrayList<E> list = new ArrayList<>();
49          return new ListIteratorWrapper<>(list.iterator());
50      }
51  
52      @Override
53      public ResettableListIterator<E> makeObject() {
54          return new ListIteratorWrapper<>(list1.iterator());
55      }
56  
57      @BeforeEach
58      @SuppressWarnings("unchecked")
59      public void setUp() {
60          list1 = new ArrayList<>();
61          list1.add((E) "One");
62          list1.add((E) "Two");
63          list1.add((E) "Three");
64          list1.add((E) "Four");
65          list1.add((E) "Five");
66          list1.add((E) "Six");
67      }
68  
69      @Test
70      public void testIterator() {
71          final ListIterator<E> iter = makeObject();
72          for (final String testValue : testArray) {
73              final Object iterValue = iter.next();
74              assertEquals(testValue, iterValue, "Iteration value is correct");
75          }
76          assertFalse(iter.hasNext(), "Iterator should now be empty");
77          assertThrows(NoSuchElementException.class, iter::next);
78          // now, read it backwards
79          for (int i = testArray.length - 1; i > -1; --i) {
80              final Object testValue = testArray[i];
81              final E iterValue = iter.previous();
82              assertEquals(testValue, iterValue, "Iteration value is correct");
83          }
84          assertThrows(NoSuchElementException.class, iter::previous);
85          // now, read it forwards again
86          for (final String testValue : testArray) {
87              final Object iterValue = iter.next();
88              assertEquals(testValue, iterValue, "Iteration value is correct");
89          }
90      }
91  
92      @Test
93      @Override
94      public void testRemove() {
95          final ListIterator<E> iter = makeObject();
96  
97          //initial state:
98          assertEquals(-1, iter.previousIndex());
99          assertEquals(0, iter.nextIndex());
100 
101         assertThrows(IllegalStateException.class, () -> iter.remove(),
102                 "ListIteratorWrapper#remove() should fail; must be initially positioned first");
103 
104         //no change from invalid op:
105         assertEquals(-1, iter.previousIndex());
106         assertEquals(0, iter.nextIndex());
107 
108         //establish size:
109         int sz = list1.size();
110 
111         //verify initial next() call:
112         assertEquals(list1.get(0), iter.next());
113         assertEquals(0, iter.previousIndex());
114         assertEquals(1, iter.nextIndex());
115 
116         //verify remove():
117         iter.remove();
118         assertEquals(--sz, list1.size());
119         //like we never started iterating:
120         assertEquals(-1, iter.previousIndex());
121         assertEquals(0, iter.nextIndex());
122 
123         assertThrows(IllegalStateException.class, () -> iter.remove(),
124                 "ListIteratorWrapper#remove() should fail; must be repositioned first");
125 
126         //no change from invalid op:
127         assertEquals(-1, iter.previousIndex());
128         assertEquals(0, iter.nextIndex());
129 
130         //two consecutive next() calls:
131         assertEquals(list1.get(0), iter.next());
132         assertEquals(0, iter.previousIndex());
133         assertEquals(1, iter.nextIndex());
134 
135         assertEquals(list1.get(1), iter.next());
136         assertEquals(1, iter.previousIndex());
137         assertEquals(2, iter.nextIndex());
138 
139         //call previous():
140         assertEquals(list1.get(1), iter.previous());
141         assertEquals(0, iter.previousIndex());
142         assertEquals(1, iter.nextIndex());
143 
144         //should support remove() after calling previous() once from tip because we haven't changed the underlying iterator's position:
145         iter.remove();
146         assertEquals(--sz, list1.size());
147         assertEquals(0, iter.previousIndex());
148         assertEquals(1, iter.nextIndex());
149 
150         //dig into cache
151         assertEquals(list1.get(0), iter.previous());
152         assertEquals(-1, iter.previousIndex());
153         assertEquals(0, iter.nextIndex());
154 
155         assertThrows(IllegalStateException.class, () -> iter.remove(),
156                 "ListIteratorWrapper does not support the remove() method while dug into the cache via previous()");
157 
158         //no change from invalid op:
159         assertEquals(-1, iter.previousIndex());
160         assertEquals(0, iter.nextIndex());
161 
162         //dig out of cache, first next() maintains current position:
163         assertEquals(list1.get(0), iter.next());
164         assertEquals(0, iter.previousIndex());
165         assertEquals(1, iter.nextIndex());
166         //continue traversing underlying iterator with this next() call, and we're out of the hole, so to speak:
167         assertEquals(list1.get(1), iter.next());
168         assertEquals(1, iter.previousIndex());
169         assertEquals(2, iter.nextIndex());
170 
171         //verify remove() works again:
172         iter.remove();
173         assertEquals(--sz, list1.size());
174         assertEquals(0, iter.previousIndex());
175         assertEquals(1, iter.nextIndex());
176 
177         assertEquals(list1.get(1), iter.next());
178         assertEquals(1, iter.previousIndex());
179         assertEquals(2, iter.nextIndex());
180 
181     }
182 
183     @Test
184     public void testReset() {
185         final ResettableListIterator<E> iter = makeObject();
186         final E first = iter.next();
187         final E second = iter.next();
188 
189         iter.reset();
190 
191         // after reset, there shouldn't be any previous elements
192         assertFalse(iter.hasPrevious(), "No previous elements after reset()");
193 
194         // after reset, the results should be the same as before
195         assertEquals(first, iter.next(), "First element should be the same");
196         assertEquals(second, iter.next(), "Second element should be the same");
197 
198         // after passing the point, where we reset, continuation should work as expected
199         for (int i = 2; i < testArray.length; i++) {
200             final Object testValue = testArray[i];
201             final E iterValue = iter.next();
202 
203             assertEquals(testValue, iterValue, "Iteration value is correct");
204         }
205     }
206 
207 }