/* * Copyright 2016 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.google.gwt.emultest.java8.util.stream; import com.google.gwt.emultest.java.util.EmulTestBase; import java.util.ArrayList; import java.util.Arrays; import java.util.DoubleSummaryStatistics; import java.util.Iterator; import java.util.List; import java.util.OptionalDouble; import java.util.Spliterator; import java.util.function.DoubleSupplier; import java.util.function.Supplier; import java.util.stream.DoubleStream; import java.util.stream.Stream; /** * Tests {@link DoubleStream}. */ public class DoubleStreamTest extends EmulTestBase { public void testEmptyStream() { DoubleStream empty = DoubleStream.empty(); assertEquals(0, empty.count()); try { empty.count(); fail("second terminal operation should have thrown IllegalStateEx"); } catch (IllegalStateException expected) { // expected } assertEquals(0, DoubleStream.empty().limit(2).toArray().length); assertEquals(0L, DoubleStream.empty().count()); assertEquals(0L, DoubleStream.empty().limit(2).count()); assertFalse(DoubleStream.empty().findFirst().isPresent()); assertFalse(DoubleStream.empty().findAny().isPresent()); assertFalse(DoubleStream.empty().max().isPresent()); assertFalse(DoubleStream.empty().min().isPresent()); assertTrue(DoubleStream.empty().noneMatch(item -> true)); assertTrue(DoubleStream.empty().allMatch(item -> true)); assertFalse(DoubleStream.empty().anyMatch(item -> true)); assertEquals(new double[0], DoubleStream.empty().toArray()); } public void testStreamOfOne() { Supplier<DoubleStream> one = () -> DoubleStream.of(1); assertEquals(new double[] {1d}, one.get().toArray()); assertEquals(1L, one.get().count()); assertEquals(1d, one.get().findFirst().getAsDouble(), 0d); assertEquals(1d, one.get().findAny().getAsDouble(), 0d); } public void testBuilder() { DoubleStream s = DoubleStream.builder().add(1d).add(3d).add(2d).build(); assertEquals(new double[] {1d, 3d, 2d}, s.toArray()); DoubleStream.Builder builder = DoubleStream.builder(); DoubleStream built = builder.build(); assertEquals(0, built.count()); try { builder.build(); fail("build() after build() should fail"); } catch (IllegalStateException expected) { // expected } try { builder.add(10d); fail("add() after build() should fail"); } catch (IllegalStateException expected) { // expected } } public void testConcat() { Supplier<DoubleStream> adbc = () -> { return DoubleStream.concat(DoubleStream.of(1, 4), DoubleStream.of(2, 3)); }; assertEquals(new double[] {1d, 4d, 2d, 3d}, adbc.get().toArray()); assertEquals(new double[] {1d, 2d, 3d, 4d}, adbc.get().sorted().toArray()); List<String> closed = new ArrayList<>(); DoubleStream first = DoubleStream.of(1d).onClose(() -> closed.add("first")); DoubleStream second = DoubleStream.of(2d).onClose(() -> closed.add("second")); DoubleStream concat = DoubleStream.concat(first, second); // read everything, make sure we saw it all and didn't close automatically double collectedAll = concat.sum(); assertEquals(3d, collectedAll); assertEquals(0, closed.size()); concat.close(); assertEquals(Arrays.asList("first", "second"), closed); } public void testIterate() { assertEquals( new double[] {10d, 11d, 12d, 13d, 14d}, DoubleStream.iterate(0d, l -> l + 1d).skip(10).limit(5).toArray()); } public void testGenerate() { // infinite, but if you limit it is already too short to skip much assertEquals(new double[0], DoubleStream.generate(makeGenerator()).limit(4).skip(5).toArray()); assertEquals( new double[] {10d, 11d, 12d, 13d, 14d}, DoubleStream.generate(makeGenerator()).skip(10).limit(5).toArray()); } private DoubleSupplier makeGenerator() { return new DoubleSupplier() { double next = 0d; @Override public double getAsDouble() { return next++; } }; } public void testToArray() { assertEquals(new double[0], DoubleStream.of().toArray()); assertEquals(new double[] {1d}, DoubleStream.of(1d).toArray()); assertEquals(new double[] {3d, 2d, 0d}, DoubleStream.of(3d, 2d, 0d).toArray()); } public void testReduce() { double reduced = DoubleStream.of(1d, 2d, 4d).reduce(0, Double::sum); assertEquals(7d, reduced, 0d); reduced = DoubleStream.of().reduce(0, Double::sum); assertEquals(0d, reduced, 0d); OptionalDouble maybe = DoubleStream.of(1d, 4d, 8d).reduce(Double::sum); assertTrue(maybe.isPresent()); assertEquals(13, maybe.getAsDouble(), 0d); maybe = DoubleStream.of().reduce(Double::sum); assertFalse(maybe.isPresent()); } public void testFilter() { // unconsumed stream never runs filter boolean[] data = {false}; DoubleStream.of(1d, 2d, 3d).filter(i -> data[0] |= true); assertFalse(data[0]); // one result assertEquals( new double[] {1d}, DoubleStream.of(1d, 2d, 3d, 4d, 3d).filter(a -> a == 1).toArray()); // zero results assertEquals(new double[0], DoubleStream.of(1d, 2d, 3d, 4d, 3d).filter(a -> false).toArray()); // two results assertEquals( new double[] {2d, 4d}, DoubleStream.of(1d, 2d, 3d, 4d, 3d).filter(a -> a % 2 == 0).toArray()); // all assertEquals( new double[] {1d, 2d, 3d, 4d, 3d}, DoubleStream.of(1d, 2d, 3d, 4d, 3d).filter(a -> true).toArray()); } public void testMap() { // unconsumed stream never runs map int[] data = {0}; DoubleStream.of(1d, 2d, 3d).map(i -> data[0]++); assertEquals(0, data[0]); assertEquals(new double[] {2d, 4d, 6d}, DoubleStream.of(1d, 2d, 3d).map(i -> i * 2).toArray()); } public void testPeek() { // unconsumed stream never peeks boolean[] data = {false}; DoubleStream.of(1d, 2d, 3d).peek(i -> data[0] |= true); assertFalse(data[0]); // make sure we saw it all in order double[] items = new double[] {1d, 2d, 3d}; List<Double> peeked = new ArrayList<>(); DoubleStream.of(items) .peek(peeked::add) .forEach( item -> { // do nothing, just run }); assertEquals(items.length, peeked.size()); for (int i = 0; i < items.length; i++) { assertEquals(items[i], peeked.get(i), 0d); } } // same impl, no parallel in browser public void testFindFirstOrAny() { OptionalDouble any = DoubleStream.of(1d, 2d).findAny(); assertTrue(any.isPresent()); assertEquals(1d, any.getAsDouble(), 0d); } public void testAnyMatch() { // all assertTrue(DoubleStream.of(1d, 2d).anyMatch(s -> true)); // some assertTrue(DoubleStream.of(1d, 2d).anyMatch(s -> s == 1d)); // none assertFalse(DoubleStream.of(1d, 2d).anyMatch(s -> false)); } public void testAllMatch() { // all assertTrue(DoubleStream.of(1d, 2d).allMatch(s -> true)); // some assertFalse(DoubleStream.of(1d, 2d).allMatch(s -> s == 1d)); // none assertFalse(DoubleStream.of(1d, 2d).allMatch(s -> false)); } public void testNoneMatch() { // all assertFalse(DoubleStream.of(1d, 2d).noneMatch(s -> true)); // some assertFalse(DoubleStream.of(1d, 2d).noneMatch(s -> s == 1d)); // none assertTrue(DoubleStream.of(1d, 2d).noneMatch(s -> false)); } public void testFlatMap() { assertEquals(0L, DoubleStream.empty().flatMap(value -> DoubleStream.of(1d)).count()); assertEquals(0L, DoubleStream.of(1d).flatMap(value -> DoubleStream.empty()).count()); assertEquals(0L, DoubleStream.of(1d).flatMap(value -> DoubleStream.of()).count()); assertEquals(0L, DoubleStream.of().flatMap(value -> DoubleStream.of(1d)).count()); assertEquals(1L, DoubleStream.of(1d).flatMap(value -> DoubleStream.of(1d)).count()); DoubleStream values = DoubleStream.of(1d, 2d, 3d); assertEquals( new double[] {1d, 2d, 2d, 4d, 3d, 6d}, values.flatMap(i -> DoubleStream.of(i, i * 2d)).toArray()); } public void testMapToOthers() { Supplier<DoubleStream> s = () -> DoubleStream.of(1d, 2d, 10d); assertEquals( new String[] {"1", "2", "10"}, s.get().mapToObj(DoubleStreamTest::toIntegralString).toArray(String[]::new)); assertEquals(new long[] {1L, 2L, 10L}, s.get().mapToLong(i -> (long) i).toArray()); assertEquals(new int[] {1, 2, 10}, s.get().mapToInt(i -> (int) i).toArray()); } public void testDistinct() { double[] distinct = DoubleStream.of(1d, 2d, 3d, 2d).distinct().toArray(); assertEquals(3, distinct.length); assertEquals(1d + 2d + 3d, distinct[0] + distinct[1] + distinct[2], 0d); } public void testSorted() { double[] sorted = DoubleStream.of(3d, 1d, 2d).sorted().toArray(); assertEquals(new double[] {1d, 2d, 3d}, sorted); } public void testMinMax() { Supplier<DoubleStream> stream = () -> DoubleStream.of(2d, 3d, 4d, 1d); assertEquals(1d, stream.get().min().orElse(0), 0d); assertEquals(4d, stream.get().max().orElse(0), 0d); assertFalse(stream.get().filter(a -> false).max().isPresent()); assertFalse(stream.get().filter(a -> false).min().isPresent()); } public void testCountLimitSkip() { Supplier<DoubleStream> stream = () -> DoubleStream.of(1d, 2d, 3d, 4d); assertEquals(4L, stream.get().count()); assertEquals(4L, stream.get().limit(4).count()); assertEquals(4L, stream.get().limit(5).count()); assertEquals(3L, stream.get().limit(3).count()); assertEquals(3L, stream.get().skip(1).limit(3).count()); assertEquals(2L, stream.get().limit(3).skip(1).count()); assertEquals(1L, stream.get().skip(3).count()); assertEquals(new double[] {3d, 4d}, stream.get().skip(2).limit(3).toArray()); assertEquals(new double[] {3d}, stream.get().skip(2).limit(1).toArray()); assertEquals(new double[] {4d}, stream.get().skip(3).toArray()); assertEquals(new double[] {}, stream.get().skip(5).toArray()); assertEquals(new double[] {1d, 2d}, stream.get().limit(2).toArray()); assertEquals(new double[] {2d}, stream.get().limit(2).skip(1).toArray()); } public void testBoxed() { Supplier<DoubleStream> stream = () -> DoubleStream.of(1d, 2d); Stream<Double> expected = stream.get().mapToObj(Double::valueOf); assertEquals(expected.toArray(), stream.get().boxed().toArray()); } public void testSummaryStats() { Supplier<DoubleStream> stream = () -> DoubleStream.of(1d, 2d, 3d); DoubleSummaryStatistics summaryStats = stream.get().summaryStatistics(); assertEquals(3L, summaryStats.getCount()); assertEquals(1d, summaryStats.getMin(), 0d); assertEquals(2d, summaryStats.getAverage(), 0d); assertEquals(3d, summaryStats.getMax(), 0d); assertEquals(6d, summaryStats.getSum(), 0d); summaryStats.accept(6L); assertEquals(4L, summaryStats.getCount()); assertEquals(1d, summaryStats.getMin(), 0d); assertEquals(3d, summaryStats.getAverage(), 0d); assertEquals(6d, summaryStats.getMax(), 0d); assertEquals(12d, summaryStats.getSum(), 0d); DoubleSummaryStatistics combinedSumStats = stream.get().summaryStatistics(); combinedSumStats.combine(DoubleStream.of(4d, 5d, 6d, 0d).summaryStatistics()); assertEquals(7L, combinedSumStats.getCount()); assertEquals(0d, combinedSumStats.getMin(), 0d); assertEquals(3d, combinedSumStats.getAverage(), 0d); assertEquals(6d, combinedSumStats.getMax(), 0d); assertEquals(21d, combinedSumStats.getSum(), 0d); } public void testAverage() { assertFalse(DoubleStream.empty().average().isPresent()); assertEquals(2.0d, DoubleStream.of(1d, 2d, 3d).average().getAsDouble(), 0d); assertEquals(0d, DoubleStream.of(1d, 2d, -3d).average().getAsDouble(), 0d); assertEquals(-2.0d, DoubleStream.of(-1d, -2d, -3d).average().getAsDouble(), 0d); } public void testSum() { assertEquals(6d, DoubleStream.of(1d, 2d, 3d).sum(), 0d); assertEquals(0d, DoubleStream.of(1d, 2d, -3d).sum(), 0d); assertEquals(-6d, DoubleStream.of(-1d, -2d, -3d).sum(), 0d); } public void testCollect() { // noinspection StringConcatenationInsideStringBufferAppend String val = DoubleStream.of(1d, 2d, 3d, 4d, 5d) .collect( StringBuilder::new, (stringBuilder, d) -> stringBuilder.append(toIntegralString(d)), StringBuilder::append) .toString(); assertEquals("12345", val); } public void testForEach() { List<Double> vals = new ArrayList<>(); DoubleStream.of(1d, 2d, 3d, 4d, 5d).forEach(vals::add); assertEquals(5, vals.size()); assertEquals(new Double[] {1d, 2d, 3d, 4d, 5d}, vals.toArray(new Double[vals.size()])); } public void testIterator() { List<Double> vals = new ArrayList<>(); Iterator<Double> iterator = DoubleStream.of(1d, 2d, 3d, 4d, 5d).iterator(); while (iterator.hasNext()) { vals.add(iterator.next()); } assertEquals(5, vals.size()); assertEquals(new Double[] {1d, 2d, 3d, 4d, 5d}, vals.toArray(new Double[vals.size()])); } public void testSpliterator() { Spliterator<Double> spliterator = DoubleStream.of(1d, 2d, 3d, 4d, 5d).spliterator(); assertEquals(5, spliterator.estimateSize()); assertEquals(5, spliterator.getExactSizeIfKnown()); List<Double> vals = new ArrayList<>(); while (spliterator.tryAdvance(vals::add)) { // work is all done in the condition } assertEquals(5, vals.size()); assertEquals(new Double[] {1d, 2d, 3d, 4d, 5d}, vals.toArray(new Double[vals.size()])); } // See https://github.com/gwtproject/gwt/issues/8615 private static String toIntegralString(double value) { return "" + (int) value; } }