/* * Copyright (c) 2013, 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 java.util.stream; import org.testng.annotations.Test; import java.util.Arrays; import java.util.List; import java.util.function.BiConsumer; import java.util.function.Function; import java.util.function.UnaryOperator; @Test public class UnorderedTest extends OpTestCase { @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class) public void testTerminalOps(String name, TestData<Integer, Stream<Integer>> data) { testTerminal(data, s -> { s.forEach(x -> { }); return 0; }); testTerminal(data, s -> s.findAny(), (a, b) -> assertEquals(a.isPresent(), b.isPresent())); testTerminal(data, s -> s.anyMatch(e -> true)); } private <T, R> void testTerminal(TestData<T, Stream<T>> data, Function<Stream<T>, R> terminalF) { testTerminal(data, terminalF, LambdaTestHelpers::assertContentsEqual); } static class WrappingUnaryOperator<S> implements UnaryOperator<S> { final boolean isLimit; final UnaryOperator<S> uo; WrappingUnaryOperator(UnaryOperator<S> uo) { this(uo, false); } WrappingUnaryOperator(UnaryOperator<S> uo, boolean isLimit) { this.uo = uo; this.isLimit = isLimit; } @Override public S apply(S s) { return uo.apply(s); } } static <S> WrappingUnaryOperator<S> wrap(UnaryOperator<S> uo) { return new WrappingUnaryOperator<>(uo); } static <S> WrappingUnaryOperator<S> wrap(UnaryOperator<S> uo, boolean isLimit) { return new WrappingUnaryOperator<>(uo, isLimit); } @SuppressWarnings("rawtypes") private List permutationOfFunctions = LambdaTestHelpers.perm(Arrays.<WrappingUnaryOperator<Stream<Object>>>asList( wrap(s -> s.sorted()), wrap(s -> s.distinct()), wrap(s -> s.limit(5), true) )); @SuppressWarnings("unchecked") private <T, R> void testTerminal(TestData<T, Stream<T>> data, Function<Stream<T>, R> terminalF, BiConsumer<R, R> equalityAsserter) { testTerminal(data, terminalF, equalityAsserter, permutationOfFunctions, StreamShape.REFERENCE); } // @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class) public void testIntTerminalOps(String name, TestData.OfInt data) { testIntTerminal(data, s -> { s.forEach(x -> { }); return 0; }); testIntTerminal(data, s -> s.findAny(), (a, b) -> assertEquals(a.isPresent(), b.isPresent())); testIntTerminal(data, s -> s.anyMatch(e -> true)); } private <T, R> void testIntTerminal(TestData.OfInt data, Function<IntStream, R> terminalF) { testIntTerminal(data, terminalF, LambdaTestHelpers::assertContentsEqual); } private List<List<WrappingUnaryOperator<IntStream>>> intPermutationOfFunctions = LambdaTestHelpers.perm(Arrays.asList( wrap(s -> s.sorted()), wrap(s -> s.distinct()), wrap(s -> s.limit(5), true) )); private <R> void testIntTerminal(TestData.OfInt data, Function<IntStream, R> terminalF, BiConsumer<R, R> equalityAsserter) { testTerminal(data, terminalF, equalityAsserter, intPermutationOfFunctions, StreamShape.INT_VALUE); } // @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class) public void testLongTerminalOps(String name, TestData.OfLong data) { testLongTerminal(data, s -> { s.forEach(x -> { }); return 0; }); testLongTerminal(data, s -> s.findAny(), (a, b) -> assertEquals(a.isPresent(), b.isPresent())); testLongTerminal(data, s -> s.anyMatch(e -> true)); } private <T, R> void testLongTerminal(TestData.OfLong data, Function<LongStream, R> terminalF) { testLongTerminal(data, terminalF, LambdaTestHelpers::assertContentsEqual); } private List<List<WrappingUnaryOperator<LongStream>>> longPermutationOfFunctions = LambdaTestHelpers.perm(Arrays.asList( wrap(s -> s.sorted()), wrap(s -> s.distinct()), wrap(s -> s.limit(5), true) )); private <R> void testLongTerminal(TestData.OfLong data, Function<LongStream, R> terminalF, BiConsumer<R, R> equalityAsserter) { testTerminal(data, terminalF, equalityAsserter, longPermutationOfFunctions, StreamShape.LONG_VALUE); } // @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class) public void testDoubleTerminalOps(String name, TestData.OfDouble data) { testDoubleTerminal(data, s -> { s.forEach(x -> { }); return 0; }); testDoubleTerminal(data, s -> s.findAny(), (a, b) -> assertEquals(a.isPresent(), b.isPresent())); testDoubleTerminal(data, s -> s.anyMatch(e -> true)); } private <T, R> void testDoubleTerminal(TestData.OfDouble data, Function<DoubleStream, R> terminalF) { testDoubleTerminal(data, terminalF, LambdaTestHelpers::assertContentsEqual); } private List<List<WrappingUnaryOperator<DoubleStream>>> doublePermutationOfFunctions = LambdaTestHelpers.perm(Arrays.asList( wrap(s -> s.sorted()), wrap(s -> s.distinct()), wrap(s -> s.limit(5), true) )); private <R> void testDoubleTerminal(TestData.OfDouble data, Function<DoubleStream, R> terminalF, BiConsumer<R, R> equalityAsserter) { testTerminal(data, terminalF, equalityAsserter, doublePermutationOfFunctions, StreamShape.DOUBLE_VALUE); } // private <T, S extends BaseStream<T, S>, R> void testTerminal(TestData<T, S> data, Function<S, R> terminalF, BiConsumer<R, R> equalityAsserter, List<List<WrappingUnaryOperator<S>>> pFunctions, StreamShape shape) { CheckClearOrderedOp<T> checkClearOrderedOp = new CheckClearOrderedOp<>(shape); for (List<WrappingUnaryOperator<S>> f : pFunctions) { @SuppressWarnings("unchecked") UnaryOperator<S> fi = interpose(f, (S s) -> (S) chain(s, checkClearOrderedOp)); withData(data). terminal(fi, terminalF). equalator(equalityAsserter). exercise(); } CheckSetOrderedOp<T> checkSetOrderedOp = new CheckSetOrderedOp<>(shape); for (List<WrappingUnaryOperator<S>> f : pFunctions) { @SuppressWarnings("unchecked") UnaryOperator<S> fi = interpose(f, (S s) -> (S) chain(s, checkSetOrderedOp)); withData(data). terminal(fi, s -> terminalF.apply(s.sequential())). equalator(equalityAsserter). exercise(); } } static class CheckClearOrderedOp<T> implements StatelessTestOp<T, T> { private final StreamShape shape; CheckClearOrderedOp(StreamShape shape) { this.shape = shape; } @Override public StreamShape outputShape() { return shape; } @Override public StreamShape inputShape() { return shape; } @Override public Sink<T> opWrapSink(int flags, boolean parallel, Sink<T> sink) { if (parallel) { assertTrue(StreamOpFlag.ORDERED.isCleared(flags)); } return sink; } } static class CheckSetOrderedOp<T> extends CheckClearOrderedOp<T> { CheckSetOrderedOp(StreamShape shape) { super(shape); } @Override public Sink<T> opWrapSink(int flags, boolean parallel, Sink<T> sink) { assertTrue(StreamOpFlag.ORDERED.isKnown(flags) || StreamOpFlag.ORDERED.isPreserved(flags)); return sink; } } private <T, S extends BaseStream<T, S>> UnaryOperator<S> interpose(List<WrappingUnaryOperator<S>> fs, UnaryOperator<S> fi) { int l = -1; for (int i = 0; i < fs.size(); i++) { if (fs.get(i).isLimit) { l = i; } } final int lastLimitIndex = l; return s -> { if (lastLimitIndex == -1) s = fi.apply(s); for (int i = 0; i < fs.size(); i++) { s = fs.get(i).apply(s); if (i >= lastLimitIndex) { s = fi.apply(s); } } return s; }; } }