View Javadoc
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.function;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertNotNull;
22  import static org.junit.jupiter.api.Assertions.assertNull;
23  import static org.junit.jupiter.api.Assertions.assertSame;
24  import static org.junit.jupiter.api.Assertions.assertThrows;
25  import static org.junit.jupiter.api.Assertions.assertTrue;
26  
27  import java.io.IOException;
28  import java.io.UncheckedIOException;
29  import java.lang.reflect.UndeclaredThrowableException;
30  import java.util.concurrent.Callable;
31  import java.util.function.BiConsumer;
32  import java.util.function.BiFunction;
33  import java.util.function.BiPredicate;
34  import java.util.function.Consumer;
35  import java.util.function.Function;
36  import java.util.function.Predicate;
37  import java.util.function.Supplier;
38  
39  import org.apache.commons.lang3.AbstractLangTest;
40  import org.junit.jupiter.api.DisplayName;
41  import org.junit.jupiter.api.Test;
42  
43  /**
44   * Tests "failable" interfaces defined in this package.
45   */
46  public class FailableFunctionsTest extends AbstractLangTest {
47  
48      public static class CloseableObject {
49          private boolean closed;
50  
51          public void close() {
52              closed = true;
53          }
54  
55          public boolean isClosed() {
56              return closed;
57          }
58  
59          public void reset() {
60              closed = false;
61          }
62  
63          public void run(final Throwable pTh) throws Throwable {
64              if (pTh != null) {
65                  throw pTh;
66              }
67          }
68      }
69  
70      public static class FailureOnOddInvocations {
71          private static int invocations;
72  
73          static boolean failingBool() throws SomeException {
74              throwOnOdd();
75              return true;
76          }
77  
78          static boolean testDouble(final double value) throws SomeException {
79              throwOnOdd();
80              return true;
81          }
82  
83          static boolean testInt(final int value) throws SomeException {
84              throwOnOdd();
85              return true;
86          }
87  
88          static boolean testLong(final long value) throws SomeException {
89              throwOnOdd();
90              return true;
91          }
92  
93          private static void throwOnOdd() throws SomeException {
94              final int i = ++invocations;
95              if (i % 2 == 1) {
96                  throw new SomeException("Odd Invocation: " + i);
97              }
98          }
99  
100         FailureOnOddInvocations() throws SomeException {
101             throwOnOdd();
102         }
103 
104         boolean getAsBoolean() throws SomeException {
105             throwOnOdd();
106             return true;
107         }
108     }
109 
110     public static class SomeException extends Exception {
111 
112         private static final long serialVersionUID = -4965704778119283411L;
113 
114         private Throwable t;
115 
116         SomeException(final String message) {
117             super(message);
118         }
119 
120         public void setThrowable(final Throwable throwable) {
121             t = throwable;
122         }
123 
124         public void test() throws Throwable {
125             if (t != null) {
126                 throw t;
127             }
128         }
129     }
130 
131     public static class Testable<T, P> {
132         private T acceptedObject;
133         private P acceptedPrimitiveObject1;
134         private P acceptedPrimitiveObject2;
135         private Throwable throwable;
136 
137         Testable(final Throwable throwable) {
138             this.throwable = throwable;
139         }
140 
141         public T getAcceptedObject() {
142             return acceptedObject;
143         }
144 
145         public P getAcceptedPrimitiveObject1() {
146             return acceptedPrimitiveObject1;
147         }
148 
149         public P getAcceptedPrimitiveObject2() {
150             return acceptedPrimitiveObject2;
151         }
152 
153         public void setThrowable(final Throwable throwable) {
154             this.throwable = throwable;
155         }
156 
157         public void test() throws Throwable {
158             test(throwable);
159         }
160 
161         public Object test(final Object input1, final Object input2) throws Throwable {
162             test(throwable);
163             return acceptedObject;
164         }
165 
166         public void test(final Throwable throwable) throws Throwable {
167             if (throwable != null) {
168                 throw throwable;
169             }
170         }
171 
172         public boolean testAsBooleanPrimitive() throws Throwable {
173             return testAsBooleanPrimitive(throwable);
174         }
175 
176         public boolean testAsBooleanPrimitive(final Throwable throwable) throws Throwable {
177             if (throwable != null) {
178                 throw throwable;
179             }
180             return false;
181         }
182 
183         public double testAsDoublePrimitive() throws Throwable {
184             return testAsDoublePrimitive(throwable);
185         }
186 
187         public double testAsDoublePrimitive(final Throwable throwable) throws Throwable {
188             if (throwable != null) {
189                 throw throwable;
190             }
191             return 0;
192         }
193 
194         public Integer testAsInteger() throws Throwable {
195             return testAsInteger(throwable);
196         }
197 
198         public Integer testAsInteger(final Throwable throwable) throws Throwable {
199             if (throwable != null) {
200                 throw throwable;
201             }
202             return 0;
203         }
204 
205         public int testAsIntPrimitive() throws Throwable {
206             return testAsIntPrimitive(throwable);
207         }
208 
209         public int testAsIntPrimitive(final Throwable throwable) throws Throwable {
210             if (throwable != null) {
211                 throw throwable;
212             }
213             return 0;
214         }
215 
216         public long testAsLongPrimitive() throws Throwable {
217             return testAsLongPrimitive(throwable);
218         }
219 
220         public long testAsLongPrimitive(final Throwable throwable) throws Throwable {
221             if (throwable != null) {
222                 throw throwable;
223             }
224             return 0;
225         }
226 
227         public short testAsShortPrimitive() throws Throwable {
228             return testAsShortPrimitive(throwable);
229         }
230 
231         public short testAsShortPrimitive(final Throwable throwable) throws Throwable {
232             if (throwable != null) {
233                 throw throwable;
234             }
235             return 0;
236         }
237 
238         public void testDouble(final double i) throws Throwable {
239             test(throwable);
240             acceptedPrimitiveObject1 = (P) (Double) i;
241         }
242 
243         public double testDoubleDouble(final double i, final double j) throws Throwable {
244             test(throwable);
245             acceptedPrimitiveObject1 = (P) (Double) i;
246             acceptedPrimitiveObject2 = (P) (Double) j;
247             return 3d;
248         }
249 
250         public void testInt(final int i) throws Throwable {
251             test(throwable);
252             acceptedPrimitiveObject1 = (P) (Integer) i;
253         }
254 
255         public void testLong(final long i) throws Throwable {
256             test(throwable);
257             acceptedPrimitiveObject1 = (P) (Long) i;
258         }
259 
260         public void testObjDouble(final T object, final double i) throws Throwable {
261             test(throwable);
262             acceptedObject = object;
263             acceptedPrimitiveObject1 = (P) (Double) i;
264         }
265 
266         public void testObjInt(final T object, final int i) throws Throwable {
267             test(throwable);
268             acceptedObject = object;
269             acceptedPrimitiveObject1 = (P) (Integer) i;
270         }
271 
272         public void testObjLong(final T object, final long i) throws Throwable {
273             test(throwable);
274             acceptedObject = object;
275             acceptedPrimitiveObject1 = (P) (Long) i;
276         }
277     }
278 
279     private static final OutOfMemoryError ERROR = new OutOfMemoryError();
280 
281     private static final IllegalStateException ILLEGAL_STATE_EXCEPTION = new IllegalStateException();
282 
283     @Test
284     public void testAcceptBiConsumer() {
285         final Testable<?, ?> testable = new Testable<>(null);
286         Throwable e = assertThrows(IllegalStateException.class,
287             () -> Failable.accept(Testable::test, testable, ILLEGAL_STATE_EXCEPTION));
288         assertSame(ILLEGAL_STATE_EXCEPTION, e);
289 
290         e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(Testable::test, testable, ERROR));
291         assertSame(ERROR, e);
292 
293         final IOException ioe = new IOException("Unknown I/O error");
294         testable.setThrowable(ioe);
295         e = assertThrows(UncheckedIOException.class, () -> Failable.accept(Testable::test, testable, ioe));
296         final Throwable t = e.getCause();
297         assertNotNull(t);
298         assertSame(ioe, t);
299 
300         testable.setThrowable(null);
301         Failable.accept(Testable::test, testable, (Throwable) null);
302     }
303 
304     @Test
305     public void testAcceptConsumer() {
306         final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
307         Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(Testable::test, testable));
308         assertSame(ILLEGAL_STATE_EXCEPTION, e);
309 
310         testable.setThrowable(ERROR);
311         e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(Testable::test, testable));
312         assertSame(ERROR, e);
313 
314         final IOException ioe = new IOException("Unknown I/O error");
315         testable.setThrowable(ioe);
316         e = assertThrows(UncheckedIOException.class, () -> Failable.accept(Testable::test, testable));
317         final Throwable t = e.getCause();
318         assertNotNull(t);
319         assertSame(ioe, t);
320 
321         testable.setThrowable(null);
322         Failable.accept(Testable::test, testable);
323     }
324 
325     @Test
326     public void testAcceptDoubleConsumer() {
327         final Testable<?, Double> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
328         Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(testable::testDouble, 1d));
329         assertSame(ILLEGAL_STATE_EXCEPTION, e);
330         assertNull(testable.getAcceptedPrimitiveObject1());
331 
332         testable.setThrowable(ERROR);
333         e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testDouble, 1d));
334         assertSame(ERROR, e);
335         assertNull(testable.getAcceptedPrimitiveObject1());
336 
337         final IOException ioe = new IOException("Unknown I/O error");
338         testable.setThrowable(ioe);
339         e = assertThrows(UncheckedIOException.class, () -> Failable.accept(testable::testDouble, 1d));
340         final Throwable t = e.getCause();
341         assertNotNull(t);
342         assertSame(ioe, t);
343         assertNull(testable.getAcceptedPrimitiveObject1());
344 
345         testable.setThrowable(null);
346         Failable.accept(testable::testDouble, 1d);
347         assertEquals(1, testable.getAcceptedPrimitiveObject1());
348     }
349 
350     @Test
351     public void testAcceptIntConsumer() {
352         final Testable<?, Integer> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
353         Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(testable::testInt, 1));
354         assertSame(ILLEGAL_STATE_EXCEPTION, e);
355         assertNull(testable.getAcceptedPrimitiveObject1());
356 
357         testable.setThrowable(ERROR);
358         e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testInt, 1));
359         assertSame(ERROR, e);
360         assertNull(testable.getAcceptedPrimitiveObject1());
361 
362         final IOException ioe = new IOException("Unknown I/O error");
363         testable.setThrowable(ioe);
364         e = assertThrows(UncheckedIOException.class, () -> Failable.accept(testable::testInt, 1));
365         final Throwable t = e.getCause();
366         assertNotNull(t);
367         assertSame(ioe, t);
368         assertNull(testable.getAcceptedPrimitiveObject1());
369 
370         testable.setThrowable(null);
371         Failable.accept(testable::testInt, 1);
372         assertEquals(1, testable.getAcceptedPrimitiveObject1());
373     }
374 
375     @Test
376     public void testAcceptLongConsumer() {
377         final Testable<?, Long> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
378         Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(testable::testLong, 1L));
379         assertSame(ILLEGAL_STATE_EXCEPTION, e);
380         assertNull(testable.getAcceptedPrimitiveObject1());
381 
382         testable.setThrowable(ERROR);
383         e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testLong, 1L));
384         assertSame(ERROR, e);
385         assertNull(testable.getAcceptedPrimitiveObject1());
386 
387         final IOException ioe = new IOException("Unknown I/O error");
388         testable.setThrowable(ioe);
389         e = assertThrows(UncheckedIOException.class, () -> Failable.accept(testable::testLong, 1L));
390         final Throwable t = e.getCause();
391         assertNotNull(t);
392         assertSame(ioe, t);
393         assertNull(testable.getAcceptedPrimitiveObject1());
394 
395         testable.setThrowable(null);
396         Failable.accept(testable::testLong, 1L);
397         assertEquals(1, testable.getAcceptedPrimitiveObject1());
398     }
399 
400     @Test
401     public void testAcceptObjDoubleConsumer() {
402         final Testable<String, Double> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
403         Throwable e = assertThrows(IllegalStateException.class,
404             () -> Failable.accept(testable::testObjDouble, "X", 1d));
405         assertSame(ILLEGAL_STATE_EXCEPTION, e);
406         assertNull(testable.getAcceptedObject());
407         assertNull(testable.getAcceptedPrimitiveObject1());
408 
409         testable.setThrowable(ERROR);
410         e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testObjDouble, "X", 1d));
411         assertSame(ERROR, e);
412         assertNull(testable.getAcceptedObject());
413         assertNull(testable.getAcceptedPrimitiveObject1());
414 
415         final IOException ioe = new IOException("Unknown I/O error");
416         testable.setThrowable(ioe);
417         e = assertThrows(UncheckedIOException.class, () -> Failable.accept(testable::testObjDouble, "X", 1d));
418         final Throwable t = e.getCause();
419         assertNotNull(t);
420         assertSame(ioe, t);
421         assertNull(testable.getAcceptedObject());
422         assertNull(testable.getAcceptedPrimitiveObject1());
423 
424         testable.setThrowable(null);
425         Failable.accept(testable::testObjDouble, "X", 1d);
426         assertEquals("X", testable.getAcceptedObject());
427         assertEquals(1d, testable.getAcceptedPrimitiveObject1());
428     }
429 
430     @Test
431     public void testAcceptObjIntConsumer() {
432         final Testable<String, Integer> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
433         Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(testable::testObjInt, "X", 1));
434         assertSame(ILLEGAL_STATE_EXCEPTION, e);
435         assertNull(testable.getAcceptedObject());
436         assertNull(testable.getAcceptedPrimitiveObject1());
437 
438         testable.setThrowable(ERROR);
439         e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testObjInt, "X", 1));
440         assertSame(ERROR, e);
441         assertNull(testable.getAcceptedObject());
442         assertNull(testable.getAcceptedPrimitiveObject1());
443 
444         final IOException ioe = new IOException("Unknown I/O error");
445         testable.setThrowable(ioe);
446         e = assertThrows(UncheckedIOException.class, () -> Failable.accept(testable::testObjInt, "X", 1));
447         final Throwable t = e.getCause();
448         assertNotNull(t);
449         assertSame(ioe, t);
450         assertNull(testable.getAcceptedObject());
451         assertNull(testable.getAcceptedPrimitiveObject1());
452 
453         testable.setThrowable(null);
454         Failable.accept(testable::testObjInt, "X", 1);
455         assertEquals("X", testable.getAcceptedObject());
456         assertEquals(1, testable.getAcceptedPrimitiveObject1());
457     }
458 
459     @Test
460     public void testAcceptObjLongConsumer() {
461         final Testable<String, Long> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
462         Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(testable::testObjLong, "X", 1L));
463         assertSame(ILLEGAL_STATE_EXCEPTION, e);
464         assertNull(testable.getAcceptedObject());
465         assertNull(testable.getAcceptedPrimitiveObject1());
466 
467         testable.setThrowable(ERROR);
468         e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testObjLong, "X", 1L));
469         assertSame(ERROR, e);
470         assertNull(testable.getAcceptedObject());
471         assertNull(testable.getAcceptedPrimitiveObject1());
472 
473         final IOException ioe = new IOException("Unknown I/O error");
474         testable.setThrowable(ioe);
475         e = assertThrows(UncheckedIOException.class, () -> Failable.accept(testable::testObjLong, "X", 1L));
476         final Throwable t = e.getCause();
477         assertNotNull(t);
478         assertSame(ioe, t);
479         assertNull(testable.getAcceptedObject());
480         assertNull(testable.getAcceptedPrimitiveObject1());
481 
482         testable.setThrowable(null);
483         Failable.accept(testable::testObjLong, "X", 1L);
484         assertEquals("X", testable.getAcceptedObject());
485         assertEquals(1L, testable.getAcceptedPrimitiveObject1());
486     }
487 
488     @Test
489     public void testApplyBiFunction() {
490         final Testable<?, ?> testable = new Testable<>(null);
491         Throwable e = assertThrows(IllegalStateException.class,
492             () -> Failable.apply(Testable::testAsInteger, testable, ILLEGAL_STATE_EXCEPTION));
493         assertSame(ILLEGAL_STATE_EXCEPTION, e);
494 
495         e = assertThrows(OutOfMemoryError.class, () -> Failable.apply(Testable::testAsInteger, testable, ERROR));
496         assertSame(ERROR, e);
497 
498         final IOException ioe = new IOException("Unknown I/O error");
499         e = assertThrows(UncheckedIOException.class, () -> Failable.apply(Testable::testAsInteger, testable, ioe));
500         final Throwable t = e.getCause();
501         assertNotNull(t);
502         assertSame(ioe, t);
503 
504         final Integer i = Failable.apply(Testable::testAsInteger, testable, (Throwable) null);
505         assertNotNull(i);
506         assertEquals(0, i.intValue());
507     }
508 
509     @Test
510     public void testApplyDoubleBinaryOperator() {
511         final Testable<?, Double> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
512         final Throwable e = assertThrows(IllegalStateException.class,
513             () -> Failable.applyAsDouble(testable::testDoubleDouble, 1d, 2d));
514         assertSame(ILLEGAL_STATE_EXCEPTION, e);
515 
516         final Testable<?, Double> testable2 = new Testable<>(null);
517         final double i = Failable.applyAsDouble(testable2::testDoubleDouble, 1d, 2d);
518         assertEquals(3d, i);
519     }
520 
521     @Test
522     public void testApplyFunction() {
523         final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
524         Throwable e = assertThrows(IllegalStateException.class,
525             () -> Failable.apply(Testable::testAsInteger, testable));
526         assertSame(ILLEGAL_STATE_EXCEPTION, e);
527 
528         testable.setThrowable(ERROR);
529         e = assertThrows(OutOfMemoryError.class, () -> Failable.apply(Testable::testAsInteger, testable));
530         assertSame(ERROR, e);
531 
532         final IOException ioe = new IOException("Unknown I/O error");
533         testable.setThrowable(ioe);
534         e = assertThrows(UncheckedIOException.class, () -> Failable.apply(Testable::testAsInteger, testable));
535         final Throwable t = e.getCause();
536         assertNotNull(t);
537         assertSame(ioe, t);
538 
539         testable.setThrowable(null);
540         final Integer i = Failable.apply(Testable::testAsInteger, testable);
541         assertNotNull(i);
542         assertEquals(0, i.intValue());
543     }
544 
545     @Test
546     public void testAsCallable() {
547         FailureOnOddInvocations.invocations = 0;
548         final FailableCallable<FailureOnOddInvocations, SomeException> failableCallable = FailureOnOddInvocations::new;
549         final Callable<FailureOnOddInvocations> callable = Failable.asCallable(failableCallable);
550         final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, callable::call);
551         final Throwable cause = e.getCause();
552         assertNotNull(cause);
553         assertTrue(cause instanceof SomeException);
554         assertEquals("Odd Invocation: 1", cause.getMessage());
555         final FailureOnOddInvocations instance;
556         try {
557             instance = callable.call();
558         } catch (final Exception ex) {
559             throw Failable.rethrow(ex);
560         }
561         assertNotNull(instance);
562     }
563 
564     @Test
565     public void testAsConsumer() {
566         final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
567         final Consumer<Testable<?, ?>> consumer = Failable.asConsumer(Testable::test);
568         Throwable e = assertThrows(IllegalStateException.class, () -> consumer.accept(testable));
569         assertSame(ILLEGAL_STATE_EXCEPTION, e);
570 
571         testable.setThrowable(ERROR);
572         e = assertThrows(OutOfMemoryError.class, () -> consumer.accept(testable));
573         assertSame(ERROR, e);
574 
575         final IOException ioe = new IOException("Unknown I/O error");
576         testable.setThrowable(ioe);
577         e = assertThrows(UncheckedIOException.class, () -> consumer.accept(testable));
578         final Throwable t = e.getCause();
579         assertNotNull(t);
580         assertSame(ioe, t);
581 
582         testable.setThrowable(null);
583         Failable.accept(Testable::test, testable);
584     }
585 
586     @Test
587     public void testAsRunnable() {
588         FailureOnOddInvocations.invocations = 0;
589         final Runnable runnable = Failable.asRunnable(FailureOnOddInvocations::new);
590         final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, runnable::run);
591         final Throwable cause = e.getCause();
592         assertNotNull(cause);
593         assertTrue(cause instanceof SomeException);
594         assertEquals("Odd Invocation: 1", cause.getMessage());
595 
596         // Even invocations, should not throw an exception
597         runnable.run();
598     }
599 
600     @Test
601     public void testAsSupplier() {
602         FailureOnOddInvocations.invocations = 0;
603         final FailableSupplier<FailureOnOddInvocations, Throwable> failableSupplier = FailureOnOddInvocations::new;
604         final Supplier<FailureOnOddInvocations> supplier = Failable.asSupplier(failableSupplier);
605         final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, supplier::get);
606         final Throwable cause = e.getCause();
607         assertNotNull(cause);
608         assertTrue(cause instanceof SomeException);
609         assertEquals("Odd Invocation: 1", cause.getMessage());
610         assertNotNull(supplier.get());
611     }
612 
613     @Test
614     public void testBiConsumer() throws Throwable {
615         final Testable<?, ?> testable = new Testable<>(null);
616         final FailableBiConsumer<Testable<?, ?>, Throwable, Throwable> failableBiConsumer = (t, th) -> {
617             t.setThrowable(th);
618             t.test();
619         };
620         final BiConsumer<Testable<?, ?>, Throwable> consumer = Failable.asBiConsumer(failableBiConsumer);
621         Throwable e = assertThrows(IllegalStateException.class,
622             () -> consumer.accept(testable, ILLEGAL_STATE_EXCEPTION));
623         assertSame(ILLEGAL_STATE_EXCEPTION, e);
624 
625         e = assertThrows(OutOfMemoryError.class, () -> consumer.accept(testable, ERROR));
626         assertSame(ERROR, e);
627 
628         e = assertThrows(OutOfMemoryError.class, () -> failableBiConsumer.accept(testable, ERROR));
629         assertSame(ERROR, e);
630 
631         final IOException ioe = new IOException("Unknown I/O error");
632         testable.setThrowable(ioe);
633         e = assertThrows(UncheckedIOException.class, () -> consumer.accept(testable, ioe));
634         final Throwable t = e.getCause();
635         assertNotNull(t);
636         assertSame(ioe, t);
637 
638         consumer.accept(testable, null);
639     }
640 
641     @Test
642     public void testBiConsumerAndThen() throws Throwable {
643         final Testable<?, ?> testable = new Testable<>(null);
644         final FailableBiConsumer<Testable<?, ?>, Throwable, Throwable> failing = (t, th) -> {
645             t.setThrowable(th);
646             t.test();
647         };
648         final FailableBiConsumer<Testable<?, ?>, Throwable, Throwable> nop = FailableBiConsumer.nop();
649         Throwable e = assertThrows(OutOfMemoryError.class, () -> nop.andThen(failing).accept(testable, ERROR));
650         assertSame(ERROR, e);
651         e = assertThrows(OutOfMemoryError.class, () -> failing.andThen(nop).accept(testable, ERROR));
652         assertSame(ERROR, e);
653         // Does not throw
654         nop.andThen(nop);
655         // Documented in Javadoc edge-case.
656         assertThrows(NullPointerException.class, () -> failing.andThen(null));
657     }
658 
659     @Test
660     public void testBiFunction() {
661         final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
662         final FailableBiFunction<Testable<?, ?>, Throwable, Integer, Throwable> failableBiFunction = (t, th) -> {
663             t.setThrowable(th);
664             return t.testAsInteger();
665         };
666         final BiFunction<Testable<?, ?>, Throwable, Integer> biFunction = Failable.asBiFunction(failableBiFunction);
667         Throwable e = assertThrows(IllegalStateException.class,
668             () -> biFunction.apply(testable, ILLEGAL_STATE_EXCEPTION));
669         assertSame(ILLEGAL_STATE_EXCEPTION, e);
670 
671         testable.setThrowable(ERROR);
672         e = assertThrows(OutOfMemoryError.class, () -> biFunction.apply(testable, ERROR));
673         assertSame(ERROR, e);
674 
675         final IOException ioe = new IOException("Unknown I/O error");
676         testable.setThrowable(ioe);
677         e = assertThrows(UncheckedIOException.class, () -> biFunction.apply(testable, ioe));
678         final Throwable t = e.getCause();
679         assertNotNull(t);
680         assertSame(ioe, t);
681 
682         assertEquals(0, biFunction.apply(testable, null).intValue());
683     }
684 
685     @Test
686     public void testBiFunctionAndThen() throws IOException {
687         // Unchecked usage pattern in JRE
688         final BiFunction<Object, Integer, Integer> nopBiFunction = (t, u) -> null;
689         final Function<Object, Integer> nopFunction = t -> null;
690         nopBiFunction.andThen(nopFunction);
691         // Checked usage pattern
692         final FailableBiFunction<Object, Integer, Integer, IOException> failingBiFunctionTest = (t, u) -> {
693             throw new IOException();
694         };
695         final FailableFunction<Object, Integer, IOException> failingFunction = t -> {
696             throw new IOException();
697         };
698         final FailableBiFunction<Object, Integer, Integer, IOException> nopFailableBiFunction = FailableBiFunction
699             .nop();
700         final FailableFunction<Object, Integer, IOException> nopFailableFunction = FailableFunction.nop();
701         //
702         assertThrows(IOException.class, () -> failingBiFunctionTest.andThen(failingFunction).apply(null, null));
703         assertThrows(IOException.class, () -> failingBiFunctionTest.andThen(nopFailableFunction).apply(null, null));
704         //
705         assertThrows(IOException.class, () -> nopFailableBiFunction.andThen(failingFunction).apply(null, null));
706         nopFailableBiFunction.andThen(nopFailableFunction).apply(null, null);
707         // Documented in Javadoc edge-case.
708         assertThrows(NullPointerException.class, () -> failingBiFunctionTest.andThen(null));
709     }
710 
711     @Test
712     @DisplayName("Test that asPredicate(FailableBiPredicate) is converted to -> BiPredicate ")
713     public void testBiPredicate() {
714         FailureOnOddInvocations.invocations = 0;
715         final FailableBiPredicate<Object, Object, Throwable> failableBiPredicate = (t1, t2) -> FailureOnOddInvocations
716             .failingBool();
717         final BiPredicate<?, ?> predicate = Failable.asBiPredicate(failableBiPredicate);
718         final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class,
719             () -> predicate.test(null, null));
720         final Throwable cause = e.getCause();
721         assertNotNull(cause);
722         assertTrue(cause instanceof SomeException);
723         assertEquals("Odd Invocation: 1", cause.getMessage());
724         assertTrue(predicate.test(null, null));
725     }
726 
727     @Test
728     public void testBiPredicateAnd() throws Throwable {
729         assertTrue(FailableBiPredicate.TRUE.and(FailableBiPredicate.TRUE).test(null, null));
730         assertFalse(FailableBiPredicate.TRUE.and(FailableBiPredicate.FALSE).test(null, null));
731         assertFalse(FailableBiPredicate.FALSE.and(FailableBiPredicate.TRUE).test(null, null));
732         assertFalse(FailableBiPredicate.FALSE.and(FailableBiPredicate.FALSE).test(null, null));
733         // null tests
734         assertThrows(NullPointerException.class,
735             () -> assertFalse(FailableBiPredicate.falsePredicate().and(null).test(null, null)));
736         assertThrows(NullPointerException.class,
737             () -> assertTrue(FailableBiPredicate.truePredicate().and(null).test(null, null)));
738     }
739 
740     @Test
741     public void testBiPredicateNegate() throws Throwable {
742         assertFalse(FailableBiPredicate.TRUE.negate().test(null, null));
743         assertFalse(FailableBiPredicate.truePredicate().negate().test(null, null));
744         assertTrue(FailableBiPredicate.FALSE.negate().test(null, null));
745         assertTrue(FailableBiPredicate.falsePredicate().negate().test(null, null));
746     }
747 
748     @Test
749     public void testBiPredicateOr() throws Throwable {
750         assertTrue(FailableBiPredicate.TRUE.or(FailableBiPredicate.TRUE).test(null, null));
751         assertTrue(FailableBiPredicate.TRUE.or(FailableBiPredicate.FALSE).test(null, null));
752         assertTrue(FailableBiPredicate.FALSE.or(FailableBiPredicate.TRUE).test(null, null));
753         assertFalse(FailableBiPredicate.FALSE.or(FailableBiPredicate.FALSE).test(null, null));
754         // null tests
755         assertThrows(NullPointerException.class,
756             () -> assertFalse(FailableBiPredicate.falsePredicate().or(null).test(null, null)));
757         assertThrows(NullPointerException.class,
758             () -> assertTrue(FailableBiPredicate.truePredicate().or(null).test(null, null)));
759     }
760 
761     @Test
762     public void testCallable() {
763         FailureOnOddInvocations.invocations = 0;
764         final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class,
765             () -> Failable.run(FailureOnOddInvocations::new));
766         final Throwable cause = e.getCause();
767         assertNotNull(cause);
768         assertTrue(cause instanceof SomeException);
769         assertEquals("Odd Invocation: 1", cause.getMessage());
770         final FailureOnOddInvocations instance = Failable.call(FailureOnOddInvocations::new);
771         assertNotNull(instance);
772     }
773 
774     @Test
775     public void testConsumerAndThen() throws Throwable {
776         final Testable<?, ?> testable = new Testable<>(null);
777         final FailableConsumer<Throwable, Throwable> failableConsumer = th -> {
778             testable.setThrowable(th);
779             testable.test();
780         };
781         final FailableConsumer<Throwable, Throwable> nop = FailableConsumer.nop();
782         final Throwable e = assertThrows(OutOfMemoryError.class, () -> nop.andThen(failableConsumer).accept(ERROR));
783         assertSame(ERROR, e);
784         // Does not throw
785         nop.andThen(nop);
786         // Documented in Javadoc edge-case.
787         assertThrows(NullPointerException.class, () -> failableConsumer.andThen(null));
788     }
789 
790     @Test
791     public void testDoubleConsumerAndThen() throws Throwable {
792         final Testable<?, ?> testable = new Testable<>(null);
793         final FailableDoubleConsumer<Throwable> failing = t -> {
794             testable.setThrowable(ERROR);
795             testable.test();
796         };
797         final FailableDoubleConsumer<Throwable> nop = FailableDoubleConsumer.nop();
798         Throwable e = assertThrows(OutOfMemoryError.class, () -> nop.andThen(failing).accept(0d));
799         assertSame(ERROR, e);
800         e = assertThrows(OutOfMemoryError.class, () -> failing.andThen(nop).accept(0d));
801         assertSame(ERROR, e);
802         // Does not throw
803         nop.andThen(nop);
804         // Documented in Javadoc edge-case.
805         assertThrows(NullPointerException.class, () -> failing.andThen(null));
806     }
807 
808     @Test
809     public void testDoublePredicate() throws Throwable {
810         FailureOnOddInvocations.invocations = 0;
811         final FailableDoublePredicate<Throwable> failablePredicate = FailureOnOddInvocations::testDouble;
812         assertThrows(SomeException.class, () -> failablePredicate.test(1d));
813         failablePredicate.test(1d);
814     }
815 
816     @Test
817     public void testDoublePredicateAnd() throws Throwable {
818         assertTrue(FailableDoublePredicate.TRUE.and(FailableDoublePredicate.TRUE).test(0));
819         assertFalse(FailableDoublePredicate.TRUE.and(FailableDoublePredicate.FALSE).test(0));
820         assertFalse(FailableDoublePredicate.FALSE.and(FailableDoublePredicate.TRUE).test(0));
821         assertFalse(FailableDoublePredicate.FALSE.and(FailableDoublePredicate.FALSE).test(0));
822         // null tests
823         assertThrows(NullPointerException.class,
824             () -> assertFalse(FailableDoublePredicate.falsePredicate().and(null).test(0)));
825         assertThrows(NullPointerException.class,
826             () -> assertTrue(FailableDoublePredicate.truePredicate().and(null).test(0)));
827     }
828 
829     @Test
830     public void testDoublePredicateNegate() throws Throwable {
831         assertFalse(FailableDoublePredicate.TRUE.negate().test(0d));
832         assertFalse(FailableDoublePredicate.truePredicate().negate().test(0d));
833         assertTrue(FailableDoublePredicate.FALSE.negate().test(0d));
834         assertTrue(FailableDoublePredicate.falsePredicate().negate().test(0d));
835     }
836 
837     @Test
838     public void testDoublePredicateOr() throws Throwable {
839         assertTrue(FailableDoublePredicate.TRUE.or(FailableDoublePredicate.TRUE).test(0));
840         assertTrue(FailableDoublePredicate.TRUE.or(FailableDoublePredicate.FALSE).test(0));
841         assertTrue(FailableDoublePredicate.FALSE.or(FailableDoublePredicate.TRUE).test(0));
842         assertFalse(FailableDoublePredicate.FALSE.or(FailableDoublePredicate.FALSE).test(0));
843         // null tests
844         assertThrows(NullPointerException.class,
845             () -> assertFalse(FailableDoublePredicate.falsePredicate().or(null).test(0)));
846         assertThrows(NullPointerException.class,
847             () -> assertTrue(FailableDoublePredicate.truePredicate().or(null).test(0)));
848     }
849 
850     @Test
851     public void testDoubleUnaryOperatorAndThen() throws Throwable {
852         final Testable<?, ?> testable = new Testable<>(null);
853         final FailableDoubleUnaryOperator<Throwable> failing = t -> {
854             testable.setThrowable(ERROR);
855             testable.test();
856             return 0d;
857         };
858         final FailableDoubleUnaryOperator<Throwable> nop = FailableDoubleUnaryOperator.nop();
859         Throwable e = assertThrows(OutOfMemoryError.class, () -> nop.andThen(failing).applyAsDouble(0d));
860         assertSame(ERROR, e);
861         e = assertThrows(OutOfMemoryError.class, () -> failing.andThen(nop).applyAsDouble(0d));
862         assertSame(ERROR, e);
863         // Does not throw
864         nop.andThen(nop);
865         // Documented in Javadoc edge-case.
866         assertThrows(NullPointerException.class, () -> failing.andThen(null));
867     }
868 
869     @Test
870     public void testDoubleUnaryOperatorCompose() throws Throwable {
871         final Testable<?, ?> testable = new Testable<>(null);
872         final FailableDoubleUnaryOperator<Throwable> failing = t -> {
873             testable.setThrowable(ERROR);
874             testable.test();
875             return 0d;
876         };
877         final FailableDoubleUnaryOperator<Throwable> nop = FailableDoubleUnaryOperator.nop();
878         Throwable e = assertThrows(OutOfMemoryError.class, () -> nop.compose(failing).applyAsDouble(0d));
879         assertSame(ERROR, e);
880         e = assertThrows(OutOfMemoryError.class, () -> failing.compose(nop).applyAsDouble(0d));
881         assertSame(ERROR, e);
882         // Does not throw
883         nop.compose(nop);
884         // Documented in Javadoc edge-case.
885         assertThrows(NullPointerException.class, () -> failing.compose(null));
886     }
887 
888     @Test
889     public void testDoubleUnaryOperatorIdentity() throws Throwable {
890         final FailableDoubleUnaryOperator<Throwable> nop = FailableDoubleUnaryOperator.identity();
891         // Does not throw
892         nop.compose(nop);
893         // Documented in Javadoc edge-case.
894         assertThrows(NullPointerException.class, () -> nop.compose(null));
895     }
896 
897     @Test
898     public void testFailableBiFunctionNop() throws Throwable {
899         assertNull(FailableBiFunction.nop().apply("Foo", "Bar"), "Expect NOP to return null");
900     }
901 
902     @Test
903     public void testFailableConsumerNop() throws Throwable {
904         // Expect nothing thrown
905         FailableConsumer.nop().accept("Foo");
906     }
907 
908     @Test
909     public void testFailableDoubleFunctionNop() throws Throwable {
910         assertNull(FailableDoubleFunction.nop().apply(Double.MAX_VALUE), "Expect NOP to return null");
911     }
912 
913     @Test
914     public void testFailableDoubleToIntFunctionNop() throws Throwable {
915         assertEquals(0, FailableDoubleToIntFunction.nop().applyAsInt(Double.MAX_VALUE), "Expect NOP to return 0");
916     }
917 
918     @Test
919     public void testFailableDoubleToLongFunctionNop() throws Throwable {
920         assertEquals(0, FailableDoubleToLongFunction.nop().applyAsLong(Double.MAX_VALUE), "Expect NOP to return 0");
921     }
922 
923     @Test
924     public void testFailableIntFunctionNop() throws Throwable {
925         assertNull(FailableIntFunction.nop().apply(Integer.MAX_VALUE), "Expect NOP to return null");
926     }
927 
928     @Test
929     public void testFailableIntToDoubleFunctionNop() throws Throwable {
930         assertEquals(0, FailableIntToDoubleFunction.nop().applyAsDouble(Integer.MAX_VALUE), "Expect NOP to return 0");
931     }
932 
933     @Test
934     public void testFailableIntToLongFunctionNop() throws Throwable {
935         assertEquals(0, FailableIntToLongFunction.nop().applyAsLong(Integer.MAX_VALUE), "Expect NOP to return 0");
936     }
937 
938     @Test
939     public void testFailableLongFunctionNop() throws Throwable {
940         assertNull(FailableLongFunction.nop().apply(Long.MAX_VALUE), "Expect NOP to return null");
941     }
942 
943     @Test
944     public void testFailableLongToDoubleFunctionNop() throws Throwable {
945         assertEquals(0, FailableLongToDoubleFunction.nop().applyAsDouble(Long.MAX_VALUE), "Expect NOP to return 0");
946     }
947 
948     @Test
949     public void testFailableLongToIntFunctionNop() throws Throwable {
950         assertEquals(0, FailableLongToIntFunction.nop().applyAsInt(Long.MAX_VALUE), "Expect NOP to return 0");
951     }
952 
953     @Test
954     public void testFailableObjDoubleConsumerNop() throws Throwable {
955         // Expect nothing thrown
956         FailableObjDoubleConsumer.nop().accept("Foo", Double.MAX_VALUE);
957     }
958 
959     @Test
960     public void testFailableObjIntConsumerNop() throws Throwable {
961         // Expect nothing thrown
962         FailableObjIntConsumer.nop().accept("Foo", Integer.MAX_VALUE);
963     }
964 
965     @Test
966     public void testFailableObjLongConsumerNop() throws Throwable {
967         // Expect nothing thrown
968         FailableObjLongConsumer.nop().accept("Foo", Long.MAX_VALUE);
969     }
970 
971     @Test
972     public void testFailableToDoubleBiFunctionNop() throws Throwable {
973         assertEquals(0, FailableToDoubleBiFunction.nop().applyAsDouble("Foo", "Bar"), "Expect NOP to return 0");
974     }
975 
976     @Test
977     public void testFailableToDoubleFunctionNop() throws Throwable {
978         assertEquals(0, FailableToDoubleFunction.nop().applyAsDouble("Foo"), "Expect NOP to return 0");
979     }
980 
981     @Test
982     public void testFailableToIntBiFunctionNop() throws Throwable {
983         assertEquals(0, FailableToIntBiFunction.nop().applyAsInt("Foo", "Bar"), "Expect NOP to return 0");
984     }
985 
986     @Test
987     public void testFailableToIntFunctionNop() throws Throwable {
988         assertEquals(0, FailableToIntFunction.nop().applyAsInt("Foo"), "Expect NOP to return 0");
989     }
990 
991     @Test
992     public void testFailableToLongBiFunctionNop() throws Throwable {
993         assertEquals(0, FailableToLongBiFunction.nop().applyAsLong("Foo", "Bar"), "Expect NOP to return 0");
994     }
995 
996     @Test
997     public void testFailableToLongFunctionNop() throws Throwable {
998         assertEquals(0, FailableToLongFunction.nop().applyAsLong("Foo"), "Expect NOP to return 0");
999     }
1000 
1001     @Test
1002     public void testFunction() {
1003         final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
1004         final FailableFunction<Throwable, Integer, Throwable> failableFunction = th -> {
1005             testable.setThrowable(th);
1006             return testable.testAsInteger();
1007         };
1008         final Function<Throwable, Integer> function = Failable.asFunction(failableFunction);
1009         Throwable e = assertThrows(IllegalStateException.class, () -> function.apply(ILLEGAL_STATE_EXCEPTION));
1010         assertSame(ILLEGAL_STATE_EXCEPTION, e);
1011 
1012         testable.setThrowable(ERROR);
1013         e = assertThrows(OutOfMemoryError.class, () -> function.apply(ERROR));
1014         assertSame(ERROR, e);
1015 
1016         final IOException ioe = new IOException("Unknown I/O error");
1017         testable.setThrowable(ioe);
1018         e = assertThrows(UncheckedIOException.class, () -> function.apply(ioe));
1019         final Throwable t = e.getCause();
1020         assertNotNull(t);
1021         assertSame(ioe, t);
1022 
1023         assertEquals(0, function.apply(null).intValue());
1024     }
1025 
1026     @Test
1027     public void testFunctionAndThen() throws IOException {
1028         // Unchecked usage pattern in JRE
1029         final Function<Object, Integer> nopFunction = t -> null;
1030         nopFunction.andThen(nopFunction);
1031         // Checked usage pattern
1032         final FailableFunction<Object, Integer, IOException> failingFunction = t -> {
1033             throw new IOException();
1034         };
1035         final FailableFunction<Object, Integer, IOException> nopFailableFunction = FailableFunction.nop();
1036         //
1037         assertThrows(IOException.class, () -> failingFunction.andThen(failingFunction).apply(null));
1038         assertThrows(IOException.class, () -> failingFunction.andThen(nopFailableFunction).apply(null));
1039         //
1040         assertThrows(IOException.class, () -> nopFailableFunction.andThen(failingFunction).apply(null));
1041         nopFailableFunction.andThen(nopFailableFunction).apply(null);
1042         // Documented in Javadoc edge-case.
1043         assertThrows(NullPointerException.class, () -> failingFunction.andThen(null));
1044     }
1045 
1046     @Test
1047     public void testFunctionCompose() throws Throwable {
1048         final Testable<?, ?> testable = new Testable<>(null);
1049         final FailableFunction<Object, Integer, Throwable> failing = t -> {
1050             testable.setThrowable(ERROR);
1051             testable.test();
1052             return 0;
1053         };
1054         final FailableFunction<Object, Integer, Throwable> nop = FailableFunction.nop();
1055         Throwable e = assertThrows(OutOfMemoryError.class, () -> nop.compose(failing).apply(0));
1056         assertSame(ERROR, e);
1057         e = assertThrows(OutOfMemoryError.class, () -> failing.compose(nop).apply(0));
1058         assertSame(ERROR, e);
1059         // Does not throw
1060         nop.compose(nop);
1061         // Documented in Javadoc edge-case.
1062         assertThrows(NullPointerException.class, () -> failing.compose(null));
1063     }
1064 
1065     @Test
1066     public void testFunctionFunction() throws Exception {
1067         assertEquals("foo", FailableFunction.function(this::throwingFunction).andThen(this::throwingFunction).apply("foo"));
1068     }
1069 
1070     @Test
1071     public void testFunctionIdentity() throws Throwable {
1072         final FailableFunction<Integer, Integer, Throwable> nop = FailableFunction.identity();
1073         // Does not throw
1074         nop.compose(nop);
1075         // Documented in Javadoc edge-case.
1076         assertThrows(NullPointerException.class, () -> nop.compose(null));
1077     }
1078 
1079     @Test
1080     public void testGetAsBooleanSupplier() {
1081         final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
1082         Throwable e = assertThrows(IllegalStateException.class,
1083             () -> Failable.getAsBoolean(testable::testAsBooleanPrimitive));
1084         assertSame(ILLEGAL_STATE_EXCEPTION, e);
1085 
1086         testable.setThrowable(ERROR);
1087         e = assertThrows(OutOfMemoryError.class, () -> Failable.getAsBoolean(testable::testAsBooleanPrimitive));
1088         assertSame(ERROR, e);
1089 
1090         final IOException ioe = new IOException("Unknown I/O error");
1091         testable.setThrowable(ioe);
1092         e = assertThrows(UncheckedIOException.class, () -> Failable.getAsBoolean(testable::testAsBooleanPrimitive));
1093         final Throwable t = e.getCause();
1094         assertNotNull(t);
1095         assertSame(ioe, t);
1096 
1097         testable.setThrowable(null);
1098         assertFalse(Failable.getAsBoolean(testable::testAsBooleanPrimitive));
1099     }
1100 
1101     @Test
1102     public void testGetAsDoubleSupplier() {
1103         final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
1104         Throwable e = assertThrows(IllegalStateException.class,
1105             () -> Failable.getAsDouble(testable::testAsDoublePrimitive));
1106         assertSame(ILLEGAL_STATE_EXCEPTION, e);
1107 
1108         testable.setThrowable(ERROR);
1109         e = assertThrows(OutOfMemoryError.class, () -> Failable.getAsDouble(testable::testAsDoublePrimitive));
1110         assertSame(ERROR, e);
1111 
1112         final IOException ioe = new IOException("Unknown I/O error");
1113         testable.setThrowable(ioe);
1114         e = assertThrows(UncheckedIOException.class, () -> Failable.getAsDouble(testable::testAsDoublePrimitive));
1115         final Throwable t = e.getCause();
1116         assertNotNull(t);
1117         assertSame(ioe, t);
1118 
1119         testable.setThrowable(null);
1120         assertEquals(0, Failable.getAsDouble(testable::testAsDoublePrimitive));
1121     }
1122 
1123     @Test
1124     public void testGetAsIntSupplier() {
1125         final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
1126         Throwable e = assertThrows(IllegalStateException.class, () -> Failable.getAsInt(testable::testAsIntPrimitive));
1127         assertSame(ILLEGAL_STATE_EXCEPTION, e);
1128 
1129         testable.setThrowable(ERROR);
1130         e = assertThrows(OutOfMemoryError.class, () -> Failable.getAsInt(testable::testAsIntPrimitive));
1131         assertSame(ERROR, e);
1132 
1133         final IOException ioe = new IOException("Unknown I/O error");
1134         testable.setThrowable(ioe);
1135         e = assertThrows(UncheckedIOException.class, () -> Failable.getAsInt(testable::testAsIntPrimitive));
1136         final Throwable t = e.getCause();
1137         assertNotNull(t);
1138         assertSame(ioe, t);
1139 
1140         testable.setThrowable(null);
1141         final int i = Failable.getAsInt(testable::testAsInteger);
1142         assertEquals(0, i);
1143     }
1144 
1145     @Test
1146     public void testGetAsLongSupplier() {
1147         final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
1148         Throwable e = assertThrows(IllegalStateException.class,
1149             () -> Failable.getAsLong(testable::testAsLongPrimitive));
1150         assertSame(ILLEGAL_STATE_EXCEPTION, e);
1151 
1152         testable.setThrowable(ERROR);
1153         e = assertThrows(OutOfMemoryError.class, () -> Failable.getAsLong(testable::testAsLongPrimitive));
1154         assertSame(ERROR, e);
1155 
1156         final IOException ioe = new IOException("Unknown I/O error");
1157         testable.setThrowable(ioe);
1158         e = assertThrows(UncheckedIOException.class, () -> Failable.getAsLong(testable::testAsLongPrimitive));
1159         final Throwable t = e.getCause();
1160         assertNotNull(t);
1161         assertSame(ioe, t);
1162 
1163         testable.setThrowable(null);
1164         final long i = Failable.getAsLong(testable::testAsLongPrimitive);
1165         assertEquals(0, i);
1166     }
1167 
1168     @Test
1169     public void testGetAsShortSupplier() {
1170         final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
1171         Throwable e = assertThrows(IllegalStateException.class,
1172             () -> Failable.getAsShort(testable::testAsShortPrimitive));
1173         assertSame(ILLEGAL_STATE_EXCEPTION, e);
1174 
1175         testable.setThrowable(ERROR);
1176         e = assertThrows(OutOfMemoryError.class, () -> Failable.getAsShort(testable::testAsShortPrimitive));
1177         assertSame(ERROR, e);
1178 
1179         final IOException ioe = new IOException("Unknown I/O error");
1180         testable.setThrowable(ioe);
1181         e = assertThrows(UncheckedIOException.class, () -> Failable.getAsShort(testable::testAsShortPrimitive));
1182         final Throwable t = e.getCause();
1183         assertNotNull(t);
1184         assertSame(ioe, t);
1185 
1186         testable.setThrowable(null);
1187         final short i = Failable.getAsShort(testable::testAsShortPrimitive);
1188         assertEquals(0, i);
1189     }
1190 
1191     @Test
1192     public void testGetFromSupplier() {
1193         FailureOnOddInvocations.invocations = 0;
1194         final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class,
1195             () -> Failable.run(FailureOnOddInvocations::new));
1196         final Throwable cause = e.getCause();
1197         assertNotNull(cause);
1198         assertTrue(cause instanceof SomeException);
1199         assertEquals("Odd Invocation: 1", cause.getMessage());
1200         final FailureOnOddInvocations instance = Failable.call(FailureOnOddInvocations::new);
1201         assertNotNull(instance);
1202     }
1203 
1204     @Test
1205     public void testGetSupplier() {
1206         final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
1207         Throwable e = assertThrows(IllegalStateException.class, () -> Failable.get(testable::testAsInteger));
1208         assertSame(ILLEGAL_STATE_EXCEPTION, e);
1209 
1210         testable.setThrowable(ERROR);
1211         e = assertThrows(OutOfMemoryError.class, () -> Failable.get(testable::testAsInteger));
1212         assertSame(ERROR, e);
1213 
1214         final IOException ioe = new IOException("Unknown I/O error");
1215         testable.setThrowable(ioe);
1216         e = assertThrows(UncheckedIOException.class, () -> Failable.get(testable::testAsInteger));
1217         final Throwable t = e.getCause();
1218         assertNotNull(t);
1219         assertSame(ioe, t);
1220 
1221         testable.setThrowable(null);
1222         final Integer i = Failable.apply(Testable::testAsInteger, testable);
1223         assertNotNull(i);
1224         assertEquals(0, i.intValue());
1225     }
1226 
1227     @Test
1228     public void testIntConsumerAndThen() throws Throwable {
1229         final Testable<?, ?> testable = new Testable<>(null);
1230         final FailableIntConsumer<Throwable> failing = t -> {
1231             testable.setThrowable(ERROR);
1232             testable.test();
1233         };
1234         final FailableIntConsumer<Throwable> nop = FailableIntConsumer.nop();
1235         Throwable e = assertThrows(OutOfMemoryError.class, () -> nop.andThen(failing).accept(0));
1236         assertSame(ERROR, e);
1237         e = assertThrows(OutOfMemoryError.class, () -> failing.andThen(nop).accept(0));
1238         assertSame(ERROR, e);
1239         // Does not throw
1240         nop.andThen(nop);
1241         // Documented in Javadoc edge-case.
1242         assertThrows(NullPointerException.class, () -> failing.andThen(null));
1243     }
1244 
1245     @Test
1246     public void testIntPredicate() throws Throwable {
1247         FailureOnOddInvocations.invocations = 0;
1248         final FailableIntPredicate<Throwable> failablePredicate = FailureOnOddInvocations::testInt;
1249         assertThrows(SomeException.class, () -> failablePredicate.test(1));
1250         failablePredicate.test(1);
1251     }
1252 
1253     @Test
1254     public void testIntPredicateAnd() throws Throwable {
1255         assertTrue(FailableIntPredicate.TRUE.and(FailableIntPredicate.TRUE).test(0));
1256         assertFalse(FailableIntPredicate.TRUE.and(FailableIntPredicate.FALSE).test(0));
1257         assertFalse(FailableIntPredicate.FALSE.and(FailableIntPredicate.TRUE).test(0));
1258         assertFalse(FailableIntPredicate.FALSE.and(FailableIntPredicate.FALSE).test(0));
1259         // null tests
1260         assertThrows(NullPointerException.class,
1261             () -> assertFalse(FailableIntPredicate.falsePredicate().and(null).test(0)));
1262         assertThrows(NullPointerException.class,
1263             () -> assertTrue(FailableIntPredicate.truePredicate().and(null).test(0)));
1264     }
1265 
1266     @Test
1267     public void testIntPredicateNegate() throws Throwable {
1268         assertFalse(FailableIntPredicate.TRUE.negate().test(0));
1269         assertFalse(FailableIntPredicate.truePredicate().negate().test(0));
1270         assertTrue(FailableIntPredicate.FALSE.negate().test(0));
1271         assertTrue(FailableIntPredicate.falsePredicate().negate().test(0));
1272     }
1273 
1274     @Test
1275     public void testIntPredicateOr() throws Throwable {
1276         assertTrue(FailableIntPredicate.TRUE.or(FailableIntPredicate.TRUE).test(0));
1277         assertTrue(FailableIntPredicate.TRUE.or(FailableIntPredicate.FALSE).test(0));
1278         assertTrue(FailableIntPredicate.FALSE.or(FailableIntPredicate.TRUE).test(0));
1279         assertFalse(FailableIntPredicate.FALSE.or(FailableIntPredicate.FALSE).test(0));
1280         // null tests
1281         assertThrows(NullPointerException.class,
1282             () -> assertFalse(FailableIntPredicate.falsePredicate().or(null).test(0)));
1283         assertThrows(NullPointerException.class,
1284             () -> assertTrue(FailableIntPredicate.truePredicate().or(null).test(0)));
1285     }
1286 
1287     @Test
1288     public void testIntUnaryOperatorAndThen() throws Throwable {
1289         final Testable<?, ?> testable = new Testable<>(null);
1290         final FailableIntUnaryOperator<Throwable> failing = t -> {
1291             testable.setThrowable(ERROR);
1292             testable.test();
1293             return 0;
1294         };
1295         final FailableIntUnaryOperator<Throwable> nop = FailableIntUnaryOperator.nop();
1296         Throwable e = assertThrows(OutOfMemoryError.class, () -> nop.andThen(failing).applyAsInt(0));
1297         assertSame(ERROR, e);
1298         e = assertThrows(OutOfMemoryError.class, () -> failing.andThen(nop).applyAsInt(0));
1299         assertSame(ERROR, e);
1300         // Does not throw
1301         nop.andThen(nop);
1302         // Documented in Javadoc edge-case.
1303         assertThrows(NullPointerException.class, () -> failing.andThen(null));
1304     }
1305 
1306     @Test
1307     public void testIntUnaryOperatorCompose() throws Throwable {
1308         final Testable<?, ?> testable = new Testable<>(null);
1309         final FailableIntUnaryOperator<Throwable> failing = t -> {
1310             testable.setThrowable(ERROR);
1311             testable.test();
1312             return 0;
1313         };
1314         final FailableIntUnaryOperator<Throwable> nop = FailableIntUnaryOperator.nop();
1315         Throwable e = assertThrows(OutOfMemoryError.class, () -> nop.compose(failing).applyAsInt(0));
1316         assertSame(ERROR, e);
1317         e = assertThrows(OutOfMemoryError.class, () -> failing.compose(nop).applyAsInt(0));
1318         assertSame(ERROR, e);
1319         // Does not throw
1320         nop.compose(nop);
1321         // Documented in Javadoc edge-case.
1322         assertThrows(NullPointerException.class, () -> failing.compose(null));
1323     }
1324 
1325     @Test
1326     public void testIntUnaryOperatorIdentity() throws Throwable {
1327         final FailableIntUnaryOperator<Throwable> nop = FailableIntUnaryOperator.identity();
1328         // Does not throw
1329         nop.compose(nop);
1330         // Documented in Javadoc edge-case.
1331         assertThrows(NullPointerException.class, () -> nop.compose(null));
1332     }
1333 
1334     @Test
1335     public void testLongConsumerAndThen() throws Throwable {
1336         final Testable<?, ?> testable = new Testable<>(null);
1337         final FailableLongConsumer<Throwable> failing = t -> {
1338             testable.setThrowable(ERROR);
1339             testable.test();
1340         };
1341         final FailableLongConsumer<Throwable> nop = FailableLongConsumer.nop();
1342         Throwable e = assertThrows(OutOfMemoryError.class, () -> nop.andThen(failing).accept(0L));
1343         assertSame(ERROR, e);
1344         e = assertThrows(OutOfMemoryError.class, () -> failing.andThen(nop).accept(0L));
1345         assertSame(ERROR, e);
1346         // Does not throw
1347         nop.andThen(nop);
1348         // Documented in Javadoc edge-case.
1349         assertThrows(NullPointerException.class, () -> failing.andThen(null));
1350     }
1351 
1352     @Test
1353     public void testLongPredicate() throws Throwable {
1354         FailureOnOddInvocations.invocations = 0;
1355         final FailableLongPredicate<Throwable> failablePredicate = FailureOnOddInvocations::testLong;
1356         assertThrows(SomeException.class, () -> failablePredicate.test(1L));
1357         failablePredicate.test(1L);
1358     }
1359 
1360     @Test
1361     public void testLongPredicateAnd() throws Throwable {
1362         assertTrue(FailableLongPredicate.TRUE.and(FailableLongPredicate.TRUE).test(0));
1363         assertFalse(FailableLongPredicate.TRUE.and(FailableLongPredicate.FALSE).test(0));
1364         assertFalse(FailableLongPredicate.FALSE.and(FailableLongPredicate.TRUE).test(0));
1365         assertFalse(FailableLongPredicate.FALSE.and(FailableLongPredicate.FALSE).test(0));
1366         // null tests
1367         assertThrows(NullPointerException.class, () -> assertFalse(FailableLongPredicate.falsePredicate().and(null).test(0)));
1368         assertThrows(NullPointerException.class, () -> assertTrue(FailableLongPredicate.truePredicate().and(null).test(0)));
1369     }
1370 
1371     @Test
1372     public void testLongPredicateNegate() throws Throwable {
1373         assertFalse(FailableLongPredicate.TRUE.negate().test(0L));
1374         assertFalse(FailableLongPredicate.truePredicate().negate().test(0L));
1375         assertTrue(FailableLongPredicate.FALSE.negate().test(0L));
1376         assertTrue(FailableLongPredicate.falsePredicate().negate().test(0L));
1377     }
1378 
1379     @Test
1380     public void testLongPredicateOr() throws Throwable {
1381         assertTrue(FailableLongPredicate.TRUE.or(FailableLongPredicate.TRUE).test(0));
1382         assertTrue(FailableLongPredicate.TRUE.or(FailableLongPredicate.FALSE).test(0));
1383         assertTrue(FailableLongPredicate.FALSE.or(FailableLongPredicate.TRUE).test(0));
1384         assertFalse(FailableLongPredicate.FALSE.or(FailableLongPredicate.FALSE).test(0));
1385         // null tests
1386         assertThrows(NullPointerException.class, () -> assertFalse(FailableLongPredicate.falsePredicate().or(null).test(0)));
1387         assertThrows(NullPointerException.class, () -> assertTrue(FailableLongPredicate.truePredicate().or(null).test(0)));
1388     }
1389 
1390     @Test
1391     public void testLongUnaryOperatorAndThen() throws Throwable {
1392         final Testable<?, ?> testable = new Testable<>(null);
1393         final FailableLongUnaryOperator<Throwable> failing = t -> {
1394             testable.setThrowable(ERROR);
1395             testable.test();
1396             return 0L;
1397         };
1398         final FailableLongUnaryOperator<Throwable> nop = FailableLongUnaryOperator.nop();
1399         Throwable e = assertThrows(OutOfMemoryError.class, () -> nop.andThen(failing).applyAsLong(0L));
1400         assertSame(ERROR, e);
1401         e = assertThrows(OutOfMemoryError.class, () -> failing.andThen(nop).applyAsLong(0L));
1402         assertSame(ERROR, e);
1403         // Does not throw
1404         nop.andThen(nop);
1405         // Documented in Javadoc edge-case.
1406         assertThrows(NullPointerException.class, () -> failing.andThen(null));
1407     }
1408 
1409     @Test
1410     public void testLongUnaryOperatorCompose() throws Throwable {
1411         final Testable<?, ?> testable = new Testable<>(null);
1412         final FailableLongUnaryOperator<Throwable> failing = t -> {
1413             testable.setThrowable(ERROR);
1414             testable.test();
1415             return 0L;
1416         };
1417         final FailableLongUnaryOperator<Throwable> nop = FailableLongUnaryOperator.nop();
1418         Throwable e = assertThrows(OutOfMemoryError.class, () -> nop.compose(failing).applyAsLong(0L));
1419         assertSame(ERROR, e);
1420         e = assertThrows(OutOfMemoryError.class, () -> failing.compose(nop).applyAsLong(0L));
1421         assertSame(ERROR, e);
1422         // Does not throw
1423         nop.compose(nop);
1424         // Documented in Javadoc edge-case.
1425         assertThrows(NullPointerException.class, () -> failing.compose(null));
1426     }
1427 
1428     @Test
1429     public void testLongUnaryOperatorIdentity() throws Throwable {
1430         final FailableLongUnaryOperator<Throwable> nop = FailableLongUnaryOperator.identity();
1431         // Does not throw
1432         nop.compose(nop);
1433         // Documented in Javadoc edge-case.
1434         assertThrows(NullPointerException.class, () -> nop.compose(null));
1435     }
1436 
1437     @Test
1438     @DisplayName("Test that asPredicate(FailablePredicate) is converted to -> Predicate ")
1439     public void testPredicate() {
1440         FailureOnOddInvocations.invocations = 0;
1441         final FailablePredicate<Object, Throwable> failablePredicate = t -> FailureOnOddInvocations.failingBool();
1442         final Predicate<?> predicate = Failable.asPredicate(failablePredicate);
1443         final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class,
1444             () -> predicate.test(null));
1445         final Throwable cause = e.getCause();
1446         assertNotNull(cause);
1447         assertTrue(cause instanceof SomeException);
1448         assertEquals("Odd Invocation: 1", cause.getMessage());
1449         final boolean instance = predicate.test(null);
1450         assertNotNull(instance);
1451     }
1452 
1453     @Test
1454     public void testPredicateAnd() throws Throwable {
1455         assertTrue(FailablePredicate.TRUE.and(FailablePredicate.TRUE).test(null));
1456         assertFalse(FailablePredicate.TRUE.and(FailablePredicate.FALSE).test(null));
1457         assertFalse(FailablePredicate.FALSE.and(FailablePredicate.TRUE).test(null));
1458         assertFalse(FailablePredicate.FALSE.and(FailablePredicate.FALSE).test(null));
1459         // null tests
1460         assertThrows(NullPointerException.class, () -> assertFalse(FailablePredicate.FALSE.and(null).test(null)));
1461         assertThrows(NullPointerException.class, () -> assertTrue(FailablePredicate.TRUE.and(null).test(null)));
1462     }
1463 
1464     @Test
1465     public void testPredicateNegate() throws Throwable {
1466         assertFalse(FailablePredicate.TRUE.negate().test(null));
1467         assertFalse(FailablePredicate.truePredicate().negate().test(null));
1468         assertTrue(FailablePredicate.FALSE.negate().test(null));
1469         assertTrue(FailablePredicate.falsePredicate().negate().test(null));
1470     }
1471 
1472     @Test
1473     public void testPredicateOr() throws Throwable {
1474         assertTrue(FailablePredicate.TRUE.or(FailablePredicate.TRUE).test(null));
1475         assertTrue(FailablePredicate.TRUE.or(FailablePredicate.FALSE).test(null));
1476         assertTrue(FailablePredicate.FALSE.or(FailablePredicate.TRUE).test(null));
1477         assertFalse(FailablePredicate.FALSE.or(FailablePredicate.FALSE).test(null));
1478         // null tests
1479         assertThrows(NullPointerException.class, () -> assertFalse(FailablePredicate.FALSE.or(null).test(null)));
1480         assertThrows(NullPointerException.class, () -> assertTrue(FailablePredicate.TRUE.or(null).test(null)));
1481     }
1482 
1483     @Test
1484     public void testRunnable() {
1485         FailureOnOddInvocations.invocations = 0;
1486         final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class,
1487             () -> Failable.run(FailureOnOddInvocations::new));
1488         final Throwable cause = e.getCause();
1489         assertNotNull(cause);
1490         assertTrue(cause instanceof SomeException);
1491         assertEquals("Odd Invocation: 1", cause.getMessage());
1492 
1493         // Even invocations, should not throw an exception
1494         Failable.run(FailureOnOddInvocations::new);
1495     }
1496 
1497     /**
1498      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1499      * Object and Throwable.
1500      */
1501     @Test
1502     public void testThrows_FailableBiConsumer_Object_Throwable() {
1503         new FailableBiConsumer<Object, Object, Throwable>() {
1504 
1505             @Override
1506             public void accept(final Object object1, final Object object2) throws Throwable {
1507                 throw new IOException("test");
1508             }
1509         };
1510     }
1511 
1512     /**
1513      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1514      * generic test types.
1515      */
1516     @Test
1517     public void testThrows_FailableBiConsumer_String_IOException() {
1518         new FailableBiConsumer<String, String, IOException>() {
1519 
1520             @Override
1521             public void accept(final String object1, final String object2) throws IOException {
1522                 throw new IOException("test");
1523 
1524             }
1525         };
1526     }
1527 
1528     /**
1529      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1530      * Object and Throwable.
1531      */
1532     @Test
1533     public void testThrows_FailableBiFunction_Object_Throwable() {
1534         new FailableBiFunction<Object, Object, Object, Throwable>() {
1535 
1536             @Override
1537             public Object apply(final Object input1, final Object input2) throws Throwable {
1538                 throw new IOException("test");
1539             }
1540         };
1541     }
1542 
1543     /**
1544      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1545      * generic test types.
1546      */
1547     @Test
1548     public void testThrows_FailableBiFunction_String_IOException() {
1549         new FailableBiFunction<String, String, String, IOException>() {
1550 
1551             @Override
1552             public String apply(final String input1, final String input2) throws IOException {
1553                 throw new IOException("test");
1554             }
1555         };
1556     }
1557 
1558     /**
1559      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1560      * Object and Throwable.
1561      */
1562     @Test
1563     public void testThrows_FailableBiPredicate_Object_Throwable() {
1564         new FailableBiPredicate<Object, Object, Throwable>() {
1565 
1566             @Override
1567             public boolean test(final Object object1, final Object object2) throws Throwable {
1568                 throw new IOException("test");
1569             }
1570         };
1571     }
1572 
1573     /**
1574      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1575      * generic test types.
1576      */
1577     @Test
1578     public void testThrows_FailableBiPredicate_String_IOException() {
1579         new FailableBiPredicate<String, String, IOException>() {
1580 
1581             @Override
1582             public boolean test(final String object1, final String object2) throws IOException {
1583                 throw new IOException("test");
1584             }
1585         };
1586     }
1587 
1588     /**
1589      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1590      * generic test types.
1591      */
1592     @Test
1593     public void testThrows_FailableBooleanSupplier_IOException() {
1594         new FailableBooleanSupplier<IOException>() {
1595 
1596             @Override
1597             public boolean getAsBoolean() throws IOException {
1598                 throw new IOException("test");
1599             }
1600         };
1601     }
1602 
1603     /**
1604      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1605      * Object and Throwable.
1606      */
1607     @Test
1608     public void testThrows_FailableBooleanSupplier_Throwable() {
1609         new FailableBooleanSupplier<Throwable>() {
1610 
1611             @Override
1612             public boolean getAsBoolean() throws Throwable {
1613                 throw new IOException("test");
1614             }
1615         };
1616     }
1617 
1618     /**
1619      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1620      * Object and Throwable.
1621      */
1622     @Test
1623     public void testThrows_FailableCallable_Object_Throwable() {
1624         new FailableCallable<Object, Throwable>() {
1625 
1626             @Override
1627             public Object call() throws Throwable {
1628                 throw new IOException("test");
1629             }
1630         };
1631     }
1632 
1633     /**
1634      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1635      * generic test types.
1636      */
1637     @Test
1638     public void testThrows_FailableCallable_String_IOException() {
1639         new FailableCallable<String, IOException>() {
1640 
1641             @Override
1642             public String call() throws IOException {
1643                 throw new IOException("test");
1644             }
1645         };
1646     }
1647 
1648     /**
1649      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1650      * Object and Throwable.
1651      */
1652     @Test
1653     public void testThrows_FailableConsumer_Object_Throwable() {
1654         new FailableConsumer<Object, Throwable>() {
1655 
1656             @Override
1657             public void accept(final Object object) throws Throwable {
1658                 throw new IOException("test");
1659 
1660             }
1661         };
1662     }
1663 
1664     /**
1665      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1666      * generic test types.
1667      */
1668     @Test
1669     public void testThrows_FailableConsumer_String_IOException() {
1670         new FailableConsumer<String, IOException>() {
1671 
1672             @Override
1673             public void accept(final String object) throws IOException {
1674                 throw new IOException("test");
1675 
1676             }
1677         };
1678     }
1679 
1680     /**
1681      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1682      * generic test types.
1683      */
1684     @Test
1685     public void testThrows_FailableDoubleBinaryOperator_IOException() {
1686         new FailableDoubleBinaryOperator<IOException>() {
1687 
1688             @Override
1689             public double applyAsDouble(final double left, final double right) throws IOException {
1690                 throw new IOException("test");
1691             }
1692         };
1693     }
1694 
1695     /**
1696      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1697      * Object and Throwable.
1698      */
1699     @Test
1700     public void testThrows_FailableDoubleBinaryOperator_Throwable() {
1701         new FailableDoubleBinaryOperator<Throwable>() {
1702 
1703             @Override
1704             public double applyAsDouble(final double left, final double right) throws Throwable {
1705                 throw new IOException("test");
1706             }
1707         };
1708     }
1709 
1710     /**
1711      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1712      * generic test types.
1713      */
1714     @Test
1715     public void testThrows_FailableDoubleConsumer_IOException() {
1716         new FailableDoubleConsumer<IOException>() {
1717 
1718             @Override
1719             public void accept(final double value) throws IOException {
1720                 throw new IOException("test");
1721             }
1722         };
1723     }
1724 
1725     /**
1726      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1727      * Object and Throwable.
1728      */
1729     @Test
1730     public void testThrows_FailableDoubleConsumer_Throwable() {
1731         new FailableDoubleConsumer<Throwable>() {
1732 
1733             @Override
1734             public void accept(final double value) throws Throwable {
1735                 throw new IOException("test");
1736 
1737             }
1738         };
1739     }
1740 
1741     /**
1742      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1743      * generic test types.
1744      */
1745     @Test
1746     public void testThrows_FailableDoubleFunction_IOException() {
1747         new FailableDoubleFunction<String, IOException>() {
1748 
1749             @Override
1750             public String apply(final double input) throws IOException {
1751                 throw new IOException("test");
1752             }
1753         };
1754     }
1755 
1756     /**
1757      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1758      * Object and Throwable.
1759      */
1760     @Test
1761     public void testThrows_FailableDoubleFunction_Throwable() {
1762         new FailableDoubleFunction<Object, Throwable>() {
1763 
1764             @Override
1765             public Object apply(final double input) throws Throwable {
1766                 throw new IOException("test");
1767             }
1768         };
1769     }
1770 
1771     /**
1772      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1773      * generic test types.
1774      */
1775     @Test
1776     public void testThrows_FailableDoubleSupplier_IOException() {
1777         new FailableDoubleSupplier<IOException>() {
1778 
1779             @Override
1780             public double getAsDouble() throws IOException {
1781                 throw new IOException("test");
1782             }
1783         };
1784     }
1785 
1786     /**
1787      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1788      * Object and Throwable.
1789      */
1790     @Test
1791     public void testThrows_FailableDoubleSupplier_Throwable() {
1792         new FailableDoubleSupplier<Throwable>() {
1793 
1794             @Override
1795             public double getAsDouble() throws Throwable {
1796                 throw new IOException("test");
1797             }
1798         };
1799     }
1800 
1801     /**
1802      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1803      * generic test types.
1804      */
1805     @Test
1806     public void testThrows_FailableDoubleToIntFunction_IOException() {
1807         new FailableDoubleToIntFunction<IOException>() {
1808 
1809             @Override
1810             public int applyAsInt(final double value) throws IOException {
1811                 throw new IOException("test");
1812             }
1813         };
1814     }
1815 
1816     /**
1817      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1818      * Object and Throwable.
1819      */
1820     @Test
1821     public void testThrows_FailableDoubleToIntFunction_Throwable() {
1822         new FailableDoubleToIntFunction<Throwable>() {
1823 
1824             @Override
1825             public int applyAsInt(final double value) throws Throwable {
1826                 throw new IOException("test");
1827             }
1828         };
1829     }
1830 
1831     /**
1832      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1833      * generic test types.
1834      */
1835     @Test
1836     public void testThrows_FailableDoubleToLongFunction_IOException() {
1837         new FailableDoubleToLongFunction<IOException>() {
1838 
1839             @Override
1840             public int applyAsLong(final double value) throws IOException {
1841                 throw new IOException("test");
1842             }
1843         };
1844     }
1845 
1846     /**
1847      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1848      * Object and Throwable.
1849      */
1850     @Test
1851     public void testThrows_FailableDoubleToLongFunction_Throwable() {
1852         new FailableDoubleToLongFunction<Throwable>() {
1853 
1854             @Override
1855             public int applyAsLong(final double value) throws Throwable {
1856                 throw new IOException("test");
1857             }
1858         };
1859     }
1860 
1861     /**
1862      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1863      * Object and Throwable.
1864      */
1865     @Test
1866     public void testThrows_FailableFunction_Object_Throwable() {
1867         new FailableFunction<Object, Object, Throwable>() {
1868 
1869             @Override
1870             public Object apply(final Object input) throws Throwable {
1871                 throw new IOException("test");
1872             }
1873         };
1874     }
1875 
1876     /**
1877      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1878      * generic test types.
1879      */
1880     @Test
1881     public void testThrows_FailableFunction_String_IOException() {
1882         new FailableFunction<String, String, IOException>() {
1883 
1884             @Override
1885             public String apply(final String input) throws IOException {
1886                 throw new IOException("test");
1887             }
1888         };
1889     }
1890 
1891     /**
1892      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1893      * generic test types.
1894      */
1895     @Test
1896     public void testThrows_FailableIntBinaryOperator_IOException() {
1897         new FailableIntBinaryOperator<IOException>() {
1898 
1899             @Override
1900             public int applyAsInt(final int left, final int right) throws IOException {
1901                 throw new IOException("test");
1902             }
1903         };
1904     }
1905 
1906     /**
1907      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1908      * Object and Throwable.
1909      */
1910     @Test
1911     public void testThrows_FailableIntBinaryOperator_Throwable() {
1912         new FailableIntBinaryOperator<Throwable>() {
1913 
1914             @Override
1915             public int applyAsInt(final int left, final int right) throws Throwable {
1916                 throw new IOException("test");
1917             }
1918         };
1919     }
1920 
1921     /**
1922      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1923      * generic test types.
1924      */
1925     @Test
1926     public void testThrows_FailableIntConsumer_IOException() {
1927         new FailableIntConsumer<IOException>() {
1928 
1929             @Override
1930             public void accept(final int value) throws IOException {
1931                 throw new IOException("test");
1932             }
1933         };
1934     }
1935 
1936     /**
1937      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1938      * Object and Throwable.
1939      */
1940     @Test
1941     public void testThrows_FailableIntConsumer_Throwable() {
1942         new FailableIntConsumer<Throwable>() {
1943 
1944             @Override
1945             public void accept(final int value) throws Throwable {
1946                 throw new IOException("test");
1947 
1948             }
1949         };
1950     }
1951 
1952     /**
1953      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1954      * Object and Throwable.
1955      */
1956     @Test
1957     public void testThrows_FailableIntFunction_Object_Throwable() {
1958         new FailableIntFunction<Object, Throwable>() {
1959 
1960             @Override
1961             public Object apply(final int input) throws Throwable {
1962                 throw new IOException("test");
1963             }
1964         };
1965     }
1966 
1967     /**
1968      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1969      * generic test types.
1970      */
1971     @Test
1972     public void testThrows_FailableIntFunction_String_IOException() {
1973         new FailableIntFunction<String, IOException>() {
1974 
1975             @Override
1976             public String apply(final int input) throws IOException {
1977                 throw new IOException("test");
1978             }
1979         };
1980     }
1981 
1982     /**
1983      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1984      * generic test types.
1985      */
1986     @Test
1987     public void testThrows_FailableIntSupplier_IOException() {
1988         new FailableIntSupplier<IOException>() {
1989 
1990             @Override
1991             public int getAsInt() throws IOException {
1992                 throw new IOException("test");
1993             }
1994         };
1995     }
1996 
1997     /**
1998      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
1999      * Object and Throwable.
2000      */
2001     @Test
2002     public void testThrows_FailableIntSupplier_Throwable() {
2003         new FailableIntSupplier<Throwable>() {
2004 
2005             @Override
2006             public int getAsInt() throws Throwable {
2007                 throw new IOException("test");
2008             }
2009         };
2010     }
2011 
2012     /**
2013      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2014      * generic test types.
2015      */
2016     @Test
2017     public void testThrows_FailableIntToDoubleFunction_IOException() {
2018         new FailableIntToDoubleFunction<IOException>() {
2019 
2020             @Override
2021             public double applyAsDouble(final int value) throws IOException {
2022                 throw new IOException("test");
2023             }
2024         };
2025     }
2026 
2027     /**
2028      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2029      * Object and Throwable.
2030      */
2031     @Test
2032     public void testThrows_FailableIntToDoubleFunction_Throwable() {
2033         new FailableIntToDoubleFunction<Throwable>() {
2034 
2035             @Override
2036             public double applyAsDouble(final int value) throws Throwable {
2037                 throw new IOException("test");
2038             }
2039         };
2040     }
2041 
2042     /**
2043      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2044      * generic test types.
2045      */
2046     @Test
2047     public void testThrows_FailableIntToLongFunction_IOException() {
2048         new FailableIntToLongFunction<IOException>() {
2049 
2050             @Override
2051             public long applyAsLong(final int value) throws IOException {
2052                 throw new IOException("test");
2053             }
2054         };
2055     }
2056 
2057     /**
2058      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2059      * Object and Throwable.
2060      */
2061     @Test
2062     public void testThrows_FailableIntToLongFunction_Throwable() {
2063         new FailableIntToLongFunction<Throwable>() {
2064 
2065             @Override
2066             public long applyAsLong(final int value) throws Throwable {
2067                 throw new IOException("test");
2068             }
2069         };
2070     }
2071 
2072     /**
2073      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2074      * generic test types.
2075      */
2076     @Test
2077     public void testThrows_FailableLongBinaryOperator_IOException() {
2078         new FailableLongBinaryOperator<IOException>() {
2079 
2080             @Override
2081             public long applyAsLong(final long left, final long right) throws IOException {
2082                 throw new IOException("test");
2083             }
2084         };
2085     }
2086 
2087     /**
2088      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2089      * Object and Throwable.
2090      */
2091     @Test
2092     public void testThrows_FailableLongBinaryOperator_Throwable() {
2093         new FailableLongBinaryOperator<Throwable>() {
2094 
2095             @Override
2096             public long applyAsLong(final long left, final long right) throws Throwable {
2097                 throw new IOException("test");
2098             }
2099         };
2100     }
2101 
2102     /**
2103      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2104      * generic test types.
2105      */
2106     @Test
2107     public void testThrows_FailableLongConsumer_IOException() {
2108         new FailableLongConsumer<IOException>() {
2109 
2110             @Override
2111             public void accept(final long object) throws IOException {
2112                 throw new IOException("test");
2113 
2114             }
2115         };
2116     }
2117 
2118     /**
2119      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2120      * Object and Throwable.
2121      */
2122     @Test
2123     public void testThrows_FailableLongConsumer_Throwable() {
2124         new FailableLongConsumer<Throwable>() {
2125 
2126             @Override
2127             public void accept(final long object) throws Throwable {
2128                 throw new IOException("test");
2129 
2130             }
2131         };
2132     }
2133 
2134     /**
2135      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2136      * generic test types.
2137      */
2138     @Test
2139     public void testThrows_FailableLongFunction_IOException() {
2140         new FailableLongFunction<String, IOException>() {
2141 
2142             @Override
2143             public String apply(final long input) throws IOException {
2144                 throw new IOException("test");
2145             }
2146         };
2147     }
2148 
2149     /**
2150      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2151      * Object and Throwable.
2152      */
2153     @Test
2154     public void testThrows_FailableLongFunction_Throwable() {
2155         new FailableLongFunction<Object, Throwable>() {
2156 
2157             @Override
2158             public Object apply(final long input) throws Throwable {
2159                 throw new IOException("test");
2160             }
2161         };
2162     }
2163 
2164     /**
2165      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2166      * generic test types.
2167      */
2168     @Test
2169     public void testThrows_FailableLongSupplier_IOException() {
2170         new FailableLongSupplier<IOException>() {
2171 
2172             @Override
2173             public long getAsLong() throws IOException {
2174                 throw new IOException("test");
2175             }
2176         };
2177     }
2178 
2179     /**
2180      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2181      * Object and Throwable.
2182      */
2183     @Test
2184     public void testThrows_FailableLongSupplier_Throwable() {
2185         new FailableLongSupplier<Throwable>() {
2186 
2187             @Override
2188             public long getAsLong() throws Throwable {
2189                 throw new IOException("test");
2190             }
2191         };
2192     }
2193 
2194     /**
2195      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2196      * generic test types.
2197      */
2198     @Test
2199     public void testThrows_FailableLongToDoubleFunction_IOException() {
2200         new FailableLongToDoubleFunction<IOException>() {
2201 
2202             @Override
2203             public double applyAsDouble(final long value) throws IOException {
2204                 throw new IOException("test");
2205             }
2206         };
2207     }
2208 
2209     /**
2210      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2211      * Object and Throwable.
2212      */
2213     @Test
2214     public void testThrows_FailableLongToDoubleFunction_Throwable() {
2215         new FailableLongToDoubleFunction<Throwable>() {
2216 
2217             @Override
2218             public double applyAsDouble(final long value) throws Throwable {
2219                 throw new IOException("test");
2220             }
2221         };
2222     }
2223 
2224     /**
2225      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2226      * generic test types.
2227      */
2228     @Test
2229     public void testThrows_FailableLongToIntFunction_IOException() {
2230         new FailableLongToIntFunction<IOException>() {
2231 
2232             @Override
2233             public int applyAsInt(final long value) throws IOException {
2234                 throw new IOException("test");
2235             }
2236         };
2237     }
2238 
2239     /**
2240      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2241      * Object and Throwable.
2242      */
2243     @Test
2244     public void testThrows_FailableLongToIntFunction_Throwable() {
2245         new FailableLongToIntFunction<Throwable>() {
2246 
2247             @Override
2248             public int applyAsInt(final long value) throws Throwable {
2249                 throw new IOException("test");
2250             }
2251         };
2252     }
2253 
2254     /**
2255      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2256      * Object and Throwable.
2257      */
2258     @Test
2259     public void testThrows_FailableObjDoubleConsumer_Object_Throwable() {
2260         new FailableObjDoubleConsumer<Object, Throwable>() {
2261 
2262             @Override
2263             public void accept(final Object object, final double value) throws Throwable {
2264                 throw new IOException("test");
2265 
2266             }
2267         };
2268     }
2269 
2270     /**
2271      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2272      * generic test types.
2273      */
2274     @Test
2275     public void testThrows_FailableObjDoubleConsumer_String_IOException() {
2276         new FailableObjDoubleConsumer<String, IOException>() {
2277 
2278             @Override
2279             public void accept(final String object, final double value) throws IOException {
2280                 throw new IOException("test");
2281             }
2282         };
2283     }
2284 
2285     /**
2286      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2287      * Object and Throwable.
2288      */
2289     @Test
2290     public void testThrows_FailableObjIntConsumer_Object_Throwable() {
2291         new FailableObjIntConsumer<Object, Throwable>() {
2292 
2293             @Override
2294             public void accept(final Object object, final int value) throws Throwable {
2295                 throw new IOException("test");
2296 
2297             }
2298         };
2299     }
2300 
2301     /**
2302      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2303      * generic test types.
2304      */
2305     @Test
2306     public void testThrows_FailableObjIntConsumer_String_IOException() {
2307         new FailableObjIntConsumer<String, IOException>() {
2308 
2309             @Override
2310             public void accept(final String object, final int value) throws IOException {
2311                 throw new IOException("test");
2312             }
2313         };
2314     }
2315 
2316     /**
2317      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2318      * Object and Throwable.
2319      */
2320     @Test
2321     public void testThrows_FailableObjLongConsumer_Object_Throwable() {
2322         new FailableObjLongConsumer<Object, Throwable>() {
2323 
2324             @Override
2325             public void accept(final Object object, final long value) throws Throwable {
2326                 throw new IOException("test");
2327 
2328             }
2329         };
2330     }
2331 
2332     /**
2333      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2334      * generic test types.
2335      */
2336     @Test
2337     public void testThrows_FailableObjLongConsumer_String_IOException() {
2338         new FailableObjLongConsumer<String, IOException>() {
2339 
2340             @Override
2341             public void accept(final String object, final long value) throws IOException {
2342                 throw new IOException("test");
2343             }
2344         };
2345     }
2346 
2347     /**
2348      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2349      * Object and Throwable.
2350      */
2351     @Test
2352     public void testThrows_FailablePredicate_Object_Throwable() {
2353         new FailablePredicate<Object, Throwable>() {
2354 
2355             @Override
2356             public boolean test(final Object object) throws Throwable {
2357                 throw new IOException("test");
2358             }
2359         };
2360     }
2361 
2362     /**
2363      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2364      * generic test types.
2365      */
2366     @Test
2367     public void testThrows_FailablePredicate_String_IOException() {
2368         new FailablePredicate<String, IOException>() {
2369 
2370             @Override
2371             public boolean test(final String object) throws IOException {
2372                 throw new IOException("test");
2373             }
2374         };
2375     }
2376 
2377     /**
2378      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2379      * generic test types.
2380      */
2381     @Test
2382     public void testThrows_FailableRunnable_IOException() {
2383         new FailableRunnable<IOException>() {
2384 
2385             @Override
2386             public void run() throws IOException {
2387                 throw new IOException("test");
2388             }
2389         };
2390     }
2391 
2392     /**
2393      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2394      * Object and Throwable.
2395      */
2396     @Test
2397     public void testThrows_FailableRunnable_Throwable() {
2398         new FailableRunnable<Throwable>() {
2399 
2400             @Override
2401             public void run() throws Throwable {
2402                 throw new IOException("test");
2403 
2404             }
2405         };
2406     }
2407 
2408     /**
2409      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2410      * generic test types.
2411      */
2412     @Test
2413     public void testThrows_FailableShortSupplier_IOException() {
2414         new FailableShortSupplier<IOException>() {
2415 
2416             @Override
2417             public short getAsShort() throws IOException {
2418                 throw new IOException("test");
2419             }
2420         };
2421     }
2422 
2423     /**
2424      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2425      * Object and Throwable.
2426      */
2427     @Test
2428     public void testThrows_FailableShortSupplier_Throwable() {
2429         new FailableShortSupplier<Throwable>() {
2430 
2431             @Override
2432             public short getAsShort() throws Throwable {
2433                 throw new IOException("test");
2434             }
2435         };
2436     }
2437 
2438     /**
2439      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2440      * Object and Throwable.
2441      */
2442     @Test
2443     public void testThrows_FailableSupplier_Object_Throwable() {
2444         new FailableSupplier<Object, Throwable>() {
2445 
2446             @Override
2447             public Object get() throws Throwable {
2448                 throw new IOException("test");
2449             }
2450         };
2451     }
2452 
2453     /**
2454      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2455      * generic test types.
2456      */
2457     @Test
2458     public void testThrows_FailableSupplier_String_IOException() {
2459         new FailableSupplier<String, IOException>() {
2460 
2461             @Override
2462             public String get() throws IOException {
2463                 throw new IOException("test");
2464             }
2465         };
2466     }
2467 
2468     /**
2469      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2470      * Object and Throwable.
2471      */
2472     @Test
2473     public void testThrows_FailableToDoubleBiFunction_Object_Throwable() {
2474         new FailableToDoubleBiFunction<Object, Object, Throwable>() {
2475 
2476             @Override
2477             public double applyAsDouble(final Object t, final Object u) throws Throwable {
2478                 throw new IOException("test");
2479             }
2480         };
2481     }
2482 
2483     /**
2484      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2485      * generic test types.
2486      */
2487     @Test
2488     public void testThrows_FailableToDoubleBiFunction_String_IOException() {
2489         new FailableToDoubleBiFunction<String, String, IOException>() {
2490 
2491             @Override
2492             public double applyAsDouble(final String t, final String u) throws IOException {
2493                 throw new IOException("test");
2494             }
2495         };
2496     }
2497 
2498     /**
2499      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2500      * Object and Throwable.
2501      */
2502     @Test
2503     public void testThrows_FailableToDoubleFunction_Object_Throwable() {
2504         new FailableToDoubleFunction<Object, Throwable>() {
2505 
2506             @Override
2507             public double applyAsDouble(final Object t) throws Throwable {
2508                 throw new IOException("test");
2509             }
2510         };
2511     }
2512 
2513     /**
2514      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2515      * generic test types.
2516      */
2517     @Test
2518     public void testThrows_FailableToDoubleFunction_String_IOException() {
2519         new FailableToDoubleFunction<String, IOException>() {
2520 
2521             @Override
2522             public double applyAsDouble(final String t) throws IOException {
2523                 throw new IOException("test");
2524             }
2525         };
2526     }
2527 
2528     /**
2529      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2530      * Object and Throwable.
2531      */
2532     @Test
2533     public void testThrows_FailableToIntBiFunction_Object_Throwable() {
2534         new FailableToIntBiFunction<Object, Object, Throwable>() {
2535 
2536             @Override
2537             public int applyAsInt(final Object t, final Object u) throws Throwable {
2538                 throw new IOException("test");
2539             }
2540         };
2541     }
2542 
2543     /**
2544      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2545      * generic test types.
2546      */
2547     @Test
2548     public void testThrows_FailableToIntBiFunction_String_IOException() {
2549         new FailableToIntBiFunction<String, String, IOException>() {
2550 
2551             @Override
2552             public int applyAsInt(final String t, final String u) throws IOException {
2553                 throw new IOException("test");
2554             }
2555         };
2556     }
2557 
2558     /**
2559      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2560      * Object and Throwable.
2561      */
2562     @Test
2563     public void testThrows_FailableToIntFunction_Object_Throwable() {
2564         new FailableToIntFunction<Object, Throwable>() {
2565 
2566             @Override
2567             public int applyAsInt(final Object t) throws Throwable {
2568                 throw new IOException("test");
2569             }
2570         };
2571     }
2572 
2573     /**
2574      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2575      * generic test types.
2576      */
2577     @Test
2578     public void testThrows_FailableToIntFunction_String_IOException() {
2579         new FailableToIntFunction<String, IOException>() {
2580 
2581             @Override
2582             public int applyAsInt(final String t) throws IOException {
2583                 throw new IOException("test");
2584             }
2585         };
2586     }
2587 
2588     /**
2589      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2590      * Object and Throwable.
2591      */
2592     @Test
2593     public void testThrows_FailableToLongBiFunction_Object_Throwable() {
2594         new FailableToLongBiFunction<Object, Object, Throwable>() {
2595 
2596             @Override
2597             public long applyAsLong(final Object t, final Object u) throws Throwable {
2598                 throw new IOException("test");
2599             }
2600         };
2601     }
2602 
2603     /**
2604      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2605      * generic test types.
2606      */
2607     @Test
2608     public void testThrows_FailableToLongBiFunction_String_IOException() {
2609         new FailableToLongBiFunction<String, String, IOException>() {
2610 
2611             @Override
2612             public long applyAsLong(final String t, final String u) throws IOException {
2613                 throw new IOException("test");
2614             }
2615         };
2616     }
2617 
2618     /**
2619      * Tests that our failable interface is properly defined to throw any exception using the top level generic types
2620      * Object and Throwable.
2621      */
2622     @Test
2623     public void testThrows_FailableToLongFunction_Object_Throwable() {
2624         new FailableToLongFunction<Object, Throwable>() {
2625 
2626             @Override
2627             public long applyAsLong(final Object t) throws Throwable {
2628                 throw new IOException("test");
2629             }
2630         };
2631     }
2632 
2633     /**
2634      * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
2635      * generic test types.
2636      */
2637     @Test
2638     public void testThrows_FailableToLongFunction_String_IOException() {
2639         new FailableToLongFunction<String, IOException>() {
2640 
2641             @Override
2642             public long applyAsLong(final String t) throws IOException {
2643                 throw new IOException("test");
2644             }
2645         };
2646     }
2647 
2648     @Test
2649     public void testTryWithResources() {
2650         final CloseableObject closeable = new CloseableObject();
2651         final FailableConsumer<Throwable, ? extends Throwable> consumer = closeable::run;
2652         Throwable e = assertThrows(IllegalStateException.class,
2653             () -> Failable.tryWithResources(() -> consumer.accept(ILLEGAL_STATE_EXCEPTION), closeable::close));
2654         assertSame(ILLEGAL_STATE_EXCEPTION, e);
2655 
2656         assertTrue(closeable.isClosed());
2657         closeable.reset();
2658         e = assertThrows(OutOfMemoryError.class,
2659             () -> Failable.tryWithResources(() -> consumer.accept(ERROR), closeable::close));
2660         assertSame(ERROR, e);
2661 
2662         assertTrue(closeable.isClosed());
2663         closeable.reset();
2664         final IOException ioe = new IOException("Unknown I/O error");
2665         final UncheckedIOException uioe = assertThrows(UncheckedIOException.class,
2666             () -> Failable.tryWithResources(() -> consumer.accept(ioe), closeable::close));
2667         final IOException cause = uioe.getCause();
2668         assertSame(ioe, cause);
2669 
2670         assertTrue(closeable.isClosed());
2671         closeable.reset();
2672         Failable.tryWithResources(() -> consumer.accept(null), closeable::close);
2673         assertTrue(closeable.isClosed());
2674     }
2675 
2676     private String throwingFunction(final String input) throws Exception {
2677         return input;
2678     }
2679 
2680 }