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.junit.jupiter.api.Assertions.assertArrayEquals;
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.assertNotNull;
23  import static org.junit.jupiter.api.Assertions.assertSame;
24  import static org.junit.jupiter.api.Assertions.assertThrows;
25  import static org.junit.jupiter.api.Assertions.assertTrue;
26  
27  import java.util.ArrayList;
28  import java.util.Arrays;
29  import java.util.Collection;
30  import java.util.Collections;
31  import java.util.Enumeration;
32  import java.util.Iterator;
33  import java.util.LinkedList;
34  import java.util.List;
35  import java.util.concurrent.atomic.AtomicInteger;
36  
37  import org.junit.jupiter.api.BeforeEach;
38  import org.junit.jupiter.api.Test;
39  
40  /**
41   * Tests for FluentIterable.
42   */
43  public class FluentIterableTest {
44  
45      private static final Predicate<Number> EVEN = input -> input.intValue() % 2 == 0;
46  
47      /**
48       * Iterable of {@link Integer}s
49       */
50      private Iterable<Integer> iterableA;
51  
52      /**
53       * Iterable of {@link Long}s
54       */
55      private Iterable<Long> iterableB;
56  
57      /**
58       * Collection of even {@link Integer}s
59       */
60      private Iterable<Integer> iterableEven;
61  
62      /**
63       * Collection of odd {@link Integer}s
64       */
65      private Iterable<Integer> iterableOdd;
66  
67      /**
68       * An empty Iterable.
69       */
70      private Iterable<Integer> emptyIterable;
71  
72      @BeforeEach
73      public void setUp() {
74          final Collection<Integer> collectionA = new ArrayList<>();
75          collectionA.add(1);
76          collectionA.add(2);
77          collectionA.add(2);
78          collectionA.add(3);
79          collectionA.add(3);
80          collectionA.add(3);
81          collectionA.add(4);
82          collectionA.add(4);
83          collectionA.add(4);
84          collectionA.add(4);
85          iterableA = collectionA;
86  
87          final Collection<Long> collectionB = new LinkedList<>();
88          collectionB.add(5L);
89          collectionB.add(4L);
90          collectionB.add(4L);
91          collectionB.add(3L);
92          collectionB.add(3L);
93          collectionB.add(3L);
94          collectionB.add(2L);
95          collectionB.add(2L);
96          collectionB.add(2L);
97          collectionB.add(2L);
98          iterableB = collectionB;
99  
100         iterableEven = Arrays.asList(2, 4, 6, 8, 10, 12);
101         iterableOdd = Arrays.asList(1, 3, 5, 7, 9, 11);
102 
103         emptyIterable = Collections.emptyList();
104     }
105 
106     @Test
107     public void testAllMatch() {
108         assertTrue(FluentIterable.of(iterableEven).allMatch(EVEN));
109         assertFalse(FluentIterable.of(iterableOdd).allMatch(EVEN));
110         assertFalse(FluentIterable.of(iterableA).allMatch(EVEN));
111 
112         assertThrows(NullPointerException.class, () -> FluentIterable.of(iterableEven).allMatch(null),
113                 "expecting NullPointerException");
114     }
115 
116     @Test
117     public void testAnyMatch() {
118         assertTrue(FluentIterable.of(iterableEven).anyMatch(EVEN));
119         assertFalse(FluentIterable.of(iterableOdd).anyMatch(EVEN));
120         assertTrue(FluentIterable.of(iterableA).anyMatch(EVEN));
121 
122         assertThrows(NullPointerException.class, () -> FluentIterable.of(iterableEven).anyMatch(null),
123                 "expecting NullPointerException");
124     }
125 
126     @Test
127     public void testAppendElements() {
128         final FluentIterable<Integer> it = FluentIterable.of(iterableA).append(10, 20, 30);
129         assertEquals(IterableUtils.size(iterableA) + 3, IterableUtils.size(it));
130         assertTrue(IterableUtils.contains(it, 1));
131         assertTrue(IterableUtils.contains(it, 10));
132         assertTrue(IterableUtils.contains(it, 20));
133         assertTrue(IterableUtils.contains(it, 30));
134         assertFalse(IterableUtils.contains(it, 40));
135 
136         final FluentIterable<Integer> empty = FluentIterable.of(emptyIterable).append();
137         assertTrue(IterableUtils.isEmpty(empty));
138     }
139 
140     @Test
141     public void testAppendIterable() {
142         final List<Integer> listB = Arrays.asList(10, 20, 30);
143         final FluentIterable<Integer> it = FluentIterable.of(iterableA).append(listB);
144         assertEquals(IterableUtils.size(iterableA) + listB.size(), IterableUtils.size(it));
145         assertTrue(IterableUtils.contains(it, 1));
146         assertTrue(IterableUtils.contains(it, 10));
147         assertTrue(IterableUtils.contains(it, 20));
148         assertTrue(IterableUtils.contains(it, 30));
149         assertFalse(IterableUtils.contains(it, 40));
150     }
151 
152     @Test
153     public void testAsEnumeration() {
154         Enumeration<Long> enumeration = FluentIterable.of(iterableB).asEnumeration();
155         final List<Long> result = EnumerationUtils.toList(enumeration);
156         assertEquals(iterableB, result);
157 
158         enumeration = FluentIterable.<Long>empty().asEnumeration();
159         assertFalse(enumeration.hasMoreElements());
160     }
161 
162     @Test
163     public void testCollate() {
164         final List<Integer> result = FluentIterable.of(iterableOdd).collate(iterableEven).toList();
165         final List<Integer> combinedList = new ArrayList<>();
166         CollectionUtils.addAll(combinedList, iterableOdd);
167         CollectionUtils.addAll(combinedList, iterableEven);
168         combinedList.sort(null);
169         assertEquals(combinedList, result);
170 
171         assertThrows(NullPointerException.class, () -> FluentIterable.of(iterableOdd).collate(null).toList(),
172                 "expecting NullPointerException");
173     }
174 
175     @Test
176     public void testCollateWithComparator() {
177         List<Integer> result =
178                 FluentIterable
179                     .of(iterableOdd)
180                     .collate(iterableEven, ComparatorUtils.<Integer>naturalComparator())
181                     .toList();
182 
183         final List<Integer> combinedList = new ArrayList<>();
184         CollectionUtils.addAll(combinedList, iterableOdd);
185         CollectionUtils.addAll(combinedList, iterableEven);
186         combinedList.sort(null);
187         assertEquals(combinedList, result);
188 
189         // null comparator is equivalent to natural ordering
190         result = FluentIterable.of(iterableOdd).collate(iterableEven, null).toList();
191         assertEquals(combinedList, result);
192     }
193 
194     @Test
195     public void testContains() {
196         assertTrue(FluentIterable.of(iterableEven).contains(2));
197         assertFalse(FluentIterable.of(iterableEven).contains(1));
198         assertFalse(FluentIterable.of(iterableEven).contains(null));
199         assertTrue(FluentIterable.of(iterableEven).append((Integer) null).contains(null));
200     }
201 
202     @Test
203     public void testCopyInto() {
204         List<Integer> result = new ArrayList<>();
205         FluentIterable.of(iterableA).copyInto(result);
206 
207         List<Integer> expected = IterableUtils.toList(iterableA);
208         assertEquals(expected.size(), result.size());
209         assertEquals(expected, result);
210 
211         result = new ArrayList<>();
212         result.add(10);
213         result.add(9);
214         result.add(8);
215         FluentIterable.of(iterableA).copyInto(result);
216 
217         expected = new ArrayList<>(Arrays.asList(10, 9, 8));
218         expected.addAll(IterableUtils.toList(iterableA));
219         assertEquals(expected.size(), result.size());
220         assertEquals(expected, result);
221 
222         assertThrows(NullPointerException.class, () -> FluentIterable.of(iterableA).copyInto(null),
223                 "expecting NullPointerException");
224     }
225 
226     @Test
227     public void testEval() {
228         final List<Integer> listNumbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
229         final FluentIterable<Integer> iterable = FluentIterable.of(listNumbers).filter(EVEN);
230         final FluentIterable<Integer> materialized = iterable.eval();
231 
232         listNumbers.addAll(Arrays.asList(11, 12, 13, 14, 15, 16, 17, 18, 19, 20));
233         assertEquals(5, materialized.size());
234         assertEquals(10, iterable.size());
235 
236         assertEquals(Arrays.asList(2, 4, 6, 8, 10), materialized.toList());
237         assertEquals(Arrays.asList(2, 4, 6, 8, 10, 12, 14, 16, 18, 20), iterable.toList());
238     }
239 
240     @Test
241     public void testFactoryMethodOf() {
242         FluentIterable<Integer> iterable = FluentIterable.of(1, 2, 3, 4, 5);
243         List<Integer> result = iterable.toList();
244         assertEquals(Arrays.asList(1, 2, 3, 4, 5), result);
245 
246         iterable = FluentIterable.of(1);
247         assertEquals(1, iterable.size());
248         assertFalse(iterable.isEmpty());
249         assertEquals(Arrays.asList(1), iterable.toList());
250 
251         result = FluentIterable.of(new Integer[0]).toList();
252         assertTrue(result.isEmpty());
253 
254         final Iterable<Integer> it = null;
255         assertThrows(NullPointerException.class, () -> FluentIterable.of(it).toList(),
256                 "expecting NullPointerException");
257     }
258 
259     @Test
260     public void testFilter() {
261         final Predicate<Integer> smallerThan3 = object -> object.intValue() < 3;
262         List<Integer> result = FluentIterable.of(iterableA).filter(smallerThan3).toList();
263         assertEquals(3, result.size());
264         assertEquals(Arrays.asList(1, 2, 2), result);
265 
266         // empty iterable
267         result = FluentIterable.of(emptyIterable).filter(smallerThan3).toList();
268         assertEquals(0, result.size());
269 
270         assertThrows(NullPointerException.class, () -> FluentIterable.of(iterableA).filter(null).toList(),
271                 "expecting NullPointerException");
272     }
273 
274     @Test
275     public void testForEach() {
276         final AtomicInteger sum = new AtomicInteger();
277         final Closure<Integer> closure = sum::addAndGet;
278 
279         FluentIterable.of(iterableA).forEach(closure);
280         int expectedSum = 0;
281         for (final Integer i : iterableA) {
282             expectedSum += i;
283         }
284         assertEquals(expectedSum, sum.get());
285 
286         assertThrows(NullPointerException.class, () -> FluentIterable.of(iterableA).forEach((Closure<Integer>) null),
287                 "expecting NullPointerException");
288     }
289 
290     @Test
291     public void testGet() {
292         assertEquals(2, FluentIterable.of(iterableEven).get(0).intValue());
293 
294         assertThrows(IndexOutOfBoundsException.class, () -> FluentIterable.of(iterableEven).get(-1),
295                 "expecting IndexOutOfBoundsException");
296 
297         assertThrows(IndexOutOfBoundsException.class, () -> FluentIterable.of(iterableEven).get(IterableUtils.size(iterableEven)),
298                 "expecting IndexOutOfBoundsException");
299     }
300 
301     @Test
302     public void testIsEmpty() {
303         assertTrue(FluentIterable.of(emptyIterable).isEmpty());
304         assertFalse(FluentIterable.of(iterableOdd).isEmpty());
305     }
306 
307     @Test
308     public void testIterator() {
309         Iterator<Integer> iterator = FluentIterable.of(iterableA).iterator();
310         assertTrue(iterator.hasNext());
311 
312         iterator = FluentIterable.<Integer>empty().iterator();
313         assertFalse(iterator.hasNext());
314     }
315 
316     @Test
317     public void testLimit() {
318         List<Integer> result = FluentIterable.of(iterableA).limit(3).toList();
319         assertEquals(3, result.size());
320         assertEquals(Arrays.asList(1, 2, 2), result);
321 
322         // limit larger than input
323         result = FluentIterable.of(iterableA).limit(100).toList();
324         final List<Integer> expected = IterableUtils.toList(iterableA);
325         assertEquals(expected.size(), result.size());
326         assertEquals(expected, result);
327 
328         // limit is 0
329         result = FluentIterable.of(iterableA).limit(0).toList();
330         assertEquals(0, result.size());
331 
332         // empty iterable
333         result = FluentIterable.of(emptyIterable).limit(3).toList();
334         assertEquals(0, result.size());
335 
336         assertThrows(IllegalArgumentException.class, () -> FluentIterable.of(iterableA).limit(-2).toList(),
337                 "expecting IllegalArgumentException");
338     }
339 
340     @Test
341     public void testReverse() {
342         List<Integer> result = FluentIterable.of(iterableA).reverse().toList();
343         final List<Integer> expected = IterableUtils.toList(iterableA);
344         Collections.reverse(expected);
345         assertEquals(expected, result);
346 
347         // empty iterable
348         result = FluentIterable.of(emptyIterable).reverse().toList();
349         assertEquals(0, result.size());
350     }
351 
352     @Test
353     public void testSize() {
354         assertEquals(0, FluentIterable.of(emptyIterable).size());
355         assertEquals(IterableUtils.toList(iterableOdd).size(), FluentIterable.of(iterableOdd).size());
356     }
357 
358     @Test
359     public void testSkip() {
360         List<Integer> result = FluentIterable.of(iterableA).skip(4).toList();
361         assertEquals(6, result.size());
362         assertEquals(Arrays.asList(3, 3, 4, 4, 4, 4), result);
363 
364         // skip larger than input
365         result = FluentIterable.of(iterableA).skip(100).toList();
366         assertEquals(0, result.size());
367 
368         // skip 0 elements
369         result = FluentIterable.of(iterableA).skip(0).toList();
370         final List<Integer> expected = IterableUtils.toList(iterableA);
371         assertEquals(expected.size(), result.size());
372         assertEquals(expected, result);
373 
374         // empty iterable
375         result = FluentIterable.of(emptyIterable).skip(3).toList();
376         assertEquals(0, result.size());
377 
378         assertThrows(IllegalArgumentException.class, () -> FluentIterable.of(iterableA).skip(-4).toList(),
379                 "expecting IllegalArgumentException");
380     }
381 
382     @SuppressWarnings({ "rawtypes", "unchecked" })
383     @Test
384     public void testToArray() {
385         final Long[] arr = {1L, 2L, 3L, 4L, 5L};
386         final Long[] result = FluentIterable.of(arr).toArray(Long.class);
387         assertNotNull(result);
388         assertArrayEquals(arr, result);
389 
390         assertThrows(ArrayStoreException.class, () -> FluentIterable.of(arr).toArray((Class) String.class));
391     }
392 
393     @Test
394     public void testToString() {
395         String result = FluentIterable.of(iterableA).toString();
396         assertEquals(iterableA.toString(), result);
397 
398         result = FluentIterable.empty().toString();
399         assertEquals("[]", result);
400     }
401 
402     @Test
403     public void testTransform() {
404         final Transformer<Integer, Integer> squared = object -> object * object;
405         List<Integer> result = FluentIterable.of(iterableA).transform(squared).toList();
406         assertEquals(10, result.size());
407         assertEquals(Arrays.asList(1, 4, 4, 9, 9, 9, 16, 16, 16, 16), result);
408 
409         // empty iterable
410         result = FluentIterable.of(emptyIterable).transform(squared).toList();
411         assertEquals(0, result.size());
412 
413         assertThrows(NullPointerException.class, () -> FluentIterable.of(iterableA).transform(null).toList(),
414                 "expecting NullPointerException");
415     }
416 
417     @Test
418     public void testUnique() {
419         List<Integer> result = FluentIterable.of(iterableA).unique().toList();
420         assertEquals(4, result.size());
421         assertEquals(Arrays.asList(1, 2, 3, 4), result);
422 
423         // empty iterable
424         result = FluentIterable.of(emptyIterable).unique().toList();
425         assertEquals(0, result.size());
426     }
427 
428     @Test
429     public void testUnmodifiable() {
430         final FluentIterable<Integer> iterable1 = FluentIterable.of(iterableA).unmodifiable();
431         final Iterator<Integer> it = iterable1.iterator();
432         assertEquals(1, it.next().intValue());
433 
434         assertThrows(UnsupportedOperationException.class, () -> it.remove(),
435                 "expecting UnsupportedOperationException");
436 
437         // calling unmodifiable on an already unmodifiable iterable shall return the same instance
438         final FluentIterable<Integer> iterable2 = iterable1.unmodifiable();
439         assertSame(iterable1, iterable2);
440     }
441 
442     @SuppressWarnings("unchecked")
443     @Test
444     public void testZip() {
445         List<Integer> result = FluentIterable.of(iterableOdd).zip(iterableEven).toList();
446         List<Integer> combinedList = new ArrayList<>();
447         CollectionUtils.addAll(combinedList, iterableOdd);
448         CollectionUtils.addAll(combinedList, iterableEven);
449         combinedList.sort(null);
450         assertEquals(combinedList, result);
451 
452         assertThrows(NullPointerException.class, () -> FluentIterable.of(iterableOdd).zip((Iterable<Integer>) null).toList(),
453                 "expecting NullPointerException");
454 
455         result = FluentIterable
456                     .of(Arrays.asList(1, 4, 7))
457                     .zip(Arrays.asList(2, 5, 8), Arrays.asList(3, 6, 9))
458                     .toList();
459         combinedList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
460         assertEquals(combinedList, result);
461     }
462 
463 }