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 
 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 
 135     public static <T> Function<T, T> identity() {
 136         return t -> t;
 137     }
 138 
 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 
 144     public static List<Integer> empty() {
 145         ArrayList<Integer> list = new ArrayList<>();
 146         list.add(null);
 147         return list;
 148     }
 149 
 150     public static List<Integer> countTo(int n) {
 151         return range(1, n);
 152     }
 153 
 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 
 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 
 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 
 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 
 186     public static void assertCountSum(Stream<? super Integer> it, int count, int sum) {
 187         assertCountSum(it.iterator(), count, sum);
 188     }
 189 
 190     public static void assertCountSum(Iterable<? super Integer> it, int count, int sum) {
 191         assertCountSum(it.iterator(), count, sum);
 192     }
 193 
 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 
 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 
 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 
 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 
 248     public static<T extends Comparable<? super T>> void assertSorted(Iterable<T> iter) {
 249         assertSorted(iter.iterator());
 250     }
 251 
 252     public static<T> void assertSorted(Iterable<T> iter, Comparator<? super T> comp) {
 253         assertSorted(iter.iterator(), comp);
 254     }
 255 
 256     public static <T> void assertUnique(Iterable<T> iter) {
 257         assertUnique(iter.iterator());
 258     }
 259 
 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 
 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 
 287     public static<T> void assertContents(Iterator<T> actual, Iterator<T> expected) {
 288         assertEquals(toBoxedList(actual), toBoxedList(expected));
 289     }
 290 
 291     // Workaround String creation in inner loop inside org.testng.Assert.assertEquals(Iterable<?>, Iterable<?>)
 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 String creation in inner loop inside org.testng.Assert.assertEquals(Iterator<?>, Iterator<?>)
 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 
 321         if(actual.hasNext()) {
 322             fail("Actual iterator returned more elements than the expected iterator.");
 323         } else if(expected.hasNext()) {
 324             fail("Expected iterator returned more elements than the actual iterator.");
 325         }
 326 
 327     }
 328     @SafeVarargs
 329     @SuppressWarnings("varargs")
 330     public static<T> void assertContents(Iterator<T> actual, T... expected) {
 331         assertContents(actual, Arrays.asList(expected).iterator());
 332     }
 333 
 334     /**
 335      * The all consuming consumer (rampant capitalist) that can accepting a reference or any primitive value.
 336      */
 337     private static interface OmnivorousConsumer<T>
 338             extends Consumer<T>, IntConsumer, LongConsumer, DoubleConsumer { }
 339 
 340     @SuppressWarnings({"rawtypes", "unchecked"})
 341     public static<T> Consumer<T> toBoxingConsumer(Consumer<? super T> c) {
 342         return (Consumer<T>) new OmnivorousConsumer() {
 343             @Override
 344             public void accept(Object t) {
 345                 c.accept((T) t);
 346             }
 347 
 348             @Override
 349             public void accept(int t) {
 350                 accept((Object) t);
 351             }
 352 
 353             @Override
 354             public void accept(long t) {
 355                 accept((Object) t);
 356             }
 357 
 358             @Override
 359             public void accept(double t) {
 360                 accept((Object) t);
 361             }
 362         };
 363     }
 364 
 365     /**
 366      * Convert an iterator to a list using forEach with an implementation of
 367      * {@link java.util.stream.LambdaTestHelpers.OmnivorousConsumer}.
 368      *
 369      * This ensures equality comparisons for test results do not trip
 370      * the boxing trip-wires.
 371      */
 372     private static<T> List<T> toBoxedList(Iterator<T> it) {
 373         List<T> l = new ArrayList<>();
 374         it.forEachRemaining(toBoxingConsumer(l::add));
 375         return l;
 376     }
 377 
 378     /**
 379      * Convert a spliterator to a list using forEach with an implementation of
 380      * {@link java.util.stream.LambdaTestHelpers.OmnivorousConsumer}.
 381      *
 382      * This ensures equality comparisons for test results do not trip
 383      * the boxing trip-wires.
 384      */
 385     public static<T> List<T> toBoxedList(Spliterator<T> sp) {
 386         List<T> l = new ArrayList<>();
 387         sp.forEachRemaining(toBoxingConsumer(l::add));
 388         return l;
 389     }
 390 
 391     /**
 392      * Convert an iterator to a multi-set, represented as a Map, using forEach with an implementation of
 393      * {@link java.util.stream.LambdaTestHelpers.OmnivorousConsumer}.
 394      *
 395      * This ensures equality comparisons for test results do not trip
 396      * the boxing trip-wires.
 397      */
 398     @SuppressWarnings("unchecked")
 399     private static<T> Map<T, Integer> toBoxedMultiset(Iterator<T> it) {
 400         Map<Object, Integer> result = new HashMap<>();
 401 
 402         it.forEachRemaining(toBoxingConsumer(o -> {
 403                 if (result.containsKey(o))
 404                     result.put(o, result.get(o) + 1);
 405                 else
 406                     result.put(o, 1);
 407             }));
 408 
 409         return (Map<T, Integer>) result;
 410     }
 411 
 412     @SuppressWarnings("unchecked")
 413     public static<T> Map<T, Integer> toBoxedMultiset(Spliterator<T> it) {
 414         Map<Object, Integer> result = new HashMap<>();
 415 
 416         it.forEachRemaining(toBoxingConsumer(o -> {
 417                 if (result.containsKey(o))
 418                     result.put(o, result.get(o) + 1);
 419                 else
 420                     result.put(o, 1);
 421             }));
 422 
 423         return (Map<T, Integer>) result;
 424     }
 425 
 426     @SuppressWarnings("unchecked")
 427     public static void assertContentsEqual(Object a, Object b) {
 428         if (a instanceof Iterable && b instanceof Iterable)
 429             assertContents((Iterable) a, (Iterable) b);
 430         else
 431             assertEquals(a, b);
 432     }
 433 
 434     public static<T> void assertContentsUnordered(Iterable<T> actual, Iterable<T> expected) {
 435         assertContentsUnordered(actual.iterator(), expected.iterator());
 436     }
 437 
 438     public static<T> void assertContentsUnordered(Iterator<T> actual, Iterator<T> expected) {
 439         assertEquals(toBoxedMultiset(actual), toBoxedMultiset(expected));
 440     }
 441 
 442     public static<T> void assertContains(Optional<T> actual, Iterator<T> it) {
 443         actual.ifPresentOrElse(r -> {
 444             boolean contained = false;
 445             while (!contained && it.hasNext()) {
 446                 contained = Objects.equals(r, it.next());
 447             }
 448             assertTrue(contained, "Not found: "+r);
 449         }, () -> assertFalse(it.hasNext()));
 450     }
 451 
 452     public static void launderAssertion(Runnable r, Supplier<String> additionalInfo) {
 453         try {
 454             r.run();
 455         }
 456         catch (AssertionError ae) {
 457             AssertionError cloned = new AssertionError(ae.getMessage() + String.format("%n%s", additionalInfo.get()));
 458             cloned.setStackTrace(ae.getStackTrace());
 459             if (ae.getCause() != null)
 460                 cloned.initCause(ae.getCause());
 461             throw cloned;
 462         }
 463     }
 464 
 465     public static <T, S extends BaseStream<T, S>>
 466     List<Function<S, S>> permuteStreamFunctions(List<Function<S, S>> opFunctions) {
 467         List<List<Function<S, S>>> opFunctionPermutations = perm(opFunctions);
 468 
 469         List<Function<S, S>> appliedFunctions = new ArrayList<>();
 470         for (List<Function<S, S>> fs : opFunctionPermutations) {
 471             Function<S, S> applied = s -> {
 472                 for (Function<S, S> f : fs) {
 473                     s = f.apply(s);
 474                 }
 475                 return s;
 476             };
 477             appliedFunctions.add(applied);
 478         }
 479 
 480         return appliedFunctions;
 481     }
 482 
 483     private static <T> List<T> sub(List<T> l, int index) {
 484         List<T> subL = new ArrayList<>(l);
 485         subL.remove(index);
 486         return subL;
 487     }
 488 
 489     public static <T> List<List<T>> perm(List<T> l) {
 490         List<List<T>> result = new ArrayList<>();
 491         for (int i = 0; i < l.size(); i++) {
 492             for (List<T> perm : perm(sub(l, i))) {
 493                 perm.add(0, l.get(i));
 494                 result.add(perm);
 495             }
 496         }
 497         result.add(new ArrayList<T>());
 498 
 499         return result;
 500     }
 501 
 502     public static String flagsToString(int flags) {
 503         StringJoiner sj = new StringJoiner(", ", "StreamOpFlag[", "]");
 504         if (StreamOpFlag.DISTINCT.isKnown(flags)) sj.add("IS_DISTINCT");
 505         if (StreamOpFlag.ORDERED.isKnown(flags)) sj.add("IS_ORDERED");
 506         if (StreamOpFlag.SIZED.isKnown(flags)) sj.add("IS_SIZED");
 507         if (StreamOpFlag.SORTED.isKnown(flags)) sj.add("IS_SORTED");
 508         if (StreamOpFlag.SHORT_CIRCUIT.isKnown(flags)) sj.add("IS_SHORT_CIRCUIT");
 509         return sj.toString();
 510     }
 511 }