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