changeset 5848:185ac7f3e977 it2-bootstrap

A new minimal test for UniqOp
author mduigou
date Sun, 12 Aug 2012 12:38:32 -0700
parents a018842c6b2d
children 5f2ae9c265f0
files src/share/classes/java/util/functions/FlatMapper.java src/share/classes/java/util/streams/ops/UniqOp.java test-ng/tests/org/openjdk/tests/java/util/LambdaTestHelpers.java test-ng/tests/org/openjdk/tests/java/util/streams/ops/StreamOpTestCase.java test-ng/tests/org/openjdk/tests/java/util/streams/ops/UniqOpTest.java
diffstat 5 files changed, 155 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/functions/FlatMapper.java	Thu Aug 09 12:45:46 2012 -0700
+++ b/src/share/classes/java/util/functions/FlatMapper.java	Sun Aug 12 12:38:32 2012 -0700
@@ -25,7 +25,7 @@
 package java.util.functions;
 
 /**
- * Map an element and add results to a sink.
+ * Map an element to zero or more results and add all results to a sink.
  *
  * @author Brian Goetz
  */
--- a/src/share/classes/java/util/streams/ops/UniqOp.java	Thu Aug 09 12:45:46 2012 -0700
+++ b/src/share/classes/java/util/streams/ops/UniqOp.java	Sun Aug 12 12:38:32 2012 -0700
@@ -38,6 +38,15 @@
  * @author Brian Goetz
  */
 public class UniqOp<T> implements StatefulOp<T, T, Void> {
+    private static UniqOp<?> INSTANCE = new UniqOp<>();
+
+    public UniqOp() {
+    }
+
+    public static <T> UniqOp<T> singleton() {
+        return (UniqOp<T>) INSTANCE;
+    }
+
     @Override
     public int getStreamState(int upstreamState) {
         // If the upstream is sorted, we need only cache last element
@@ -63,8 +72,9 @@
 
             @Override
             public void accept(T t) {
-                if (seen.add(t))
+                if (seen.add(t)) {
                     sink.accept(t);
+                }
             }
         };
     }
@@ -108,8 +118,8 @@
         };
     }
 
-    @Override
-    public <V> ParallelStreamable<T> computeParallel(ParallelStreamable<V> source, ParallelOpHelper<T, V> helper) {
-        throw new UnsupportedOperationException("nyi");
-    }
+//    @Override
+//    public <V> ParallelStreamable<T> computeParallel(ParallelStreamable<V> source, ParallelOpHelper<T, V> helper) {
+//        throw new UnsupportedOperationException("nyi");
+//    }
 }
--- a/test-ng/tests/org/openjdk/tests/java/util/LambdaTestHelpers.java	Thu Aug 09 12:45:46 2012 -0700
+++ b/test-ng/tests/org/openjdk/tests/java/util/LambdaTestHelpers.java	Sun Aug 12 12:38:32 2012 -0700
@@ -80,6 +80,14 @@
         return list;
     }
 
+    public static List<Integer> repeat(int value, int n) {
+        ArrayList<Integer> list = new ArrayList<>(n);
+        for (int i=1; i<=n; i++) {
+            list.add(value);
+        }
+        return list;
+    }
+
     public static List<Double> asDoubles(List<Integer> integers) {
         ArrayList<Double> list = new ArrayList<>();
         for (Integer i : integers)
@@ -152,6 +160,23 @@
         assertSorted(iter.iterator(), comp);
     }
 
+    public static <T> void assertUnique(Iterable<T> iter) {
+        assertUnique(iter.iterator());
+    }
+
+    public static<T> void assertUnique(Iterator<T> iter) {
+        if (!iter.hasNext()) {
+            return;
+        }
+
+        Set<T> uniq = new HashSet<>();
+        while(iter.hasNext()) {
+            T each = iter.next();
+            assertTrue(!uniq.contains(each));
+            uniq.add(each);
+        }
+    }
+
     public static<T> void assertContents(Iterable<T> pi, Iterable<T> list) {
         assertContents(pi.iterator(), list.iterator());
     }
@@ -209,10 +234,12 @@
             if (pI == null)
                 pI = mI.next().iterator();
             while (!pI.hasNext()) {
-                if (!mI.hasNext())
+                if (!mI.hasNext()) {
                     break;
-                else
+                }
+                else {
                     pI = mI.next().iterator();
+                }
             }
             assertTrue(pI.hasNext());
             T pT = pI.next();
@@ -220,8 +247,9 @@
             assertEquals(pT, lT);
         }
 
-        if (pI != null)
+        if (pI != null) {
             assertTrue(!pI.hasNext());
+        }
 
         while(mI.hasNext()) {
             pI = mI.next().iterator();
@@ -236,8 +264,9 @@
     private static <T> Iterable<Iterable<T>> splitHelper(Spliterator<T> s, int depth, List<Iterable<T>> iterables) {
         if (depth == 0) {
             List<T> list = new ArrayList<>();
-            while (s.hasNext())
+            while (s.hasNext()) {
                 list.add(s.next());
+            }
             iterables.add(list);
         }
         else {
--- a/test-ng/tests/org/openjdk/tests/java/util/streams/ops/StreamOpTestCase.java	Thu Aug 09 12:45:46 2012 -0700
+++ b/test-ng/tests/org/openjdk/tests/java/util/streams/ops/StreamOpTestCase.java	Sun Aug 12 12:38:32 2012 -0700
@@ -46,14 +46,16 @@
  */
 @Test
 public abstract class StreamOpTestCase {
-    protected<T, U> void assertConsistentOpBehavior(T[] data,
-                                                    ElementwiseOp<T,U> op,
-                                                    Mapper<Integer, Integer> lengthMapper) {
+
+    protected <T, U> void assertConsistentOpBehavior(T[] data,
+            ElementwiseOp<T, U> op,
+            Mapper<Integer, Integer> lengthMapper) {
         Streamable<T> seq = Arrays.asList(data);
         ParallelStreamable<T> par = Arrays.parallel(data);
         int length = data.length;
-        if (lengthMapper != null)
+        if (lengthMapper != null) {
             length = lengthMapper.map(data.length);
+        }
 
         ArraySink<U> sink1 = new ArraySink<>(length);
         ArraySink<U> sink2 = new ArraySink<>(length);
@@ -64,24 +66,26 @@
 
         // First pass -- grab an iterator and wrap it
         Iterator<U> it = op.iterator(seq.iterator());
-        while (it.hasNext())
+        while (it.hasNext()) {
             sink1.accept(it.next());
+        }
 
         // If a length mapper has been specified, make sure it is right
-        if (lengthMapper != null)
-            Assert.assertEquals(sink1.size(), (int) lengthMapper.map(data.length));
+        if (lengthMapper != null) {
+            Assert.assertEquals(sink1.size(), (int)lengthMapper.map(data.length));
+        }
 
         // Second pass -- create a sink and wrap it
         {
             Sink<T> wrapped = op.sink(sink2);
             if (wrapped instanceof StatefulSink) {
-                StatefulSink<T,?> stateful = (StatefulSink<T, ?>) wrapped;
+                StatefulSink<T, ?> stateful = (StatefulSink<T, ?>)wrapped;
                 stateful.begin(-1);
                 seq.forEach(stateful);
                 stateful.end();
+            } else {
+                seq.forEach(wrapped);
             }
-            else
-                seq.forEach(wrapped);
             assertEquals(sink1, sink2);
         }
 
@@ -91,26 +95,28 @@
 
         // Wrap with SequentialPipeline.op, and iterate in pull mode
         Iterator<U> seqIter = new SequentialPipeline<>(seq, op);
-        while (seqIter.hasNext())
+        while (seqIter.hasNext()) {
             sink4.accept(seqIter.next());
+        }
         assertEquals(sink1, sink4);
 
         // Wrap with SequentialPipeline.op, and iterate in mixed mode
         Stream<U> mixedIter = new SequentialPipeline<>(seq, op);
-        if (mixedIter.hasNext())
+        if (mixedIter.hasNext()) {
             sink5.accept(mixedIter.next());
+        }
         mixedIter.forEach(sink5);
         assertEquals(sink1, sink5);
 
         // Wrap with ParallelPipeline.op.sequential
-        if (op instanceof StatelessOp)
-            new ParallelPipeline<>(par, (StatelessOp<T, U>) op).sequential().forEach(sink6);
-        else if (op instanceof StatefulOp) {
-            SizedStreamable<U> sequential = ParallelPipeline.wrap(par).pipeline((StatefulOp<T, U, ?>) op).sequential();
+        if (op instanceof StatelessOp) {
+            new ParallelPipeline<>(par, (StatelessOp<T, U>)op).sequential().forEach(sink6);
+        } else if (op instanceof StatefulOp) {
+            SizedStreamable<U> sequential = ParallelPipeline.wrap(par).pipeline((StatefulOp<T, U, ?>)op).sequential();
             sequential.forEach(sink6);
+        } else {
+            fail("Op neither stateful nor stateless");
         }
-        else
-            fail("Op neither stateful nor stateless");
         assertEquals(sink1, sink6);
 
         // @@@ Extend parallel testing to include
@@ -118,11 +124,11 @@
         //  - More ways to iterate the PSS: .sequential().into(), iterate result of op
     }
 
-    protected<T, U> void assertConsistentOpBehavior(T[] data, StatelessOp<T,U> op) {
+    protected <T, U> void assertConsistentOpBehavior(T[] data, StatelessOp<T, U> op) {
         assertConsistentOpBehavior(data, op, null);
     }
 
-    protected<T, U> void assertConsistentOpBehavior(T[] data, EagerOp<T, U> op) {
+    protected <T, U> void assertConsistentOpBehavior(T[] data, EagerOp<T, U> op) {
         SizedStreamable<T> seq = Arrays.asList(data);
         ParallelStreamable<T> par = Arrays.parallel(data);
         int length = data.length;
@@ -149,7 +155,7 @@
         Assert.assertEquals(answer1, answer4);
     }
 
-    protected<T, U> void assertConsistentOpBehavior(T[] data, ShortCircuitEagerOp<T, U> op) {
+    protected <T, U> void assertConsistentOpBehavior(T[] data, ShortCircuitEagerOp<T, U> op) {
         SizedStreamable<T> seq = Arrays.asList(data);
         ParallelStreamable<T> par = Arrays.parallel(data);
         int length = data.length;
@@ -166,7 +172,7 @@
         Assert.assertEquals(answer1, answer3);
     }
 
-    private static<U> void assertEquals(ArraySink<U> sink1, ArraySink<U> sink2) {
+    private static <U> void assertEquals(ArraySink<U> sink1, ArraySink<U> sink2) {
         Assert.assertEquals(sink1.size(), sink2.size());
         Iterator<U> it1 = sink1.iterator();
         Iterator<U> it2 = sink2.iterator();
@@ -188,34 +194,41 @@
     private static final Integer[] pseudoRandom;
 
     static {
-        Integer[][] arrays = { to0, to1, to10, to100, to1000 };
-        for (Integer[] arr : arrays)
-            for (int i=0; i < arr.length; i++)
+        Integer[][] arrays = {to0, to1, to10, to100, to1000};
+        for (Integer[] arr : arrays) {
+            for (int i = 0; i < arr.length; i++) {
                 arr[i] = i;
-        for (int i=0; i < reversed.length; i++)
-            reversed[i] = reversed.length-i;
-        for (int i=0; i< ones.length; i++)
+            }
+        }
+        for (int i = 0; i < reversed.length; i++) {
+            reversed[i] = reversed.length - i;
+        }
+        for (int i = 0; i < ones.length; i++) {
             ones[i] = 1;
+        }
         System.arraycopy(to100, 0, twice, 0, to100.length);
         System.arraycopy(to100, 0, twice, to100.length, to100.length);
         pseudoRandom = new Integer[LambdaTestHelpers.LONG_STRING.length()];
-        for (int i=0; i< LambdaTestHelpers.LONG_STRING.length(); i++)
-            pseudoRandom[i] = (int) LambdaTestHelpers.LONG_STRING.charAt(i);
+        for (int i = 0; i < LambdaTestHelpers.LONG_STRING.length(); i++) {
+            pseudoRandom[i] = (int)LambdaTestHelpers.LONG_STRING.charAt(i);
+        }
     }
 
     // Return an array of Integer[]
     @DataProvider(name = "opArrays")
     public static Object[][] makeOpArrays() {
-        return new Object[][] { { to0 }, { to1 }, { to10 }, { to100 }, { to1000 }, { ones }, { twice }, { reversed }, { pseudoRandom } };
+        return new Object[][]{{to0}, {to1}, {to10}, {to100}, {to1000}, {ones}, {twice}, {reversed}, {pseudoRandom}};
     }
 
     private static class ArraySink<T> implements Sink<T>, Traversable<T>, Sized {
+
         private T[] array;
+
         private int offset;
 
         @SuppressWarnings("unchecked")
         public ArraySink(int initialSize) {
-            array = (T[]) new Object[initialSize];
+            array = (T[])new Object[initialSize];
         }
 
         public ArraySink() {
@@ -224,8 +237,9 @@
 
         @Override
         public void forEach(Sink<? super T> sink) {
-            for (int i=0; i<offset; i++)
+            for (int i = 0; i < offset; i++) {
                 sink.accept(array[i]);
+            }
         }
 
         @Override
@@ -237,7 +251,7 @@
         public void accept(T t) {
             if (offset == array.length) {
                 @SuppressWarnings("unchecked")
-                T[] temp = (T[]) new Object[Math.max(array.length, 1)*2];
+                T[] temp = (T[])new Object[Math.max(array.length, 1) * 2];
                 System.arraycopy(array, 0, temp, 0, array.length);
                 array = temp;
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-ng/tests/org/openjdk/tests/java/util/streams/ops/UniqOpTest.java	Sun Aug 12 12:38:32 2012 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.streams.ops;
+
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.streams.SequentialPipeline;
+import java.util.streams.ops.UniqOp;
+
+import static org.openjdk.tests.java.util.LambdaTestHelpers.*;
+
+/**
+ * SortedOpTest
+ *
+ * @author Brian Goetz
+ */
+public class UniqOpTest extends StreamOpTestCase {
+    public void testRawIterator() {
+        assertCountSum(UniqOp.<Integer>singleton().iterator(repeat(10, 0).iterator()), 0 , 0);
+        assertCountSum(UniqOp.<Integer>singleton().iterator(repeat(10, 0).iterator()), 1 , 0);
+        assertCountSum(UniqOp.<Integer>singleton().iterator(repeat(10, 1).iterator()), 1 , 1);
+        assertCountSum(UniqOp.<Integer>singleton().iterator(countTo(0).iterator()), 0, 0);
+        assertCountSum(UniqOp.<Integer>singleton().iterator(countTo(10).iterator()), 10, 55);
+        assertCountSum(UniqOp.<Integer>singleton().iterator(countTo(10).iterator()), 10, 55);
+    }
+
+    @Test(dataProvider = "opArrays")
+    public void testOps(Integer[] data) {
+        UniqOp<Integer> op = UniqOp.<Integer>singleton();
+        assertUnique(new SequentialPipeline<>(Arrays.asList(data), op).into(new ArrayList<Integer>()).iterator());
+        assertConsistentOpBehavior(data, op, null);
+    }
+}