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.assertAll;
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertFalse;
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.Arrays;
27  import java.util.List;
28  import java.util.NoSuchElementException;
29  
30  import org.junit.jupiter.api.Test;
31  
32  /**
33   * Tests the LoopingListIterator class.
34   */
35  public class LoopingListIteratorTest {
36  
37      /**
38       * Tests the add method.
39       */
40      @Test
41      public void testAdd() {
42          List<String> list = new ArrayList<>(Arrays.asList("b", "e", "f"));
43          LoopingListIterator<String> loop = new LoopingListIterator<>(list); // <b> e f
44  
45          loop.add("a");                      // <a> b e f
46          assertEquals("b", loop.next());     // a <b> e f
47          loop.reset();                       // <a> b e f
48          assertEquals("a", loop.next());     // a <b> e f
49          assertEquals("b", loop.next());     // a b <e> f
50  
51          loop.add("c");                      // a b c <e> f
52          assertEquals("e", loop.next());     // a b c e <f>
53          assertEquals("e", loop.previous()); // a b c <e> f
54          assertEquals("c", loop.previous()); // a b <c> e f
55          assertEquals("c", loop.next());     // a b c <e> f
56  
57          loop.add("d");                      // a b c d <e> f
58          loop.reset();                       // <a> b c d e f
59          assertEquals("a", loop.next());     // a <b> c d e f
60          assertEquals("b", loop.next());     // a b <c> d e f
61          assertEquals("c", loop.next());     // a b c <d> e f
62          assertEquals("d", loop.next());     // a b c d <e> f
63          assertEquals("e", loop.next());     // a b c d e <f>
64          assertEquals("f", loop.next());     // <a> b c d e f
65          assertEquals("a", loop.next());     // a <b> c d e f
66  
67          list = new ArrayList<>(Arrays.asList("b", "e", "f"));
68          loop = new LoopingListIterator<>(list); // <b> e f
69  
70          loop.add("a");                      // a <b> e f
71          assertEquals("a", loop.previous()); // a b e <f>
72          loop.reset();                       // <a> b e f
73          assertEquals("f", loop.previous()); // a b e <f>
74          assertEquals("e", loop.previous()); // a b <e> f
75  
76          loop.add("d");                      // a b d <e> f
77          assertEquals("d", loop.previous()); // a b <d> e f
78  
79          loop.add("c");                      // a b c <d> e f
80          assertEquals("c", loop.previous()); // a b <c> d e f
81  
82          loop.reset();
83          assertEquals("a", loop.next());     // a <b> c d e f
84          assertEquals("b", loop.next());     // a b <c> d e f
85          assertEquals("c", loop.next());     // a b c <d> e f
86          assertEquals("d", loop.next());     // a b c d <e> f
87          assertEquals("e", loop.next());     // a b c d e <f>
88          assertEquals("f", loop.next());     // <a> b c d e f
89          assertEquals("a", loop.next());     // a <b> c d e f
90      }
91  
92      /**
93       * Tests constructor exception.
94       */
95      @Test
96      public void testConstructorEx() {
97          assertThrows(NullPointerException.class, () -> new LoopingListIterator<>(null));
98      }
99  
100     /**
101      * Tests jogging back and forth between two elements, but not over
102      * the begin/end boundary of the list.
103      */
104     @Test
105     public void testJoggingNotOverBoundary() {
106         final List<String> list = Arrays.asList("a", "b");
107         final LoopingListIterator<String> loop = new LoopingListIterator<>(list); // <a> b
108 
109         // Try jogging back and forth between the elements, but not
110         // over the begin/end boundary.
111         loop.reset();
112         assertEquals("a", loop.next());     // a <b>
113         assertEquals("a", loop.previous()); // <a> b
114         assertEquals("a", loop.next());     // a <b>
115 
116         assertEquals("b", loop.next());     // <a> b
117         assertEquals("b", loop.previous()); // a <b>
118         assertEquals("b", loop.next());     // <a> b
119     }
120 
121     /**
122      * Tests jogging back and forth between two elements over the
123      * begin/end boundary of the list.
124      */
125     @Test
126     public void testJoggingOverBoundary() {
127         final List<String> list = Arrays.asList("a", "b");
128         final LoopingListIterator<String> loop = new LoopingListIterator<>(list); // <a> b
129 
130         // Try jogging back and forth between the elements, but not
131         // over the begin/end boundary.
132         assertEquals("b", loop.previous()); // a <b>
133         assertEquals("b", loop.next());     // <a> b
134         assertEquals("b", loop.previous()); // a <b>
135 
136         assertEquals("a", loop.previous()); // <a> b
137         assertEquals("a", loop.next());     // a <b>
138         assertEquals("a", loop.previous()); // <a> b
139     }
140 
141     /**
142      * Tests whether an empty looping list iterator works.
143      */
144     @Test
145     public void testLooping0() {
146         final List<Object> list = new ArrayList<>();
147         final LoopingListIterator<Object> loop = new LoopingListIterator<>(list);
148         assertFalse(loop.hasNext());
149         assertFalse(loop.hasPrevious());
150         assertAll(
151                 () -> assertThrows(NoSuchElementException.class, () -> loop.next()),
152                 () -> assertThrows(NoSuchElementException.class, () -> loop.previous())
153         );
154     }
155 
156     /**
157      * Tests whether a looping list iterator works on a list with only
158      * one element.
159      */
160     @Test
161     public void testLooping1() {
162         final List<String> list = Arrays.asList("a");
163         final LoopingListIterator<String> loop = new LoopingListIterator<>(list); // <a>
164 
165         assertTrue(loop.hasNext());
166         assertEquals("a", loop.next());     // <a>
167 
168         assertTrue(loop.hasNext());
169         assertEquals("a", loop.next());     // <a>
170 
171         assertTrue(loop.hasNext());
172         assertEquals("a", loop.next());     // <a>
173 
174         assertTrue(loop.hasPrevious());
175         assertEquals("a", loop.previous()); // <a>
176 
177         assertTrue(loop.hasPrevious());
178         assertEquals("a", loop.previous()); // <a>
179 
180         assertTrue(loop.hasPrevious());
181         assertEquals("a", loop.previous()); // <a>
182     }
183 
184     /**
185      * Tests whether a looping list iterator works on a list with two
186      * elements.
187      */
188     @Test
189     public void testLooping2() {
190         final List<String> list = Arrays.asList("a", "b");
191         final LoopingListIterator<String> loop = new LoopingListIterator<>(list); // <a> b
192 
193         assertTrue(loop.hasNext());
194         assertEquals("a", loop.next());     // a <b>
195 
196         assertTrue(loop.hasNext());
197         assertEquals("b", loop.next());     // <a> b
198 
199         assertTrue(loop.hasNext());
200         assertEquals("a", loop.next());     // a <b>
201 
202         // Reset the iterator and try using previous.
203         loop.reset();                       // <a> b
204 
205         assertTrue(loop.hasPrevious());
206         assertEquals("b", loop.previous()); // a <b>
207 
208         assertTrue(loop.hasPrevious());
209         assertEquals("a", loop.previous()); // <a> b
210 
211         assertTrue(loop.hasPrevious());
212         assertEquals("b", loop.previous()); // a <b>
213     }
214 
215     /**
216      * Tests nextIndex and previousIndex.
217      */
218     @Test
219     public void testNextAndPreviousIndex() {
220         final List<String> list = Arrays.asList("a", "b", "c");
221         final LoopingListIterator<String> loop = new LoopingListIterator<>(list); // <a> b c
222 
223         assertEquals(0, loop.nextIndex());
224         assertEquals(2, loop.previousIndex());
225 
226         assertEquals("a", loop.next());        // a <b> c
227         assertEquals(1, loop.nextIndex());
228         assertEquals(0, loop.previousIndex());
229 
230         assertEquals("a", loop.previous());    // <a> b c
231         assertEquals(0, loop.nextIndex());
232         assertEquals(2, loop.previousIndex());
233 
234         assertEquals("c", loop.previous());    // a b <c>
235         assertEquals(2, loop.nextIndex());
236         assertEquals(1, loop.previousIndex());
237 
238         assertEquals("b", loop.previous());    // a <b> c
239         assertEquals(1, loop.nextIndex());
240         assertEquals(0, loop.previousIndex());
241 
242         assertEquals("a", loop.previous());    // <a> b c
243         assertEquals(0, loop.nextIndex());
244         assertEquals(2, loop.previousIndex());
245     }
246 
247     /**
248      * Tests removing an element from a wrapped ArrayList.
249      */
250     @Test
251     public void testRemovingElementsAndIteratingBackwards() {
252         final List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
253         final LoopingListIterator<String> loop = new LoopingListIterator<>(list); // <a> b c
254 
255         assertTrue(loop.hasPrevious());
256         assertEquals("c", loop.previous()); // a b <c>
257         loop.remove();                      // <a> b
258         assertEquals(2, list.size());
259 
260         assertTrue(loop.hasPrevious());
261         assertEquals("b", loop.previous()); // a <b>
262         loop.remove();                      // <a>
263         assertEquals(1, list.size());
264 
265         assertTrue(loop.hasPrevious());
266         assertEquals("a", loop.previous()); // <a>
267         loop.remove();                      // ---
268         assertEquals(0, list.size());
269 
270         assertFalse(loop.hasPrevious());
271 
272         assertThrows(NoSuchElementException.class, () -> loop.previous());
273     }
274 
275     /**
276      * Tests removing an element from a wrapped ArrayList.
277      */
278     @Test
279     public void testRemovingElementsAndIteratingForward() {
280         final List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
281         final LoopingListIterator<String> loop = new LoopingListIterator<>(list); // <a> b c
282 
283         assertTrue(loop.hasNext());
284         assertEquals("a", loop.next()); // a <b> c
285         loop.remove();                  // <b> c
286         assertEquals(2, list.size());
287 
288         assertTrue(loop.hasNext());
289         assertEquals("b", loop.next()); // b <c>
290         loop.remove();                  // <c>
291         assertEquals(1, list.size());
292 
293         assertTrue(loop.hasNext());
294         assertEquals("c", loop.next()); // <c>
295         loop.remove();                  // ---
296         assertEquals(0, list.size());
297 
298         assertFalse(loop.hasNext());
299 
300         assertThrows(NoSuchElementException.class, () -> loop.next());
301     }
302 
303     /**
304      * Tests the reset method.
305      */
306     @Test
307     public void testReset() {
308         final List<String> list = Arrays.asList("a", "b", "c");
309         final LoopingListIterator<String> loop = new LoopingListIterator<>(list); // <a> b c
310 
311         assertEquals("a", loop.next()); // a <b> c
312         assertEquals("b", loop.next()); // a b <c>
313         loop.reset();                   // <a> b c
314         assertEquals("a", loop.next()); // a <b> c
315         loop.reset();                   // <a> b c
316         assertEquals("a", loop.next()); // a <b> c
317         assertEquals("b", loop.next()); // a b <c>
318         assertEquals("c", loop.next()); // <a> b c
319         loop.reset();                   // <a> b c
320 
321         assertEquals("c", loop.previous()); // a b <c>
322         assertEquals("b", loop.previous()); // a <b> c
323         loop.reset();                       // <a> b c
324         assertEquals("c", loop.previous()); // a b <c>
325         loop.reset();                       // <a> b c
326         assertEquals("c", loop.previous()); // a b <c>
327         assertEquals("b", loop.previous()); // a <b> c
328         assertEquals("a", loop.previous()); // <a> b c
329     }
330 
331     /**
332      * Tests using the set method to change elements.
333      */
334     @Test
335     public void testSet() {
336         final List<String> list = Arrays.asList("q", "r", "z");
337         final LoopingListIterator<String> loop = new LoopingListIterator<>(list); // <q> r z
338 
339         assertEquals("z", loop.previous()); // q r <z>
340         loop.set("c");                      // q r <c>
341 
342         loop.reset();                       // <q> r c
343         assertEquals("q", loop.next());     // q <r> c
344         loop.set("a");                      // a <r> c
345 
346         assertEquals("r", loop.next());     // a r <c>
347         loop.set("b");                      // a b <c>
348 
349         loop.reset();                       // <a> b c
350         assertEquals("a", loop.next());     // a <b> c
351         assertEquals("b", loop.next());     // a b <c>
352         assertEquals("c", loop.next());     // <a> b c
353     }
354 
355 }