--- jsr166/src/test/tck/Collection8Test.java 2018/03/26 21:06:51 1.49 +++ jsr166/src/test/tck/Collection8Test.java 2021/01/26 13:33:05 1.61 @@ -8,6 +8,7 @@ import static java.util.concurrent.TimeUnit.HOURS; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -92,28 +93,28 @@ public class Collection8Test extends JSR void emptyMeansEmpty(Collection c) throws InterruptedException { assertTrue(c.isEmpty()); - assertEquals(0, c.size()); - assertEquals("[]", c.toString()); + mustEqual(0, c.size()); + mustEqual("[]", c.toString()); if (c instanceof List) { List x = (List) c; - assertEquals(1, x.hashCode()); - assertEquals(x, Collections.emptyList()); - assertEquals(Collections.emptyList(), x); - assertEquals(-1, x.indexOf(impl.makeElement(86))); - assertEquals(-1, x.lastIndexOf(impl.makeElement(99))); + mustEqual(1, x.hashCode()); + mustEqual(x, Collections.emptyList()); + mustEqual(Collections.emptyList(), x); + mustEqual(-1, x.indexOf(impl.makeElement(86))); + mustEqual(-1, x.lastIndexOf(impl.makeElement(99))); assertThrows( IndexOutOfBoundsException.class, () -> x.get(0), () -> x.set(0, impl.makeElement(42))); } else if (c instanceof Set) { - assertEquals(0, c.hashCode()); - assertEquals(c, Collections.emptySet()); - assertEquals(Collections.emptySet(), c); + mustEqual(0, c.hashCode()); + mustEqual(c, Collections.emptySet()); + mustEqual(Collections.emptySet(), c); } { Object[] a = c.toArray(); - assertEquals(0, a.length); + mustEqual(0, a.length); assertSame(Object[].class, a.getClass()); } { @@ -121,15 +122,15 @@ public class Collection8Test extends JSR assertSame(a, c.toArray(a)); } { - Integer[] a = new Integer[0]; + Item[] a = new Item[0]; assertSame(a, c.toArray(a)); } { - Integer[] a = { 1, 2, 3}; + Item[] a = { one, two, three}; assertSame(a, c.toArray(a)); assertNull(a[0]); - assertSame(2, a[1]); - assertSame(3, a[2]); + mustEqual(2, a[1]); + mustEqual(3, a[2]); } assertIteratorExhausted(c.iterator()); Consumer alwaysThrows = e -> { throw new AssertionError(); }; @@ -138,7 +139,7 @@ public class Collection8Test extends JSR c.spliterator().forEachRemaining(alwaysThrows); assertFalse(c.spliterator().tryAdvance(alwaysThrows)); if (c.spliterator().hasCharacteristics(Spliterator.SIZED)) - assertEquals(0, c.spliterator().estimateSize()); + mustEqual(0, c.spliterator().estimateSize()); assertFalse(c.contains(bomb())); assertFalse(c.remove(bomb())); if (c instanceof Queue) { @@ -170,18 +171,19 @@ public class Collection8Test extends JSR public void testNullPointerExceptions() throws InterruptedException { Collection c = impl.emptyCollection(); + Collection nullCollection = null; assertThrows( NullPointerException.class, - () -> c.addAll(null), - () -> c.containsAll(null), - () -> c.retainAll(null), - () -> c.removeAll(null), + () -> c.addAll(nullCollection), + () -> c.containsAll(nullCollection), + () -> c.retainAll(nullCollection), + () -> c.removeAll(nullCollection), () -> c.removeIf(null), () -> c.forEach(null), () -> c.iterator().forEachRemaining(null), () -> c.spliterator().forEachRemaining(null), () -> c.spliterator().tryAdvance(null), - () -> c.toArray(null)); + () -> c.toArray((Object[])null)); if (!impl.permitsNulls()) { assertThrows( @@ -209,41 +211,17 @@ public class Collection8Test extends JSR BlockingQueue q = (BlockingQueue) c; assertThrows( NullPointerException.class, - () -> { - try { q.offer(null, 1L, HOURS); } - catch (InterruptedException ex) { - throw new AssertionError(ex); - }}, - () -> { - try { q.put(null); } - catch (InterruptedException ex) { - throw new AssertionError(ex); - }}); + () -> q.offer(null, 1L, HOURS), + () -> q.put(null)); } if (c instanceof BlockingDeque) { BlockingDeque q = (BlockingDeque) c; assertThrows( NullPointerException.class, - () -> { - try { q.offerFirst(null, 1L, HOURS); } - catch (InterruptedException ex) { - throw new AssertionError(ex); - }}, - () -> { - try { q.offerLast(null, 1L, HOURS); } - catch (InterruptedException ex) { - throw new AssertionError(ex); - }}, - () -> { - try { q.putFirst(null); } - catch (InterruptedException ex) { - throw new AssertionError(ex); - }}, - () -> { - try { q.putLast(null); } - catch (InterruptedException ex) { - throw new AssertionError(ex); - }}); + () -> q.offerFirst(null, 1L, HOURS), + () -> q.offerLast(null, 1L, HOURS), + () -> q.putFirst(null), + () -> q.putLast(null)); } } @@ -315,14 +293,14 @@ public class Collection8Test extends JSR try { boolean modified = c.removeIf(randomPredicate); assertNull(threwAt.get()); - assertEquals(modified, accepts.size() > 0); - assertEquals(modified, rejects.size() != n); - assertEquals(accepts.size() + rejects.size(), n); + mustEqual(modified, accepts.size() > 0); + mustEqual(modified, rejects.size() != n); + mustEqual(accepts.size() + rejects.size(), n); if (ordered) { - assertEquals(rejects, + mustEqual(rejects, Arrays.asList(c.toArray())); } else { - assertEquals(new HashSet(rejects), + mustEqual(new HashSet(rejects), new HashSet(Arrays.asList(c.toArray()))); } } catch (ArithmeticException ok) { @@ -346,7 +324,7 @@ public class Collection8Test extends JSR assertTrue(c.containsAll(survivors)); assertTrue(survivors.containsAll(rejects)); if (threwAt.get() == null) { - assertEquals(n - accepts.size(), c.size()); + mustEqual(n - accepts.size(), c.size()); for (Object x : accepts) assertFalse(c.contains(x)); } else { // Two acceptable behaviors: entire removeIf call is one @@ -436,7 +414,6 @@ public class Collection8Test extends JSR if (rnd.nextBoolean()) assertTrue(it.hasNext()); it.next(); } - Consumer alwaysThrows = e -> { throw new AssertionError(); }; // TODO: many more removal methods if (rnd.nextBoolean()) { for (Iterator z = c.iterator(); z.hasNext(); ) { @@ -510,24 +487,24 @@ public class Collection8Test extends JSR if (c instanceof List || c instanceof Deque) assertTrue(ordered); HashSet cset = new HashSet(c); - assertEquals(cset, new HashSet(parallelStreamForEached)); + mustEqual(cset, new HashSet(parallelStreamForEached)); if (ordered) { - assertEquals(iterated, iteratedForEachRemaining); - assertEquals(iterated, tryAdvanced); - assertEquals(iterated, spliterated); - assertEquals(iterated, splitonced); - assertEquals(iterated, forEached); - assertEquals(iterated, streamForEached); - assertEquals(iterated, removeIfed); + mustEqual(iterated, iteratedForEachRemaining); + mustEqual(iterated, tryAdvanced); + mustEqual(iterated, spliterated); + mustEqual(iterated, splitonced); + mustEqual(iterated, forEached); + mustEqual(iterated, streamForEached); + mustEqual(iterated, removeIfed); } else { - assertEquals(cset, new HashSet(iterated)); - assertEquals(cset, new HashSet(iteratedForEachRemaining)); - assertEquals(cset, new HashSet(tryAdvanced)); - assertEquals(cset, new HashSet(spliterated)); - assertEquals(cset, new HashSet(splitonced)); - assertEquals(cset, new HashSet(forEached)); - assertEquals(cset, new HashSet(streamForEached)); - assertEquals(cset, new HashSet(removeIfed)); + mustEqual(cset, new HashSet(iterated)); + mustEqual(cset, new HashSet(iteratedForEachRemaining)); + mustEqual(cset, new HashSet(tryAdvanced)); + mustEqual(cset, new HashSet(spliterated)); + mustEqual(cset, new HashSet(splitonced)); + mustEqual(cset, new HashSet(forEached)); + mustEqual(cset, new HashSet(streamForEached)); + mustEqual(cset, new HashSet(removeIfed)); } if (c instanceof Deque) { Deque d = (Deque) c; @@ -539,8 +516,8 @@ public class Collection8Test extends JSR e -> descendingForEachRemaining.add(e)); Collections.reverse(descending); Collections.reverse(descendingForEachRemaining); - assertEquals(iterated, descending); - assertEquals(iterated, descendingForEachRemaining); + mustEqual(iterated, descending); + mustEqual(iterated, descendingForEachRemaining); } } @@ -578,7 +555,7 @@ public class Collection8Test extends JSR r2 = ConcurrentModificationException.class; assertFalse(impl.isConcurrent()); } - assertEquals(r1, r2); + mustEqual(r1, r2); } /** @@ -588,15 +565,32 @@ public class Collection8Test extends JSR public void testRemoveAfterForEachRemaining() { Collection c = impl.emptyCollection(); ThreadLocalRandom rnd = ThreadLocalRandom.current(); + ArrayList copy = new ArrayList(); + boolean ordered = c.spliterator().hasCharacteristics(Spliterator.ORDERED); testCollection: { int n = 3 + rnd.nextInt(2); - for (int i = 0; i < n; i++) c.add(impl.makeElement(i)); + for (int i = 0; i < n; i++) { + Object x = impl.makeElement(i); + c.add(x); + copy.add(x); + } Iterator it = c.iterator(); - assertTrue(it.hasNext()); - assertEquals(impl.makeElement(0), it.next()); - assertTrue(it.hasNext()); - assertEquals(impl.makeElement(1), it.next()); - it.forEachRemaining(e -> assertTrue(c.contains(e))); + if (ordered) { + if (rnd.nextBoolean()) assertTrue(it.hasNext()); + mustEqual(impl.makeElement(0), it.next()); + if (rnd.nextBoolean()) assertTrue(it.hasNext()); + mustEqual(impl.makeElement(1), it.next()); + } else { + if (rnd.nextBoolean()) assertTrue(it.hasNext()); + assertTrue(copy.contains(it.next())); + if (rnd.nextBoolean()) assertTrue(it.hasNext()); + assertTrue(copy.contains(it.next())); + } + if (rnd.nextBoolean()) assertTrue(it.hasNext()); + it.forEachRemaining( + e -> { + assertTrue(c.contains(e)); + assertTrue(copy.contains(e));}); if (testImplementationDetails) { if (c instanceof java.util.concurrent.ArrayBlockingQueue) { assertIteratorExhausted(it); @@ -605,26 +599,29 @@ public class Collection8Test extends JSR catch (UnsupportedOperationException ok) { break testCollection; } - assertEquals(n - 1, c.size()); - for (int i = 0; i < n - 1; i++) - assertTrue(c.contains(impl.makeElement(i))); - assertFalse(c.contains(impl.makeElement(n - 1))); + mustEqual(n - 1, c.size()); + if (ordered) { + for (int i = 0; i < n - 1; i++) + assertTrue(c.contains(impl.makeElement(i))); + assertFalse(c.contains(impl.makeElement(n - 1))); + } } } } if (c instanceof Deque) { Deque d = (Deque) impl.emptyCollection(); + assertTrue(ordered); int n = 3 + rnd.nextInt(2); for (int i = 0; i < n; i++) d.add(impl.makeElement(i)); Iterator it = d.descendingIterator(); assertTrue(it.hasNext()); - assertEquals(impl.makeElement(n - 1), it.next()); + mustEqual(impl.makeElement(n - 1), it.next()); assertTrue(it.hasNext()); - assertEquals(impl.makeElement(n - 2), it.next()); + mustEqual(impl.makeElement(n - 2), it.next()); it.forEachRemaining(e -> assertTrue(c.contains(e))); if (testImplementationDetails) { it.remove(); - assertEquals(n - 1, d.size()); + mustEqual(n - 1, d.size()); for (int i = 1; i < n; i++) assertTrue(d.contains(impl.makeElement(i))); assertFalse(d.contains(impl.makeElement(0))); @@ -637,7 +634,6 @@ public class Collection8Test extends JSR */ public void testStreamForEach() throws Throwable { final Collection c = impl.emptyCollection(); - final AtomicLong count = new AtomicLong(0L); final Object x = impl.makeElement(1); final Object y = impl.makeElement(2); final ArrayList found = new ArrayList(); @@ -647,12 +643,12 @@ public class Collection8Test extends JSR assertTrue(c.add(x)); c.stream().forEach(spy); - assertEquals(Collections.singletonList(x), found); + mustEqual(Collections.singletonList(x), found); found.clear(); assertTrue(c.add(y)); c.stream().forEach(spy); - assertEquals(2, found.size()); + mustEqual(2, found.size()); assertTrue(found.contains(x)); assertTrue(found.contains(y)); found.clear(); @@ -695,7 +691,6 @@ public class Collection8Test extends JSR */ public void testForEach() throws Throwable { final Collection c = impl.emptyCollection(); - final AtomicLong count = new AtomicLong(0L); final Object x = impl.makeElement(1); final Object y = impl.makeElement(2); final ArrayList found = new ArrayList(); @@ -705,12 +700,12 @@ public class Collection8Test extends JSR assertTrue(c.add(x)); c.forEach(spy); - assertEquals(Collections.singletonList(x), found); + mustEqual(Collections.singletonList(x), found); found.clear(); assertTrue(c.add(y)); c.forEach(spy); - assertEquals(2, found.size()); + mustEqual(2, found.size()); assertTrue(found.contains(x)); assertTrue(found.contains(y)); found.clear(); @@ -884,7 +879,7 @@ public class Collection8Test extends JSR c.add(one); split.forEachRemaining( e -> { assertSame(e, one); count.getAndIncrement(); }); - assertEquals(1L, count.get()); + mustEqual(1L, count.get()); assertFalse(split.tryAdvance(e -> { throw new AssertionError(); })); assertTrue(c.contains(one)); } @@ -906,6 +901,54 @@ public class Collection8Test extends JSR } } + public void testCollectionCopies() throws Exception { + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + Collection c = impl.emptyCollection(); + for (int n = rnd.nextInt(4); n--> 0; ) + c.add(impl.makeElement(rnd.nextInt())); + mustEqual(c, c); + if (c instanceof List) + assertCollectionsEquals(c, new ArrayList(c)); + else if (c instanceof Set) + assertCollectionsEquals(c, new HashSet(c)); + else if (c instanceof Deque) + assertCollectionsEquivalent(c, new ArrayDeque(c)); + + Collection clone = cloneableClone(c); + if (clone != null) { + assertSame(c.getClass(), clone.getClass()); + assertCollectionsEquivalent(c, clone); + } + try { + Collection serialClone = serialClonePossiblyFailing(c); + assertSame(c.getClass(), serialClone.getClass()); + assertCollectionsEquivalent(c, serialClone); + } catch (java.io.NotSerializableException acceptable) {} + } + + /** + * TODO: move out of limbo + * 8203662: remove increment of modCount from ArrayList and Vector replaceAll() + */ + public void DISABLED_testReplaceAllIsNotStructuralModification() { + Collection c = impl.emptyCollection(); + if (!(c instanceof List)) + return; + List list = (List) c; + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + for (int n = rnd.nextInt(2, 10); n--> 0; ) + list.add(impl.makeElement(rnd.nextInt())); + ArrayList copy = new ArrayList(list); + int size = list.size(), half = size / 2; + Iterator it = list.iterator(); + for (int i = 0; i < half; i++) + mustEqual(it.next(), copy.get(i)); + list.replaceAll(n -> n); + // ConcurrentModificationException must not be thrown here. + for (int i = half; i < size; i++) + mustEqual(it.next(), copy.get(i)); + } + // public void testCollection8DebugFail() { // fail(impl.klazz().getSimpleName()); // }