ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/jtreg/util/List/ListDefaults.java
Revision: 1.2
Committed: Thu Sep 10 01:00:05 2015 UTC (8 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.1: +1 -1 lines
Log Message:
typo

File Contents

# Content
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 // Reuse the supplier to store AtomicInteger instead of Integer
385 // 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 }