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