1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.lang3; 18 19 import static org.junit.jupiter.api.Assertions.assertEquals; 20 import static org.junit.jupiter.api.Assertions.assertNotNull; 21 import static org.junit.jupiter.api.Assertions.assertNull; 22 import static org.junit.jupiter.api.Assertions.assertSame; 23 import static org.junit.jupiter.api.Assertions.assertThrows; 24 import static org.junit.jupiter.api.Assertions.assertTrue; 25 26 import java.io.IOException; 27 import java.io.UncheckedIOException; 28 import java.lang.reflect.UndeclaredThrowableException; 29 import java.util.concurrent.Callable; 30 import java.util.function.BiConsumer; 31 import java.util.function.BiFunction; 32 import java.util.function.BiPredicate; 33 import java.util.function.Consumer; 34 import java.util.function.Function; 35 import java.util.function.Predicate; 36 import java.util.function.Supplier; 37 38 import org.apache.commons.lang3.Functions.FailableBiConsumer; 39 import org.apache.commons.lang3.Functions.FailableBiFunction; 40 import org.apache.commons.lang3.Functions.FailableCallable; 41 import org.apache.commons.lang3.Functions.FailableConsumer; 42 import org.apache.commons.lang3.Functions.FailableFunction; 43 import org.apache.commons.lang3.Functions.FailableSupplier; 44 import org.junit.jupiter.api.DisplayName; 45 import org.junit.jupiter.api.Test; 46 47 public class FunctionsTest extends AbstractLangTest { 48 49 public static class CloseableObject { 50 private boolean closed; 51 close()52 public void close() { 53 closed = true; 54 } 55 isClosed()56 public boolean isClosed() { 57 return closed; 58 } 59 reset()60 public void reset() { 61 closed = false; 62 } 63 run(final Throwable pTh)64 public void run(final Throwable pTh) throws Throwable { 65 if (pTh != null) { 66 throw pTh; 67 } 68 } 69 } 70 71 public static class FailureOnOddInvocations { 72 private static int invocations; 73 failingBool()74 static boolean failingBool() throws SomeException { 75 throwOnOdd(); 76 return true; 77 } 78 testDouble(final double value)79 static boolean testDouble(final double value) throws SomeException { 80 throwOnOdd(); 81 return true; 82 } 83 testInt(final int value)84 static boolean testInt(final int value) throws SomeException { 85 throwOnOdd(); 86 return true; 87 } 88 testLong(final long value)89 static boolean testLong(final long value) throws SomeException { 90 throwOnOdd(); 91 return true; 92 } 93 throwOnOdd()94 private static void throwOnOdd() throws SomeException { 95 final int i = ++invocations; 96 if (i % 2 == 1) { 97 throw new SomeException("Odd Invocation: " + i); 98 } 99 } 100 FailureOnOddInvocations()101 FailureOnOddInvocations() throws SomeException { 102 throwOnOdd(); 103 } 104 getAsBoolean()105 boolean getAsBoolean() throws SomeException { 106 throwOnOdd(); 107 return true; 108 } 109 } 110 111 public static class SomeException extends Exception { 112 113 private static final long serialVersionUID = -4965704778119283411L; 114 115 private Throwable t; 116 SomeException(final String message)117 SomeException(final String message) { 118 super(message); 119 } 120 setThrowable(final Throwable throwable)121 public void setThrowable(final Throwable throwable) { 122 t = throwable; 123 } 124 test()125 public void test() throws Throwable { 126 if (t != null) { 127 throw t; 128 } 129 } 130 } 131 132 public static class Testable<T, P> { 133 private T acceptedObject; 134 private P acceptedPrimitiveObject1; 135 private P acceptedPrimitiveObject2; 136 private Throwable throwable; 137 Testable(final Throwable throwable)138 Testable(final Throwable throwable) { 139 this.throwable = throwable; 140 } 141 getAcceptedObject()142 public T getAcceptedObject() { 143 return acceptedObject; 144 } 145 getAcceptedPrimitiveObject1()146 public P getAcceptedPrimitiveObject1() { 147 return acceptedPrimitiveObject1; 148 } 149 getAcceptedPrimitiveObject2()150 public P getAcceptedPrimitiveObject2() { 151 return acceptedPrimitiveObject2; 152 } 153 setThrowable(final Throwable throwable)154 public void setThrowable(final Throwable throwable) { 155 this.throwable = throwable; 156 } 157 test()158 public void test() throws Throwable { 159 test(throwable); 160 } 161 test(final Object input1, final Object input2)162 public Object test(final Object input1, final Object input2) throws Throwable { 163 test(throwable); 164 return acceptedObject; 165 } 166 test(final Throwable throwable)167 public void test(final Throwable throwable) throws Throwable { 168 if (throwable != null) { 169 throw throwable; 170 } 171 } 172 testAsBooleanPrimitive()173 public boolean testAsBooleanPrimitive() throws Throwable { 174 return testAsBooleanPrimitive(throwable); 175 } 176 testAsBooleanPrimitive(final Throwable throwable)177 public boolean testAsBooleanPrimitive(final Throwable throwable) throws Throwable { 178 if (throwable != null) { 179 throw throwable; 180 } 181 return false; 182 } 183 testAsDoublePrimitive()184 public double testAsDoublePrimitive() throws Throwable { 185 return testAsDoublePrimitive(throwable); 186 } 187 testAsDoublePrimitive(final Throwable throwable)188 public double testAsDoublePrimitive(final Throwable throwable) throws Throwable { 189 if (throwable != null) { 190 throw throwable; 191 } 192 return 0; 193 } 194 testAsInteger()195 public Integer testAsInteger() throws Throwable { 196 return testAsInteger(throwable); 197 } 198 testAsInteger(final Throwable throwable)199 public Integer testAsInteger(final Throwable throwable) throws Throwable { 200 if (throwable != null) { 201 throw throwable; 202 } 203 return 0; 204 } 205 testAsIntPrimitive()206 public int testAsIntPrimitive() throws Throwable { 207 return testAsIntPrimitive(throwable); 208 } 209 testAsIntPrimitive(final Throwable throwable)210 public int testAsIntPrimitive(final Throwable throwable) throws Throwable { 211 if (throwable != null) { 212 throw throwable; 213 } 214 return 0; 215 } 216 testAsLongPrimitive()217 public long testAsLongPrimitive() throws Throwable { 218 return testAsLongPrimitive(throwable); 219 } 220 testAsLongPrimitive(final Throwable throwable)221 public long testAsLongPrimitive(final Throwable throwable) throws Throwable { 222 if (throwable != null) { 223 throw throwable; 224 } 225 return 0; 226 } 227 testDouble(final double i)228 public void testDouble(final double i) throws Throwable { 229 test(throwable); 230 acceptedPrimitiveObject1 = (P) ((Double) i); 231 } 232 testDoubleDouble(final double i, final double j)233 public double testDoubleDouble(final double i, final double j) throws Throwable { 234 test(throwable); 235 acceptedPrimitiveObject1 = (P) ((Double) i); 236 acceptedPrimitiveObject2 = (P) ((Double) j); 237 return 3d; 238 } 239 testInt(final int i)240 public void testInt(final int i) throws Throwable { 241 test(throwable); 242 acceptedPrimitiveObject1 = (P) ((Integer) i); 243 } 244 testLong(final long i)245 public void testLong(final long i) throws Throwable { 246 test(throwable); 247 acceptedPrimitiveObject1 = (P) ((Long) i); 248 } 249 testObjDouble(final T object, final double i)250 public void testObjDouble(final T object, final double i) throws Throwable { 251 test(throwable); 252 acceptedObject = object; 253 acceptedPrimitiveObject1 = (P) ((Double) i); 254 } 255 testObjInt(final T object, final int i)256 public void testObjInt(final T object, final int i) throws Throwable { 257 test(throwable); 258 acceptedObject = object; 259 acceptedPrimitiveObject1 = (P) ((Integer) i); 260 } 261 testObjLong(final T object, final long i)262 public void testObjLong(final T object, final long i) throws Throwable { 263 test(throwable); 264 acceptedObject = object; 265 acceptedPrimitiveObject1 = (P) ((Long) i); 266 } 267 } 268 269 @Test testAcceptBiConsumer()270 public void testAcceptBiConsumer() { 271 final IllegalStateException ise = new IllegalStateException(); 272 final Testable<?, ?> testable = new Testable<>(null); 273 Throwable e = assertThrows(IllegalStateException.class, () -> Functions.accept(Testable::test, testable, ise)); 274 assertSame(ise, e); 275 276 final Error error = new OutOfMemoryError(); 277 e = assertThrows(OutOfMemoryError.class, () -> Functions.accept(Testable::test, testable, error)); 278 assertSame(error, e); 279 280 final IOException ioe = new IOException("Unknown I/O error"); 281 testable.setThrowable(ioe); 282 e = assertThrows(UncheckedIOException.class, () -> Functions.accept(Testable::test, testable, ioe)); 283 final Throwable t = e.getCause(); 284 assertNotNull(t); 285 assertSame(ioe, t); 286 287 testable.setThrowable(null); 288 Functions.accept(Testable::test, testable, (Throwable) null); 289 } 290 291 @Test testAcceptConsumer()292 public void testAcceptConsumer() { 293 final IllegalStateException ise = new IllegalStateException(); 294 final Testable<?, ?> testable = new Testable<>(ise); 295 Throwable e = assertThrows(IllegalStateException.class, () -> Functions.accept(Testable::test, testable)); 296 assertSame(ise, e); 297 298 final Error error = new OutOfMemoryError(); 299 testable.setThrowable(error); 300 e = assertThrows(OutOfMemoryError.class, () -> Functions.accept(Testable::test, testable)); 301 assertSame(error, e); 302 303 final IOException ioe = new IOException("Unknown I/O error"); 304 testable.setThrowable(ioe); 305 e = assertThrows(UncheckedIOException.class, () -> Functions.accept(Testable::test, testable)); 306 final Throwable t = e.getCause(); 307 assertNotNull(t); 308 assertSame(ioe, t); 309 310 testable.setThrowable(null); 311 Functions.accept(Testable::test, testable); 312 } 313 314 @Test testAcceptDoubleConsumer()315 public void testAcceptDoubleConsumer() { 316 final IllegalStateException ise = new IllegalStateException(); 317 final Testable<?, Double> testable = new Testable<>(ise); 318 Throwable e = assertThrows(IllegalStateException.class, () -> Functions.accept(testable::testDouble, 1d)); 319 assertSame(ise, e); 320 assertNull(testable.getAcceptedPrimitiveObject1()); 321 322 final Error error = new OutOfMemoryError(); 323 testable.setThrowable(error); 324 e = assertThrows(OutOfMemoryError.class, () -> Functions.accept(testable::testDouble, 1d)); 325 assertSame(error, e); 326 assertNull(testable.getAcceptedPrimitiveObject1()); 327 328 final IOException ioe = new IOException("Unknown I/O error"); 329 testable.setThrowable(ioe); 330 e = assertThrows(UncheckedIOException.class, () -> Functions.accept(testable::testDouble, 1d)); 331 final Throwable t = e.getCause(); 332 assertNotNull(t); 333 assertSame(ioe, t); 334 assertNull(testable.getAcceptedPrimitiveObject1()); 335 336 testable.setThrowable(null); 337 Functions.accept(testable::testDouble, 1d); 338 assertEquals(1, testable.getAcceptedPrimitiveObject1()); 339 } 340 341 @Test testAcceptIntConsumer()342 public void testAcceptIntConsumer() { 343 final IllegalStateException ise = new IllegalStateException(); 344 final Testable<?, Integer> testable = new Testable<>(ise); 345 Throwable e = assertThrows(IllegalStateException.class, () -> Functions.accept(testable::testInt, 1)); 346 assertSame(ise, e); 347 assertNull(testable.getAcceptedPrimitiveObject1()); 348 349 final Error error = new OutOfMemoryError(); 350 testable.setThrowable(error); 351 e = assertThrows(OutOfMemoryError.class, () -> Functions.accept(testable::testInt, 1)); 352 assertSame(error, e); 353 assertNull(testable.getAcceptedPrimitiveObject1()); 354 355 final IOException ioe = new IOException("Unknown I/O error"); 356 testable.setThrowable(ioe); 357 e = assertThrows(UncheckedIOException.class, () -> Functions.accept(testable::testInt, 1)); 358 final Throwable t = e.getCause(); 359 assertNotNull(t); 360 assertSame(ioe, t); 361 assertNull(testable.getAcceptedPrimitiveObject1()); 362 363 testable.setThrowable(null); 364 Functions.accept(testable::testInt, 1); 365 assertEquals(1, testable.getAcceptedPrimitiveObject1()); 366 } 367 368 @Test testAcceptLongConsumer()369 public void testAcceptLongConsumer() { 370 final IllegalStateException ise = new IllegalStateException(); 371 final Testable<?, Long> testable = new Testable<>(ise); 372 Throwable e = assertThrows(IllegalStateException.class, () -> Functions.accept(testable::testLong, 1L)); 373 assertSame(ise, e); 374 assertNull(testable.getAcceptedPrimitiveObject1()); 375 376 final Error error = new OutOfMemoryError(); 377 testable.setThrowable(error); 378 e = assertThrows(OutOfMemoryError.class, () -> Functions.accept(testable::testLong, 1L)); 379 assertSame(error, e); 380 assertNull(testable.getAcceptedPrimitiveObject1()); 381 382 final IOException ioe = new IOException("Unknown I/O error"); 383 testable.setThrowable(ioe); 384 e = assertThrows(UncheckedIOException.class, () -> Functions.accept(testable::testLong, 1L)); 385 final Throwable t = e.getCause(); 386 assertNotNull(t); 387 assertSame(ioe, t); 388 assertNull(testable.getAcceptedPrimitiveObject1()); 389 390 testable.setThrowable(null); 391 Functions.accept(testable::testLong, 1L); 392 assertEquals(1, testable.getAcceptedPrimitiveObject1()); 393 } 394 395 @Test testAcceptObjDoubleConsumer()396 public void testAcceptObjDoubleConsumer() { 397 final IllegalStateException ise = new IllegalStateException(); 398 final Testable<String, Double> testable = new Testable<>(ise); 399 Throwable e = assertThrows(IllegalStateException.class, 400 () -> Functions.accept(testable::testObjDouble, "X", 1d)); 401 assertSame(ise, e); 402 assertNull(testable.getAcceptedObject()); 403 assertNull(testable.getAcceptedPrimitiveObject1()); 404 405 final Error error = new OutOfMemoryError(); 406 testable.setThrowable(error); 407 e = assertThrows(OutOfMemoryError.class, () -> Functions.accept(testable::testObjDouble, "X", 1d)); 408 assertSame(error, e); 409 assertNull(testable.getAcceptedObject()); 410 assertNull(testable.getAcceptedPrimitiveObject1()); 411 412 final IOException ioe = new IOException("Unknown I/O error"); 413 testable.setThrowable(ioe); 414 e = assertThrows(UncheckedIOException.class, () -> Functions.accept(testable::testObjDouble, "X", 1d)); 415 final Throwable t = e.getCause(); 416 assertNotNull(t); 417 assertSame(ioe, t); 418 assertNull(testable.getAcceptedObject()); 419 assertNull(testable.getAcceptedPrimitiveObject1()); 420 421 testable.setThrowable(null); 422 Functions.accept(testable::testObjDouble, "X", 1d); 423 assertEquals("X", testable.getAcceptedObject()); 424 assertEquals(1d, testable.getAcceptedPrimitiveObject1()); 425 } 426 427 @Test testAcceptObjIntConsumer()428 public void testAcceptObjIntConsumer() { 429 final IllegalStateException ise = new IllegalStateException(); 430 final Testable<String, Integer> testable = new Testable<>(ise); 431 Throwable e = assertThrows(IllegalStateException.class, () -> Functions.accept(testable::testObjInt, "X", 1)); 432 assertSame(ise, e); 433 assertNull(testable.getAcceptedObject()); 434 assertNull(testable.getAcceptedPrimitiveObject1()); 435 436 final Error error = new OutOfMemoryError(); 437 testable.setThrowable(error); 438 e = assertThrows(OutOfMemoryError.class, () -> Functions.accept(testable::testObjInt, "X", 1)); 439 assertSame(error, e); 440 assertNull(testable.getAcceptedObject()); 441 assertNull(testable.getAcceptedPrimitiveObject1()); 442 443 final IOException ioe = new IOException("Unknown I/O error"); 444 testable.setThrowable(ioe); 445 e = assertThrows(UncheckedIOException.class, () -> Functions.accept(testable::testObjInt, "X", 1)); 446 final Throwable t = e.getCause(); 447 assertNotNull(t); 448 assertSame(ioe, t); 449 assertNull(testable.getAcceptedObject()); 450 assertNull(testable.getAcceptedPrimitiveObject1()); 451 452 testable.setThrowable(null); 453 Functions.accept(testable::testObjInt, "X", 1); 454 assertEquals("X", testable.getAcceptedObject()); 455 assertEquals(1, testable.getAcceptedPrimitiveObject1()); 456 } 457 458 @Test testAcceptObjLongConsumer()459 public void testAcceptObjLongConsumer() { 460 final IllegalStateException ise = new IllegalStateException(); 461 final Testable<String, Long> testable = new Testable<>(ise); 462 Throwable e = assertThrows(IllegalStateException.class, () -> Functions.accept(testable::testObjLong, "X", 1L)); 463 assertSame(ise, e); 464 assertNull(testable.getAcceptedObject()); 465 assertNull(testable.getAcceptedPrimitiveObject1()); 466 467 final Error error = new OutOfMemoryError(); 468 testable.setThrowable(error); 469 e = assertThrows(OutOfMemoryError.class, () -> Functions.accept(testable::testObjLong, "X", 1L)); 470 assertSame(error, e); 471 assertNull(testable.getAcceptedObject()); 472 assertNull(testable.getAcceptedPrimitiveObject1()); 473 474 final IOException ioe = new IOException("Unknown I/O error"); 475 testable.setThrowable(ioe); 476 e = assertThrows(UncheckedIOException.class, () -> Functions.accept(testable::testObjLong, "X", 1L)); 477 final Throwable t = e.getCause(); 478 assertNotNull(t); 479 assertSame(ioe, t); 480 assertNull(testable.getAcceptedObject()); 481 assertNull(testable.getAcceptedPrimitiveObject1()); 482 483 testable.setThrowable(null); 484 Functions.accept(testable::testObjLong, "X", 1L); 485 assertEquals("X", testable.getAcceptedObject()); 486 assertEquals(1L, testable.getAcceptedPrimitiveObject1()); 487 } 488 489 @Test testApplyBiFunction()490 public void testApplyBiFunction() { 491 final IllegalStateException ise = new IllegalStateException(); 492 final Testable<?, ?> testable = new Testable<>(null); 493 Throwable e = assertThrows(IllegalStateException.class, 494 () -> Functions.apply(Testable::testAsInteger, testable, ise)); 495 assertSame(ise, e); 496 497 final Error error = new OutOfMemoryError(); 498 e = assertThrows(OutOfMemoryError.class, () -> Functions.apply(Testable::testAsInteger, testable, error)); 499 assertSame(error, e); 500 501 final IOException ioe = new IOException("Unknown I/O error"); 502 e = assertThrows(UncheckedIOException.class, () -> Functions.apply(Testable::testAsInteger, testable, ioe)); 503 final Throwable t = e.getCause(); 504 assertNotNull(t); 505 assertSame(ioe, t); 506 507 final Integer i = Functions.apply(Testable::testAsInteger, testable, (Throwable) null); 508 assertNotNull(i); 509 assertEquals(0, i.intValue()); 510 } 511 512 @Test testApplyFunction()513 public void testApplyFunction() { 514 final IllegalStateException ise = new IllegalStateException(); 515 final Testable<?, ?> testable = new Testable<>(ise); 516 Throwable e = assertThrows(IllegalStateException.class, 517 () -> Functions.apply(Testable::testAsInteger, testable)); 518 assertSame(ise, e); 519 520 final Error error = new OutOfMemoryError(); 521 testable.setThrowable(error); 522 e = assertThrows(OutOfMemoryError.class, () -> Functions.apply(Testable::testAsInteger, testable)); 523 assertSame(error, e); 524 525 final IOException ioe = new IOException("Unknown I/O error"); 526 testable.setThrowable(ioe); 527 e = assertThrows(UncheckedIOException.class, () -> Functions.apply(Testable::testAsInteger, testable)); 528 final Throwable t = e.getCause(); 529 assertNotNull(t); 530 assertSame(ioe, t); 531 532 testable.setThrowable(null); 533 final Integer i = Functions.apply(Testable::testAsInteger, testable); 534 assertNotNull(i); 535 assertEquals(0, i.intValue()); 536 } 537 538 @Test testAsCallable()539 public void testAsCallable() { 540 FailureOnOddInvocations.invocations = 0; 541 final FailableCallable<FailureOnOddInvocations, SomeException> failableCallable = FailureOnOddInvocations::new; 542 final Callable<FailureOnOddInvocations> callable = Functions.asCallable(failableCallable); 543 final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, callable::call); 544 final Throwable cause = e.getCause(); 545 assertNotNull(cause); 546 assertTrue(cause instanceof SomeException); 547 assertEquals("Odd Invocation: 1", cause.getMessage()); 548 final FailureOnOddInvocations instance; 549 try { 550 instance = callable.call(); 551 } catch (final Exception ex) { 552 throw Functions.rethrow(ex); 553 } 554 assertNotNull(instance); 555 } 556 557 @Test testAsConsumer()558 public void testAsConsumer() { 559 final IllegalStateException ise = new IllegalStateException(); 560 final Testable<?, ?> testable = new Testable<>(ise); 561 final Consumer<Testable<?, ?>> consumer = Functions.asConsumer(Testable::test); 562 Throwable e = assertThrows(IllegalStateException.class, () -> consumer.accept(testable)); 563 assertSame(ise, e); 564 565 final Error error = new OutOfMemoryError(); 566 testable.setThrowable(error); 567 e = assertThrows(OutOfMemoryError.class, () -> consumer.accept(testable)); 568 assertSame(error, e); 569 570 final IOException ioe = new IOException("Unknown I/O error"); 571 testable.setThrowable(ioe); 572 e = assertThrows(UncheckedIOException.class, () -> consumer.accept(testable)); 573 final Throwable t = e.getCause(); 574 assertNotNull(t); 575 assertSame(ioe, t); 576 577 testable.setThrowable(null); 578 Functions.accept(Testable::test, testable); 579 } 580 581 @Test testAsRunnable()582 public void testAsRunnable() { 583 FailureOnOddInvocations.invocations = 0; 584 final Runnable runnable = Functions.asRunnable(FailureOnOddInvocations::new); 585 final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, runnable::run); 586 final Throwable cause = e.getCause(); 587 assertNotNull(cause); 588 assertTrue(cause instanceof SomeException); 589 assertEquals("Odd Invocation: 1", cause.getMessage()); 590 591 // Even invocations, should not throw an exception 592 runnable.run(); 593 } 594 595 @Test testAsSupplier()596 public void testAsSupplier() { 597 FailureOnOddInvocations.invocations = 0; 598 final FailableSupplier<FailureOnOddInvocations, Throwable> failableSupplier = FailureOnOddInvocations::new; 599 final Supplier<FailureOnOddInvocations> supplier = Functions.asSupplier(failableSupplier); 600 final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, supplier::get); 601 final Throwable cause = e.getCause(); 602 assertNotNull(cause); 603 assertTrue(cause instanceof SomeException); 604 assertEquals("Odd Invocation: 1", cause.getMessage()); 605 assertNotNull(supplier.get()); 606 } 607 608 @Test testBiConsumer()609 public void testBiConsumer() { 610 final IllegalStateException ise = new IllegalStateException(); 611 final Testable<?, ?> testable = new Testable<>(null); 612 final FailableBiConsumer<Testable<?, ?>, Throwable, Throwable> failableBiConsumer = (t, th) -> { 613 t.setThrowable(th); 614 t.test(); 615 }; 616 final BiConsumer<Testable<?, ?>, Throwable> consumer = Functions.asBiConsumer(failableBiConsumer); 617 Throwable e = assertThrows(IllegalStateException.class, () -> consumer.accept(testable, ise)); 618 assertSame(ise, e); 619 620 final Error error = new OutOfMemoryError(); 621 e = assertThrows(OutOfMemoryError.class, () -> consumer.accept(testable, error)); 622 assertSame(error, e); 623 624 final IOException ioe = new IOException("Unknown I/O error"); 625 testable.setThrowable(ioe); 626 e = assertThrows(UncheckedIOException.class, () -> consumer.accept(testable, ioe)); 627 final Throwable t = e.getCause(); 628 assertNotNull(t); 629 assertSame(ioe, t); 630 631 consumer.accept(testable, null); 632 } 633 634 @Test testBiFunction()635 public void testBiFunction() { 636 final IllegalStateException ise = new IllegalStateException(); 637 final Testable<?, ?> testable = new Testable<>(ise); 638 final FailableBiFunction<Testable<?, ?>, Throwable, Integer, Throwable> failableBiFunction = (t, th) -> { 639 t.setThrowable(th); 640 return Integer.valueOf(t.testAsInteger()); 641 }; 642 final BiFunction<Testable<?, ?>, Throwable, Integer> biFunction = Functions.asBiFunction(failableBiFunction); 643 Throwable e = assertThrows(IllegalStateException.class, () -> biFunction.apply(testable, ise)); 644 assertSame(ise, e); 645 646 final Error error = new OutOfMemoryError(); 647 testable.setThrowable(error); 648 e = assertThrows(OutOfMemoryError.class, () -> biFunction.apply(testable, error)); 649 assertSame(error, e); 650 651 final IOException ioe = new IOException("Unknown I/O error"); 652 testable.setThrowable(ioe); 653 e = assertThrows(UncheckedIOException.class, () -> biFunction.apply(testable, ioe)); 654 final Throwable t = e.getCause(); 655 assertNotNull(t); 656 assertSame(ioe, t); 657 658 assertEquals(0, biFunction.apply(testable, null).intValue()); 659 } 660 661 @Test 662 @DisplayName("Test that asPredicate(FailableBiPredicate) is converted to -> BiPredicate ") testBiPredicate()663 public void testBiPredicate() { 664 FailureOnOddInvocations.invocations = 0; 665 final Functions.FailableBiPredicate<Object, Object, Throwable> failableBiPredicate = (t1, 666 t2) -> FailureOnOddInvocations.failingBool(); 667 final BiPredicate<?, ?> predicate = Functions.asBiPredicate(failableBiPredicate); 668 final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, 669 () -> predicate.test(null, null)); 670 final Throwable cause = e.getCause(); 671 assertNotNull(cause); 672 assertTrue(cause instanceof SomeException); 673 assertEquals("Odd Invocation: 1", cause.getMessage()); 674 final boolean instance = predicate.test(null, null); 675 assertNotNull(instance); 676 } 677 678 @Test testCallable()679 public void testCallable() { 680 FailureOnOddInvocations.invocations = 0; 681 final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, 682 () -> Functions.run(FailureOnOddInvocations::new)); 683 final Throwable cause = e.getCause(); 684 assertNotNull(cause); 685 assertTrue(cause instanceof SomeException); 686 assertEquals("Odd Invocation: 1", cause.getMessage()); 687 final FailureOnOddInvocations instance = Functions.call(FailureOnOddInvocations::new); 688 assertNotNull(instance); 689 } 690 691 @Test testConstructor()692 public void testConstructor() { 693 // We allow this, which must have been an omission to make the ctor private. 694 // We could make the ctor private in 4.0. 695 new Functions(); 696 } 697 698 @Test testFunction()699 public void testFunction() { 700 final IllegalStateException ise = new IllegalStateException(); 701 final Testable<?, ?> testable = new Testable<>(ise); 702 final FailableFunction<Throwable, Integer, Throwable> failableFunction = th -> { 703 testable.setThrowable(th); 704 return Integer.valueOf(testable.testAsInteger()); 705 }; 706 final Function<Throwable, Integer> function = Functions.asFunction(failableFunction); 707 Throwable e = assertThrows(IllegalStateException.class, () -> function.apply(ise)); 708 assertSame(ise, e); 709 710 final Error error = new OutOfMemoryError(); 711 testable.setThrowable(error); 712 e = assertThrows(OutOfMemoryError.class, () -> function.apply(error)); 713 assertSame(error, e); 714 715 final IOException ioe = new IOException("Unknown I/O error"); 716 testable.setThrowable(ioe); 717 e = assertThrows(UncheckedIOException.class, () -> function.apply(ioe)); 718 final Throwable t = e.getCause(); 719 assertNotNull(t); 720 assertSame(ioe, t); 721 722 assertEquals(0, function.apply(null).intValue()); 723 } 724 725 @Test testGetFromSupplier()726 public void testGetFromSupplier() { 727 FailureOnOddInvocations.invocations = 0; 728 final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, 729 () -> Functions.run(FailureOnOddInvocations::new)); 730 final Throwable cause = e.getCause(); 731 assertNotNull(cause); 732 assertTrue(cause instanceof SomeException); 733 assertEquals("Odd Invocation: 1", cause.getMessage()); 734 final FailureOnOddInvocations instance = Functions.call(FailureOnOddInvocations::new); 735 assertNotNull(instance); 736 } 737 738 @Test testGetSupplier()739 public void testGetSupplier() { 740 final IllegalStateException ise = new IllegalStateException(); 741 final Testable<?, ?> testable = new Testable<>(ise); 742 Throwable e = assertThrows(IllegalStateException.class, () -> Functions.get(testable::testAsInteger)); 743 assertSame(ise, e); 744 745 final Error error = new OutOfMemoryError(); 746 testable.setThrowable(error); 747 e = assertThrows(OutOfMemoryError.class, () -> Functions.get(testable::testAsInteger)); 748 assertSame(error, e); 749 750 final IOException ioe = new IOException("Unknown I/O error"); 751 testable.setThrowable(ioe); 752 e = assertThrows(UncheckedIOException.class, () -> Functions.get(testable::testAsInteger)); 753 final Throwable t = e.getCause(); 754 assertNotNull(t); 755 assertSame(ioe, t); 756 757 testable.setThrowable(null); 758 final Integer i = Functions.apply(Testable::testAsInteger, testable); 759 assertNotNull(i); 760 assertEquals(0, i.intValue()); 761 } 762 763 @Test 764 @DisplayName("Test that asPredicate(FailablePredicate) is converted to -> Predicate ") testPredicate()765 public void testPredicate() { 766 FailureOnOddInvocations.invocations = 0; 767 final Functions.FailablePredicate<Object, Throwable> failablePredicate = t -> FailureOnOddInvocations 768 .failingBool(); 769 final Predicate<?> predicate = Functions.asPredicate(failablePredicate); 770 final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, 771 () -> predicate.test(null)); 772 final Throwable cause = e.getCause(); 773 assertNotNull(cause); 774 assertTrue(cause instanceof SomeException); 775 assertEquals("Odd Invocation: 1", cause.getMessage()); 776 final boolean instance = predicate.test(null); 777 assertNotNull(instance); 778 } 779 780 @Test testRunnable()781 public void testRunnable() { 782 FailureOnOddInvocations.invocations = 0; 783 final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, 784 () -> Functions.run(FailureOnOddInvocations::new)); 785 final Throwable cause = e.getCause(); 786 assertNotNull(cause); 787 assertTrue(cause instanceof SomeException); 788 assertEquals("Odd Invocation: 1", cause.getMessage()); 789 790 // Even invocations, should not throw an exception 791 Functions.run(FailureOnOddInvocations::new); 792 } 793 794 /** 795 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types 796 * Object and Throwable. 797 */ 798 @Test testThrows_FailableBiConsumer_Object_Throwable()799 public void testThrows_FailableBiConsumer_Object_Throwable() { 800 new Functions.FailableBiConsumer<Object, Object, Throwable>() { 801 802 @Override 803 public void accept(final Object object1, final Object object2) throws Throwable { 804 throw new IOException("test"); 805 } 806 }; 807 } 808 809 /** 810 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as 811 * generic test types. 812 */ 813 @Test testThrows_FailableBiConsumer_String_IOException()814 public void testThrows_FailableBiConsumer_String_IOException() { 815 new Functions.FailableBiConsumer<String, String, IOException>() { 816 817 @Override 818 public void accept(final String object1, final String object2) throws IOException { 819 throw new IOException("test"); 820 821 } 822 }; 823 } 824 825 /** 826 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types 827 * Object and Throwable. 828 */ 829 @Test testThrows_FailableBiFunction_Object_Throwable()830 public void testThrows_FailableBiFunction_Object_Throwable() { 831 new Functions.FailableBiFunction<Object, Object, Object, Throwable>() { 832 833 @Override 834 public Object apply(final Object input1, final Object input2) throws Throwable { 835 throw new IOException("test"); 836 } 837 }; 838 } 839 840 /** 841 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as 842 * generic test types. 843 */ 844 @Test testThrows_FailableBiFunction_String_IOException()845 public void testThrows_FailableBiFunction_String_IOException() { 846 new Functions.FailableBiFunction<String, String, String, IOException>() { 847 848 @Override 849 public String apply(final String input1, final String input2) throws IOException { 850 throw new IOException("test"); 851 } 852 }; 853 } 854 855 /** 856 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types 857 * Object and Throwable. 858 */ 859 @Test testThrows_FailableBiPredicate_Object_Throwable()860 public void testThrows_FailableBiPredicate_Object_Throwable() { 861 new Functions.FailableBiPredicate<Object, Object, Throwable>() { 862 863 @Override 864 public boolean test(final Object object1, final Object object2) throws Throwable { 865 throw new IOException("test"); 866 } 867 }; 868 } 869 870 /** 871 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as 872 * generic test types. 873 */ 874 @Test testThrows_FailableBiPredicate_String_IOException()875 public void testThrows_FailableBiPredicate_String_IOException() { 876 new Functions.FailableBiPredicate<String, String, IOException>() { 877 878 @Override 879 public boolean test(final String object1, final String object2) throws IOException { 880 throw new IOException("test"); 881 } 882 }; 883 } 884 885 /** 886 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types 887 * Object and Throwable. 888 */ 889 @Test testThrows_FailableCallable_Object_Throwable()890 public void testThrows_FailableCallable_Object_Throwable() { 891 new Functions.FailableCallable<Object, Throwable>() { 892 893 @Override 894 public Object call() throws Throwable { 895 throw new IOException("test"); 896 } 897 }; 898 } 899 900 /** 901 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as 902 * generic test types. 903 */ 904 @Test testThrows_FailableCallable_String_IOException()905 public void testThrows_FailableCallable_String_IOException() { 906 new Functions.FailableCallable<String, IOException>() { 907 908 @Override 909 public String call() throws IOException { 910 throw new IOException("test"); 911 } 912 }; 913 } 914 915 /** 916 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types 917 * Object and Throwable. 918 */ 919 @Test testThrows_FailableConsumer_Object_Throwable()920 public void testThrows_FailableConsumer_Object_Throwable() { 921 new Functions.FailableConsumer<Object, Throwable>() { 922 923 @Override 924 public void accept(final Object object) throws Throwable { 925 throw new IOException("test"); 926 927 } 928 }; 929 } 930 931 /** 932 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as 933 * generic test types. 934 */ 935 @Test testThrows_FailableConsumer_String_IOException()936 public void testThrows_FailableConsumer_String_IOException() { 937 new Functions.FailableConsumer<String, IOException>() { 938 939 @Override 940 public void accept(final String object) throws IOException { 941 throw new IOException("test"); 942 943 } 944 }; 945 } 946 947 /** 948 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types 949 * Object and Throwable. 950 */ 951 @Test testThrows_FailableFunction_Object_Throwable()952 public void testThrows_FailableFunction_Object_Throwable() { 953 new Functions.FailableFunction<Object, Object, Throwable>() { 954 955 @Override 956 public Object apply(final Object input) throws Throwable { 957 throw new IOException("test"); 958 } 959 }; 960 } 961 962 /** 963 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as 964 * generic test types. 965 */ 966 @Test testThrows_FailableFunction_String_IOException()967 public void testThrows_FailableFunction_String_IOException() { 968 new Functions.FailableFunction<String, String, IOException>() { 969 970 @Override 971 public String apply(final String input) throws IOException { 972 throw new IOException("test"); 973 } 974 }; 975 } 976 977 /** 978 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types 979 * Object and Throwable. 980 */ 981 @Test testThrows_FailablePredicate_Object_Throwable()982 public void testThrows_FailablePredicate_Object_Throwable() { 983 new Functions.FailablePredicate<Object, Throwable>() { 984 985 @Override 986 public boolean test(final Object object) throws Throwable { 987 throw new IOException("test"); 988 } 989 }; 990 } 991 992 /** 993 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as 994 * generic test types. 995 */ 996 @Test testThrows_FailablePredicate_String_IOException()997 public void testThrows_FailablePredicate_String_IOException() { 998 new Functions.FailablePredicate<String, IOException>() { 999 1000 @Override 1001 public boolean test(final String object) throws IOException { 1002 throw new IOException("test"); 1003 } 1004 }; 1005 } 1006 1007 /** 1008 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types 1009 * Object and Throwable. 1010 */ 1011 @Test testThrows_FailableRunnable_Object_Throwable()1012 public void testThrows_FailableRunnable_Object_Throwable() { 1013 new Functions.FailableRunnable<Throwable>() { 1014 1015 @Override 1016 public void run() throws Throwable { 1017 throw new IOException("test"); 1018 1019 } 1020 }; 1021 } 1022 1023 /** 1024 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as 1025 * generic test types. 1026 */ 1027 @Test testThrows_FailableRunnable_String_IOException()1028 public void testThrows_FailableRunnable_String_IOException() { 1029 new Functions.FailableRunnable<IOException>() { 1030 1031 @Override 1032 public void run() throws IOException { 1033 throw new IOException("test"); 1034 } 1035 }; 1036 } 1037 1038 /** 1039 * Tests that our failable interface is properly defined to throw any exception. using the top level generic types 1040 * Object and Throwable. 1041 */ 1042 @Test testThrows_FailableSupplier_Object_Throwable()1043 public void testThrows_FailableSupplier_Object_Throwable() { 1044 new Functions.FailableSupplier<Object, Throwable>() { 1045 1046 @Override 1047 public Object get() throws Throwable { 1048 throw new IOException("test"); 1049 } 1050 }; 1051 } 1052 1053 /** 1054 * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as 1055 * generic test types. 1056 */ 1057 @Test testThrows_FailableSupplier_String_IOException()1058 public void testThrows_FailableSupplier_String_IOException() { 1059 new Functions.FailableSupplier<String, IOException>() { 1060 1061 @Override 1062 public String get() throws IOException { 1063 throw new IOException("test"); 1064 } 1065 }; 1066 } 1067 1068 @Test testTryWithResources()1069 public void testTryWithResources() { 1070 final CloseableObject co = new CloseableObject(); 1071 final FailableConsumer<Throwable, ? extends Throwable> consumer = co::run; 1072 final IllegalStateException ise = new IllegalStateException(); 1073 Throwable e = assertThrows(IllegalStateException.class, 1074 () -> Functions.tryWithResources(() -> consumer.accept(ise), co::close)); 1075 assertSame(ise, e); 1076 1077 assertTrue(co.isClosed()); 1078 co.reset(); 1079 final Error error = new OutOfMemoryError(); 1080 e = assertThrows(OutOfMemoryError.class, 1081 () -> Functions.tryWithResources(() -> consumer.accept(error), co::close)); 1082 assertSame(error, e); 1083 1084 assertTrue(co.isClosed()); 1085 co.reset(); 1086 final IOException ioe = new IOException("Unknown I/O error"); 1087 final UncheckedIOException uioe = assertThrows(UncheckedIOException.class, 1088 () -> Functions.tryWithResources(() -> consumer.accept(ioe), co::close)); 1089 final IOException cause = uioe.getCause(); 1090 assertSame(ioe, cause); 1091 1092 assertTrue(co.isClosed()); 1093 co.reset(); 1094 Functions.tryWithResources(() -> consumer.accept(null), co::close); 1095 assertTrue(co.isClosed()); 1096 } 1097 } 1098