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;
18  
19  import static org.easymock.EasyMock.createMock;
20  import static org.easymock.EasyMock.expect;
21  import static org.easymock.EasyMock.replay;
22  import static org.junit.jupiter.api.Assertions.assertEquals;
23  import static org.junit.jupiter.api.Assertions.assertFalse;
24  import static org.junit.jupiter.api.Assertions.assertNull;
25  import static org.junit.jupiter.api.Assertions.assertSame;
26  import static org.junit.jupiter.api.Assertions.assertThrows;
27  import static org.junit.jupiter.api.Assertions.assertTrue;
28  
29  import java.util.ArrayList;
30  import java.util.Arrays;
31  import java.util.Collection;
32  import java.util.Collections;
33  import java.util.Comparator;
34  import java.util.Dictionary;
35  import java.util.Enumeration;
36  import java.util.HashMap;
37  import java.util.HashSet;
38  import java.util.Iterator;
39  import java.util.LinkedHashSet;
40  import java.util.List;
41  import java.util.ListIterator;
42  import java.util.Map;
43  import java.util.NoSuchElementException;
44  import java.util.Set;
45  import java.util.Vector;
46  
47  import org.apache.commons.collections4.functors.EqualPredicate;
48  import org.apache.commons.collections4.functors.TruePredicate;
49  import org.apache.commons.collections4.iterators.ArrayIterator;
50  import org.apache.commons.collections4.iterators.EmptyIterator;
51  import org.apache.commons.collections4.iterators.EmptyListIterator;
52  import org.apache.commons.collections4.iterators.EmptyMapIterator;
53  import org.apache.commons.collections4.iterators.EmptyOrderedIterator;
54  import org.apache.commons.collections4.iterators.EmptyOrderedMapIterator;
55  import org.apache.commons.collections4.iterators.EnumerationIterator;
56  import org.apache.commons.collections4.iterators.IteratorChainTest;
57  import org.apache.commons.collections4.iterators.NodeListIterator;
58  import org.apache.commons.collections4.iterators.ObjectArrayIterator;
59  import org.apache.commons.collections4.iterators.ZippingIterator;
60  import org.apache.commons.collections4.map.EntrySetToMapIteratorAdapter;
61  import org.junit.jupiter.api.BeforeEach;
62  import org.junit.jupiter.api.Test;
63  import org.w3c.dom.Node;
64  import org.w3c.dom.NodeList;
65  
66  /**
67   * Tests for IteratorUtils.
68   */
69  public class IteratorUtilsTest {
70  
71      /**
72       * Collection of {@link Integer}s
73       */
74      private List<Integer> collectionA;
75  
76      /**
77       * Collection of even {@link Integer}s
78       */
79      private List<Integer> collectionEven;
80  
81      /**
82       * Collection of odd {@link Integer}s
83       */
84      private List<Integer> collectionOdd;
85  
86      private final Collection<Integer> emptyCollection = new ArrayList<>(1);
87  
88      private Iterable<Integer> iterableA;
89  
90      /**
91       * Creates a NodeList containing the specified nodes.
92       */
93      private NodeList createNodeList(final Node[] nodes) {
94          return new NodeList() {
95              @Override
96              public int getLength() {
97                  return nodes.length;
98              }
99  
100             @Override
101             public Node item(final int index) {
102                 return nodes[index];
103             }
104         };
105     }
106 
107     /**
108      * creates an array of four Node instances, mocked by EasyMock.
109      */
110     private Node[] createNodes() {
111         final Node node1 = createMock(Node.class);
112         final Node node2 = createMock(Node.class);
113         final Node node3 = createMock(Node.class);
114         final Node node4 = createMock(Node.class);
115         replay(node1);
116         replay(node2);
117         replay(node3);
118         replay(node4);
119 
120         return new Node[] { node1, node2, node3, node4 };
121     }
122 
123     /**
124      * Gets an immutable Iterator operating on the elements ["a", "b", "c", "d"].
125      */
126     private Iterator<String> getImmutableIterator() {
127         final List<String> list = new ArrayList<>();
128         list.add("a");
129         list.add("b");
130         list.add("c");
131         list.add("d");
132         return IteratorUtils.unmodifiableIterator(list.iterator());
133     }
134 
135     /**
136      * Gets an immutable ListIterator operating on the elements ["a", "b", "c", "d"].
137      */
138     private ListIterator<String> getImmutableListIterator() {
139         final List<String> list = new ArrayList<>();
140         list.add("a");
141         list.add("b");
142         list.add("c");
143         list.add("d");
144         return IteratorUtils.unmodifiableListIterator(list.listIterator());
145     }
146 
147     @BeforeEach
148     public void setUp() {
149         collectionA = new ArrayList<>();
150         collectionA.add(1);
151         collectionA.add(2);
152         collectionA.add(2);
153         collectionA.add(3);
154         collectionA.add(3);
155         collectionA.add(3);
156         collectionA.add(4);
157         collectionA.add(4);
158         collectionA.add(4);
159         collectionA.add(4);
160 
161         iterableA = collectionA;
162 
163         collectionEven = Arrays.asList(2, 4, 6, 8, 10, 12);
164         collectionOdd = Arrays.asList(1, 3, 5, 7, 9, 11);
165     }
166 
167     @Test
168     public void testArrayIterator() {
169         final Object[] objArray = { "a", "b", "c" };
170         ResettableIterator<Object> iterator = IteratorUtils.arrayIterator(objArray);
171         assertEquals("a", iterator.next());
172         assertEquals("b", iterator.next());
173         iterator.reset();
174         assertEquals("a", iterator.next());
175 
176         assertThrows(IllegalArgumentException.class, () -> IteratorUtils.arrayIterator(Integer.valueOf(0)));
177         assertThrows(NullPointerException.class, () -> IteratorUtils.arrayIterator((Object[]) null));
178 
179         iterator = IteratorUtils.arrayIterator(objArray, 1);
180         assertEquals("b", iterator.next());
181 
182         assertThrows(ArrayIndexOutOfBoundsException.class, () -> IteratorUtils.arrayIterator(objArray, -1));
183 
184         iterator = IteratorUtils.arrayIterator(objArray, 3);
185         assertFalse(iterator.hasNext());
186         iterator.reset();
187 
188         assertThrows(ArrayIndexOutOfBoundsException.class, () -> IteratorUtils.arrayIterator(objArray, 4));
189 
190         iterator = IteratorUtils.arrayIterator(objArray, 2, 3);
191         assertEquals("c", iterator.next());
192 
193         assertThrows(ArrayIndexOutOfBoundsException.class, () -> IteratorUtils.arrayIterator(objArray, 2, 4));
194         assertThrows(ArrayIndexOutOfBoundsException.class, () -> IteratorUtils.arrayIterator(objArray, -1, 1));
195         assertThrows(IllegalArgumentException.class, () -> IteratorUtils.arrayIterator(objArray, 2, 1));
196 
197         final int[] intArray = { 0, 1, 2 };
198         iterator = IteratorUtils.arrayIterator(intArray);
199         assertEquals(0, iterator.next());
200         assertEquals(1, iterator.next());
201         iterator.reset();
202         assertEquals(0, iterator.next());
203 
204         iterator = IteratorUtils.arrayIterator(intArray, 1);
205         assertEquals(1, iterator.next());
206 
207         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayIterator(intArray, -1));
208 
209         iterator = IteratorUtils.arrayIterator(intArray, 3);
210         assertFalse(iterator.hasNext());
211         iterator.reset();
212 
213         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayIterator(intArray, 4));
214 
215         iterator = IteratorUtils.arrayIterator(intArray, 2, 3);
216         assertEquals(2, iterator.next());
217 
218         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayIterator(intArray, 2, 4));
219         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayIterator(intArray, -1, 1));
220         assertThrows(IllegalArgumentException.class, () -> IteratorUtils.arrayIterator(intArray, 2, 1));
221     }
222 
223     @Test
224     public void testArrayListIterator() {
225         final Object[] objArray = { "a", "b", "c", "d" };
226         ResettableListIterator<Object> iterator = IteratorUtils.arrayListIterator(objArray);
227         assertFalse(iterator.hasPrevious());
228         assertEquals(-1, iterator.previousIndex());
229         assertEquals(0, iterator.nextIndex());
230         assertEquals("a", iterator.next());
231         assertEquals("a", iterator.previous());
232         assertEquals("a", iterator.next());
233         assertEquals(0, iterator.previousIndex());
234         assertEquals(1, iterator.nextIndex());
235         assertEquals("b", iterator.next());
236         assertEquals("c", iterator.next());
237         assertEquals("d", iterator.next());
238         assertEquals(4, iterator.nextIndex()); // size of list
239         assertEquals(3, iterator.previousIndex());
240 
241         assertThrows(IllegalArgumentException.class, () -> IteratorUtils.arrayListIterator(Integer.valueOf(0)));
242         assertThrows(NullPointerException.class, () -> IteratorUtils.arrayListIterator((Object[]) null));
243 
244         iterator = IteratorUtils.arrayListIterator(objArray, 1);
245         assertEquals(-1, iterator.previousIndex());
246         assertFalse(iterator.hasPrevious());
247         assertEquals(0, iterator.nextIndex());
248         assertEquals("b", iterator.next());
249         assertEquals(0, iterator.previousIndex());
250         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayListIterator(objArray, -1));
251 
252         iterator = IteratorUtils.arrayListIterator(objArray, 3);
253         assertTrue(iterator.hasNext());
254 
255         final ResettableListIterator<Object> finalIterator = iterator;
256 
257         assertThrows(NoSuchElementException.class, () -> finalIterator.previous());
258         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayListIterator(objArray, 5));
259 
260         iterator = IteratorUtils.arrayListIterator(objArray, 2, 3);
261         assertEquals("c", iterator.next());
262 
263         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayListIterator(objArray, 2, 5));
264         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayListIterator(objArray, -1, 1));
265         assertThrows(IllegalArgumentException.class, () -> IteratorUtils.arrayListIterator(objArray, 2, 1));
266 
267         final int[] intArray = { 0, 1, 2 };
268         iterator = IteratorUtils.arrayListIterator(intArray);
269         assertEquals(iterator.previousIndex(), -1);
270         assertFalse(iterator.hasPrevious());
271         assertEquals(0, iterator.nextIndex());
272         assertEquals(0, iterator.next());
273         assertEquals(0, iterator.previousIndex());
274         assertEquals(1, iterator.nextIndex());
275         assertEquals(1, iterator.next());
276         assertEquals(1, iterator.previousIndex());
277         assertEquals(2, iterator.nextIndex());
278         assertEquals(1, iterator.previous());
279         assertEquals(1, iterator.next());
280 
281         iterator = IteratorUtils.arrayListIterator(intArray, 1);
282         assertEquals(-1, iterator.previousIndex());
283         assertFalse(iterator.hasPrevious());
284         assertEquals(0, iterator.nextIndex());
285         assertEquals(1, iterator.next());
286         assertEquals(1, iterator.previous());
287         assertEquals(1, iterator.next());
288         assertEquals(0, iterator.previousIndex());
289         assertEquals(1, iterator.nextIndex());
290         assertEquals(2, iterator.next());
291         assertEquals(1, iterator.previousIndex());
292         assertEquals(2, iterator.nextIndex());
293         assertEquals(2, iterator.previous());
294         assertEquals(0, iterator.previousIndex());
295         assertEquals(1, iterator.nextIndex());
296 
297         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayListIterator(intArray, -1),
298                 "Expecting IndexOutOfBoundsException");
299 
300         iterator = IteratorUtils.arrayListIterator(intArray, 3);
301         assertFalse(iterator.hasNext());
302 
303         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayListIterator(intArray, 4),
304                 "Expecting IndexOutOfBoundsException");
305 
306         iterator = IteratorUtils.arrayListIterator(intArray, 2, 3);
307         assertFalse(iterator.hasPrevious());
308         assertEquals(-1, iterator.previousIndex());
309         assertEquals(2, iterator.next());
310         assertTrue(iterator.hasPrevious());
311         assertFalse(iterator.hasNext());
312 
313         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayListIterator(intArray, 2, 4));
314         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.arrayListIterator(intArray, -1, 1));
315         assertThrows(IllegalArgumentException.class, () -> IteratorUtils.arrayListIterator(intArray, 2, 1));
316     }
317 
318     @Test
319     public void testAsEnumerationNull() {
320         assertThrows(NullPointerException.class, () -> IteratorUtils.asEnumeration(null));
321     }
322 
323     @Test
324     public void testAsIterable() {
325         final List<Integer> list = new ArrayList<>();
326         list.add(Integer.valueOf(0));
327         list.add(Integer.valueOf(1));
328         list.add(Integer.valueOf(2));
329         final Iterator<Integer> iterator = list.iterator();
330 
331         final Iterable<Integer> iterable = IteratorUtils.asIterable(iterator);
332         int expected = 0;
333         for (final Integer actual : iterable) {
334             assertEquals(expected, actual.intValue());
335             ++expected;
336         }
337         // insure iteration occurred
338         assertTrue(expected > 0);
339 
340         // single use iterator
341         assertFalse(IteratorUtils.asIterable(iterator).iterator().hasNext(), "should not be able to iterate twice");
342     }
343 
344     @Test
345     public void testAsIterableNull() {
346         assertThrows(NullPointerException.class, () -> IteratorUtils.asIterable(null));
347     }
348 
349     @Test
350     public void testAsIterator() {
351         final Vector<String> vector = new Vector<>();
352         vector.addElement("zero");
353         vector.addElement("one");
354         final Enumeration<String> en = vector.elements();
355         assertTrue(IteratorUtils.asIterator(en) instanceof Iterator, "create instance fail");
356         assertThrows(NullPointerException.class, () -> IteratorUtils.asIterator(null));
357     }
358 
359     @Test
360     public void testAsIteratorNull() {
361         final Collection coll = new ArrayList();
362         coll.add("test");
363         final Vector<String> vector = new Vector<>();
364         vector.addElement("test");
365         vector.addElement("one");
366         final Enumeration<String> en = vector.elements();
367         assertTrue(IteratorUtils.asIterator(en, coll) instanceof Iterator, "create instance fail");
368 
369         assertThrows(NullPointerException.class, () -> IteratorUtils.asIterator(null, coll));
370         assertThrows(NullPointerException.class, () -> IteratorUtils.asIterator(en, null));
371     }
372 
373     @Test
374     public void testAsMultipleIterable() {
375         final List<Integer> list = new ArrayList<>();
376         list.add(Integer.valueOf(0));
377         list.add(Integer.valueOf(1));
378         list.add(Integer.valueOf(2));
379         final Iterator<Integer> iterator = list.iterator();
380 
381         final Iterable<Integer> iterable = IteratorUtils.asMultipleUseIterable(iterator);
382         int expected = 0;
383         for (final Integer actual : iterable) {
384             assertEquals(expected, actual.intValue());
385             ++expected;
386         }
387         // insure iteration occurred
388         assertTrue(expected > 0);
389 
390         // multiple use iterator
391         expected = 0;
392         for (final Integer actual : iterable) {
393             assertEquals(expected, actual.intValue());
394             ++expected;
395         }
396         // insure iteration occurred
397         assertTrue(expected > 0);
398     }
399 
400     @Test
401     public void testAsMultipleIterableNull() {
402         assertThrows(NullPointerException.class, () -> IteratorUtils.asMultipleUseIterable(null));
403     }
404 
405     @Test
406     public void testChainedIteratorArrayOfIterator() {
407         // String
408         final IteratorChainTest iteratorChainTest = new IteratorChainTest();
409         iteratorChainTest.setUp();
410         // @formatter:off
411         final Iterator<String> iterator = IteratorUtils.chainedIterator(
412                 iteratorChainTest.getList1().iterator(),
413                 iteratorChainTest.getList2().iterator(),
414                 iteratorChainTest.getList3().iterator());
415         // @formatter:on
416         assertEquals("One", iterator.next());
417         assertEquals("Two", iterator.next());
418         assertEquals("Three", iterator.next());
419         assertEquals("Four", iterator.next());
420         assertEquals("Five", iterator.next());
421         assertEquals("Six", iterator.next());
422         assertFalse(iterator.hasNext());
423     }
424 
425     @Test
426     public void testChainedIteratorList() {
427         final IteratorChainTest iteratorChainTest = new IteratorChainTest();
428         iteratorChainTest.setUp();
429         final List<Iterator<String>> list = new ArrayList<>();
430         list.add(iteratorChainTest.getList1().iterator());
431         list.add(iteratorChainTest.getList2().iterator());
432         list.add(iteratorChainTest.getList3().iterator());
433         final List<String> expected = new ArrayList<>(iteratorChainTest.getList1());
434         expected.addAll(iteratorChainTest.getList2());
435         expected.addAll(iteratorChainTest.getList3());
436         final Iterator<String> iter = IteratorUtils.chainedIterator(list);
437         final List<String> actual = new ArrayList<>();
438         iter.forEachRemaining(actual::add);
439         assertEquals(actual, expected);
440     }
441 
442     @Test
443     public void testChainedIteratorOfIterators() {
444         final List<List<Number>> lst = new ArrayList<>();
445         final List<Integer> iList = Arrays.asList(1, 3);
446         lst.add(Arrays.asList(3.14f, Math.sqrt(2.0)));
447         final Iterator<Iterator<Number>> toBeUnwound = new Iterator<Iterator<Number>>() {
448             List<List<Number>> lst = Arrays.asList(Arrays.asList(1, 3), Arrays.asList(3.14F, Math.sqrt(2.0)));
449             Iterator<List<Number>> lstIter = lst.iterator();
450 
451             @Override
452             public boolean hasNext() {
453                 return lstIter.hasNext();
454             }
455 
456             @Override
457             public Iterator<Number> next() {
458                 return lstIter.next().iterator();
459             }
460         };
461 
462         final List<Number> expected = Arrays.asList(1, 3, 3.14f, Math.sqrt(2.0));
463         final Iterator<Number> iter = IteratorUtils.chainedIterator(toBeUnwound);
464         final List<Number> actual = new ArrayList<>();
465         iter.forEachRemaining(actual::add);
466         assertEquals(actual, expected);
467     }
468 
469     @Test
470     public void testChainedIteratorRawGenerics() {
471         final ArrayList arrayList = new ArrayList();
472         final Iterator iterator = arrayList.iterator();
473         assertTrue(IteratorUtils.chainedIterator(iterator) instanceof Iterator, "create instance fail");
474         final Collection<Iterator<?>> coll = new ArrayList();
475         assertTrue(IteratorUtils.chainedIterator(coll) instanceof Iterator, "create instance fail");
476     }
477 
478     /**
479      * Tests methods collatedIterator(...)
480      */
481     @Test
482     public void testCollatedIterator() {
483 
484         assertThrows(NullPointerException.class, () -> IteratorUtils.collatedIterator(null, collectionOdd.iterator(), null));
485         assertThrows(NullPointerException.class, () -> IteratorUtils.collatedIterator(null, null, collectionEven.iterator()));
486 
487         // natural ordering
488         Iterator<Integer> it = IteratorUtils.collatedIterator(null, collectionOdd.iterator(),
489                 collectionEven.iterator());
490 
491         List<Integer> result = IteratorUtils.toList(it);
492         assertEquals(12, result.size());
493 
494         final List<Integer> combinedList = new ArrayList<>(collectionOdd);
495         combinedList.addAll(collectionEven);
496         Collections.sort(combinedList);
497 
498         assertEquals(combinedList, result);
499 
500         it = IteratorUtils.collatedIterator(null, collectionOdd.iterator(), emptyCollection.iterator());
501         result = IteratorUtils.toList(it);
502         assertEquals(collectionOdd, result);
503 
504         final Comparator<Integer> reverseComparator = ComparatorUtils
505                 .reversedComparator(ComparatorUtils.<Integer>naturalComparator());
506 
507         Collections.reverse(collectionOdd);
508         Collections.reverse(collectionEven);
509         Collections.reverse(combinedList);
510 
511         it = IteratorUtils.collatedIterator(reverseComparator, collectionOdd.iterator(), collectionEven.iterator());
512         result = IteratorUtils.toList(it);
513         assertEquals(combinedList, result);
514     }
515 
516     @Test
517     public void testCollatedIteratorCollectionNull() {
518         final Collection<Iterator<?>> coll = new ArrayList<>();
519         coll.add(collectionOdd.iterator());
520         // natural ordering
521         final Iterator<?> it = IteratorUtils.collatedIterator(null, coll);
522         final List<?> result = IteratorUtils.toList(it);
523         assertEquals(6, result.size());
524         assertThrows(NullPointerException.class, () -> IteratorUtils.collatedIterator(null, (Collection<Iterator<?>>) null));
525     }
526 
527     @Test
528     public void testCollatedIteratorNull() {
529         final ArrayList arrayList = new ArrayList();
530         // natural ordering
531         Iterator<Integer> it = IteratorUtils.collatedIterator(null, collectionOdd.iterator(), collectionOdd.iterator(),
532                 collectionOdd.iterator());
533 
534         List<Integer> result = IteratorUtils.toList(it);
535         assertEquals(18, result.size());
536 
537         it = IteratorUtils.collatedIterator(null, collectionOdd.iterator());
538         result = IteratorUtils.toList(it);
539         assertEquals(collectionOdd, result);
540 
541         final Comparator<Integer> reverseComparator = ComparatorUtils
542                 .reversedComparator(ComparatorUtils.<Integer>naturalComparator());
543 
544         Collections.reverse(collectionOdd);
545 
546         it = IteratorUtils.collatedIterator(reverseComparator, collectionOdd.iterator());
547         result = IteratorUtils.toList(it);
548         assertEquals(collectionOdd, result);
549         assertThrows(NullPointerException.class, () -> IteratorUtils.collatedIterator(null, arrayList.iterator(), arrayList.listIterator(), null));
550     }
551 
552     /**
553      * Test empty iterator
554      */
555     @Test
556     public void testEmptyIterator() {
557         assertSame(EmptyIterator.INSTANCE, IteratorUtils.EMPTY_ITERATOR);
558         assertSame(EmptyIterator.RESETTABLE_INSTANCE, IteratorUtils.EMPTY_ITERATOR);
559         assertTrue(IteratorUtils.EMPTY_ITERATOR instanceof Iterator);
560         assertTrue(IteratorUtils.EMPTY_ITERATOR instanceof ResettableIterator);
561         assertFalse(IteratorUtils.EMPTY_ITERATOR instanceof OrderedIterator);
562         assertFalse(IteratorUtils.EMPTY_ITERATOR instanceof ListIterator);
563         assertFalse(IteratorUtils.EMPTY_ITERATOR instanceof MapIterator);
564         assertFalse(IteratorUtils.EMPTY_ITERATOR.hasNext());
565         IteratorUtils.EMPTY_ITERATOR.reset();
566         assertSame(IteratorUtils.EMPTY_ITERATOR, IteratorUtils.EMPTY_ITERATOR);
567         assertSame(IteratorUtils.EMPTY_ITERATOR, IteratorUtils.emptyIterator());
568 
569         assertThrows(NoSuchElementException.class, () -> IteratorUtils.EMPTY_ITERATOR.next());
570         assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_ITERATOR.remove());
571     }
572 
573     /**
574      * Test empty list iterator
575      */
576     @Test
577     public void testEmptyListIterator() {
578         assertSame(EmptyListIterator.INSTANCE, IteratorUtils.EMPTY_LIST_ITERATOR);
579         assertSame(EmptyListIterator.RESETTABLE_INSTANCE, IteratorUtils.EMPTY_LIST_ITERATOR);
580         assertTrue(IteratorUtils.EMPTY_LIST_ITERATOR instanceof Iterator);
581         assertTrue(IteratorUtils.EMPTY_LIST_ITERATOR instanceof ListIterator);
582         assertTrue(IteratorUtils.EMPTY_LIST_ITERATOR instanceof ResettableIterator);
583         assertTrue(IteratorUtils.EMPTY_LIST_ITERATOR instanceof ResettableListIterator);
584         assertFalse(IteratorUtils.EMPTY_LIST_ITERATOR instanceof MapIterator);
585         assertFalse(IteratorUtils.EMPTY_LIST_ITERATOR.hasNext());
586         assertEquals(0, IteratorUtils.EMPTY_LIST_ITERATOR.nextIndex());
587         assertEquals(-1, IteratorUtils.EMPTY_LIST_ITERATOR.previousIndex());
588         IteratorUtils.EMPTY_LIST_ITERATOR.reset();
589         assertSame(IteratorUtils.EMPTY_LIST_ITERATOR, IteratorUtils.EMPTY_LIST_ITERATOR);
590         assertSame(IteratorUtils.EMPTY_LIST_ITERATOR, IteratorUtils.emptyListIterator());
591 
592         assertThrows(NoSuchElementException.class, () -> IteratorUtils.EMPTY_LIST_ITERATOR.next());
593         assertThrows(NoSuchElementException.class, () -> IteratorUtils.EMPTY_LIST_ITERATOR.previous());
594         assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_LIST_ITERATOR.remove());
595         assertThrows(IllegalStateException.class, () -> IteratorUtils.emptyListIterator().set(null));
596         assertThrows(UnsupportedOperationException.class, () -> IteratorUtils.emptyListIterator().add(null));
597     }
598 
599     /**
600      * Test empty map iterator
601      */
602     @Test
603     @SuppressWarnings("unchecked")
604     public void testEmptyMapIterator() {
605         assertSame(EmptyMapIterator.INSTANCE, IteratorUtils.EMPTY_MAP_ITERATOR);
606         assertTrue(IteratorUtils.EMPTY_MAP_ITERATOR instanceof Iterator);
607         assertTrue(IteratorUtils.EMPTY_MAP_ITERATOR instanceof MapIterator);
608         assertTrue(IteratorUtils.EMPTY_MAP_ITERATOR instanceof ResettableIterator);
609         assertFalse(IteratorUtils.EMPTY_MAP_ITERATOR instanceof ListIterator);
610         assertFalse(IteratorUtils.EMPTY_MAP_ITERATOR instanceof OrderedIterator);
611         assertFalse(IteratorUtils.EMPTY_MAP_ITERATOR instanceof OrderedMapIterator);
612         assertFalse(IteratorUtils.EMPTY_MAP_ITERATOR.hasNext());
613         ((ResettableIterator<Object>) IteratorUtils.EMPTY_MAP_ITERATOR).reset();
614         assertSame(IteratorUtils.EMPTY_MAP_ITERATOR, IteratorUtils.EMPTY_MAP_ITERATOR);
615         assertSame(IteratorUtils.EMPTY_MAP_ITERATOR, IteratorUtils.emptyMapIterator());
616 
617         assertThrows(NoSuchElementException.class, () -> IteratorUtils.EMPTY_MAP_ITERATOR.next());
618         assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_MAP_ITERATOR.remove());
619         assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_MAP_ITERATOR.getKey());
620         assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_MAP_ITERATOR.getValue());
621         assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_MAP_ITERATOR.setValue(null));
622     }
623 
624     /**
625      * Test empty map iterator
626      */
627     @Test
628     @SuppressWarnings("unchecked")
629     public void testEmptyOrderedIterator() {
630         assertSame(EmptyOrderedIterator.INSTANCE, IteratorUtils.EMPTY_ORDERED_ITERATOR);
631         assertTrue(IteratorUtils.EMPTY_ORDERED_ITERATOR instanceof Iterator);
632         assertTrue(IteratorUtils.EMPTY_ORDERED_ITERATOR instanceof OrderedIterator);
633         assertTrue(IteratorUtils.EMPTY_ORDERED_ITERATOR instanceof ResettableIterator);
634         assertFalse(IteratorUtils.EMPTY_ORDERED_ITERATOR instanceof ListIterator);
635         assertFalse(IteratorUtils.EMPTY_ORDERED_ITERATOR instanceof MapIterator);
636         assertFalse(IteratorUtils.EMPTY_ORDERED_ITERATOR.hasNext());
637         assertFalse(IteratorUtils.EMPTY_ORDERED_ITERATOR.hasPrevious());
638         ((ResettableIterator<Object>) IteratorUtils.EMPTY_ORDERED_ITERATOR).reset();
639         assertSame(IteratorUtils.EMPTY_ORDERED_ITERATOR, IteratorUtils.EMPTY_ORDERED_ITERATOR);
640         assertSame(IteratorUtils.EMPTY_ORDERED_ITERATOR, IteratorUtils.emptyOrderedIterator());
641 
642         assertThrows(NoSuchElementException.class, () -> IteratorUtils.EMPTY_ORDERED_ITERATOR.next());
643         assertThrows(NoSuchElementException.class, () -> IteratorUtils.EMPTY_ORDERED_ITERATOR.previous());
644         assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_ORDERED_ITERATOR.remove());
645     }
646 
647     /**
648      * Test empty map iterator
649      */
650     @Test
651     @SuppressWarnings("unchecked")
652     public void testEmptyOrderedMapIterator() {
653         assertSame(EmptyOrderedMapIterator.INSTANCE, IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR);
654         assertTrue(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR instanceof Iterator);
655         assertTrue(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR instanceof MapIterator);
656         assertTrue(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR instanceof OrderedMapIterator);
657         assertTrue(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR instanceof ResettableIterator);
658         assertFalse(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR instanceof ListIterator);
659         assertFalse(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR.hasNext());
660         assertFalse(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR.hasPrevious());
661         ((ResettableIterator<Object>) IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR).reset();
662         assertSame(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR, IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR);
663         assertSame(IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR, IteratorUtils.emptyOrderedMapIterator());
664 
665         assertThrows(NoSuchElementException.class, () -> IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR.next());
666         assertThrows(NoSuchElementException.class, () -> IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR.previous());
667         assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR.remove());
668         assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR.getKey());
669         assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR.getValue());
670         assertThrows(IllegalStateException.class, () -> IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR.setValue(null));
671     }
672 
673     @Test
674     public void testFilteredIterator() {
675         final ArrayList arrayList = new ArrayList();
676         final Iterator iterator = arrayList.iterator();
677 
678         assertThrows(NullPointerException.class, () -> IteratorUtils.filteredIterator(iterator, null));
679         assertThrows(NullPointerException.class, () -> IteratorUtils.filteredIterator(null, null));
680     }
681 
682     @Test
683     public void testFilteredListIterator() {
684         final List arrayList = new ArrayList();
685         arrayList.add("test");
686         final Predicate predicate = TruePredicate.INSTANCE;
687         assertTrue(IteratorUtils.filteredListIterator(arrayList.listIterator(), predicate) instanceof ListIterator,
688                 "create instance fail");
689 
690         assertThrows(NullPointerException.class, () -> IteratorUtils.filteredListIterator(null, predicate));
691         assertThrows(NullPointerException.class, () -> IteratorUtils.filteredListIterator(arrayList.listIterator(), null));
692     }
693 
694     @Test
695     public void testFind() {
696         Predicate<Number> testPredicate = EqualPredicate.equalPredicate((Number) 4);
697         Integer test = IteratorUtils.find(iterableA.iterator(), testPredicate);
698         assertEquals(4, (int) test);
699         testPredicate = EqualPredicate.equalPredicate((Number) 45);
700         test = IteratorUtils.find(iterableA.iterator(), testPredicate);
701         assertNull(test);
702         assertNull(IteratorUtils.find(null, testPredicate));
703 
704         assertThrows(NullPointerException.class, () -> IteratorUtils.find(iterableA.iterator(), null));
705     }
706 
707     @Test
708     public void testFirstFromIterator() throws Exception {
709         // Iterator, entry exists
710         final Iterator<Integer> iterator = iterableA.iterator();
711         assertEquals(1, (int) IteratorUtils.first(iterator));
712     }
713 
714     @Test
715     public void testForEach() {
716         final List<Integer> listA = new ArrayList<>();
717         listA.add(1);
718 
719         final List<Integer> listB = new ArrayList<>();
720         listB.add(2);
721 
722         final Closure<List<Integer>> testClosure = ClosureUtils.invokerClosure("clear");
723         final Collection<List<Integer>> col = new ArrayList<>();
724         col.add(listA);
725         col.add(listB);
726         IteratorUtils.forEach(col.iterator(), testClosure);
727         assertTrue(listA.isEmpty() && listB.isEmpty());
728 
729         assertThrows(NullPointerException.class, () -> IteratorUtils.forEach(col.iterator(), null));
730 
731         IteratorUtils.forEach(null, testClosure);
732 
733         // null should be OK
734         col.add(null);
735         IteratorUtils.forEach(col.iterator(), testClosure);
736     }
737 
738     @Test
739     public void testForEachButLast() {
740         final List<Integer> listA = new ArrayList<>();
741         listA.add(1);
742 
743         final List<Integer> listB = new ArrayList<>();
744         listB.add(2);
745 
746         final Closure<List<Integer>> testClosure = ClosureUtils.invokerClosure("clear");
747         final Collection<List<Integer>> col = new ArrayList<>();
748         col.add(listA);
749         col.add(listB);
750         List<Integer> last = IteratorUtils.forEachButLast(col.iterator(), testClosure);
751         assertTrue(listA.isEmpty() && !listB.isEmpty());
752         assertSame(listB, last);
753 
754         assertThrows(NullPointerException.class, () -> IteratorUtils.forEachButLast(col.iterator(), null));
755 
756         IteratorUtils.forEachButLast(null, testClosure);
757 
758         // null should be OK
759         col.add(null);
760         col.add(null);
761         last = IteratorUtils.forEachButLast(col.iterator(), testClosure);
762         assertNull(last);
763     }
764 
765     @Test
766     public void testGetAtIndexFromIterator() throws Exception {
767         // Iterator, entry exists
768         Iterator<Integer> iterator = iterableA.iterator();
769         assertEquals(1, (int) IteratorUtils.get(iterator, 0));
770         iterator = iterableA.iterator();
771         assertEquals(2, (int) IteratorUtils.get(iterator, 1));
772         // Iterator, non-existent entry
773         final Iterator<Integer> finalIterator = iterator;
774         assertThrows(IndexOutOfBoundsException.class, () -> IteratorUtils.get(finalIterator, 10));
775         assertFalse(iterator.hasNext());
776     }
777 
778     @Test
779     public void testGetAtIndexFromIteratorDefault() throws Exception {
780         // Iterator, entry exists
781         Iterator<Integer> iterator = iterableA.iterator();
782         assertEquals(1, (int) IteratorUtils.get(iterator, 0, i -> 0));
783         iterator = iterableA.iterator();
784         assertEquals(2, (int) IteratorUtils.get(iterator, 1, i -> 0));
785         // Iterator, non-existent entry
786         assertEquals(111, (int) IteratorUtils.get(iterator, 10, i -> 111));
787         assertFalse(iterator.hasNext());
788     }
789 
790     @Test
791     public void testGetIterator() {
792         final Object[] objArray = { "a", "b", "c" };
793         final Map<String, String> inMap = new HashMap<>();
794         final Node[] nodes = createNodes();
795         final NodeList nodeList = createNodeList(nodes);
796 
797         assertTrue(IteratorUtils.getIterator(null) instanceof EmptyIterator, "returns empty iterator when null passed");
798         assertTrue(IteratorUtils.getIterator(iterableA.iterator()) instanceof Iterator, "returns Iterator when Iterator directly ");
799         assertTrue(IteratorUtils.getIterator(iterableA) instanceof Iterator, "returns Iterator when iterable passed");
800         assertTrue(IteratorUtils.getIterator(objArray) instanceof ObjectArrayIterator,
801                 "returns ObjectArrayIterator when Object array passed");
802         assertTrue(IteratorUtils.getIterator(inMap) instanceof Iterator, "returns Iterator when Map passed");
803         assertTrue(IteratorUtils.getIterator(nodeList) instanceof NodeListIterator, "returns NodeListIterator when nodeList passed");
804         assertTrue(IteratorUtils.getIterator(new Vector().elements()) instanceof EnumerationIterator,
805                 "returns EnumerationIterator when Enumeration passed");
806         final Node node1 = createMock(Node.class);
807         assertTrue(IteratorUtils.getIterator(node1) instanceof NodeListIterator,
808                 "returns NodeListIterator when nodeList passed");
809         final Dictionary dic = createMock(Dictionary.class);
810         assertTrue(IteratorUtils.getIterator(dic) instanceof EnumerationIterator,
811                 "returns EnumerationIterator when Dictionary passed");
812         final int[] arr = new int[8];
813         assertTrue(IteratorUtils.getIterator(arr) instanceof ArrayIterator, "returns ArrayIterator when array passed");
814     }
815 
816     @Test
817     public void testIndexOf() {
818         Predicate<Number> testPredicate = EqualPredicate.equalPredicate((Number) 4);
819         int index = IteratorUtils.indexOf(iterableA.iterator(), testPredicate);
820         assertEquals(6, index);
821         testPredicate = EqualPredicate.equalPredicate((Number) 45);
822         index = IteratorUtils.indexOf(iterableA.iterator(), testPredicate);
823         assertEquals(-1, index);
824         assertEquals(-1, IteratorUtils.indexOf(null, testPredicate));
825 
826         assertThrows(NullPointerException.class, () -> IteratorUtils.indexOf(iterableA.iterator(), null));
827     }
828 
829     @Test
830     public void testLoopingIterator() {
831         final ArrayList arrayList = new ArrayList();
832         arrayList.add("test");
833         final Collection coll = new ArrayList();
834         coll.add("test");
835         final Iterator iterator = arrayList.iterator();
836         assertTrue(IteratorUtils.loopingIterator(coll) instanceof ResettableIterator, "create instance fail");
837         assertThrows(NullPointerException.class, () -> IteratorUtils.loopingIterator(null));
838     }
839 
840     @Test
841     public void testLoopingListIterator() {
842         final ArrayList arrayList = new ArrayList();
843         arrayList.add("test");
844         final Iterator iterator = arrayList.iterator();
845         assertTrue(IteratorUtils.loopingListIterator(arrayList) instanceof ResettableIterator, "create instance fail");
846         assertThrows(NullPointerException.class, () -> IteratorUtils.loopingListIterator(null));
847     }
848 
849     /**
850      * Tests method nodeListIterator(Node)
851      */
852     @Test
853     public void testNodeIterator() {
854         final Node[] nodes = createNodes();
855         final NodeList nodeList = createNodeList(nodes);
856         final Node parentNode = createMock(Node.class);
857         expect(parentNode.getChildNodes()).andStubReturn(nodeList);
858         replay(parentNode);
859 
860         final Iterator<Node> iterator = IteratorUtils.nodeListIterator(parentNode);
861         int expectedNodeIndex = 0;
862         for (final Node actual : IteratorUtils.asIterable(iterator)) {
863             assertEquals(nodes[expectedNodeIndex], actual);
864             ++expectedNodeIndex;
865         }
866 
867         // insure iteration occurred
868         assertTrue(expectedNodeIndex > 0);
869 
870         // single use iterator
871         assertFalse(IteratorUtils.asIterable(iterator).iterator().hasNext(), "should not be able to iterate twice");
872 
873         assertThrows(NullPointerException.class, () -> IteratorUtils.nodeListIterator((Node) null));
874     }
875 
876     /**
877      * Tests method nodeListIterator(NodeList)
878      */
879     @Test
880     public void testNodeListIterator() {
881         final Node[] nodes = createNodes();
882         final NodeList nodeList = createNodeList(nodes);
883 
884         final Iterator<Node> iterator = IteratorUtils.nodeListIterator(nodeList);
885         int expectedNodeIndex = 0;
886         for (final Node actual : IteratorUtils.asIterable(iterator)) {
887             assertEquals(nodes[expectedNodeIndex], actual);
888             ++expectedNodeIndex;
889         }
890 
891         // insure iteration occurred
892         assertTrue(expectedNodeIndex > 0);
893 
894         // single use iterator
895         assertFalse(IteratorUtils.asIterable(iterator).iterator().hasNext(), "should not be able to iterate twice");
896 
897         assertThrows(NullPointerException.class, () -> IteratorUtils.nodeListIterator((NodeList) null));
898     }
899 
900     @Test
901     public void testObjectGraphIterator() {
902         assertTrue(IteratorUtils.objectGraphIterator(null, null) instanceof Iterator, "create instance fail");
903     }
904 
905     @Test
906     public void testPeekingIterator() {
907         final ArrayList arrayList = new ArrayList();
908         final Iterator iterator = arrayList.iterator();
909         assertTrue(IteratorUtils.peekingIterator(iterator) instanceof Iterator, "create instance fail");
910         assertThrows(NullPointerException.class, () -> IteratorUtils.peekingIterator(null));
911     }
912 
913     @Test
914     public void testPushBackIterator() {
915         final ArrayList arrayList = new ArrayList();
916         final Iterator iterator = arrayList.iterator();
917         assertTrue(IteratorUtils.pushbackIterator(iterator) instanceof Iterator, "create instance fail");
918         assertThrows(NullPointerException.class, () -> IteratorUtils.pushbackIterator(null));
919     }
920 
921     @Test
922     public void testSingletonIterator() {
923         assertTrue(IteratorUtils.singletonIterator(new Object()) instanceof ResettableIterator, "create instance fail");
924     }
925 
926     @Test
927     public void testSingletonListIterator() {
928         assertTrue(IteratorUtils.singletonListIterator(new Object()) instanceof Iterator, "create instance fail");
929     }
930 
931     @Test
932     public void testToArray() {
933         final List<Object> list = new ArrayList<>();
934         list.add(Integer.valueOf(1));
935         list.add("Two");
936         list.add(null);
937         final Object[] result = IteratorUtils.toArray(list.iterator());
938         assertEquals(list, Arrays.asList(result));
939 
940         assertThrows(NullPointerException.class, () -> IteratorUtils.toArray(null));
941     }
942 
943     @Test
944     public void testToArray2() {
945         final List<String> list = new ArrayList<>();
946         list.add("One");
947         list.add("Two");
948         list.add(null);
949         final String[] result = IteratorUtils.toArray(list.iterator(), String.class);
950         assertEquals(list, Arrays.asList(result));
951 
952         assertThrows(NullPointerException.class, () -> IteratorUtils.toArray(list.iterator(), null));
953         assertThrows(NullPointerException.class, () -> IteratorUtils.toArray(null, String.class));
954     }
955 
956     @Test
957     public void testToList() {
958         final List<Object> list = new ArrayList<>();
959         list.add(Integer.valueOf(1));
960         list.add("Two");
961         list.add(null);
962         final List<Object> result = IteratorUtils.toList(list.iterator());
963         assertEquals(list, result);
964         // add
965 
966         assertThrows(NullPointerException.class, () -> IteratorUtils.toList(null, 10));
967         assertThrows(IllegalArgumentException.class, () -> IteratorUtils.toList(list.iterator(), -1));
968     }
969 
970     @Test
971     public void testToSet() {
972         final Set<Object> set = new HashSet<>();
973         set.add(Integer.valueOf(1));
974         set.add("Two");
975         set.add(null);
976         final Set<Object> result = IteratorUtils.toSet(set.iterator());
977         assertEquals(set, result);
978         assertThrows(NullPointerException.class, () -> IteratorUtils.toSet(null, 10));
979         assertThrows(IllegalArgumentException.class, () -> IteratorUtils.toSet(set.iterator(), -1));
980     }
981 
982     @Test
983     public void testToListIterator() {
984         final List<Integer> list = new ArrayList<>();
985         list.add(Integer.valueOf(0));
986         list.add(Integer.valueOf(1));
987         list.add(Integer.valueOf(2));
988         final Iterator<Integer> iterator = list.iterator();
989 
990         final ListIterator<Integer> liItr = IteratorUtils.toListIterator(iterator);
991         int expected = 0;
992         while (liItr.hasNext()) {
993             assertEquals(expected, liItr.next().intValue());
994             ++expected;
995         }
996     }
997 
998     @Test
999     public void testToListIteratorNull() {
1000         assertThrows(NullPointerException.class, () -> IteratorUtils.toListIterator(null));
1001     }
1002 
1003     @Test
1004     public void testTransformedIterator() {
1005         final ArrayList arrayList = new ArrayList();
1006         final Iterator iterator = arrayList.iterator();
1007 
1008         assertThrows(NullPointerException.class, () -> IteratorUtils.transformedIterator(iterator, null));
1009         assertThrows(NullPointerException.class, () -> IteratorUtils.transformedIterator(null, null));
1010     }
1011 
1012     /**
1013      * Test remove() for an immutable Iterator.
1014      */
1015     @Test
1016     public void testUnmodifiableIteratorImmutability() {
1017         final Iterator<String> iterator = getImmutableIterator();
1018 
1019         assertThrows(UnsupportedOperationException.class, () -> iterator.remove());
1020 
1021         iterator.next();
1022 
1023         assertThrows(UnsupportedOperationException.class, () -> iterator.remove());
1024     }
1025 
1026     /**
1027      * Test next() and hasNext() for an immutable Iterator.
1028      */
1029     @Test
1030     public void testUnmodifiableIteratorIteration() {
1031         final Iterator<String> iterator = getImmutableIterator();
1032 
1033         assertTrue(iterator.hasNext());
1034 
1035         assertEquals("a", iterator.next());
1036 
1037         assertTrue(iterator.hasNext());
1038 
1039         assertEquals("b", iterator.next());
1040 
1041         assertTrue(iterator.hasNext());
1042 
1043         assertEquals("c", iterator.next());
1044 
1045         assertTrue(iterator.hasNext());
1046 
1047         assertEquals("d", iterator.next());
1048 
1049         assertFalse(iterator.hasNext());
1050     }
1051 
1052     /**
1053      * Test remove() for an immutable ListIterator.
1054      */
1055     @Test
1056     public void testUnmodifiableListIteratorImmutability() {
1057         final ListIterator<String> listIterator = getImmutableListIterator();
1058 
1059         assertThrows(UnsupportedOperationException.class, () -> listIterator.remove());
1060         assertThrows(UnsupportedOperationException.class, () -> listIterator.set("a"));
1061         assertThrows(UnsupportedOperationException.class, () -> listIterator.add("a"));
1062 
1063         listIterator.next();
1064 
1065         assertThrows(UnsupportedOperationException.class, () -> listIterator.remove());
1066         assertThrows(UnsupportedOperationException.class, () -> listIterator.set("a"));
1067         assertThrows(UnsupportedOperationException.class, () -> listIterator.add("a"));
1068     }
1069 
1070     /**
1071      * Test next(), hasNext(), previous() and hasPrevious() for an immutable ListIterator.
1072      */
1073     @Test
1074     public void testUnmodifiableListIteratorIteration() {
1075         final ListIterator<String> listIterator = getImmutableListIterator();
1076 
1077         assertFalse(listIterator.hasPrevious());
1078         assertTrue(listIterator.hasNext());
1079 
1080         assertEquals("a", listIterator.next());
1081 
1082         assertTrue(listIterator.hasPrevious());
1083         assertTrue(listIterator.hasNext());
1084 
1085         assertEquals("b", listIterator.next());
1086 
1087         assertTrue(listIterator.hasPrevious());
1088         assertTrue(listIterator.hasNext());
1089 
1090         assertEquals("c", listIterator.next());
1091 
1092         assertTrue(listIterator.hasPrevious());
1093         assertTrue(listIterator.hasNext());
1094 
1095         assertEquals("d", listIterator.next());
1096 
1097         assertTrue(listIterator.hasPrevious());
1098         assertFalse(listIterator.hasNext());
1099 
1100         assertEquals("d", listIterator.previous());
1101 
1102         assertTrue(listIterator.hasPrevious());
1103         assertTrue(listIterator.hasNext());
1104 
1105         assertEquals("c", listIterator.previous());
1106 
1107         assertTrue(listIterator.hasPrevious());
1108         assertTrue(listIterator.hasNext());
1109 
1110         assertEquals("b", listIterator.previous());
1111 
1112         assertTrue(listIterator.hasPrevious());
1113         assertTrue(listIterator.hasNext());
1114 
1115         assertEquals("a", listIterator.previous());
1116 
1117         assertFalse(listIterator.hasPrevious());
1118         assertTrue(listIterator.hasNext());
1119     }
1120 
1121     @Test
1122     public void testUnmodifiableMapIterator() {
1123         final Set<?> set = new LinkedHashSet<>();
1124         final MapIterator iterator = new EntrySetToMapIteratorAdapter(set);
1125         assertTrue(IteratorUtils.unmodifiableMapIterator(iterator) instanceof MapIterator, "create instance fail");
1126         assertThrows(NullPointerException.class, () -> IteratorUtils.unmodifiableMapIterator(null));
1127     }
1128 
1129     @Test
1130     public void testZippingIterator() {
1131         final ArrayList arrayList = new ArrayList();
1132         final Iterator iterator = arrayList.iterator();
1133         assertTrue(IteratorUtils.zippingIterator(iterator, iterator, iterator) instanceof ZippingIterator, "create instance fail");
1134         assertTrue(IteratorUtils.zippingIterator(iterator, iterator) instanceof ZippingIterator, "create instance fail");
1135     }
1136 
1137 }