1 /*
   2  * Copyright (c) 1997, 2010, 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 
  51 /**
  52  * LambdaTestHelpers -- assertion methods and useful objects for lambda test cases
  53  */
  54 public 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 }