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.Iterator;
27  import java.util.List;
28  import java.util.NoSuchElementException;
29  
30  import org.apache.commons.collections4.IteratorUtils;
31  import org.apache.commons.collections4.Predicate;
32  import org.junit.jupiter.api.BeforeEach;
33  import org.junit.jupiter.api.Test;
34  
35  /**
36   * Tests the LazyIteratorChain class.
37   */
38  public class LazyIteratorChainTest extends AbstractIteratorTest<String> {
39  
40      protected String[] testArray = {
41          "One", "Two", "Three", "Four", "Five", "Six"
42      };
43  
44      protected List<String> list1;
45      protected List<String> list2;
46      protected List<String> list3;
47  
48      public LazyIteratorChainTest() {
49          super(LazyIteratorChainTest.class.getSimpleName());
50      }
51  
52      @Override
53      public LazyIteratorChain<String> makeEmptyIterator() {
54          return new LazyIteratorChain<String>() {
55              @Override
56              protected Iterator<String> nextIterator(final int count) {
57                  return null;
58              }
59          };
60      }
61  
62      @Override
63      public LazyIteratorChain<String> makeObject() {
64          final LazyIteratorChain<String> chain = new LazyIteratorChain<String>() {
65              @Override
66              protected Iterator<String> nextIterator(final int count) {
67                  switch (count) {
68                  case 1:
69                      return list1.iterator();
70                  case 2:
71                      return list2.iterator();
72                  case 3:
73                      return list3.iterator();
74                  }
75                  return null;
76              }
77          };
78  
79          return chain;
80      }
81  
82      @BeforeEach
83      public void setUp() {
84          list1 = new ArrayList<>();
85          list1.add("One");
86          list1.add("Two");
87          list1.add("Three");
88          list2 = new ArrayList<>();
89          list2.add("Four");
90          list3 = new ArrayList<>();
91          list3.add("Five");
92          list3.add("Six");
93      }
94  
95      @Test
96      public void testEmptyChain() {
97          final LazyIteratorChain<String> chain = makeEmptyIterator();
98          assertFalse(chain.hasNext());
99          assertAll(
100                 () -> assertThrows(NoSuchElementException.class, () -> chain.next()),
101                 () -> assertThrows(IllegalStateException.class, () -> chain.remove())
102         );
103     }
104 
105     @Test
106     public void testFirstIteratorIsEmptyBug() {
107         final List<String> empty = new ArrayList<>();
108         final List<String> notEmpty = new ArrayList<>();
109         notEmpty.add("A");
110         notEmpty.add("B");
111         notEmpty.add("C");
112         final LazyIteratorChain<String> chain = new LazyIteratorChain<String>() {
113             @Override
114             protected Iterator<String> nextIterator(final int count) {
115                 switch (count) {
116                 case 1:
117                     return empty.iterator();
118                 case 2:
119                     return notEmpty.iterator();
120                 }
121                 return null;
122             }
123         };
124         assertTrue(chain.hasNext(), "should have next");
125         assertEquals("A", chain.next());
126         assertTrue(chain.hasNext(), "should have next");
127         assertEquals("B", chain.next());
128         assertTrue(chain.hasNext(), "should have next");
129         assertEquals("C", chain.next());
130         assertFalse(chain.hasNext(), "should not have next");
131     }
132 
133     @Test
134     public void testIterator() {
135         final Iterator<String> iter = makeObject();
136         for (final String testValue : testArray) {
137             final Object iterValue = iter.next();
138 
139             assertEquals(testValue, iterValue, "Iteration value is correct");
140         }
141 
142         assertFalse(iter.hasNext(), "Iterator should now be empty");
143 
144         try {
145             iter.next();
146         } catch (final Exception e) {
147             assertEquals(e.getClass(), new NoSuchElementException().getClass(), "NoSuchElementException must be thrown");
148         }
149     }
150 
151     @Test
152     @Override
153     public void testRemove() {
154         final Iterator<String> iter = makeObject();
155 
156         assertThrows(IllegalStateException.class, () -> iter.remove(),
157                 "Calling remove before the first call to next() should throw an exception");
158 
159         for (final String testValue : testArray) {
160             final String iterValue = iter.next();
161 
162             assertEquals(testValue, iterValue, "Iteration value is correct");
163 
164             if (!iterValue.equals("Four")) {
165                 iter.remove();
166             }
167         }
168 
169         assertTrue(list1.isEmpty(), "List is empty");
170         assertEquals(1, list2.size(), "List is empty");
171         assertTrue(list3.isEmpty(), "List is empty");
172     }
173 
174     @Test
175     public void testRemoveFromFilteredIterator() {
176 
177         final Predicate<Integer> myPredicate = i -> i.compareTo(Integer.valueOf(4)) < 0;
178 
179         final List<Integer> list1 = new ArrayList<>();
180         final List<Integer> list2 = new ArrayList<>();
181 
182         list1.add(Integer.valueOf(1));
183         list1.add(Integer.valueOf(2));
184         list2.add(Integer.valueOf(3));
185         list2.add(Integer.valueOf(4)); // will be ignored by the predicate
186 
187         final Iterator<Integer> it1 = IteratorUtils.filteredIterator(list1.iterator(), myPredicate);
188         final Iterator<Integer> it2 = IteratorUtils.filteredIterator(list2.iterator(), myPredicate);
189 
190         final Iterator<Integer> it = IteratorUtils.chainedIterator(it1, it2);
191         while (it.hasNext()) {
192             it.next();
193             it.remove();
194         }
195         assertEquals(0, list1.size());
196         assertEquals(1, list2.size());
197     }
198 
199 }