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
24import java.util.Arrays;
25import java.util.Collection;
26import java.util.Collections;
27import java.util.HashMap;
28import java.util.HashSet;
29import java.util.Iterator;
30import java.util.LinkedHashMap;
31import java.util.LinkedHashSet;
32import java.util.LinkedList;
33import java.util.List;
34import java.util.Set;
35
36import java.util.SortedSet;
37
38import org.testng.annotations.DataProvider;
39import org.testng.annotations.Test;
40
41import static org.testng.Assert.assertTrue;
42import static org.testng.Assert.fail;
43
44import java.util.TreeMap;
45import java.util.TreeSet;
46import java.util.concurrent.ConcurrentHashMap;
47import java.util.concurrent.ConcurrentSkipListMap;
48import java.util.function.Function;
49import java.util.function.Predicate;
50
51/**
52 * @test
53 * @summary Unit tests for extension methods on Collection
54 * @library testlibrary
55 * @build CollectionAsserts CollectionSupplier ExtendsAbstractSet ExtendsAbstractCollection
56 * @run testng CollectionDefaults
57 */
58public class CollectionDefaults {
59
60    public static final Predicate<Integer> pEven = x -> 0 == x % 2;
61    public static final Predicate<Integer> pOdd = x -> 1 == x % 2;
62
63    private static final int SIZE = 100;
64
65    private static final List<Function<Collection<Integer>, Collection<Integer>>> TEST_SUPPLIERS = Arrays.asList(
66            // Collection
67            ExtendsAbstractCollection<Integer>::new,
68            java.util.ArrayDeque<Integer>::new,
69            java.util.concurrent.ConcurrentLinkedDeque<Integer>::new,
70            java.util.concurrent.ConcurrentLinkedQueue<Integer>::new,
71            java.util.concurrent.LinkedBlockingDeque<Integer>::new,
72            java.util.concurrent.LinkedBlockingQueue<Integer>::new,
73            java.util.concurrent.LinkedTransferQueue<Integer>::new,
74            (coll) -> new java.util.concurrent.ArrayBlockingQueue<Integer>(
75                3 * SIZE, false, coll),
76
77            // Lists
78            java.util.ArrayList<Integer>::new,
79            java.util.LinkedList<Integer>::new,
80            java.util.Vector<Integer>::new,
81            java.util.concurrent.CopyOnWriteArrayList<Integer>::new,
82            ExtendsAbstractList<Integer>::new,
83
84            // Sets
85            java.util.HashSet<Integer>::new,
86            java.util.LinkedHashSet<Integer>::new,
87            java.util.TreeSet<Integer>::new,
88            java.util.concurrent.ConcurrentSkipListSet<Integer>::new,
89            java.util.concurrent.CopyOnWriteArraySet<Integer>::new,
90            ExtendsAbstractSet<Integer>::new
91       );
92
93    @DataProvider(name="setProvider", parallel=true)
94    public static Iterator<Object[]> setCases() {
95        final List<Object[]> cases = new LinkedList<>();
96        cases.add(new Object[] { new HashSet<>() });
97        cases.add(new Object[] { new LinkedHashSet<>() });
98        cases.add(new Object[] { new TreeSet<>() });
99        cases.add(new Object[] { new java.util.concurrent.ConcurrentSkipListSet<>() });
100        cases.add(new Object[] { new java.util.concurrent.CopyOnWriteArraySet<>() });
101
102        cases.add(new Object[] { new ExtendsAbstractSet<>() });
103
104        cases.add(new Object[] { Collections.newSetFromMap(new HashMap<>()) });
105        cases.add(new Object[] { Collections.newSetFromMap(new LinkedHashMap<>()) });
106        cases.add(new Object[] { Collections.newSetFromMap(new TreeMap<>()) });
107        cases.add(new Object[] { Collections.newSetFromMap(new ConcurrentHashMap<>()) });
108        cases.add(new Object[] { Collections.newSetFromMap(new ConcurrentSkipListMap<>()) });
109
110        cases.add(new Object[] { new HashSet<Integer>(){{add(42);}} });
111        cases.add(new Object[] { new ExtendsAbstractSet<Integer>(){{add(42);}} });
112        cases.add(new Object[] { new LinkedHashSet<Integer>(){{add(42);}} });
113        cases.add(new Object[] { new TreeSet<Integer>(){{add(42);}} });
114        return cases.iterator();
115    }
116
117    @Test(dataProvider = "setProvider")
118    public void testProvidedWithNull(final Set<Integer> set) {
119        try {
120            set.forEach(null);
121            fail("expected NPE not thrown");
122        } catch (NullPointerException expected) { // expected
123        }
124        try {
125            set.removeIf(null);
126            fail("expected NPE not thrown");
127        } catch (NullPointerException expected) { // expected
128        }
129    }
130
131    @Test
132    public void testForEach() {
133        @SuppressWarnings("unchecked")
134        final CollectionSupplier<Collection<Integer>> supplier = new CollectionSupplier(TEST_SUPPLIERS, SIZE);
135
136        for (final CollectionSupplier.TestCase<Collection<Integer>> test : supplier.get()) {
137            final Collection<Integer> original = test.expected;
138            final Collection<Integer> set = test.collection;
139
140            try {
141                set.forEach(null);
142                fail("expected NPE not thrown");
143            } catch (NullPointerException expected) { // expected
144            }
145            if (set instanceof Set && !((set instanceof SortedSet) || (set instanceof LinkedHashSet))) {
146                CollectionAsserts.assertContentsUnordered(set, original, test.toString());
147            } else {
148                CollectionAsserts.assertContents(set, original, test.toString());
149            }
150
151            final List<Integer> actual = new LinkedList<>();
152            set.forEach(actual::add);
153            if (set instanceof Set && !((set instanceof SortedSet) || (set instanceof LinkedHashSet))) {
154                CollectionAsserts.assertContentsUnordered(actual, set, test.toString());
155                CollectionAsserts.assertContentsUnordered(actual, original, test.toString());
156            } else {
157                CollectionAsserts.assertContents(actual, set, test.toString());
158                CollectionAsserts.assertContents(actual, original, test.toString());
159            }
160        }
161    }
162
163    @Test
164    public void testRemoveIf() {
165        @SuppressWarnings("unchecked")
166        final CollectionSupplier<Collection<Integer>> supplier = new CollectionSupplier(TEST_SUPPLIERS, SIZE);
167        for (final CollectionSupplier.TestCase<Collection<Integer>> test : supplier.get()) {
168            final Collection<Integer> original = test.expected;
169            final Collection<Integer> set = test.collection;
170
171            try {
172                set.removeIf(null);
173                fail("expected NPE not thrown");
174            } catch (NullPointerException expected) { // expected
175            }
176            if (set instanceof Set && !((set instanceof SortedSet) || (set instanceof LinkedHashSet))) {
177                CollectionAsserts.assertContentsUnordered(set, original, test.toString());
178            } else {
179                CollectionAsserts.assertContents(set, original, test.toString());
180            }
181
182            set.removeIf(pEven);
183            for (int i : set) {
184                assertTrue((i % 2) == 1);
185            }
186            for (int i : original) {
187                if (i % 2 == 1) {
188                    assertTrue(set.contains(i));
189                }
190            }
191            set.removeIf(pOdd);
192            assertTrue(set.isEmpty());
193        }
194    }
195}
196