1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 package org.openjdk.tests.java.util.stream; 25 26 import org.testng.annotations.DataProvider; 27 import org.testng.annotations.Factory; 28 import org.testng.annotations.Test; 29 import org.testng.annotations.BeforeClass; 30 31 import java.util.Arrays; 32 import java.util.Collection; 33 import java.util.Collections; 34 import java.util.LinkedHashSet; 35 import java.util.LinkedList; 36 import java.util.List; 37 import java.util.Spliterator; 38 import java.util.TreeSet; 39 import java.util.stream.DoubleStream; 40 import java.util.stream.IntStream; 41 import java.util.stream.LongStream; 42 import java.util.stream.Stream; 43 44 import static org.openjdk.testlib.java.util.stream.LambdaTestHelpers.*; 45 import static org.testng.Assert.*; 46 47 @Test 48 public class ConcatTest { 49 private static Object[][] cases; 50 51 static { 52 List<Integer> part1 = Arrays.asList(5, 3, 4, 1, 2, 6, 2, 4); 53 List<Integer> part2 = Arrays.asList(8, 8, 6, 6, 9, 7, 10, 9); 54 List<Integer> p1p2 = Arrays.asList(5, 3, 4, 1, 2, 6, 2, 4, 8, 8, 6, 6, 9, 7, 10, 9); 55 List<Integer> p2p1 = Arrays.asList(8, 8, 6, 6, 9, 7, 10, 9, 5, 3, 4, 1, 2, 6, 2, 4); 56 List<Integer> empty = new LinkedList<>(); // To be ordered empty.isEmpty()57 assertTrue(empty.isEmpty()); 58 LinkedHashSet<Integer> distinctP1 = new LinkedHashSet<>(part1); 59 LinkedHashSet<Integer> distinctP2 = new LinkedHashSet<>(part2); 60 TreeSet<Integer> sortedP1 = new TreeSet<>(part1); 61 TreeSet<Integer> sortedP2 = new TreeSet<>(part2); 62 63 cases = new Object[][] { 64 { "regular", part1, part2, p1p2 }, 65 { "reverse regular", part2, part1, p2p1 }, 66 { "front distinct", distinctP1, part2, Arrays.asList(5, 3, 4, 1, 2, 6, 8, 8, 6, 6, 9, 7, 10, 9) }, 67 { "back distinct", part1, distinctP2, Arrays.asList(5, 3, 4, 1, 2, 6, 2, 4, 8, 6, 9, 7, 10) }, 68 { "both distinct", distinctP1, distinctP2, Arrays.asList(5, 3, 4, 1, 2, 6, 8, 6, 9, 7, 10) }, 69 { "front sorted", sortedP1, part2, Arrays.asList(1, 2, 3, 4, 5, 6, 8, 8, 6, 6, 9, 7, 10, 9) }, 70 { "back sorted", part1, sortedP2, Arrays.asList(5, 3, 4, 1, 2, 6, 2, 4, 6, 7, 8, 9, 10) }, 71 { "both sorted", sortedP1, sortedP2, Arrays.asList(1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 10) }, 72 { "reverse both sorted", sortedP2, sortedP1, Arrays.asList(6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6) }, 73 { "empty something", empty, part1, part1 }, 74 { "something empty", part1, empty, part1 }, 75 { "empty empty", empty, empty, empty } 76 }; 77 } 78 79 @DataProvider(name = "cases") getCases()80 private static Object[][] getCases() { 81 return cases; 82 } 83 84 @Factory(dataProvider = "cases") createTests(String scenario, Collection<Integer> c1, Collection<Integer> c2, Collection<Integer> expected)85 public static Object[] createTests(String scenario, Collection<Integer> c1, Collection<Integer> c2, Collection<Integer> expected) { 86 return new Object[] { 87 new ConcatTest(scenario, c1, c2, expected) 88 }; 89 } 90 91 protected final String scenario; 92 protected final Collection<Integer> c1; 93 protected final Collection<Integer> c2; 94 protected final Collection<Integer> expected; 95 ConcatTest(String scenario, Collection<Integer> c1, Collection<Integer> c2, Collection<Integer> expected)96 public ConcatTest(String scenario, Collection<Integer> c1, Collection<Integer> c2, Collection<Integer> expected) { 97 this.scenario = scenario; 98 this.c1 = c1; 99 this.c2 = c2; 100 this.expected = expected; 101 } 102 103 // Android-changed: Factor out the prerequisites check out of the constructor. 104 // TestNG crashes hard if an assert is thrown in the constructor. 105 // This is done for test readability only and doesn't impact test logic. 106 @BeforeClass checkPrerequisites()107 public void checkPrerequisites() { 108 // verify prerequisite 109 Stream<Integer> s1s = c1.stream(); 110 Stream<Integer> s2s = c2.stream(); 111 Stream<Integer> s1p = c1.parallelStream(); 112 Stream<Integer> s2p = c2.parallelStream(); 113 assertTrue(s1p.isParallel()); 114 assertTrue(s2p.isParallel()); 115 assertFalse(s1s.isParallel()); 116 assertFalse(s2s.isParallel()); 117 118 // Android-changed: Also add the class name to easier debug. Doesn't impact logic. 119 assertTrue(s1s.spliterator().hasCharacteristics(Spliterator.ORDERED), c1.getClass().toString()); 120 assertTrue(s1p.spliterator().hasCharacteristics(Spliterator.ORDERED), c2.getClass().toString()); 121 assertTrue(s2s.spliterator().hasCharacteristics(Spliterator.ORDERED), c1.getClass().toString()); 122 assertTrue(s2p.spliterator().hasCharacteristics(Spliterator.ORDERED), c2.getClass().toString()); 123 } 124 assertConcatContent(Spliterator<T> sp, boolean ordered, Spliterator<T> expected)125 private <T> void assertConcatContent(Spliterator<T> sp, boolean ordered, Spliterator<T> expected) { 126 // concat stream cannot guarantee uniqueness 127 assertFalse(sp.hasCharacteristics(Spliterator.DISTINCT), scenario); 128 // concat stream cannot guarantee sorted 129 assertFalse(sp.hasCharacteristics(Spliterator.SORTED), scenario); 130 // concat stream is ordered if both are ordered 131 assertEquals(sp.hasCharacteristics(Spliterator.ORDERED), ordered, scenario); 132 133 // Verify elements 134 if (ordered) { 135 assertEquals(toBoxedList(sp), 136 toBoxedList(expected), 137 scenario); 138 } else { 139 assertEquals(toBoxedMultiset(sp), 140 toBoxedMultiset(expected), 141 scenario); 142 } 143 } 144 assertRefConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered)145 private void assertRefConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered) { 146 Stream<Integer> result = Stream.concat(s1, s2); 147 assertEquals(result.isParallel(), parallel); 148 assertConcatContent(result.spliterator(), ordered, expected.spliterator()); 149 } 150 assertIntConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered)151 private void assertIntConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered) { 152 IntStream result = IntStream.concat(s1.mapToInt(Integer::intValue), 153 s2.mapToInt(Integer::intValue)); 154 assertEquals(result.isParallel(), parallel); 155 assertConcatContent(result.spliterator(), ordered, 156 expected.stream().mapToInt(Integer::intValue).spliterator()); 157 } 158 assertLongConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered)159 private void assertLongConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered) { 160 LongStream result = LongStream.concat(s1.mapToLong(Integer::longValue), 161 s2.mapToLong(Integer::longValue)); 162 assertEquals(result.isParallel(), parallel); 163 assertConcatContent(result.spliterator(), ordered, 164 expected.stream().mapToLong(Integer::longValue).spliterator()); 165 } 166 assertDoubleConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered)167 private void assertDoubleConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered) { 168 DoubleStream result = DoubleStream.concat(s1.mapToDouble(Integer::doubleValue), 169 s2.mapToDouble(Integer::doubleValue)); 170 assertEquals(result.isParallel(), parallel); 171 assertConcatContent(result.spliterator(), ordered, 172 expected.stream().mapToDouble(Integer::doubleValue).spliterator()); 173 } 174 testRefConcat()175 public void testRefConcat() { 176 // sequential + sequential -> sequential 177 assertRefConcat(c1.stream(), c2.stream(), false, true); 178 // parallel + parallel -> parallel 179 assertRefConcat(c1.parallelStream(), c2.parallelStream(), true, true); 180 // sequential + parallel -> parallel 181 assertRefConcat(c1.stream(), c2.parallelStream(), true, true); 182 // parallel + sequential -> parallel 183 assertRefConcat(c1.parallelStream(), c2.stream(), true, true); 184 185 // not ordered 186 assertRefConcat(c1.stream().unordered(), c2.stream(), false, false); 187 assertRefConcat(c1.stream(), c2.stream().unordered(), false, false); 188 assertRefConcat(c1.parallelStream().unordered(), c2.stream().unordered(), true, false); 189 } 190 testIntConcat()191 public void testIntConcat() { 192 // sequential + sequential -> sequential 193 assertIntConcat(c1.stream(), c2.stream(), false, true); 194 // parallel + parallel -> parallel 195 assertIntConcat(c1.parallelStream(), c2.parallelStream(), true, true); 196 // sequential + parallel -> parallel 197 assertIntConcat(c1.stream(), c2.parallelStream(), true, true); 198 // parallel + sequential -> parallel 199 assertIntConcat(c1.parallelStream(), c2.stream(), true, true); 200 201 // not ordered 202 assertIntConcat(c1.stream().unordered(), c2.stream(), false, false); 203 assertIntConcat(c1.stream(), c2.stream().unordered(), false, false); 204 assertIntConcat(c1.parallelStream().unordered(), c2.stream().unordered(), true, false); 205 } 206 testLongConcat()207 public void testLongConcat() { 208 // sequential + sequential -> sequential 209 assertLongConcat(c1.stream(), c2.stream(), false, true); 210 // parallel + parallel -> parallel 211 assertLongConcat(c1.parallelStream(), c2.parallelStream(), true, true); 212 // sequential + parallel -> parallel 213 assertLongConcat(c1.stream(), c2.parallelStream(), true, true); 214 // parallel + sequential -> parallel 215 assertLongConcat(c1.parallelStream(), c2.stream(), true, true); 216 217 // not ordered 218 assertLongConcat(c1.stream().unordered(), c2.stream(), false, false); 219 assertLongConcat(c1.stream(), c2.stream().unordered(), false, false); 220 assertLongConcat(c1.parallelStream().unordered(), c2.stream().unordered(), true, false); 221 } 222 testDoubleConcat()223 public void testDoubleConcat() { 224 // sequential + sequential -> sequential 225 assertDoubleConcat(c1.stream(), c2.stream(), false, true); 226 // parallel + parallel -> parallel 227 assertDoubleConcat(c1.parallelStream(), c2.parallelStream(), true, true); 228 // sequential + parallel -> parallel 229 assertDoubleConcat(c1.stream(), c2.parallelStream(), true, true); 230 // parallel + sequential -> parallel 231 assertDoubleConcat(c1.parallelStream(), c2.stream(), true, true); 232 233 // not ordered 234 assertDoubleConcat(c1.stream().unordered(), c2.stream(), false, false); 235 assertDoubleConcat(c1.stream(), c2.stream().unordered(), false, false); 236 assertDoubleConcat(c1.parallelStream().unordered(), c2.stream().unordered(), true, false); 237 } 238 } 239