| /* |
| * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| package org.openjdk.tests.java.util.stream; |
| |
| import org.testng.annotations.DataProvider; |
| import org.testng.annotations.Test; |
| |
| import java.lang.reflect.InvocationHandler; |
| import java.lang.reflect.Method; |
| import java.lang.reflect.Proxy; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Spliterator; |
| import java.util.function.Function; |
| import java.util.function.UnaryOperator; |
| import java.util.stream.DoubleStream; |
| import java.util.stream.DoubleStreamTestScenario; |
| import java.util.stream.IntStream; |
| import java.util.stream.IntStreamTestScenario; |
| import java.util.stream.LambdaTestHelpers; |
| import java.util.stream.LongStream; |
| import java.util.stream.LongStreamTestScenario; |
| import java.util.stream.OpTestCase; |
| import java.util.stream.Stream; |
| import java.util.stream.StreamSupport; |
| import java.util.stream.StreamTestScenario; |
| import java.util.stream.TestData; |
| |
| import static java.util.stream.LambdaTestHelpers.assertUnique; |
| |
| |
| @Test |
| public class InfiniteStreamWithLimitOpTest extends OpTestCase { |
| |
| private static final long SKIP_LIMIT_SIZE = 1 << 16; |
| |
| @DataProvider(name = "Stream.limit") |
| @SuppressWarnings("rawtypes") |
| public static Object[][] sliceFunctionsDataProvider() { |
| Function<String, String> f = s -> String.format(s, SKIP_LIMIT_SIZE); |
| |
| List<Object[]> data = new ArrayList<>(); |
| |
| data.add(new Object[]{f.apply("Stream.limit(%d)"), |
| (UnaryOperator<Stream>) s -> s.limit(SKIP_LIMIT_SIZE)}); |
| data.add(new Object[]{f.apply("Stream.skip(%1$d).limit(%1$d)"), |
| (UnaryOperator<Stream>) s -> s.skip(SKIP_LIMIT_SIZE).limit(SKIP_LIMIT_SIZE)}); |
| |
| return data.toArray(new Object[0][]); |
| } |
| |
| @DataProvider(name = "IntStream.limit") |
| public static Object[][] intSliceFunctionsDataProvider() { |
| Function<String, String> f = s -> String.format(s, SKIP_LIMIT_SIZE); |
| |
| List<Object[]> data = new ArrayList<>(); |
| |
| data.add(new Object[]{f.apply("IntStream.limit(%d)"), |
| (UnaryOperator<IntStream>) s -> s.limit(SKIP_LIMIT_SIZE)}); |
| data.add(new Object[]{f.apply("IntStream.skip(%1$d).limit(%1$d)"), |
| (UnaryOperator<IntStream>) s -> s.skip(SKIP_LIMIT_SIZE).limit(SKIP_LIMIT_SIZE)}); |
| |
| return data.toArray(new Object[0][]); |
| } |
| |
| @DataProvider(name = "LongStream.limit") |
| public static Object[][] longSliceFunctionsDataProvider() { |
| Function<String, String> f = s -> String.format(s, SKIP_LIMIT_SIZE); |
| |
| List<Object[]> data = new ArrayList<>(); |
| |
| data.add(new Object[]{f.apply("LongStream.limit(%d)"), |
| (UnaryOperator<LongStream>) s -> s.limit(SKIP_LIMIT_SIZE)}); |
| data.add(new Object[]{f.apply("LongStream.skip(%1$d).limit(%1$d)"), |
| (UnaryOperator<LongStream>) s -> s.skip(SKIP_LIMIT_SIZE).limit(SKIP_LIMIT_SIZE)}); |
| |
| return data.toArray(new Object[0][]); |
| } |
| |
| @DataProvider(name = "DoubleStream.limit") |
| public static Object[][] doubleSliceFunctionsDataProvider() { |
| Function<String, String> f = s -> String.format(s, SKIP_LIMIT_SIZE); |
| |
| List<Object[]> data = new ArrayList<>(); |
| |
| data.add(new Object[]{f.apply("DoubleStream.limit(%d)"), |
| (UnaryOperator<DoubleStream>) s -> s.limit(SKIP_LIMIT_SIZE)}); |
| data.add(new Object[]{f.apply("DoubleStream.skip(%1$d).limit(%1$d)"), |
| (UnaryOperator<DoubleStream>) s -> s.skip(SKIP_LIMIT_SIZE).limit(SKIP_LIMIT_SIZE)}); |
| |
| return data.toArray(new Object[0][]); |
| } |
| |
| private <T> ResultAsserter<Iterable<T>> unorderedAsserter() { |
| return (act, exp, ord, par) -> { |
| if (par & !ord) { |
| // Can only assert that all elements of the actual result |
| // are distinct and that the count is the limit size |
| // any element within the range [0, Long.MAX_VALUE) may be |
| // present |
| assertUnique(act); |
| long count = 0; |
| for (T l : act) { |
| count++; |
| } |
| assertEquals(count, SKIP_LIMIT_SIZE, "size not equal"); |
| } |
| else { |
| LambdaTestHelpers.assertContents(act, exp); |
| } |
| }; |
| } |
| |
| private TestData.OfRef<Long> refLongs() { |
| return refLongRange(0, Long.MAX_VALUE); |
| } |
| |
| private TestData.OfRef<Long> refLongRange(long l, long u) { |
| return TestData.Factory.ofSupplier( |
| String.format("[%d, %d)", l, u), |
| () -> LongStream.range(l, u).boxed()); |
| } |
| |
| private TestData.OfInt ints() { |
| return intRange(0, Integer.MAX_VALUE); |
| } |
| |
| private TestData.OfInt intRange(int l, int u) { |
| return TestData.Factory.ofIntSupplier( |
| String.format("[%d, %d)", l, u), |
| () -> IntStream.range(l, u)); |
| } |
| |
| private TestData.OfLong longs() { |
| return longRange(0, Long.MAX_VALUE); |
| } |
| |
| private TestData.OfLong longRange(long l, long u) { |
| return TestData.Factory.ofLongSupplier( |
| String.format("[%d, %d)", l, u), |
| () -> LongStream.range(l, u)); |
| } |
| |
| private TestData.OfDouble doubles() { |
| return doubleRange(0, 1L << 53); |
| } |
| |
| private TestData.OfDouble doubleRange(long l, long u) { |
| return TestData.Factory.ofDoubleSupplier( |
| String.format("[%d, %d)", l, u), |
| () -> LongStream.range(l, u).mapToDouble(i -> (double) i)); |
| } |
| |
| |
| // Sized/subsized range |
| |
| @Test(dataProvider = "Stream.limit") |
| public void testSubsizedWithRange(String description, UnaryOperator<Stream<Long>> fs) { |
| // Range is [0, Long.MAX_VALUE), splits are SUBSIZED |
| // Such a size will induce out of memory errors for incorrect |
| // slice implementations |
| withData(refLongs()). |
| stream(s -> fs.apply(s)). |
| without(StreamTestScenario.CLEAR_SIZED_SCENARIOS). |
| exercise(); |
| } |
| |
| @Test(dataProvider = "IntStream.limit") |
| public void testIntSubsizedWithRange(String description, UnaryOperator<IntStream> fs) { |
| // Range is [0, Integer.MAX_VALUE), splits are SUBSIZED |
| // Such a size will induce out of memory errors for incorrect |
| // slice implementations |
| withData(ints()). |
| stream(s -> fs.apply(s)). |
| without(IntStreamTestScenario.CLEAR_SIZED_SCENARIOS). |
| exercise(); |
| } |
| |
| @Test(dataProvider = "LongStream.limit") |
| public void testLongSubsizedWithRange(String description, UnaryOperator<LongStream> fs) { |
| // Range is [0, Long.MAX_VALUE), splits are SUBSIZED |
| // Such a size will induce out of memory errors for incorrect |
| // slice implementations |
| withData(longs()). |
| stream(s -> fs.apply(s)). |
| without(LongStreamTestScenario.CLEAR_SIZED_SCENARIOS). |
| exercise(); |
| } |
| |
| @Test(dataProvider = "DoubleStream.limit") |
| public void testDoubleSubsizedWithRange(String description, UnaryOperator<DoubleStream> fs) { |
| // Range is [0, 2^53), splits are SUBSIZED |
| // Such a size will induce out of memory errors for incorrect |
| // slice implementations |
| withData(doubles()). |
| stream(s -> fs.apply(s)). |
| without(DoubleStreamTestScenario.CLEAR_SIZED_SCENARIOS). |
| exercise(); |
| } |
| |
| |
| // Unordered finite not SIZED/SUBSIZED |
| |
| @Test(dataProvider = "Stream.limit") |
| public void testUnorderedFinite(String description, UnaryOperator<Stream<Long>> fs) { |
| // Range is [0, Long.MAX_VALUE), splits are SUBSIZED |
| // Such a size will induce out of memory errors for incorrect |
| // slice implementations |
| withData(longs()). |
| stream(s -> fs.apply(s.filter(i -> true).unordered().boxed())). |
| resultAsserter(unorderedAsserter()). |
| exercise(); |
| } |
| |
| @Test(dataProvider = "IntStream.limit") |
| public void testIntUnorderedFinite(String description, UnaryOperator<IntStream> fs) { |
| // Range is [0, Integer.MAX_VALUE), splits are SUBSIZED |
| // Such a size will induce out of memory errors for incorrect |
| // slice implementations |
| withData(ints()). |
| stream(s -> fs.apply(s.filter(i -> true).unordered())). |
| resultAsserter(unorderedAsserter()). |
| exercise(); |
| } |
| |
| @Test(dataProvider = "LongStream.limit") |
| public void testLongUnorderedFinite(String description, UnaryOperator<LongStream> fs) { |
| // Range is [0, Long.MAX_VALUE), splits are SUBSIZED |
| // Such a size will induce out of memory errors for incorrect |
| // slice implementations |
| withData(longs()). |
| stream(s -> fs.apply(s.filter(i -> true).unordered())). |
| resultAsserter(unorderedAsserter()). |
| exercise(); |
| } |
| |
| @Test(dataProvider = "DoubleStream.limit") |
| public void testDoubleUnorderedFinite(String description, UnaryOperator<DoubleStream> fs) { |
| // Range is [0, 1L << 53), splits are SUBSIZED |
| // Such a size will induce out of memory errors for incorrect |
| // slice implementations |
| // Upper bound ensures values mapped to doubles will be unique |
| withData(doubles()). |
| stream(s -> fs.apply(s.filter(i -> true).unordered())). |
| resultAsserter(unorderedAsserter()). |
| exercise(); |
| } |
| |
| |
| // Unordered finite not SUBSIZED |
| |
| @SuppressWarnings({"rawtypes", "unchecked"}) |
| private Spliterator.OfLong proxyNotSubsized(Spliterator.OfLong s) { |
| InvocationHandler ih = new InvocationHandler() { |
| @Override |
| public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { |
| switch (method.getName()) { |
| case "characteristics": { |
| int c = (Integer) method.invoke(s, args); |
| return c & ~Spliterator.SUBSIZED; |
| } |
| case "hasCharacteristics": { |
| int c = (Integer) args[0]; |
| boolean b = (Boolean) method.invoke(s, args); |
| return b & ((c & Spliterator.SUBSIZED) == 0); |
| } |
| default: |
| return method.invoke(s, args); |
| } |
| } |
| }; |
| |
| return (Spliterator.OfLong) Proxy.newProxyInstance(this.getClass().getClassLoader(), |
| new Class[]{Spliterator.OfLong.class}, |
| ih); |
| } |
| |
| private TestData.OfLong proxiedLongRange(long l, long u) { |
| return TestData.Factory.ofLongSupplier( |
| String.format("[%d, %d)", l, u), |
| () -> StreamSupport.longStream(proxyNotSubsized(LongStream.range(l, u).spliterator()), false)); |
| } |
| |
| @Test(dataProvider = "Stream.limit") |
| public void testUnorderedSizedNotSubsizedFinite(String description, UnaryOperator<Stream<Long>> fs) { |
| // Range is [0, Long.MAX_VALUE), splits are not SUBSIZED (proxy clears |
| // the SUBSIZED characteristic) |
| // Such a size will induce out of memory errors for incorrect |
| // slice implementations |
| withData(proxiedLongRange(0, Long.MAX_VALUE)). |
| stream(s -> fs.apply(s.unordered().boxed())). |
| resultAsserter(unorderedAsserter()). |
| exercise(); |
| } |
| |
| @Test(dataProvider = "IntStream.limit") |
| public void testIntUnorderedSizedNotSubsizedFinite(String description, UnaryOperator<IntStream> fs) { |
| // Range is [0, Integer.MAX_VALUE), splits are not SUBSIZED (proxy clears |
| // the SUBSIZED characteristic) |
| // Such a size will induce out of memory errors for incorrect |
| // slice implementations |
| withData(proxiedLongRange(0, Integer.MAX_VALUE)). |
| stream(s -> fs.apply(s.unordered().mapToInt(i -> (int) i))). |
| resultAsserter(unorderedAsserter()). |
| exercise(); |
| } |
| |
| @Test(dataProvider = "LongStream.limit") |
| public void testLongUnorderedSizedNotSubsizedFinite(String description, UnaryOperator<LongStream> fs) { |
| // Range is [0, Long.MAX_VALUE), splits are not SUBSIZED (proxy clears |
| // the SUBSIZED characteristic) |
| // Such a size will induce out of memory errors for incorrect |
| // slice implementations |
| withData(proxiedLongRange(0, Long.MAX_VALUE)). |
| stream(s -> fs.apply(s.unordered())). |
| resultAsserter(unorderedAsserter()). |
| exercise(); |
| } |
| |
| @Test(dataProvider = "DoubleStream.limit") |
| public void testDoubleUnorderedSizedNotSubsizedFinite(String description, UnaryOperator<DoubleStream> fs) { |
| // Range is [0, Double.MAX_VALUE), splits are not SUBSIZED (proxy clears |
| // the SUBSIZED characteristic) |
| // Such a size will induce out of memory errors for incorrect |
| // slice implementations |
| withData(proxiedLongRange(0, 1L << 53)). |
| stream(s -> fs.apply(s.unordered().mapToDouble(i -> (double) i))). |
| resultAsserter(unorderedAsserter()). |
| exercise(); |
| } |
| |
| |
| // Unordered generation |
| |
| @Test(dataProvider = "Stream.limit") |
| public void testUnorderedGenerator(String description, UnaryOperator<Stream<Long>> fs) { |
| // Source is spliterator of infinite size |
| TestData.OfRef<Long> generator = TestData.Factory.ofSupplier( |
| "[1L, 1L, ...]", () -> Stream.generate(() -> 1L)); |
| |
| withData(generator). |
| stream(s -> fs.apply(s.filter(i -> true).unordered())). |
| exercise(); |
| } |
| |
| @Test(dataProvider = "IntStream.limit") |
| public void testIntUnorderedGenerator(String description, UnaryOperator<IntStream> fs) { |
| // Source is spliterator of infinite size |
| TestData.OfInt generator = TestData.Factory.ofIntSupplier( |
| "[1, 1, ...]", () -> IntStream.generate(() -> 1)); |
| |
| withData(generator). |
| stream(s -> fs.apply(s.filter(i -> true).unordered())). |
| exercise(); |
| } |
| |
| @Test(dataProvider = "LongStream.limit") |
| public void testLongUnorderedGenerator(String description, UnaryOperator<LongStream> fs) { |
| // Source is spliterator of infinite size |
| TestData.OfLong generator = TestData.Factory.ofLongSupplier( |
| "[1L, 1L, ...]", () -> LongStream.generate(() -> 1)); |
| |
| withData(generator). |
| stream(s -> fs.apply(s.filter(i -> true).unordered())). |
| exercise(); |
| } |
| |
| @Test(dataProvider = "DoubleStream.limit") |
| public void testDoubleUnorderedGenerator(String description, UnaryOperator<DoubleStream> fs) { |
| // Source is spliterator of infinite size |
| TestData.OfDouble generator = TestData.Factory.ofDoubleSupplier( |
| "[1.0, 1.0, ...]", () -> DoubleStream.generate(() -> 1.0)); |
| |
| withData(generator). |
| stream(s -> fs.apply(s.filter(i -> true).unordered())). |
| exercise(); |
| } |
| |
| |
| // Unordered iteration |
| |
| @Test(dataProvider = "Stream.limit") |
| public void testUnorderedIteration(String description, UnaryOperator<Stream<Long>> fs) { |
| // Source is a right-balanced tree of infinite size |
| TestData.OfRef<Long> iterator = TestData.Factory.ofSupplier( |
| "[1L, 2L, 3L, ...]", () -> Stream.iterate(1L, i -> i + 1L)); |
| |
| // Ref |
| withData(iterator). |
| stream(s -> fs.apply(s.unordered())). |
| resultAsserter(unorderedAsserter()). |
| exercise(); |
| } |
| |
| @Test(dataProvider = "IntStream.limit") |
| public void testIntUnorderedIteration(String description, UnaryOperator<IntStream> fs) { |
| // Source is a right-balanced tree of infinite size |
| TestData.OfInt iterator = TestData.Factory.ofIntSupplier( |
| "[1, 2, 3, ...]", () -> IntStream.iterate(1, i -> i + 1)); |
| |
| // Ref |
| withData(iterator). |
| stream(s -> fs.apply(s.unordered())). |
| resultAsserter(unorderedAsserter()). |
| exercise(); |
| } |
| |
| @Test(dataProvider = "LongStream.limit") |
| public void testLongUnorderedIteration(String description, UnaryOperator<LongStream> fs) { |
| // Source is a right-balanced tree of infinite size |
| TestData.OfLong iterator = TestData.Factory.ofLongSupplier( |
| "[1L, 2L, 3L, ...]", () -> LongStream.iterate(1, i -> i + 1)); |
| |
| // Ref |
| withData(iterator). |
| stream(s -> fs.apply(s.unordered())). |
| resultAsserter(unorderedAsserter()). |
| exercise(); |
| } |
| |
| @Test(dataProvider = "DoubleStream.limit") |
| public void testDoubleUnorderedIteration(String description, UnaryOperator<DoubleStream> fs) { |
| // Source is a right-balanced tree of infinite size |
| TestData.OfDouble iterator = TestData.Factory.ofDoubleSupplier( |
| "[1.0, 2.0, 3.0, ...]", () -> DoubleStream.iterate(1, i -> i + 1)); |
| |
| // Ref |
| withData(iterator). |
| stream(s -> fs.apply(s.unordered())). |
| resultAsserter(unorderedAsserter()). |
| exercise(); |
| } |
| } |