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.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.Transformer;
32  import org.junit.jupiter.api.BeforeEach;
33  import org.junit.jupiter.api.Test;
34  
35  /**
36   * Testcase.
37   */
38  public class ObjectGraphIteratorTest extends AbstractIteratorTest<Object> {
39  
40      static class Branch {
41  
42          List<Leaf> leaves = new ArrayList<>();
43  
44          Leaf addLeaf() {
45              leaves.add(new Leaf());
46              return getLeaf(leaves.size() - 1);
47          }
48  
49          Leaf getLeaf(final int index) {
50              return leaves.get(index);
51          }
52  
53          Iterator<Leaf> leafIterator() {
54              return leaves.iterator();
55          }
56  
57      }
58  
59      static class Forest {
60  
61          List<Tree> trees = new ArrayList<>();
62  
63          Tree addTree() {
64              trees.add(new Tree());
65              return getTree(trees.size() - 1);
66          }
67  
68          Tree getTree(final int index) {
69              return trees.get(index);
70          }
71  
72          Iterator<Tree> treeIterator() {
73              return trees.iterator();
74          }
75  
76      }
77      static class Leaf {
78  
79          String color;
80  
81          String getColor() {
82              return color;
83          }
84  
85          void setColor(final String color) {
86              this.color = color;
87          }
88  
89      }
90      static class LeafFinder implements Transformer<Object, Object> {
91  
92          @Override
93          public Object transform(final Object input) {
94              if (input instanceof Forest) {
95                  return ((Forest) input).treeIterator();
96              }
97              if (input instanceof Tree) {
98                  return ((Tree) input).branchIterator();
99              }
100             if (input instanceof Branch) {
101                 return ((Branch) input).leafIterator();
102             }
103             if (input instanceof Leaf) {
104                 return input;
105             }
106             throw new ClassCastException();
107         }
108 
109     }
110     static class Tree {
111 
112         List<Branch> branches = new ArrayList<>();
113 
114         Branch addBranch() {
115             branches.add(new Branch());
116             return getBranch(branches.size() - 1);
117         }
118 
119         Iterator<Branch> branchIterator() {
120             return branches.iterator();
121         }
122 
123         Branch getBranch(final int index) {
124             return branches.get(index);
125         }
126 
127     }
128 
129     protected String[] testArray = { "One", "Two", "Three", "Four", "Five", "Six" };
130 
131     protected List<String> list1;
132 
133     protected List<String> list2;
134 
135     protected List<String> list3;
136 
137     protected List<Iterator<String>> iteratorList;
138 
139     @Override
140     public ObjectGraphIterator<Object> makeEmptyIterator() {
141         final ArrayList<Object> list = new ArrayList<>();
142         return new ObjectGraphIterator<>(list.iterator());
143     }
144 
145     @Override
146     public ObjectGraphIterator<Object> makeObject() {
147         setUp();
148         return new ObjectGraphIterator<>(iteratorList.iterator());
149     }
150 
151     @BeforeEach
152     public void setUp() {
153         list1 = new ArrayList<>();
154         list1.add("One");
155         list1.add("Two");
156         list1.add("Three");
157         list2 = new ArrayList<>();
158         list2.add("Four");
159         list3 = new ArrayList<>();
160         list3.add("Five");
161         list3.add("Six");
162         iteratorList = new ArrayList<>();
163         iteratorList.add(list1.iterator());
164         iteratorList.add(list2.iterator());
165         iteratorList.add(list3.iterator());
166     }
167 
168     @Test
169     public void testIteration_IteratorOfIterators() {
170         final List<Iterator<String>> iteratorList = new ArrayList<>();
171         iteratorList.add(list1.iterator());
172         iteratorList.add(list2.iterator());
173         iteratorList.add(list3.iterator());
174         final Iterator<Object> it = new ObjectGraphIterator<>(iteratorList.iterator(), null);
175 
176         for (int i = 0; i < 6; i++) {
177             assertTrue(it.hasNext());
178             assertEquals(testArray[i], it.next());
179         }
180         assertFalse(it.hasNext());
181     }
182 
183     @Test
184     public void testIteration_IteratorOfIteratorsWithEmptyIterators() {
185         final List<Iterator<String>> iteratorList = new ArrayList<>();
186         iteratorList.add(IteratorUtils.<String>emptyIterator());
187         iteratorList.add(list1.iterator());
188         iteratorList.add(IteratorUtils.<String>emptyIterator());
189         iteratorList.add(list2.iterator());
190         iteratorList.add(IteratorUtils.<String>emptyIterator());
191         iteratorList.add(list3.iterator());
192         iteratorList.add(IteratorUtils.<String>emptyIterator());
193         final Iterator<Object> it = new ObjectGraphIterator<>(iteratorList.iterator(), null);
194 
195         for (int i = 0; i < 6; i++) {
196             assertTrue(it.hasNext());
197             assertEquals(testArray[i], it.next());
198         }
199         assertFalse(it.hasNext());
200     }
201 
202     @Test
203     public void testIteration_RootNoTransformer() {
204         final Forest forest = new Forest();
205         final Iterator<Object> it = new ObjectGraphIterator<>(forest, null);
206 
207         assertTrue(it.hasNext());
208         assertSame(forest, it.next());
209         assertFalse(it.hasNext());
210 
211         assertThrows(NoSuchElementException.class, () -> it.next());
212     }
213 
214     @Test
215     public void testIteration_RootNull() {
216         final Iterator<Object> it = new ObjectGraphIterator<>(null, null);
217 
218         assertFalse(it.hasNext());
219 
220         assertThrows(NoSuchElementException.class, () -> it.next());
221 
222         assertThrows(IllegalStateException.class, () -> it.remove());
223     }
224 
225     @Test
226     public void testIteration_Transformed1() {
227         final Forest forest = new Forest();
228         final Leaf l1 = forest.addTree().addBranch().addLeaf();
229         final Iterator<Object> it = new ObjectGraphIterator<>(forest, new LeafFinder());
230 
231         assertTrue(it.hasNext());
232         assertSame(l1, it.next());
233         assertFalse(it.hasNext());
234 
235         assertThrows(NoSuchElementException.class, () -> it.next());
236     }
237 
238     @Test
239     public void testIteration_Transformed2() {
240         final Forest forest = new Forest();
241         forest.addTree();
242         forest.addTree();
243         forest.addTree();
244         final Branch b1 = forest.getTree(0).addBranch();
245         final Branch b2 = forest.getTree(0).addBranch();
246         final Branch b3 = forest.getTree(2).addBranch();
247         /* Branch b4 = */ forest.getTree(2).addBranch();
248         final Branch b5 = forest.getTree(2).addBranch();
249         final Leaf l1 = b1.addLeaf();
250         final Leaf l2 = b1.addLeaf();
251         final Leaf l3 = b2.addLeaf();
252         final Leaf l4 = b3.addLeaf();
253         final Leaf l5 = b5.addLeaf();
254 
255         final Iterator<Object> it = new ObjectGraphIterator<>(forest, new LeafFinder());
256 
257         assertTrue(it.hasNext());
258         assertSame(l1, it.next());
259         assertTrue(it.hasNext());
260         assertSame(l2, it.next());
261         assertTrue(it.hasNext());
262         assertSame(l3, it.next());
263         assertTrue(it.hasNext());
264         assertSame(l4, it.next());
265         assertTrue(it.hasNext());
266         assertSame(l5, it.next());
267         assertFalse(it.hasNext());
268 
269         assertThrows(NoSuchElementException.class, () -> it.next());
270     }
271 
272     @Test
273     public void testIteration_Transformed3() {
274         final Forest forest = new Forest();
275         forest.addTree();
276         forest.addTree();
277         forest.addTree();
278         final Branch b1 = forest.getTree(1).addBranch();
279         final Branch b2 = forest.getTree(1).addBranch();
280         final Branch b3 = forest.getTree(2).addBranch();
281         final Branch b4 = forest.getTree(2).addBranch();
282         /* Branch b5 = */ forest.getTree(2).addBranch();
283         final Leaf l1 = b1.addLeaf();
284         final Leaf l2 = b1.addLeaf();
285         final Leaf l3 = b2.addLeaf();
286         final Leaf l4 = b3.addLeaf();
287         final Leaf l5 = b4.addLeaf();
288 
289         final Iterator<Object> it = new ObjectGraphIterator<>(forest, new LeafFinder());
290 
291         assertTrue(it.hasNext());
292         assertSame(l1, it.next());
293         assertTrue(it.hasNext());
294         assertSame(l2, it.next());
295         assertTrue(it.hasNext());
296         assertSame(l3, it.next());
297         assertTrue(it.hasNext());
298         assertSame(l4, it.next());
299         assertTrue(it.hasNext());
300         assertSame(l5, it.next());
301         assertFalse(it.hasNext());
302 
303         assertThrows(NoSuchElementException.class, () -> it.next());
304     }
305 
306     @Test
307     public void testIteratorConstructor_null_next() {
308         final Iterator<Object> it = new ObjectGraphIterator<>(null);
309         assertThrows(NoSuchElementException.class, () -> it.next());
310     }
311 
312     @Test
313     public void testIteratorConstructor_null_remove() {
314         final Iterator<Object> it = new ObjectGraphIterator<>(null);
315         assertThrows(IllegalStateException.class, () -> it.remove());
316     }
317 
318     @Test
319     public void testIteratorConstructor_null1() {
320         final Iterator<Object> it = new ObjectGraphIterator<>(null);
321 
322         assertFalse(it.hasNext());
323 
324         assertThrows(NoSuchElementException.class, () -> it.next());
325 
326         assertThrows(IllegalStateException.class, () -> it.remove());
327     }
328 
329     @Test
330     public void testIteratorConstructorIteration_Empty() {
331         final List<Iterator<Object>> iteratorList = new ArrayList<>();
332         final Iterator<Object> it = new ObjectGraphIterator<>(iteratorList.iterator());
333 
334         assertFalse(it.hasNext());
335 
336         assertThrows(NoSuchElementException.class, () -> it.next());
337 
338         assertThrows(IllegalStateException.class, () -> it.remove());
339     }
340 
341     @Test
342     public void testIteratorConstructorIteration_Simple() {
343         final List<Iterator<String>> iteratorList = new ArrayList<>();
344         iteratorList.add(list1.iterator());
345         iteratorList.add(list2.iterator());
346         iteratorList.add(list3.iterator());
347         final Iterator<Object> it = new ObjectGraphIterator<>(iteratorList.iterator());
348 
349         for (int i = 0; i < 6; i++) {
350             assertTrue(it.hasNext());
351             assertEquals(testArray[i], it.next());
352         }
353         assertFalse(it.hasNext());
354 
355         assertThrows(NoSuchElementException.class, () -> it.next());
356     }
357 
358     @Test
359     public void testIteratorConstructorIteration_SimpleNoHasNext() {
360         final List<Iterator<String>> iteratorList = new ArrayList<>();
361         iteratorList.add(list1.iterator());
362         iteratorList.add(list2.iterator());
363         iteratorList.add(list3.iterator());
364         final Iterator<Object> it = new ObjectGraphIterator<>(iteratorList.iterator());
365 
366         for (int i = 0; i < 6; i++) {
367             assertEquals(testArray[i], it.next());
368         }
369 
370         assertThrows(NoSuchElementException.class, () -> it.next());
371     }
372 
373     @Test
374     public void testIteratorConstructorIteration_WithEmptyIterators() {
375         final List<Iterator<String>> iteratorList = new ArrayList<>();
376         iteratorList.add(IteratorUtils.<String>emptyIterator());
377         iteratorList.add(list1.iterator());
378         iteratorList.add(IteratorUtils.<String>emptyIterator());
379         iteratorList.add(list2.iterator());
380         iteratorList.add(IteratorUtils.<String>emptyIterator());
381         iteratorList.add(list3.iterator());
382         iteratorList.add(IteratorUtils.<String>emptyIterator());
383         final Iterator<Object> it = new ObjectGraphIterator<>(iteratorList.iterator());
384 
385         for (int i = 0; i < 6; i++) {
386             assertTrue(it.hasNext());
387             assertEquals(testArray[i], it.next());
388         }
389         assertFalse(it.hasNext());
390 
391         assertThrows(NoSuchElementException.class, () -> it.next());
392     }
393 
394     @Test
395     public void testIteratorConstructorRemove() {
396         final List<Iterator<String>> iteratorList = new ArrayList<>();
397         iteratorList.add(list1.iterator());
398         iteratorList.add(list2.iterator());
399         iteratorList.add(list3.iterator());
400         final Iterator<Object> it = new ObjectGraphIterator<>(iteratorList.iterator());
401 
402         for (int i = 0; i < 6; i++) {
403             assertEquals(testArray[i], it.next());
404             it.remove();
405         }
406         assertFalse(it.hasNext());
407         assertEquals(0, list1.size());
408         assertEquals(0, list2.size());
409         assertEquals(0, list3.size());
410     }
411 
412 }