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