1 |
jsr166 |
1.1 |
/* |
2 |
|
|
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. |
3 |
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
|
|
* |
5 |
|
|
* This code is free software; you can redistribute it and/or modify it |
6 |
|
|
* under the terms of the GNU General Public License version 2 only, as |
7 |
|
|
* published by the Free Software Foundation. |
8 |
|
|
* |
9 |
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT |
10 |
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 |
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 |
|
|
* version 2 for more details (a copy is included in the LICENSE file that |
13 |
|
|
* accompanied this code). |
14 |
|
|
* |
15 |
|
|
* You should have received a copy of the GNU General Public License version |
16 |
|
|
* 2 along with this work; if not, write to the Free Software Foundation, |
17 |
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 |
|
|
* |
19 |
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 |
|
|
* or visit www.oracle.com if you need additional information or have any |
21 |
|
|
* questions. |
22 |
|
|
*/ |
23 |
|
|
|
24 |
|
|
import java.util.ArrayList; |
25 |
|
|
import java.util.Arrays; |
26 |
|
|
import java.util.Collection; |
27 |
|
|
import java.util.Collections; |
28 |
|
|
import java.util.Comparator; |
29 |
|
|
import java.util.List; |
30 |
|
|
import java.util.LinkedList; |
31 |
|
|
import java.util.Stack; |
32 |
|
|
import java.util.Vector; |
33 |
|
|
import java.util.concurrent.CopyOnWriteArrayList; |
34 |
|
|
import java.util.concurrent.atomic.AtomicBoolean; |
35 |
|
|
import java.util.concurrent.atomic.AtomicInteger; |
36 |
|
|
|
37 |
|
|
import org.testng.annotations.DataProvider; |
38 |
|
|
import org.testng.annotations.Test; |
39 |
|
|
|
40 |
|
|
import static org.testng.Assert.assertEquals; |
41 |
|
|
import static org.testng.Assert.assertFalse; |
42 |
|
|
import static org.testng.Assert.assertTrue; |
43 |
|
|
import static org.testng.Assert.fail; |
44 |
|
|
|
45 |
|
|
import java.lang.reflect.Constructor; |
46 |
|
|
import java.util.ConcurrentModificationException; |
47 |
|
|
import java.util.function.Consumer; |
48 |
|
|
import java.util.function.Function; |
49 |
|
|
import java.util.function.Predicate; |
50 |
|
|
import java.util.function.Supplier; |
51 |
|
|
|
52 |
|
|
/** |
53 |
|
|
* @test |
54 |
|
|
* @summary Unit tests for extension methods on List |
55 |
|
|
* @bug 8023367 8037106 |
56 |
|
|
* @library ../Collection/testlibrary |
57 |
|
|
* @build CollectionAsserts CollectionSupplier ExtendsAbstractList |
58 |
|
|
* @run testng ListDefaults |
59 |
|
|
*/ |
60 |
|
|
public class ListDefaults { |
61 |
|
|
|
62 |
|
|
// Suppliers of lists that can support structural modifications |
63 |
|
|
private static final List<Function<Collection, List>> LIST_STRUCT_MOD_SUPPLIERS = Arrays.asList( |
64 |
|
|
java.util.ArrayList::new, |
65 |
|
|
java.util.LinkedList::new, |
66 |
|
|
java.util.Vector::new, |
67 |
|
|
java.util.concurrent.CopyOnWriteArrayList::new, |
68 |
|
|
ExtendsAbstractList::new |
69 |
|
|
); |
70 |
|
|
|
71 |
|
|
// Suppliers of lists that can support in place modifications |
72 |
|
|
private static final List<Function<Collection, List>> LIST_SUPPLIERS = Arrays.asList( |
73 |
|
|
java.util.ArrayList::new, |
74 |
|
|
java.util.LinkedList::new, |
75 |
|
|
java.util.Vector::new, |
76 |
|
|
java.util.concurrent.CopyOnWriteArrayList::new, |
77 |
|
|
ExtendsAbstractList::new, |
78 |
|
|
c -> Arrays.asList(c.toArray()) |
79 |
|
|
); |
80 |
|
|
|
81 |
|
|
// Suppliers of lists supporting CMEs |
82 |
|
|
private static final List<Function<Collection, List>> LIST_CME_SUPPLIERS = Arrays.asList( |
83 |
|
|
java.util.ArrayList::new, |
84 |
|
|
java.util.Vector::new |
85 |
|
|
); |
86 |
|
|
|
87 |
|
|
private static final Predicate<Integer> pEven = x -> 0 == x % 2; |
88 |
|
|
private static final Predicate<Integer> pOdd = x -> 1 == x % 2; |
89 |
|
|
|
90 |
|
|
private static final Comparator<Integer> BIT_COUNT_COMPARATOR = |
91 |
|
|
(x, y) -> Integer.bitCount(x) - Integer.bitCount(y); |
92 |
|
|
|
93 |
|
|
private static final Comparator<AtomicInteger> ATOMIC_INTEGER_COMPARATOR = |
94 |
|
|
(x, y) -> x.intValue() - y.intValue(); |
95 |
|
|
|
96 |
|
|
private static final int SIZE = 100; |
97 |
|
|
private static final int SUBLIST_FROM = 20; |
98 |
|
|
private static final int SUBLIST_TO = SIZE - 5; |
99 |
|
|
private static final int SUBLIST_SIZE = SUBLIST_TO - SUBLIST_FROM; |
100 |
|
|
|
101 |
|
|
// call the callback for each recursive subList |
102 |
|
|
private void trimmedSubList(final List<Integer> list, final Consumer<List<Integer>> callback) { |
103 |
|
|
int size = list.size(); |
104 |
|
|
if (size > 1) { |
105 |
|
|
// trim 1 element from both ends |
106 |
|
|
final List<Integer> subList = list.subList(1, size - 1); |
107 |
|
|
callback.accept(subList); |
108 |
|
|
trimmedSubList(subList, callback); |
109 |
|
|
} |
110 |
|
|
} |
111 |
|
|
|
112 |
|
|
@DataProvider(name="listProvider", parallel=true) |
113 |
|
|
public static Object[][] listCases() { |
114 |
|
|
final List<Object[]> cases = new LinkedList<>(); |
115 |
|
|
cases.add(new Object[] { Collections.emptyList() }); |
116 |
|
|
cases.add(new Object[] { new ArrayList<>() }); |
117 |
|
|
cases.add(new Object[] { new LinkedList<>() }); |
118 |
|
|
cases.add(new Object[] { new Vector<>() }); |
119 |
|
|
cases.add(new Object[] { new Stack<>() }); |
120 |
|
|
cases.add(new Object[] { new CopyOnWriteArrayList<>() }); |
121 |
|
|
cases.add(new Object[] { Arrays.asList() }); |
122 |
|
|
|
123 |
|
|
List<Integer> l = Arrays.asList(42); |
124 |
|
|
cases.add(new Object[] { new ArrayList<>(l) }); |
125 |
|
|
cases.add(new Object[] { new LinkedList<>(l) }); |
126 |
|
|
cases.add(new Object[] { new Vector<>(l) }); |
127 |
|
|
Stack<Integer> s = new Stack<>(); s.addAll(l); |
128 |
|
|
cases.add(new Object[]{s}); |
129 |
|
|
cases.add(new Object[] { new CopyOnWriteArrayList<>(l) }); |
130 |
|
|
cases.add(new Object[] { l }); |
131 |
|
|
return cases.toArray(new Object[0][cases.size()]); |
132 |
|
|
} |
133 |
|
|
|
134 |
|
|
@Test(dataProvider = "listProvider") |
135 |
|
|
public void testProvidedWithNull(final List<Integer> list) { |
136 |
|
|
try { |
137 |
|
|
list.forEach(null); |
138 |
|
|
fail("expected NPE not thrown"); |
139 |
|
|
} catch (NullPointerException npe) {} |
140 |
|
|
try { |
141 |
|
|
list.replaceAll(null); |
142 |
|
|
fail("expected NPE not thrown"); |
143 |
|
|
} catch (NullPointerException npe) {} |
144 |
|
|
try { |
145 |
|
|
list.removeIf(null); |
146 |
|
|
fail("expected NPE not thrown"); |
147 |
|
|
} catch (NullPointerException npe) {} |
148 |
|
|
try { |
149 |
|
|
list.sort(null); |
150 |
|
|
} catch (Throwable t) { |
151 |
|
|
fail("Exception not expected: " + t); |
152 |
|
|
} |
153 |
|
|
} |
154 |
|
|
|
155 |
|
|
@Test |
156 |
|
|
public void testForEach() { |
157 |
|
|
@SuppressWarnings("unchecked") |
158 |
|
|
final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier(LIST_SUPPLIERS, SIZE); |
159 |
|
|
for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) { |
160 |
|
|
final List<Integer> original = test.expected; |
161 |
|
|
final List<Integer> list = test.collection; |
162 |
|
|
|
163 |
|
|
try { |
164 |
|
|
list.forEach(null); |
165 |
|
|
fail("expected NPE not thrown"); |
166 |
|
|
} catch (NullPointerException npe) {} |
167 |
|
|
CollectionAsserts.assertContents(list, original); |
168 |
|
|
|
169 |
|
|
final List<Integer> actual = new LinkedList<>(); |
170 |
|
|
list.forEach(actual::add); |
171 |
|
|
CollectionAsserts.assertContents(actual, list); |
172 |
|
|
CollectionAsserts.assertContents(actual, original); |
173 |
|
|
|
174 |
|
|
if (original.size() > SUBLIST_SIZE) { |
175 |
|
|
final List<Integer> subList = original.subList(SUBLIST_FROM, SUBLIST_TO); |
176 |
|
|
final List<Integer> actualSubList = new LinkedList<>(); |
177 |
|
|
subList.forEach(actualSubList::add); |
178 |
|
|
assertEquals(actualSubList.size(), SUBLIST_SIZE); |
179 |
|
|
for (int i = 0; i < SUBLIST_SIZE; i++) { |
180 |
|
|
assertEquals(actualSubList.get(i), original.get(i + SUBLIST_FROM)); |
181 |
|
|
} |
182 |
|
|
} |
183 |
|
|
|
184 |
|
|
trimmedSubList(list, l -> { |
185 |
|
|
final List<Integer> a = new LinkedList<>(); |
186 |
|
|
l.forEach(a::add); |
187 |
|
|
CollectionAsserts.assertContents(a, l); |
188 |
|
|
}); |
189 |
|
|
} |
190 |
|
|
} |
191 |
|
|
|
192 |
|
|
@Test |
193 |
|
|
public void testRemoveIf() { |
194 |
|
|
@SuppressWarnings("unchecked") |
195 |
|
|
final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier(LIST_STRUCT_MOD_SUPPLIERS, SIZE); |
196 |
|
|
for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) { |
197 |
|
|
final List<Integer> original = test.expected; |
198 |
|
|
final List<Integer> list = test.collection; |
199 |
|
|
|
200 |
|
|
try { |
201 |
|
|
list.removeIf(null); |
202 |
|
|
fail("expected NPE not thrown"); |
203 |
|
|
} catch (NullPointerException npe) {} |
204 |
|
|
CollectionAsserts.assertContents(list, original); |
205 |
|
|
|
206 |
|
|
final AtomicInteger offset = new AtomicInteger(1); |
207 |
|
|
while (list.size() > 0) { |
208 |
|
|
removeFirst(original, list, offset); |
209 |
|
|
} |
210 |
|
|
} |
211 |
|
|
|
212 |
|
|
for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) { |
213 |
|
|
final List<Integer> original = test.expected; |
214 |
|
|
final List<Integer> list = test.collection; |
215 |
|
|
list.removeIf(pOdd); |
216 |
|
|
for (int i : list) { |
217 |
|
|
assertTrue((i % 2) == 0); |
218 |
|
|
} |
219 |
|
|
for (int i : original) { |
220 |
|
|
if (i % 2 == 0) { |
221 |
|
|
assertTrue(list.contains(i)); |
222 |
|
|
} |
223 |
|
|
} |
224 |
|
|
list.removeIf(pEven); |
225 |
|
|
assertTrue(list.isEmpty()); |
226 |
|
|
} |
227 |
|
|
|
228 |
|
|
for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) { |
229 |
|
|
final List<Integer> original = test.expected; |
230 |
|
|
final List<Integer> list = test.collection; |
231 |
|
|
final List<Integer> listCopy = new ArrayList<>(list); |
232 |
|
|
if (original.size() > SUBLIST_SIZE) { |
233 |
|
|
final List<Integer> subList = list.subList(SUBLIST_FROM, SUBLIST_TO); |
234 |
|
|
final List<Integer> subListCopy = new ArrayList<>(subList); |
235 |
|
|
listCopy.removeAll(subList); |
236 |
|
|
subList.removeIf(pOdd); |
237 |
|
|
for (int i : subList) { |
238 |
|
|
assertTrue((i % 2) == 0); |
239 |
|
|
} |
240 |
|
|
for (int i : subListCopy) { |
241 |
|
|
if (i % 2 == 0) { |
242 |
|
|
assertTrue(subList.contains(i)); |
243 |
|
|
} else { |
244 |
|
|
assertFalse(subList.contains(i)); |
245 |
|
|
} |
246 |
|
|
} |
247 |
|
|
subList.removeIf(pEven); |
248 |
|
|
assertTrue(subList.isEmpty()); |
249 |
|
|
// elements outside the view should remain |
250 |
|
|
CollectionAsserts.assertContents(list, listCopy); |
251 |
|
|
} |
252 |
|
|
} |
253 |
|
|
|
254 |
|
|
for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) { |
255 |
|
|
final List<Integer> list = test.collection; |
256 |
|
|
trimmedSubList(list, l -> { |
257 |
|
|
final List<Integer> copy = new ArrayList<>(l); |
258 |
|
|
l.removeIf(pOdd); |
259 |
|
|
for (int i : l) { |
260 |
|
|
assertTrue((i % 2) == 0); |
261 |
|
|
} |
262 |
|
|
for (int i : copy) { |
263 |
|
|
if (i % 2 == 0) { |
264 |
|
|
assertTrue(l.contains(i)); |
265 |
|
|
} else { |
266 |
|
|
assertFalse(l.contains(i)); |
267 |
|
|
} |
268 |
|
|
} |
269 |
|
|
}); |
270 |
|
|
} |
271 |
|
|
} |
272 |
|
|
|
273 |
|
|
// remove the first element |
274 |
|
|
private void removeFirst(final List<Integer> original, final List<Integer> list, final AtomicInteger offset) { |
275 |
|
|
final AtomicBoolean first = new AtomicBoolean(true); |
276 |
|
|
list.removeIf(x -> first.getAndSet(false)); |
277 |
|
|
CollectionAsserts.assertContents(original.subList(offset.getAndIncrement(), original.size()), list); |
278 |
|
|
} |
279 |
|
|
|
280 |
|
|
@Test |
281 |
|
|
public void testReplaceAll() { |
282 |
|
|
final int scale = 3; |
283 |
|
|
@SuppressWarnings("unchecked") |
284 |
|
|
final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier(LIST_SUPPLIERS, SIZE); |
285 |
|
|
for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) { |
286 |
|
|
final List<Integer> original = test.expected; |
287 |
|
|
final List<Integer> list = test.collection; |
288 |
|
|
|
289 |
|
|
try { |
290 |
|
|
list.replaceAll(null); |
291 |
|
|
fail("expected NPE not thrown"); |
292 |
|
|
} catch (NullPointerException npe) {} |
293 |
|
|
CollectionAsserts.assertContents(list, original); |
294 |
|
|
|
295 |
|
|
list.replaceAll(x -> scale * x); |
296 |
|
|
for (int i = 0; i < original.size(); i++) { |
297 |
|
|
assertTrue(list.get(i) == (scale * original.get(i)), "mismatch at index " + i); |
298 |
|
|
} |
299 |
|
|
|
300 |
|
|
if (original.size() > SUBLIST_SIZE) { |
301 |
|
|
final List<Integer> subList = list.subList(SUBLIST_FROM, SUBLIST_TO); |
302 |
|
|
subList.replaceAll(x -> x + 1); |
303 |
|
|
// verify elements in view [from, to) were replaced |
304 |
|
|
for (int i = 0; i < SUBLIST_SIZE; i++) { |
305 |
|
|
assertTrue(subList.get(i) == ((scale * original.get(i + SUBLIST_FROM)) + 1), |
306 |
|
|
"mismatch at sublist index " + i); |
307 |
|
|
} |
308 |
|
|
// verify that elements [0, from) remain unmodified |
309 |
|
|
for (int i = 0; i < SUBLIST_FROM; i++) { |
310 |
|
|
assertTrue(list.get(i) == (scale * original.get(i)), |
311 |
|
|
"mismatch at original index " + i); |
312 |
|
|
} |
313 |
|
|
// verify that elements [to, size) remain unmodified |
314 |
|
|
for (int i = SUBLIST_TO; i < list.size(); i++) { |
315 |
|
|
assertTrue(list.get(i) == (scale * original.get(i)), |
316 |
|
|
"mismatch at original index " + i); |
317 |
|
|
} |
318 |
|
|
} |
319 |
|
|
} |
320 |
|
|
|
321 |
|
|
for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) { |
322 |
|
|
final List<Integer> list = test.collection; |
323 |
|
|
trimmedSubList(list, l -> { |
324 |
|
|
final List<Integer> copy = new ArrayList<>(l); |
325 |
|
|
final int offset = 5; |
326 |
|
|
l.replaceAll(x -> offset + x); |
327 |
|
|
for (int i = 0; i < copy.size(); i++) { |
328 |
|
|
assertTrue(l.get(i) == (offset + copy.get(i)), "mismatch at index " + i); |
329 |
|
|
} |
330 |
|
|
}); |
331 |
|
|
} |
332 |
|
|
} |
333 |
|
|
|
334 |
|
|
@Test |
335 |
|
|
public void testSort() { |
336 |
|
|
@SuppressWarnings("unchecked") |
337 |
|
|
final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier(LIST_SUPPLIERS, SIZE); |
338 |
|
|
for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) { |
339 |
|
|
final List<Integer> original = test.expected; |
340 |
|
|
final List<Integer> list = test.collection; |
341 |
|
|
CollectionSupplier.shuffle(list); |
342 |
|
|
list.sort(Integer::compare); |
343 |
|
|
CollectionAsserts.assertSorted(list, Integer::compare); |
344 |
|
|
if (test.name.startsWith("reverse")) { |
345 |
|
|
Collections.reverse(list); |
346 |
|
|
} |
347 |
|
|
CollectionAsserts.assertContents(list, original); |
348 |
|
|
|
349 |
|
|
CollectionSupplier.shuffle(list); |
350 |
|
|
list.sort(null); |
351 |
|
|
CollectionAsserts.assertSorted(list, Comparator.naturalOrder()); |
352 |
|
|
if (test.name.startsWith("reverse")) { |
353 |
|
|
Collections.reverse(list); |
354 |
|
|
} |
355 |
|
|
CollectionAsserts.assertContents(list, original); |
356 |
|
|
|
357 |
|
|
CollectionSupplier.shuffle(list); |
358 |
|
|
list.sort(Comparator.naturalOrder()); |
359 |
|
|
CollectionAsserts.assertSorted(list, Comparator.naturalOrder()); |
360 |
|
|
if (test.name.startsWith("reverse")) { |
361 |
|
|
Collections.reverse(list); |
362 |
|
|
} |
363 |
|
|
CollectionAsserts.assertContents(list, original); |
364 |
|
|
|
365 |
|
|
CollectionSupplier.shuffle(list); |
366 |
|
|
list.sort(Comparator.reverseOrder()); |
367 |
|
|
CollectionAsserts.assertSorted(list, Comparator.reverseOrder()); |
368 |
|
|
if (!test.name.startsWith("reverse")) { |
369 |
|
|
Collections.reverse(list); |
370 |
|
|
} |
371 |
|
|
CollectionAsserts.assertContents(list, original); |
372 |
|
|
|
373 |
|
|
CollectionSupplier.shuffle(list); |
374 |
|
|
list.sort(BIT_COUNT_COMPARATOR); |
375 |
|
|
CollectionAsserts.assertSorted(list, BIT_COUNT_COMPARATOR); |
376 |
|
|
// check sort by verifying that bitCount increases and never drops |
377 |
|
|
int minBitCount = 0; |
378 |
|
|
for (final Integer i : list) { |
379 |
|
|
int bitCount = Integer.bitCount(i); |
380 |
|
|
assertTrue(bitCount >= minBitCount); |
381 |
|
|
minBitCount = bitCount; |
382 |
|
|
} |
383 |
|
|
|
384 |
jsr166 |
1.2 |
// Reuse the supplier to store AtomicInteger instead of Integer |
385 |
jsr166 |
1.1 |
// Hence the use of raw type and cast |
386 |
|
|
List<AtomicInteger> incomparablesData = new ArrayList<>(); |
387 |
|
|
for (int i = 0; i < test.expected.size(); i++) { |
388 |
|
|
incomparablesData.add(new AtomicInteger(i)); |
389 |
|
|
} |
390 |
|
|
Function f = test.supplier; |
391 |
|
|
@SuppressWarnings("unchecked") |
392 |
|
|
List<AtomicInteger> incomparables = (List<AtomicInteger>) f.apply(incomparablesData); |
393 |
|
|
|
394 |
|
|
CollectionSupplier.shuffle(incomparables); |
395 |
|
|
incomparables.sort(ATOMIC_INTEGER_COMPARATOR); |
396 |
|
|
for (int i = 0; i < test.expected.size(); i++) { |
397 |
|
|
assertEquals(i, incomparables.get(i).intValue()); |
398 |
|
|
} |
399 |
|
|
|
400 |
|
|
|
401 |
|
|
if (original.size() > SUBLIST_SIZE) { |
402 |
|
|
final List<Integer> copy = new ArrayList<>(list); |
403 |
|
|
final List<Integer> subList = list.subList(SUBLIST_FROM, SUBLIST_TO); |
404 |
|
|
CollectionSupplier.shuffle(subList); |
405 |
|
|
subList.sort(Comparator.naturalOrder()); |
406 |
|
|
CollectionAsserts.assertSorted(subList, Comparator.naturalOrder()); |
407 |
|
|
// verify that elements [0, from) remain unmodified |
408 |
|
|
for (int i = 0; i < SUBLIST_FROM; i++) { |
409 |
|
|
assertTrue(list.get(i) == copy.get(i), |
410 |
|
|
"mismatch at index " + i); |
411 |
|
|
} |
412 |
|
|
// verify that elements [to, size) remain unmodified |
413 |
|
|
for (int i = SUBLIST_TO; i < list.size(); i++) { |
414 |
|
|
assertTrue(list.get(i) == copy.get(i), |
415 |
|
|
"mismatch at index " + i); |
416 |
|
|
} |
417 |
|
|
} |
418 |
|
|
} |
419 |
|
|
|
420 |
|
|
for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) { |
421 |
|
|
final List<Integer> list = test.collection; |
422 |
|
|
trimmedSubList(list, l -> { |
423 |
|
|
CollectionSupplier.shuffle(l); |
424 |
|
|
l.sort(Comparator.naturalOrder()); |
425 |
|
|
CollectionAsserts.assertSorted(l, Comparator.naturalOrder()); |
426 |
|
|
}); |
427 |
|
|
} |
428 |
|
|
} |
429 |
|
|
|
430 |
|
|
@Test |
431 |
|
|
public void testForEachThrowsCME() { |
432 |
|
|
@SuppressWarnings("unchecked") |
433 |
|
|
final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier(LIST_CME_SUPPLIERS, SIZE); |
434 |
|
|
for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) { |
435 |
|
|
final List<Integer> list = test.collection; |
436 |
|
|
|
437 |
|
|
if (list.size() <= 1) { |
438 |
|
|
continue; |
439 |
|
|
} |
440 |
|
|
boolean gotException = false; |
441 |
|
|
try { |
442 |
|
|
// bad predicate that modifies its list, should throw CME |
443 |
|
|
list.forEach(list::add); |
444 |
|
|
} catch (ConcurrentModificationException cme) { |
445 |
|
|
gotException = true; |
446 |
|
|
} |
447 |
|
|
if (!gotException) { |
448 |
|
|
fail("expected CME was not thrown from " + test); |
449 |
|
|
} |
450 |
|
|
} |
451 |
|
|
} |
452 |
|
|
|
453 |
|
|
@Test |
454 |
|
|
public void testRemoveIfThrowsCME() { |
455 |
|
|
@SuppressWarnings("unchecked") |
456 |
|
|
final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier(LIST_CME_SUPPLIERS, SIZE); |
457 |
|
|
for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) { |
458 |
|
|
final List<Integer> list = test.collection; |
459 |
|
|
|
460 |
|
|
if (list.size() <= 1) { |
461 |
|
|
continue; |
462 |
|
|
} |
463 |
|
|
boolean gotException = false; |
464 |
|
|
try { |
465 |
|
|
// bad predicate that modifies its list, should throw CME |
466 |
|
|
list.removeIf(list::add); |
467 |
|
|
} catch (ConcurrentModificationException cme) { |
468 |
|
|
gotException = true; |
469 |
|
|
} |
470 |
|
|
if (!gotException) { |
471 |
|
|
fail("expected CME was not thrown from " + test); |
472 |
|
|
} |
473 |
|
|
} |
474 |
|
|
} |
475 |
|
|
|
476 |
|
|
@Test |
477 |
|
|
public void testReplaceAllThrowsCME() { |
478 |
|
|
@SuppressWarnings("unchecked") |
479 |
|
|
final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier(LIST_CME_SUPPLIERS, SIZE); |
480 |
|
|
for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) { |
481 |
|
|
final List<Integer> list = test.collection; |
482 |
|
|
|
483 |
|
|
if (list.size() <= 1) { |
484 |
|
|
continue; |
485 |
|
|
} |
486 |
|
|
boolean gotException = false; |
487 |
|
|
try { |
488 |
|
|
// bad predicate that modifies its list, should throw CME |
489 |
|
|
list.replaceAll(x -> {int n = 3 * x; list.add(n); return n;}); |
490 |
|
|
} catch (ConcurrentModificationException cme) { |
491 |
|
|
gotException = true; |
492 |
|
|
} |
493 |
|
|
if (!gotException) { |
494 |
|
|
fail("expected CME was not thrown from " + test); |
495 |
|
|
} |
496 |
|
|
} |
497 |
|
|
} |
498 |
|
|
|
499 |
|
|
@Test |
500 |
|
|
public void testSortThrowsCME() { |
501 |
|
|
@SuppressWarnings("unchecked") |
502 |
|
|
final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier(LIST_CME_SUPPLIERS, SIZE); |
503 |
|
|
for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) { |
504 |
|
|
final List<Integer> list = test.collection; |
505 |
|
|
|
506 |
|
|
if (list.size() <= 1) { |
507 |
|
|
continue; |
508 |
|
|
} |
509 |
|
|
boolean gotException = false; |
510 |
|
|
try { |
511 |
|
|
// bad predicate that modifies its list, should throw CME |
512 |
|
|
list.sort((x, y) -> {list.add(x); return x - y;}); |
513 |
|
|
} catch (ConcurrentModificationException cme) { |
514 |
|
|
gotException = true; |
515 |
|
|
} |
516 |
|
|
if (!gotException) { |
517 |
|
|
fail("expected CME was not thrown from " + test); |
518 |
|
|
} |
519 |
|
|
} |
520 |
|
|
} |
521 |
|
|
|
522 |
|
|
private static final List<Integer> SLICED_EXPECTED = Arrays.asList(0, 1, 2, 3, 5, 6, 7, 8, 9); |
523 |
|
|
private static final List<Integer> SLICED_EXPECTED2 = Arrays.asList(0, 1, 2, 5, 6, 7, 8, 9); |
524 |
|
|
|
525 |
|
|
@DataProvider(name="shortIntListProvider", parallel=true) |
526 |
|
|
public static Object[][] intListCases() { |
527 |
|
|
final Integer[] DATA = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; |
528 |
|
|
final List<Object[]> cases = new LinkedList<>(); |
529 |
|
|
cases.add(new Object[] { new ArrayList<>(Arrays.asList(DATA)) }); |
530 |
|
|
cases.add(new Object[] { new LinkedList<>(Arrays.asList(DATA)) }); |
531 |
|
|
cases.add(new Object[] { new Vector<>(Arrays.asList(DATA)) }); |
532 |
|
|
cases.add(new Object[] { new CopyOnWriteArrayList<>(Arrays.asList(DATA)) }); |
533 |
|
|
cases.add(new Object[] { new ExtendsAbstractList<>(Arrays.asList(DATA)) }); |
534 |
|
|
return cases.toArray(new Object[0][cases.size()]); |
535 |
|
|
} |
536 |
|
|
|
537 |
|
|
@Test(dataProvider = "shortIntListProvider") |
538 |
|
|
public void testRemoveIfFromSlice(final List<Integer> list) { |
539 |
|
|
final List<Integer> sublist = list.subList(3, 6); |
540 |
|
|
assertTrue(sublist.removeIf(x -> x == 4)); |
541 |
|
|
CollectionAsserts.assertContents(list, SLICED_EXPECTED); |
542 |
|
|
|
543 |
|
|
final List<Integer> sublist2 = list.subList(2, 5); |
544 |
|
|
assertTrue(sublist2.removeIf(x -> x == 3)); |
545 |
|
|
CollectionAsserts.assertContents(list, SLICED_EXPECTED2); |
546 |
|
|
} |
547 |
|
|
} |