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 }