1 /*
   2  * Copyright (c) 2012, 2013, 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 package org.openjdk.tests.java.util.stream;
  24 
  25 import java.util.Arrays;
  26 import java.util.Optional;
  27 import java.util.Spliterator;
  28 import java.util.stream.IntStream;
  29 import java.util.stream.LongStream;
  30 import java.util.stream.OpTestCase;
  31 import java.util.stream.SpliteratorTestHelper;
  32 import java.util.stream.Stream;
  33 import java.util.stream.TestData;
  34 
  35 import org.testng.annotations.Test;
  36 
  37 /**
  38  * Primitive range tests
  39  *
  40  * @author Brian Goetz
  41  */
  42 @Test
  43 public class RangeTest extends OpTestCase {
  44 
  45     public void testInfiniteRangeFindFirst() {
  46         Integer first = Stream.iterate(0, i -> i + 1).filter(i -> i > 10000).findFirst().get();
  47         assertEquals(first, Stream.iterate(0, i -> i + 1).parallel().filter(i -> i > 10000).findFirst().get());
  48 
  49         // Limit is required to transform the infinite stream to a finite stream
  50         // since the exercising requires a finite stream
  51         withData(TestData.Factory.ofSupplier(
  52                 "", () -> Stream.iterate(0, i -> i + 1).filter(i -> i > 10000).limit(20000))).
  53                 terminal(s->s.findFirst()).expectedResult(Optional.of(10001)).exercise();
  54     }
  55 
  56     //
  57 
  58     public void testIntRange() {
  59         // Half-open
  60         for (int start : Arrays.asList(1, 10, -1, -10)) {
  61             setContext("start", start);
  62             for (int end : Arrays.asList(1, 10, -1, -10)) {
  63                 setContext("end", end);
  64                 int size = (start < end) ? end - start : 0;
  65                 int[] exp = new int[size];
  66                 for (int i = start, p = 0; i < end; i++, p++) {
  67                     exp[p] = i;
  68                 }
  69 
  70                 int[] inc = IntStream.range(start, end).toArray();
  71                 assertEquals(inc.length, size);
  72                 assertTrue(Arrays.equals(exp, inc));
  73 
  74                 withData(intRangeData(start, end)).stream(s -> s).
  75                         expectedResult(exp).exercise();
  76             }
  77         }
  78 
  79         // Closed
  80         for (int start : Arrays.asList(1, 10, -1, -10)) {
  81             setContext("start", start);
  82             for (int end : Arrays.asList(1, 10, -1, -10)) {
  83                 setContext("end", end);
  84                 int size = (start <= end) ? end - start + 1 : 0;
  85                 int[] exp = new int[size];
  86                 for (int i = start, p = 0; i <= end; i++, p++) {
  87                     exp[p] = i;
  88                 }
  89 
  90                 int[] inc = IntStream.rangeClosed(start, end).toArray();
  91                 assertEquals(inc.length, size);
  92                 assertTrue(Arrays.equals(exp, inc));
  93 
  94                 withData(intRangeClosedData(start, end)).stream(s -> s).
  95                         expectedResult(exp).exercise();
  96             }
  97         }
  98 
  99         // Closed, maximum upper bound of Integer.MAX_VALUE
 100         {
 101             int[] inc = IntStream.rangeClosed(Integer.MAX_VALUE - 1, Integer.MAX_VALUE).toArray();
 102             assertEquals(2, inc.length);
 103             assertEquals(Integer.MAX_VALUE - 1, inc[0]);
 104             assertEquals(Integer.MAX_VALUE, inc[1]);
 105 
 106             inc = IntStream.rangeClosed(Integer.MAX_VALUE, Integer.MAX_VALUE).toArray();
 107             assertEquals(1, inc.length);
 108             assertEquals(Integer.MAX_VALUE, inc[0]);
 109 
 110             SpliteratorTestHelper.testIntSpliterator(
 111                     () -> IntStream.rangeClosed(Integer.MAX_VALUE - 8, Integer.MAX_VALUE).spliterator());
 112         }
 113 
 114         // Range wider than Integer.MAX_VALUE
 115         {
 116             Spliterator.OfInt s = IntStream.rangeClosed(Integer.MIN_VALUE, Integer.MAX_VALUE).
 117                     spliterator();
 118             assertEquals(s.estimateSize(), 1L << 32);
 119         }
 120     }
 121 
 122     TestData.OfInt intRangeData(int start, int end) {
 123         return TestData.Factory.ofIntSupplier("int range", () -> IntStream.range(start, end));
 124     }
 125 
 126     TestData.OfInt intRangeClosedData(int start, int end) {
 127         return TestData.Factory.ofIntSupplier("int rangeClosed", () -> IntStream.rangeClosed(start, end));
 128     }
 129 
 130     public void tesIntRangeReduce() {
 131         withData(intRangeData(0, 10000)).
 132                 terminal(s -> s.reduce(0, Integer::sum)).exercise();
 133     }
 134 
 135     public void testIntInfiniteRangeLimit() {
 136         withData(TestData.Factory.ofIntSupplier(
 137                 "int range", () -> IntStream.iterate(0, i -> i + 1).limit(10000))).
 138                 terminal(s -> s.reduce(0, Integer::sum)).exercise();
 139     }
 140 
 141     public void testIntInfiniteRangeFindFirst() {
 142         int first = IntStream.iterate(0, i -> i + 1).filter(i -> i > 10000).findFirst().getAsInt();
 143         assertEquals(first, IntStream.iterate(0, i -> i + 1).parallel().filter(i -> i > 10000).findFirst().getAsInt());
 144     }
 145 
 146     //
 147 
 148     public void testLongRange() {
 149         // Half-open
 150         for (long start : Arrays.asList(1, 1000, -1, -1000)) {
 151             setContext("start", start);
 152             for (long end : Arrays.asList(1, 1000, -1, -1000)) {
 153                 setContext("end", end);
 154                 long size = start < end ? end - start : 0;
 155                 long[] exp = new long[(int) size];
 156                 for (long i = start, p = 0; i < end; i++, p++) {
 157                     exp[(int) p] = i;
 158                 }
 159 
 160                 long[] inc = LongStream.range(start, end).toArray();
 161                 assertEquals(inc.length, size);
 162                 assertTrue(Arrays.equals(exp, inc));
 163 
 164                 withData(longRangeData(start, end)).stream(s -> s).
 165                         expectedResult(exp).exercise();
 166             }
 167         }
 168 
 169         // Closed
 170         for (long start : Arrays.asList(1, 1000, -1, -1000)) {
 171             setContext("start", start);
 172             for (long end : Arrays.asList(1, 1000, -1, -1000)) {
 173                 setContext("end", end);
 174                 long size = start <= end ? end - start + 1: 0;
 175                 long[] exp = new long[(int) size];
 176                 for (long i = start, p = 0; i <= end; i++, p++) {
 177                     exp[(int) p] = i;
 178                 }
 179 
 180                 long[] inc = LongStream.rangeClosed(start, end).toArray();
 181                 assertEquals(inc.length, size);
 182                 assertTrue(Arrays.equals(exp, inc));
 183 
 184                 withData(longRangeClosedData(start, end)).stream(s -> s).
 185                         expectedResult(exp).exercise();
 186             }
 187         }
 188 
 189         // Closed, maximum upper bound of Long.MAX_VALUE
 190         {
 191             long[] inc = LongStream.rangeClosed(Long.MAX_VALUE - 1, Long.MAX_VALUE).toArray();
 192             assertEquals(2, inc.length);
 193             assertEquals(Long.MAX_VALUE - 1, inc[0]);
 194             assertEquals(Long.MAX_VALUE, inc[1]);
 195 
 196             inc = LongStream.rangeClosed(Long.MAX_VALUE, Long.MAX_VALUE).toArray();
 197             assertEquals(1, inc.length);
 198             assertEquals(Long.MAX_VALUE, inc[0]);
 199 
 200             SpliteratorTestHelper.testLongSpliterator(
 201                     () -> LongStream.rangeClosed(Long.MAX_VALUE - 8, Long.MAX_VALUE).spliterator());
 202         }
 203     }
 204 
 205     TestData.OfLong longRangeData(long start, long end) {
 206         return TestData.Factory.ofLongSupplier("long range", () -> LongStream.range(start, end));
 207     }
 208 
 209     TestData.OfLong longRangeClosedData(long start, long end) {
 210         return TestData.Factory.ofLongSupplier("long rangeClosed", () -> LongStream.rangeClosed(start, end));
 211     }
 212 
 213     public void testLongRangeReduce() {
 214         withData(longRangeData(0, 10000)).
 215                 terminal(s -> s.reduce(0, Long::sum)).exercise();
 216     }
 217 
 218     public void testLongInfiniteRangeLimit() {
 219         withData(TestData.Factory.ofLongSupplier(
 220                 "long range", () -> LongStream.iterate(0, i -> i + 1).limit(10000))).
 221                 terminal(s -> s.reduce(0, Long::sum)).exercise();
 222     }
 223 
 224     public void testLongInfiniteRangeFindFirst() {
 225         long first = LongStream.iterate(0, i -> i + 1).filter(i -> i > 10000).findFirst().getAsLong();
 226         assertEquals(first, LongStream.iterate(0, i -> i + 1).parallel().filter(i -> i > 10000).findFirst().getAsLong());
 227     }
 228 
 229     private static void assertSizedAndSubSized(Spliterator<?> s) {
 230         assertTrue(s.hasCharacteristics(Spliterator.SIZED | Spliterator.SUBSIZED));
 231     }
 232 
 233     private static void assertNotSizedAndSubSized(Spliterator<?> s) {
 234         assertFalse(s.hasCharacteristics(Spliterator.SIZED | Spliterator.SUBSIZED));
 235     }
 236 
 237     public void testLongLongRange() {
 238         // Test [Long.MIN_VALUE, Long.MAX_VALUE)
 239         // This will concatenate streams of three ranges
 240         //   [Long.MIN_VALUE, x) [x, 0) [0, Long.MAX_VALUE)
 241         // where x = Long.divideUnsigned(0 - Long.MIN_VALUE, 2) + 1
 242         {
 243             Spliterator.OfLong s = LongStream.range(Long.MIN_VALUE, Long.MAX_VALUE).spliterator();
 244 
 245             assertEquals(s.estimateSize(), Long.MAX_VALUE);
 246             assertNotSizedAndSubSized(s);
 247 
 248             Spliterator.OfLong s1 = s.trySplit();
 249             assertNotSizedAndSubSized(s1);
 250             assertSizedAndSubSized(s);
 251 
 252             Spliterator.OfLong s2 = s1.trySplit();
 253             assertSizedAndSubSized(s1);
 254             assertSizedAndSubSized(s2);
 255 
 256             assertTrue(s.estimateSize() == Long.MAX_VALUE);
 257             assertTrue(s1.estimateSize() < Long.MAX_VALUE);
 258             assertTrue(s2.estimateSize() < Long.MAX_VALUE);
 259 
 260             assertEquals(s.estimateSize() + s1.estimateSize() + s2.estimateSize(),
 261                          Long.MAX_VALUE - Long.MIN_VALUE);
 262         }
 263 
 264         long[][] ranges = { {Long.MIN_VALUE, 0}, {-1, Long.MAX_VALUE} };
 265         for (int i = 0; i < ranges.length; i++) {
 266             long start = ranges[i][0];
 267             long end = ranges[i][1];
 268 
 269             Spliterator.OfLong s = LongStream.range(start, end).spliterator();
 270 
 271             assertEquals(s.estimateSize(), Long.MAX_VALUE);
 272             assertNotSizedAndSubSized(s);
 273 
 274             Spliterator.OfLong s1 = s.trySplit();
 275             assertSizedAndSubSized(s1);
 276             assertSizedAndSubSized(s);
 277 
 278             assertTrue(s.estimateSize() < Long.MAX_VALUE);
 279             assertTrue(s1.estimateSize() < Long.MAX_VALUE);
 280 
 281             assertEquals(s.estimateSize() + s1.estimateSize(), end - start);
 282         }
 283     }
 284 
 285     public void testLongLongRangeClosed() {
 286         // Test [Long.MIN_VALUE, Long.MAX_VALUE]
 287         // This will concatenate streams of four ranges
 288         //   [Long.MIN_VALUE, x) [x, 0) [0, y) [y, Long.MAX_VALUE]
 289         // where x = Long.divideUnsigned(0 - Long.MIN_VALUE, 2) + 1
 290         //       y = Long.divideUnsigned(Long.MAX_VALUE, 2) + 1
 291 
 292         {
 293             Spliterator.OfLong s = LongStream.rangeClosed(Long.MIN_VALUE, Long.MAX_VALUE).spliterator();
 294 
 295             assertEquals(s.estimateSize(), Long.MAX_VALUE);
 296             assertNotSizedAndSubSized(s);
 297 
 298             Spliterator.OfLong s1 = s.trySplit();
 299             assertNotSizedAndSubSized(s1);
 300             assertNotSizedAndSubSized(s);
 301 
 302             Spliterator.OfLong s2 = s1.trySplit();
 303             assertSizedAndSubSized(s1);
 304             assertSizedAndSubSized(s2);
 305 
 306             Spliterator.OfLong s3 = s.trySplit();
 307             assertSizedAndSubSized(s3);
 308             assertSizedAndSubSized(s);
 309 
 310             assertTrue(s.estimateSize() < Long.MAX_VALUE);
 311             assertTrue(s3.estimateSize() < Long.MAX_VALUE);
 312             assertTrue(s1.estimateSize() < Long.MAX_VALUE);
 313             assertTrue(s2.estimateSize() < Long.MAX_VALUE);
 314 
 315             assertEquals(s.estimateSize() + s3.estimateSize() + s1.estimateSize() + s2.estimateSize(),
 316                          Long.MAX_VALUE - Long.MIN_VALUE + 1);
 317         }
 318 
 319         long[][] ranges = { {Long.MIN_VALUE, 0}, {-1, Long.MAX_VALUE} };
 320         for (int i = 0; i < ranges.length; i++) {
 321             long start = ranges[i][0];
 322             long end = ranges[i][1];
 323 
 324             Spliterator.OfLong s = LongStream.rangeClosed(start, end).spliterator();
 325 
 326             assertEquals(s.estimateSize(), Long.MAX_VALUE);
 327             assertNotSizedAndSubSized(s);
 328 
 329             Spliterator.OfLong s1 = s.trySplit();
 330             assertSizedAndSubSized(s1);
 331             assertSizedAndSubSized(s);
 332 
 333             assertTrue(s.estimateSize() < Long.MAX_VALUE);
 334             assertTrue(s1.estimateSize() < Long.MAX_VALUE);
 335 
 336             assertEquals(s.estimateSize() + s1.estimateSize(), end - start + 1);
 337         }
 338     }
 339 }