1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections4.bloomfilter;
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.assertSame;
23 import static org.junit.jupiter.api.Assertions.assertTrue;
24
25 import java.util.Arrays;
26 import java.util.BitSet;
27 import java.util.function.IntPredicate;
28
29 import org.junit.jupiter.api.Test;
30
31
32
33
34 public abstract class AbstractIndexProducerTest {
35
36
37
38
39 protected static class IntList {
40 private int size;
41 private int[] data = {0};
42
43
44
45
46
47
48
49 boolean add(final int value) {
50 if (size == data.length) {
51 data = Arrays.copyOf(data, size << 1);
52 }
53 data[size++] = value;
54 return true;
55 }
56
57
58
59
60
61
62 int[] toArray() {
63 return Arrays.copyOf(data, size);
64 }
65 }
66 private static final IntPredicate TRUE_PREDICATE = i -> true;
67
68 private static final IntPredicate FALSE_PREDICATE = i -> false;
69
70 protected static final int ORDERED = 0x1;
71
72
73 protected static final int DISTINCT = 0x2;
74
75
76
77
78
79 protected abstract IndexProducer createEmptyProducer();
80
81
82
83
84
85 protected abstract IndexProducer createProducer();
86
87
88
89
90
91
92
93 protected abstract int getAsIndexArrayBehaviour();
94
95
96
97
98
99
100 protected abstract int[] getExpectedIndices();
101
102
103
104
105
106
107
108
109 protected int getForEachIndexBehaviour() {
110 return getAsIndexArrayBehaviour();
111 }
112
113
114
115
116 @Test
117 public final void testAsIndexArrayValues() {
118 final BitSet bs = new BitSet();
119 Arrays.stream(createProducer().asIndexArray()).forEach(bs::set);
120 for (final int i : getExpectedIndices()) {
121 assertTrue(bs.get(i), () -> "Missing " + i);
122 }
123 }
124
125
126
127
128
129
130
131
132 @Test
133 public final void testBehaviourAsIndexArray() {
134 final int flags = getAsIndexArrayBehaviour();
135 final int[] actual = createProducer().asIndexArray();
136 if ((flags & ORDERED) != 0) {
137 final int[] expected = Arrays.stream(actual).sorted().toArray();
138 assertArrayEquals(expected, actual);
139 }
140 if ((flags & DISTINCT) != 0) {
141 final long count = Arrays.stream(actual).distinct().count();
142 assertEquals(count, actual.length);
143 } else {
144
145
146 final int[] expected = getExpectedIndices().clone();
147 Arrays.sort(expected);
148 Arrays.sort(actual);
149 assertArrayEquals(expected, actual);
150 }
151 }
152
153
154
155
156
157
158 @Test
159 public final void testBehaviourForEachIndex() {
160 final int flags = getForEachIndexBehaviour();
161 final IntList list = new IntList();
162 createProducer().forEachIndex(list::add);
163 final int[] actual = list.toArray();
164 if ((flags & ORDERED) != 0) {
165 final int[] expected = Arrays.stream(actual).sorted().toArray();
166 assertArrayEquals(expected, actual);
167 }
168 if ((flags & DISTINCT) != 0) {
169 final long count = Arrays.stream(actual).distinct().count();
170 assertEquals(count, actual.length);
171 } else {
172
173 final int[] expected = getExpectedIndices().clone();
174 Arrays.sort(expected);
175 Arrays.sort(actual);
176 assertArrayEquals(expected, actual);
177 }
178 }
179
180
181
182
183 @Test
184 public final void testConsistency() {
185 final IndexProducer producer = createProducer();
186 final BitSet bs1 = new BitSet();
187 final BitSet bs2 = new BitSet();
188 Arrays.stream(producer.asIndexArray()).forEach(bs1::set);
189 producer.forEachIndex(i -> {
190 bs2.set(i);
191 return true;
192 });
193 assertEquals(bs1, bs2);
194 }
195
196 @Test
197 public final void testEmptyProducer() {
198 final IndexProducer empty = createEmptyProducer();
199 final int[] ary = empty.asIndexArray();
200 assertEquals(0, ary.length);
201 assertTrue(empty.forEachIndex(i -> {
202 throw new AssertionError("forEach predictate should not be called");
203 }));
204 }
205
206
207
208
209 @Test
210 public final void testForEachIndex() {
211 final BitSet bs1 = new BitSet();
212 final BitSet bs2 = new BitSet();
213 Arrays.stream(getExpectedIndices()).forEach(bs1::set);
214 createProducer().forEachIndex(i -> {
215 bs2.set(i);
216 return true;
217 });
218 assertEquals(bs1, bs2);
219 }
220
221 @Test
222 public void testForEachIndexEarlyExit() {
223 final int[] passes = new int[1];
224 assertFalse(createProducer().forEachIndex(i -> {
225 passes[0]++;
226 return false;
227 }));
228 assertEquals(1, passes[0]);
229
230 passes[0] = 0;
231 assertTrue(createEmptyProducer().forEachIndex(i -> {
232 passes[0]++;
233 return false;
234 }));
235 assertEquals(0, passes[0]);
236 }
237
238 @Test
239 public final void testForEachIndexPredicates() {
240 final IndexProducer populated = createProducer();
241 final IndexProducer empty = createEmptyProducer();
242
243 assertFalse(populated.forEachIndex(FALSE_PREDICATE), "non-empty should be false");
244 assertTrue(empty.forEachIndex(FALSE_PREDICATE), "empty should be true");
245
246 assertTrue(populated.forEachIndex(TRUE_PREDICATE), "non-empty should be true");
247 assertTrue(empty.forEachIndex(TRUE_PREDICATE), "empty should be true");
248 }
249
250 @Test
251 public void testUniqueReturnsSelf() {
252 final IndexProducer expected = createProducer().uniqueIndices();
253 assertSame(expected, expected.uniqueIndices());
254 }
255 }