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.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.assertThrows;
23  
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.Collections;
27  import java.util.Iterator;
28  import java.util.List;
29  import java.util.NoSuchElementException;
30  
31  import org.junit.jupiter.api.BeforeEach;
32  import org.junit.jupiter.api.Test;
33  
34  /**
35   * Test class for {@link CartesianProductIterator}.
36   */
37  public class CartesianProductIteratorTest extends AbstractIteratorTest<List<Character>> {
38  
39      private List<Character> letters;
40      private List<Character> numbers;
41      private List<Character> symbols;
42      private List<Character> emptyList;
43  
44      @Override
45      public CartesianProductIterator<Character> makeEmptyIterator() {
46          return new CartesianProductIterator<>();
47      }
48  
49      @Override
50      public CartesianProductIterator<Character> makeObject() {
51          return new CartesianProductIterator<>(letters, numbers, symbols);
52      }
53  
54      @BeforeEach
55      public void setUp() {
56          letters = Arrays.asList('A', 'B', 'C');
57          numbers = Arrays.asList('1', '2', '3');
58          symbols = Arrays.asList('!', '?');
59          emptyList = Collections.emptyList();
60      }
61  
62      @Override
63      public boolean supportsRemove() {
64          return false;
65      }
66  
67      @Test
68      public void testEmptyCollection() {
69          final CartesianProductIterator<Character> it = new CartesianProductIterator<>(letters, Collections.emptyList());
70          assertFalse(it.hasNext());
71          assertThrows(NoSuchElementException.class, it::next);
72      }
73  
74      /**
75       * test checking that all the tuples are returned
76       */
77      @Test
78      public void testExhaustivity() {
79          final List<Character[]> resultsList = new ArrayList<>();
80          final CartesianProductIterator<Character> it = makeObject();
81          while (it.hasNext()) {
82              final List<Character> tuple = it.next();
83              resultsList.add(tuple.toArray(new Character[0]));
84          }
85          assertThrows(NoSuchElementException.class, it::next);
86          assertEquals(18, resultsList.size());
87          final Iterator<Character[]> itResults = resultsList.iterator();
88          for (final Character a : letters) {
89              for (final Character b : numbers) {
90                  for (final Character c : symbols) {
91                      assertArrayEquals(new Character[]{a, b, c}, itResults.next());
92                  }
93              }
94          }
95      }
96  
97      /**
98       * test checking that no tuples are returned when all the lists are empty
99       */
100     @Test
101     public void testExhaustivityWithAllEmptyLists() {
102         final List<Character[]> resultsList = new ArrayList<>();
103         final CartesianProductIterator<Character> it = new CartesianProductIterator<>(emptyList, emptyList, emptyList);
104         while (it.hasNext()) {
105             final List<Character> tuple = it.next();
106             resultsList.add(tuple.toArray(new Character[0]));
107         }
108         assertThrows(NoSuchElementException.class, it::next);
109         assertEquals(0, resultsList.size());
110     }
111 
112     /**
113      * test checking that no tuples are returned when first of the lists is empty
114      */
115     @Test
116     public void testExhaustivityWithEmptyFirstList() {
117         final List<Character[]> resultsList = new ArrayList<>();
118         final CartesianProductIterator<Character> it = new CartesianProductIterator<>(emptyList, numbers, symbols);
119         while (it.hasNext()) {
120             final List<Character> tuple = it.next();
121             resultsList.add(tuple.toArray(new Character[0]));
122         }
123         assertThrows(NoSuchElementException.class, it::next);
124         assertEquals(0, resultsList.size());
125     }
126 
127     /**
128      * test checking that no tuples are returned when last of the lists is empty
129      */
130     @Test
131     public void testExhaustivityWithEmptyLastList() {
132         final List<Character[]> resultsList = new ArrayList<>();
133         final CartesianProductIterator<Character> it = new CartesianProductIterator<>(letters, numbers, emptyList);
134         while (it.hasNext()) {
135             final List<Character> tuple = it.next();
136             resultsList.add(tuple.toArray(new Character[0]));
137         }
138         assertThrows(NoSuchElementException.class, it::next);
139         assertEquals(0, resultsList.size());
140     }
141 
142     /**
143      * test checking that no tuples are returned when at least one of the lists is empty
144      */
145     @Test
146     public void testExhaustivityWithEmptyList() {
147         final List<Character[]> resultsList = new ArrayList<>();
148         final CartesianProductIterator<Character> it = new CartesianProductIterator<>(letters, emptyList, symbols);
149         while (it.hasNext()) {
150             final List<Character> tuple = it.next();
151             resultsList.add(tuple.toArray(new Character[0]));
152         }
153         assertThrows(NoSuchElementException.class, it::next);
154         assertEquals(0, resultsList.size());
155     }
156 
157     /**
158      * test checking that all tuples are returned when same list is passed multiple times
159      */
160     @Test
161     public void testExhaustivityWithSameList() {
162         final List<Character[]> resultsList = new ArrayList<>();
163         final CartesianProductIterator<Character> it = new CartesianProductIterator<>(letters, letters, letters);
164         while (it.hasNext()) {
165             final List<Character> tuple = it.next();
166             resultsList.add(tuple.toArray(new Character[0]));
167         }
168         assertThrows(NoSuchElementException.class, it::next);
169         assertEquals(27, resultsList.size());
170         final Iterator<Character[]> itResults = resultsList.iterator();
171         for (final Character a : letters) {
172             for (final Character b : letters) {
173                 for (final Character c : letters) {
174                     assertArrayEquals(new Character[]{a, b, c}, itResults.next());
175                 }
176             }
177         }
178     }
179 
180     /**
181      * test that all tuples are provided to consumer
182      */
183     @Override
184     @Test
185     public void testForEachRemaining() {
186         final List<Character[]> resultsList = new ArrayList<>();
187         final CartesianProductIterator<Character> it = makeObject();
188         it.forEachRemaining(tuple -> resultsList.add(tuple.toArray(new Character[0])));
189         assertEquals(18, resultsList.size());
190         final Iterator<Character[]> itResults = resultsList.iterator();
191         for (final Character a : letters) {
192             for (final Character b : numbers) {
193                 for (final Character c : symbols) {
194                     assertArrayEquals(new Character[]{a, b, c}, itResults.next());
195                 }
196             }
197         }
198     }
199 
200     @Test
201     public void testRemoveThrows() {
202         final CartesianProductIterator<Character> it = makeObject();
203         assertThrows(UnsupportedOperationException.class, it::remove);
204     }
205 }