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