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.assertThrows;
22  import static org.junit.jupiter.api.Assertions.assertTrue;
23  
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.HashSet;
27  import java.util.Iterator;
28  import java.util.List;
29  import java.util.NoSuchElementException;
30  import java.util.Set;
31  
32  import org.junit.jupiter.api.BeforeEach;
33  import org.junit.jupiter.api.Test;
34  
35  /**
36   * Test class for PermutationIterator.
37   */
38  public class PermutationIteratorTest extends AbstractIteratorTest<List<Character>> {
39  
40      @SuppressWarnings("boxing") // OK in test code
41      protected Character[] testArray = { 'A', 'B', 'C' };
42      protected List<Character> testList;
43  
44      public PermutationIteratorTest() {
45          super(PermutationIteratorTest.class.getSimpleName());
46      }
47  
48      @Override
49      public PermutationIterator<Character> makeEmptyIterator() {
50          return new PermutationIterator<>(new ArrayList<>());
51      }
52  
53      @Override
54      public PermutationIterator<Character> makeObject() {
55          return new PermutationIterator<>(testList);
56      }
57  
58      @BeforeEach
59      public void setUp() {
60          testList = new ArrayList<>();
61          testList.addAll(Arrays.asList(testArray));
62      }
63  
64      @Override
65      public boolean supportsEmptyIterator() {
66          return false;
67      }
68  
69      @Override
70      public boolean supportsRemove() {
71          return false;
72      }
73  
74      @Test
75      public void testEmptyCollection() {
76          final PermutationIterator<Character> it = makeEmptyIterator();
77          // there is one permutation for an empty set: 0! = 1
78          assertTrue(it.hasNext());
79  
80          final List<Character> nextPermutation = it.next();
81          assertEquals(0, nextPermutation.size());
82  
83          assertFalse(it.hasNext());
84      }
85  
86      @Test
87      public void testPermutationException() {
88          final List<List<Character>> resultsList = new ArrayList<>();
89  
90          final PermutationIterator<Character> it = makeObject();
91          while (it.hasNext()) {
92              final List<Character> permutation = it.next();
93              resultsList.add(permutation);
94          }
95          //asking for another permutation should throw an exception
96          assertThrows(NoSuchElementException.class, () -> it.next());
97      }
98  
99      /**
100      * test checking that all the permutations are returned
101      */
102     @Test
103     @SuppressWarnings("boxing") // OK in test code
104     public void testPermutationExhaustivity() {
105         final List<Character> perm1 = new ArrayList<>();
106         final List<Character> perm2 = new ArrayList<>();
107         final List<Character> perm3 = new ArrayList<>();
108         final List<Character> perm4 = new ArrayList<>();
109         final List<Character> perm5 = new ArrayList<>();
110         final List<Character> perm6 = new ArrayList<>();
111 
112         perm1.add('A');
113         perm2.add('A');
114         perm3.add('B');
115         perm4.add('B');
116         perm5.add('C');
117         perm6.add('C');
118 
119         perm1.add('B');
120         perm2.add('C');
121         perm3.add('A');
122         perm4.add('C');
123         perm5.add('A');
124         perm6.add('B');
125 
126         perm1.add('C');
127         perm2.add('B');
128         perm3.add('C');
129         perm4.add('A');
130         perm5.add('B');
131         perm6.add('A');
132 
133         final List<List<Character>> results = new ArrayList<>();
134 
135         final PermutationIterator<Character> it = makeObject();
136         while (it.hasNext()) {
137             final List<Character> next = it.next();
138             results.add(next);
139         }
140         //3! permutation for 3 elements
141         assertEquals(6, results.size());
142         assertTrue(results.contains(perm1));
143         assertTrue(results.contains(perm2));
144         assertTrue(results.contains(perm3));
145         assertTrue(results.contains(perm4));
146         assertTrue(results.contains(perm5));
147         assertTrue(results.contains(perm6));
148     }
149 
150     @Test
151     @SuppressWarnings("boxing") // OK in test code
152     public void testPermutationResultSize() {
153         int factorial = 1;
154         for (int i = 0; i < 8; i++, factorial*=i) {
155             final List<Integer> list = new ArrayList<>();
156             for (int j = 0; j < i; j++) {
157                 list.add(j);
158             }
159             final Iterator<List<Integer>> it = new PermutationIterator<>(list);
160             int count = 0;
161             while (it.hasNext()) {
162                 it.next();
163                 count++;
164             }
165             assertEquals(factorial, count);
166         }
167     }
168 
169     /**
170      * test checking that all the permutations are returned only once.
171      */
172     @Test
173     public void testPermutationUnicity() {
174         final List<List<Character>> resultsList = new ArrayList<>();
175         final Set<List<Character>> resultsSet = new HashSet<>();
176 
177         final PermutationIterator<Character> it = makeObject();
178         while (it.hasNext()) {
179             final List<Character> permutation = it.next();
180             resultsList.add(permutation);
181             resultsSet.add(permutation);
182         }
183         //3! permutation for 3 elements
184         assertEquals(6, resultsList.size());
185         assertEquals(6, resultsSet.size());
186     }
187 
188     @Test
189     public void testPermutatorHasMore() {
190         final PermutationIterator<Character> it = makeObject();
191         for (int i = 0; i < 6; i++) {
192             assertTrue(it.hasNext());
193             it.next();
194         }
195         assertFalse(it.hasNext());
196     }
197 
198 }