1 /*
2  * Copyright (c) 1997, 2016, 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 java.util.stream;
24 
25 import java.util.*;
26 import java.util.function.BiConsumer;
27 import java.util.function.BiPredicate;
28 import java.util.function.BinaryOperator;
29 import java.util.function.Consumer;
30 import java.util.function.DoubleBinaryOperator;
31 import java.util.function.DoubleConsumer;
32 import java.util.function.DoublePredicate;
33 import java.util.function.Function;
34 import java.util.function.IntBinaryOperator;
35 import java.util.function.IntConsumer;
36 import java.util.function.IntFunction;
37 import java.util.function.IntPredicate;
38 import java.util.function.IntUnaryOperator;
39 import java.util.function.LongBinaryOperator;
40 import java.util.function.LongConsumer;
41 import java.util.function.LongPredicate;
42 import java.util.function.Predicate;
43 import java.util.function.Supplier;
44 import java.util.function.ToDoubleFunction;
45 import java.util.function.ToIntFunction;
46 import java.util.function.ToLongFunction;
47 
48 import static org.testng.Assert.assertEquals;
49 import static org.testng.Assert.assertTrue;
50 import static org.testng.Assert.assertFalse;
51 import static org.testng.Assert.fail;
52 
53 /**
54  * LambdaTestHelpers -- assertion methods and useful objects for lambda test cases
55  */
56 public class LambdaTestHelpers {
57     public static final String LONG_STRING = "When in the Course of human events it becomes necessary for one people to dissolve the political bands which have connected them with another and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature's God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation.";
58 
59     @SuppressWarnings("rawtypes")
60     public static final Consumer bEmpty = x -> {  };
61     @SuppressWarnings("rawtypes")
62     public static final IntConsumer bIntEmpty = x -> {  };
63     @SuppressWarnings("rawtypes")
64     public static final BiConsumer bBiEmpty = (x,y) -> { };
65     @SuppressWarnings("rawtypes")
66     public static final Consumer bHashCode = x -> { Objects.hashCode(x); };
67     @SuppressWarnings("rawtypes")
68     public static final BiConsumer bBiHashCode = (x,y) -> { Objects.hash(x, y); };
69     public static final Function<Integer, Integer> mZero = x -> 0;
70     public static final Function<Integer, Integer> mId = x -> x;
71     public static final Function<Integer, Integer> mDoubler = x -> x * 2;
72     public static final Function<Integer, Stream<Integer>> mfId = e -> Collections.singletonList(e).stream();
73     public static final Function<Integer, Stream<Integer>> mfNull = e -> Collections.<Integer>emptyList().stream();
74     public static final Function<Integer, Stream<Integer>> mfLt = e -> {
75         List<Integer> l = new ArrayList<>();
76         for (int i=0; i<e; i++)
77             l.add(i);
78         return l.stream();
79     };
80     public static final ToIntFunction<Integer> imDoubler = x -> x * 2;
81     public static final ToLongFunction<Long> lmDoubler = x -> x * 2;
82     public static final ToDoubleFunction<Double> dmDoubler = x -> x * 2;
83     public static final Predicate<Integer> pFalse = x -> false;
84     public static final Predicate<Integer> pTrue = x -> true;
85     public static final Predicate<Integer> pEven = x -> 0 == x % 2;
86     public static final Predicate<Integer> pOdd = x -> 1 == x % 2;
87     public static final IntPredicate ipFalse = x -> false;
88     public static final IntPredicate ipTrue = x -> true;
89     public static final IntPredicate ipEven = x -> 0 == x % 2;
90     public static final IntPredicate ipOdd = x -> 1 == x % 2;
91     public static final LongPredicate lpFalse = x -> false;
92     public static final LongPredicate lpTrue = x -> true;
93     public static final LongPredicate lpEven = x -> 0 == x % 2;
94     public static final LongPredicate lpOdd = x -> 1 == x % 2;
95     public static final DoublePredicate dpFalse = x -> false;
96     public static final DoublePredicate dpTrue = x -> true;
97     public static final DoublePredicate dpEven = x -> 0 == ((long) x) % 2;
98     public static final DoublePredicate dpOdd = x -> 1 == ((long) x) % 2;
99     public static final BinaryOperator<Integer> rPlus = (x, y) -> x+y;
100     public static final BinaryOperator<Integer> rMax = (x, y) -> Math.max(x, y);
101     public static final BinaryOperator<Integer> rMin = (x, y) -> Math.min(x,y);
102     public static final IntBinaryOperator irPlus = (x, y) -> x+y;
103     public static final IntBinaryOperator irMax = (x, y) -> Math.max(x, y);
104     public static final IntBinaryOperator irMin = (x, y) -> Math.min(x,y);
105     public static final IntUnaryOperator irDoubler = x -> x * 2;
106     public static final LongBinaryOperator lrPlus = (x, y) -> x+y;
107     public static final DoubleBinaryOperator drPlus = (x, y) -> x+y;
108     public static final Comparator<Integer> cInteger = (a, b) -> Integer.compare(a, b);
109     public static final BiPredicate<?, ?> bipFalse = (x, y) -> false;
110     public static final BiPredicate<?, ?> bipTrue = (x, y) -> true;
111     public static final BiPredicate<Integer, Integer> bipBothEven = (x, y) -> 0 == (x % 2 + y % 2);
112     public static final BiPredicate<Integer, Integer> bipBothOdd = (x, y) -> 2 == (x % 2 + y % 2);
113     public static final BiPredicate<?, ?> bipSameString = (x, y) -> String.valueOf(x).equals(String.valueOf(y));
114 
115     public static final IntFunction<Integer[]> integerArrayGenerator = s -> new Integer[s];
116 
117     public static final IntFunction<Object[]> objectArrayGenerator = s -> new Object[s];
118 
119     public static final Function<String, Stream<Character>> flattenChars = string -> {
120         List<Character> l = new ArrayList<>();
121         for (int i=0; i<string.length(); i++)
122             l.add(string.charAt(i));
123         return l.stream();
124     };
125 
126     public static final Function<String, IntStream> flattenInt
127             = string -> IntStream.range(0, string.length()).map(string::charAt);
128 
forPredicate(Predicate<? super T> predicate, R forTrue, R forFalse)129     public static <T, R> Function<T, R> forPredicate(Predicate<? super T> predicate, R forTrue, R forFalse) {
130         Objects.requireNonNull(predicate);
131 
132         return t -> predicate.test(t) ? forTrue : forFalse;
133     }
134 
identity()135     public static <T> Function<T, T> identity() {
136         return t -> t;
137     }
138 
compose(Function<? super T, ? extends R> after, Function<? super V, ? extends T> before)139     public static<V, T, R> Function<V, R> compose(Function<? super T, ? extends R> after, Function<? super V, ? extends T> before) {
140         Objects.requireNonNull(before);
141         return (V v) -> after.apply(before.apply(v));
142     }
143 
empty()144     public static List<Integer> empty() {
145         ArrayList<Integer> list = new ArrayList<>();
146         list.add(null);
147         return list;
148     }
149 
countTo(int n)150     public static List<Integer> countTo(int n) {
151         return range(1, n);
152     }
153 
range(int l, int u)154     public static List<Integer> range(int l, int u) {
155         ArrayList<Integer> list = new ArrayList<>(u - l + 1);
156         for (int i=l; i<=u; i++) {
157             list.add(i);
158         }
159         return list;
160     }
161 
repeat(int value, int n)162     public static List<Integer> repeat(int value, int n) {
163         ArrayList<Integer> list = new ArrayList<>(n);
164         for (int i=1; i<=n; i++) {
165             list.add(value);
166         }
167         return list;
168     }
169 
asDoubles(List<Integer> integers)170     public static List<Double> asDoubles(List<Integer> integers) {
171         ArrayList<Double> list = new ArrayList<>();
172         for (Integer i : integers) {
173             list.add((double) i);
174         }
175         return list;
176     }
177 
asLongs(List<Integer> integers)178     public static List<Long> asLongs(List<Integer> integers) {
179         ArrayList<Long> list = new ArrayList<>();
180         for (Integer i : integers) {
181             list.add((long) i);
182         }
183         return list;
184     }
185 
assertCountSum(Stream<? super Integer> it, int count, int sum)186     public static void assertCountSum(Stream<? super Integer> it, int count, int sum) {
187         assertCountSum(it.iterator(), count, sum);
188     }
189 
assertCountSum(Iterable<? super Integer> it, int count, int sum)190     public static void assertCountSum(Iterable<? super Integer> it, int count, int sum) {
191         assertCountSum(it.iterator(), count, sum);
192     }
193 
assertCountSum(Iterator<? super Integer> it, int count, int sum)194     public static void assertCountSum(Iterator<? super Integer> it, int count, int sum) {
195         int c = 0;
196         int s = 0;
197         while (it.hasNext()) {
198             int i = (Integer) it.next();
199             c++;
200             s += i;
201         }
202 
203         assertEquals(c, count);
204         assertEquals(s, sum);
205     }
206 
assertConcat(Iterator<Character> it, String result)207     public static void assertConcat(Iterator<Character> it, String result) {
208         StringBuilder sb = new StringBuilder();
209         while (it.hasNext()) {
210             sb.append(it.next());
211         }
212 
213         assertEquals(result, sb.toString());
214     }
215 
assertSorted(Iterator<T> i)216     public static<T extends Comparable<? super T>> void assertSorted(Iterator<T> i) {
217         i = toBoxedList(i).iterator();
218 
219         if (!i.hasNext())
220             return;
221         T last = i.next();
222         while (i.hasNext()) {
223             T t = i.next();
224             assertTrue(last.compareTo(t) <= 0);
225             assertTrue(t.compareTo(last) >= 0);
226             last = t;
227         }
228     }
229 
assertSorted(Iterator<T> i, Comparator<? super T> comp)230     public static<T> void assertSorted(Iterator<T> i, Comparator<? super T> comp) {
231         if (i instanceof PrimitiveIterator.OfInt
232                 || i instanceof PrimitiveIterator.OfDouble
233                 || i instanceof PrimitiveIterator.OfLong) {
234             i = toBoxedList(i).iterator();
235         }
236 
237         if (!i.hasNext())
238             return;
239         T last = i.next();
240         while (i.hasNext()) {
241             T t = i.next();
242             assertTrue(comp.compare(last, t) <= 0);
243             assertTrue(comp.compare(t, last) >= 0);
244             last = t;
245         }
246     }
247 
assertSorted(Iterable<T> iter)248     public static<T extends Comparable<? super T>> void assertSorted(Iterable<T> iter) {
249         assertSorted(iter.iterator());
250     }
251 
assertSorted(Iterable<T> iter, Comparator<? super T> comp)252     public static<T> void assertSorted(Iterable<T> iter, Comparator<? super T> comp) {
253         assertSorted(iter.iterator(), comp);
254     }
255 
assertUnique(Iterable<T> iter)256     public static <T> void assertUnique(Iterable<T> iter) {
257         assertUnique(iter.iterator());
258     }
259 
assertUnique(Iterator<T> iter)260     public static<T> void assertUnique(Iterator<T> iter) {
261         if (!iter.hasNext()) {
262             return;
263         }
264 
265         if (iter instanceof PrimitiveIterator.OfInt
266             || iter instanceof PrimitiveIterator.OfDouble
267             || iter instanceof PrimitiveIterator.OfLong) {
268             iter = toBoxedList(iter).iterator();
269         }
270 
271         Set<T> uniq = new HashSet<>();
272         while(iter.hasNext()) {
273             T each = iter.next();
274             assertTrue(!uniq.contains(each), "Not unique");
275             uniq.add(each);
276         }
277     }
278 
assertContents(Iterable<T> actual, Iterable<T> expected)279     public static<T> void assertContents(Iterable<T> actual, Iterable<T> expected) {
280         if (actual instanceof Collection && expected instanceof Collection) {
281             assertIterableEquals(actual, expected);
282         } else {
283             assertContents(actual.iterator(), expected.iterator());
284         }
285     }
286 
assertContents(Iterator<T> actual, Iterator<T> expected)287     public static<T> void assertContents(Iterator<T> actual, Iterator<T> expected) {
288         assertEquals(toBoxedList(actual), toBoxedList(expected));
289     }
290 
291     // Workaround excessive String creation in inner loop in org.testng.Assert.assertEquals(Iterable<?>, Iterable<?>)
assertIterableEquals(Iterable<?> actual, Iterable<?> expected)292     static public void assertIterableEquals(Iterable<?> actual, Iterable<?> expected) {
293         if(actual == expected) {
294             return;
295         }
296 
297         if(actual == null || expected == null) {
298             fail("Iterables not equal: expected: " + expected + " and actual: " + actual);
299         }
300 
301         assertIteratorsEquals(actual.iterator(), expected.iterator());
302     }
303 
304     // Workaround excessive String creation in inner loop in org.testng.Assert.assertEquals(Iterator<?>, Iterator<?>)
assertIteratorsEquals(Iterator<?> actual, Iterator<?> expected)305     static public void assertIteratorsEquals(Iterator<?> actual, Iterator<?> expected) {
306         if (actual == expected) {
307             return;
308         }
309 
310         if (actual == null || expected == null) {
311             fail("Iterators not equal: expected: " + expected + " and actual: " + actual);
312         }
313 
314         while (actual.hasNext() && expected.hasNext()) {
315             Object e = expected.next();
316             Object a = actual.next();
317             assertEquals(a, e, "Iterator contents differ");
318         }
319 
320         if(actual.hasNext()) {
321             fail("Actual iterator returned more elements than the expected iterator.");
322         } else if(expected.hasNext()) {
323             fail("Expected iterator returned more elements than the actual iterator.");
324         }
325     }
326 
327     @SafeVarargs
328     @SuppressWarnings("varargs")
assertContents(Iterator<T> actual, T... expected)329     public static<T> void assertContents(Iterator<T> actual, T... expected) {
330         assertContents(actual, Arrays.asList(expected).iterator());
331     }
332 
333     /**
334      * The all consuming consumer (rampant capitalist) that can accepting a reference or any primitive value.
335      */
336     private static interface OmnivorousConsumer<T>
337             extends Consumer<T>, IntConsumer, LongConsumer, DoubleConsumer { }
338 
339     @SuppressWarnings({"rawtypes", "unchecked"})
toBoxingConsumer(Consumer<? super T> c)340     public static<T> Consumer<T> toBoxingConsumer(Consumer<? super T> c) {
341         return (Consumer<T>) new OmnivorousConsumer() {
342             @Override
343             public void accept(Object t) {
344                 c.accept((T) t);
345             }
346 
347             @Override
348             public void accept(int t) {
349                 accept((Object) t);
350             }
351 
352             @Override
353             public void accept(long t) {
354                 accept((Object) t);
355             }
356 
357             @Override
358             public void accept(double t) {
359                 accept((Object) t);
360             }
361         };
362     }
363 
364     /**
365      * Convert an iterator to a list using forEach with an implementation of
366      * {@link java.util.stream.LambdaTestHelpers.OmnivorousConsumer}.
367      *
368      * This ensures equality comparisons for test results do not trip
369      * the boxing trip-wires.
370      */
371     private static<T> List<T> toBoxedList(Iterator<T> it) {
372         List<T> l = new ArrayList<>();
373         it.forEachRemaining(toBoxingConsumer(l::add));
374         return l;
375     }
376 
377     /**
378      * Convert a spliterator to a list using forEach with an implementation of
379      * {@link java.util.stream.LambdaTestHelpers.OmnivorousConsumer}.
380      *
381      * This ensures equality comparisons for test results do not trip
382      * the boxing trip-wires.
383      */
384     public static<T> List<T> toBoxedList(Spliterator<T> sp) {
385         List<T> l = new ArrayList<>();
386         sp.forEachRemaining(toBoxingConsumer(l::add));
387         return l;
388     }
389 
390     /**
391      * Convert an iterator to a multi-set, represented as a Map, using forEach with an implementation of
392      * {@link java.util.stream.LambdaTestHelpers.OmnivorousConsumer}.
393      *
394      * This ensures equality comparisons for test results do not trip
395      * the boxing trip-wires.
396      */
397     @SuppressWarnings("unchecked")
398     private static<T> Map<T, Integer> toBoxedMultiset(Iterator<T> it) {
399         Map<Object, Integer> result = new HashMap<>();
400 
401         it.forEachRemaining(toBoxingConsumer(o -> {
402                 if (result.containsKey(o))
403                     result.put(o, result.get(o) + 1);
404                 else
405                     result.put(o, 1);
406             }));
407 
408         return (Map<T, Integer>) result;
409     }
410 
411     @SuppressWarnings("unchecked")
412     public static<T> Map<T, Integer> toBoxedMultiset(Spliterator<T> it) {
413         Map<Object, Integer> result = new HashMap<>();
414 
415         it.forEachRemaining(toBoxingConsumer(o -> {
416                 if (result.containsKey(o))
417                     result.put(o, result.get(o) + 1);
418                 else
419                     result.put(o, 1);
420             }));
421 
422         return (Map<T, Integer>) result;
423     }
424 
425     @SuppressWarnings("unchecked")
426     public static void assertContentsEqual(Object a, Object b) {
427         if (a instanceof Iterable && b instanceof Iterable)
428             assertContents((Iterable) a, (Iterable) b);
429         else
430             assertEquals(a, b);
431     }
432 
433     public static<T> void assertContentsUnordered(Iterable<T> actual, Iterable<T> expected) {
434         assertContentsUnordered(actual.iterator(), expected.iterator());
435     }
436 
437     public static<T> void assertContentsUnordered(Iterator<T> actual, Iterator<T> expected) {
438         assertEquals(toBoxedMultiset(actual), toBoxedMultiset(expected));
439     }
440 
441     public static<T> void assertContains(Optional<T> actual, Iterator<T> it) {
442         actual.ifPresentOrElse(r -> {
443             boolean contained = false;
444             while (!contained && it.hasNext()) {
445                 contained = Objects.equals(r, it.next());
446             }
447             assertTrue(contained, "Not found: "+r);
448         }, () -> assertFalse(it.hasNext()));
449     }
450 
451     public static void launderAssertion(Runnable r, Supplier<String> additionalInfo) {
452         try {
453             r.run();
454         }
455         catch (AssertionError ae) {
456             AssertionError cloned = new AssertionError(ae.getMessage() + String.format("%n%s", additionalInfo.get()));
457             cloned.setStackTrace(ae.getStackTrace());
458             if (ae.getCause() != null)
459                 cloned.initCause(ae.getCause());
460             throw cloned;
461         }
462     }
463 
464     public static <T, S extends BaseStream<T, S>>
465     List<Function<S, S>> permuteStreamFunctions(List<Function<S, S>> opFunctions) {
466         List<List<Function<S, S>>> opFunctionPermutations = perm(opFunctions);
467 
468         List<Function<S, S>> appliedFunctions = new ArrayList<>();
469         for (List<Function<S, S>> fs : opFunctionPermutations) {
470             Function<S, S> applied = s -> {
471                 for (Function<S, S> f : fs) {
472                     s = f.apply(s);
473                 }
474                 return s;
475             };
476             appliedFunctions.add(applied);
477         }
478 
479         return appliedFunctions;
480     }
481 
482     private static <T> List<T> sub(List<T> l, int index) {
483         List<T> subL = new ArrayList<>(l);
484         subL.remove(index);
485         return subL;
486     }
487 
488     public static <T> List<List<T>> perm(List<T> l) {
489         List<List<T>> result = new ArrayList<>();
490         for (int i = 0; i < l.size(); i++) {
491             for (List<T> perm : perm(sub(l, i))) {
492                 perm.add(0, l.get(i));
493                 result.add(perm);
494             }
495         }
496         result.add(new ArrayList<T>());
497 
498         return result;
499     }
500 
501     public static String flagsToString(int flags) {
502         StringJoiner sj = new StringJoiner(", ", "StreamOpFlag[", "]");
503         if (StreamOpFlag.DISTINCT.isKnown(flags)) sj.add("IS_DISTINCT");
504         if (StreamOpFlag.ORDERED.isKnown(flags)) sj.add("IS_ORDERED");
505         if (StreamOpFlag.SIZED.isKnown(flags)) sj.add("IS_SIZED");
506         if (StreamOpFlag.SORTED.isKnown(flags)) sj.add("IS_SORTED");
507         if (StreamOpFlag.SHORT_CIRCUIT.isKnown(flags)) sj.add("IS_SHORT_CIRCUIT");
508         return sj.toString();
509     }
510 }
511