[LANG-1568]

org.apache.commons.lang3.function.FailableBiConsumer.andThen(FailableBiConsumer<?
super T, ? super U, E>)
This commit is contained in:
Gary Gregory 2020-06-24 16:58:52 -04:00
parent 4cf50486a3
commit 9173173699
3 changed files with 161 additions and 145 deletions

View File

@ -17,6 +17,7 @@
package org.apache.commons.lang3.function; package org.apache.commons.lang3.function;
import java.util.Objects;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
/** /**
@ -30,13 +31,45 @@
@FunctionalInterface @FunctionalInterface
public interface FailableBiConsumer<T, U, E extends Throwable> { public interface FailableBiConsumer<T, U, E extends Throwable> {
/** NOP singleton */
@SuppressWarnings("rawtypes")
final FailableBiConsumer NOP = (t, u) -> {/* NOP */};
/**
* Returns The NOP singleton.
*
* @param <T> Consumed type 1.
* @param <U> Consumed type 2.
* @param <E> Thrown exception.
* @return The NOP singleton.
*/
static <T, U, E extends Throwable> FailableBiConsumer<T, U, E> nop() {
return NOP;
}
/** /**
* Accepts the consumer. * Accepts the consumer.
* *
* @param object1 the first parameter for the consumable to accept * @param t the first parameter for the consumable to accept
* @param object2 the second parameter for the consumable to accept * @param u the second parameter for the consumable to accept
* @throws E Thrown when the consumer fails. * @throws E Thrown when the consumer fails.
*/ */
void accept(T object1, U object2) throws E; void accept(T t, U u) throws E;
/**
* Returns a composed {@code FailableBiConsumer} that performs like {@link BiConsumer#andThen(BiConsumer)}.
*
* @param after the operation to perform after this one.
* @return a composed {@code FailableBiConsumer} that performs like {@link BiConsumer#andThen(BiConsumer)}.
* @throws E Thrown when a consumer fails.
* @throws NullPointerException if {@code after} is null
*/
default FailableBiConsumer<T, U, E> andThen(FailableBiConsumer<? super T, ? super U, E> after) throws E {
Objects.requireNonNull(after);
return (t, u) -> {
accept(t, u);
after.accept(t, u);
};
}
} }

View File

@ -19,7 +19,7 @@
* for working with Java 8 lambdas. * for working with Java 8 lambdas.
* *
* <p>Contains failable functional interfaces that address the fact that lambdas are supposed not to * <p>Contains failable functional interfaces that address the fact that lambdas are supposed not to
* throw Exceptions, at least not checked Exceptions, AKA instances of {@link java.lang.Exception}. * throw Exceptions, at least not checked Exceptions, A.K.A. instances of {@link java.lang.Exception}.
* A failable functional interface declares a type of Exception that may be raised if the function * A failable functional interface declares a type of Exception that may be raised if the function
* fails. * fails.
* *

View File

@ -45,6 +45,9 @@
*/ */
public class FailableFunctionsTest { public class FailableFunctionsTest {
private static final IllegalStateException ILLEGAL_STATE_EXCEPTION = new IllegalStateException();
private static final OutOfMemoryError ERROR = new OutOfMemoryError();
public static class CloseableObject { public static class CloseableObject {
private boolean closed; private boolean closed;
@ -267,14 +270,12 @@ public void testObjLong(final T object, final long i) throws Throwable {
@Test @Test
void testAcceptBiConsumer() { void testAcceptBiConsumer() {
final IllegalStateException ise = new IllegalStateException();
final Testable<?, ?> testable = new Testable<>(null); final Testable<?, ?> testable = new Testable<>(null);
Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(Testable::test, testable, ise)); Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(Testable::test, testable, ILLEGAL_STATE_EXCEPTION));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
final Error error = new OutOfMemoryError(); e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(Testable::test, testable, ERROR));
e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(Testable::test, testable, error)); assertSame(ERROR, e);
assertSame(error, e);
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
testable.setThrowable(ioe); testable.setThrowable(ioe);
@ -289,15 +290,13 @@ void testAcceptBiConsumer() {
@Test @Test
void testAcceptConsumer() { void testAcceptConsumer() {
final IllegalStateException ise = new IllegalStateException(); final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
final Testable<?, ?> testable = new Testable<>(ise);
Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(Testable::test, testable)); Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(Testable::test, testable));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
final Error error = new OutOfMemoryError(); testable.setThrowable(ERROR);
testable.setThrowable(error);
e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(Testable::test, testable)); e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(Testable::test, testable));
assertSame(error, e); assertSame(ERROR, e);
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
testable.setThrowable(ioe); testable.setThrowable(ioe);
@ -312,16 +311,14 @@ void testAcceptConsumer() {
@Test @Test
void testAcceptDoubleConsumer() { void testAcceptDoubleConsumer() {
final IllegalStateException ise = new IllegalStateException(); final Testable<?, Double> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
final Testable<?, Double> testable = new Testable<>(ise);
Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(testable::testDouble, 1d)); Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(testable::testDouble, 1d));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
assertNull(testable.getAcceptedPrimitiveObject1()); assertNull(testable.getAcceptedPrimitiveObject1());
final Error error = new OutOfMemoryError(); testable.setThrowable(ERROR);
testable.setThrowable(error);
e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testDouble, 1d)); e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testDouble, 1d));
assertSame(error, e); assertSame(ERROR, e);
assertNull(testable.getAcceptedPrimitiveObject1()); assertNull(testable.getAcceptedPrimitiveObject1());
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
@ -339,16 +336,14 @@ void testAcceptDoubleConsumer() {
@Test @Test
void testAcceptIntConsumer() { void testAcceptIntConsumer() {
final IllegalStateException ise = new IllegalStateException(); final Testable<?, Integer> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
final Testable<?, Integer> testable = new Testable<>(ise);
Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(testable::testInt, 1)); Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(testable::testInt, 1));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
assertNull(testable.getAcceptedPrimitiveObject1()); assertNull(testable.getAcceptedPrimitiveObject1());
final Error error = new OutOfMemoryError(); testable.setThrowable(ERROR);
testable.setThrowable(error);
e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testInt, 1)); e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testInt, 1));
assertSame(error, e); assertSame(ERROR, e);
assertNull(testable.getAcceptedPrimitiveObject1()); assertNull(testable.getAcceptedPrimitiveObject1());
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
@ -366,16 +361,14 @@ void testAcceptIntConsumer() {
@Test @Test
void testAcceptLongConsumer() { void testAcceptLongConsumer() {
final IllegalStateException ise = new IllegalStateException(); final Testable<?, Long> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
final Testable<?, Long> testable = new Testable<>(ise);
Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(testable::testLong, 1L)); Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(testable::testLong, 1L));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
assertNull(testable.getAcceptedPrimitiveObject1()); assertNull(testable.getAcceptedPrimitiveObject1());
final Error error = new OutOfMemoryError(); testable.setThrowable(ERROR);
testable.setThrowable(error);
e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testLong, 1L)); e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testLong, 1L));
assertSame(error, e); assertSame(ERROR, e);
assertNull(testable.getAcceptedPrimitiveObject1()); assertNull(testable.getAcceptedPrimitiveObject1());
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
@ -393,18 +386,16 @@ void testAcceptLongConsumer() {
@Test @Test
void testAcceptObjDoubleConsumer() { void testAcceptObjDoubleConsumer() {
final IllegalStateException ise = new IllegalStateException(); final Testable<String, Double> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
final Testable<String, Double> testable = new Testable<>(ise);
Throwable e = assertThrows(IllegalStateException.class, Throwable e = assertThrows(IllegalStateException.class,
() -> Failable.accept(testable::testObjDouble, "X", 1d)); () -> Failable.accept(testable::testObjDouble, "X", 1d));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
assertNull(testable.getAcceptedObject()); assertNull(testable.getAcceptedObject());
assertNull(testable.getAcceptedPrimitiveObject1()); assertNull(testable.getAcceptedPrimitiveObject1());
final Error error = new OutOfMemoryError(); testable.setThrowable(ERROR);
testable.setThrowable(error);
e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testObjDouble, "X", 1d)); e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testObjDouble, "X", 1d));
assertSame(error, e); assertSame(ERROR, e);
assertNull(testable.getAcceptedObject()); assertNull(testable.getAcceptedObject());
assertNull(testable.getAcceptedPrimitiveObject1()); assertNull(testable.getAcceptedPrimitiveObject1());
@ -425,17 +416,15 @@ void testAcceptObjDoubleConsumer() {
@Test @Test
void testAcceptObjIntConsumer() { void testAcceptObjIntConsumer() {
final IllegalStateException ise = new IllegalStateException(); final Testable<String, Integer> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
final Testable<String, Integer> testable = new Testable<>(ise);
Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(testable::testObjInt, "X", 1)); Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(testable::testObjInt, "X", 1));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
assertNull(testable.getAcceptedObject()); assertNull(testable.getAcceptedObject());
assertNull(testable.getAcceptedPrimitiveObject1()); assertNull(testable.getAcceptedPrimitiveObject1());
final Error error = new OutOfMemoryError(); testable.setThrowable(ERROR);
testable.setThrowable(error);
e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testObjInt, "X", 1)); e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testObjInt, "X", 1));
assertSame(error, e); assertSame(ERROR, e);
assertNull(testable.getAcceptedObject()); assertNull(testable.getAcceptedObject());
assertNull(testable.getAcceptedPrimitiveObject1()); assertNull(testable.getAcceptedPrimitiveObject1());
@ -456,17 +445,15 @@ void testAcceptObjIntConsumer() {
@Test @Test
void testAcceptObjLongConsumer() { void testAcceptObjLongConsumer() {
final IllegalStateException ise = new IllegalStateException(); final Testable<String, Long> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
final Testable<String, Long> testable = new Testable<>(ise);
Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(testable::testObjLong, "X", 1L)); Throwable e = assertThrows(IllegalStateException.class, () -> Failable.accept(testable::testObjLong, "X", 1L));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
assertNull(testable.getAcceptedObject()); assertNull(testable.getAcceptedObject());
assertNull(testable.getAcceptedPrimitiveObject1()); assertNull(testable.getAcceptedPrimitiveObject1());
final Error error = new OutOfMemoryError(); testable.setThrowable(ERROR);
testable.setThrowable(error);
e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testObjLong, "X", 1L)); e = assertThrows(OutOfMemoryError.class, () -> Failable.accept(testable::testObjLong, "X", 1L));
assertSame(error, e); assertSame(ERROR, e);
assertNull(testable.getAcceptedObject()); assertNull(testable.getAcceptedObject());
assertNull(testable.getAcceptedPrimitiveObject1()); assertNull(testable.getAcceptedPrimitiveObject1());
@ -487,15 +474,13 @@ void testAcceptObjLongConsumer() {
@Test @Test
public void testApplyBiFunction() { public void testApplyBiFunction() {
final IllegalStateException ise = new IllegalStateException();
final Testable<?, ?> testable = new Testable<>(null); final Testable<?, ?> testable = new Testable<>(null);
Throwable e = assertThrows(IllegalStateException.class, Throwable e = assertThrows(IllegalStateException.class,
() -> Failable.apply(Testable::testAsInteger, testable, ise)); () -> Failable.apply(Testable::testAsInteger, testable, ILLEGAL_STATE_EXCEPTION));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
final Error error = new OutOfMemoryError(); e = assertThrows(OutOfMemoryError.class, () -> Failable.apply(Testable::testAsInteger, testable, ERROR));
e = assertThrows(OutOfMemoryError.class, () -> Failable.apply(Testable::testAsInteger, testable, error)); assertSame(ERROR, e);
assertSame(error, e);
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
e = assertThrows(UncheckedIOException.class, () -> Failable.apply(Testable::testAsInteger, testable, ioe)); e = assertThrows(UncheckedIOException.class, () -> Failable.apply(Testable::testAsInteger, testable, ioe));
@ -510,11 +495,10 @@ public void testApplyBiFunction() {
@Test @Test
public void testApplyDoubleBinaryOperator() { public void testApplyDoubleBinaryOperator() {
final IllegalStateException ise = new IllegalStateException(); final Testable<?, Double> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
final Testable<?, Double> testable = new Testable<>(ise);
final Throwable e = assertThrows(IllegalStateException.class, final Throwable e = assertThrows(IllegalStateException.class,
() -> Failable.applyAsDouble(testable::testDoubleDouble, 1d, 2d)); () -> Failable.applyAsDouble(testable::testDoubleDouble, 1d, 2d));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
final Testable<?, Double> testable2 = new Testable<>(null); final Testable<?, Double> testable2 = new Testable<>(null);
final double i = Failable.applyAsDouble(testable2::testDoubleDouble, 1d, 2d); final double i = Failable.applyAsDouble(testable2::testDoubleDouble, 1d, 2d);
@ -523,16 +507,14 @@ public void testApplyDoubleBinaryOperator() {
@Test @Test
public void testApplyFunction() { public void testApplyFunction() {
final IllegalStateException ise = new IllegalStateException(); final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
final Testable<?, ?> testable = new Testable<>(ise);
Throwable e = assertThrows(IllegalStateException.class, Throwable e = assertThrows(IllegalStateException.class,
() -> Failable.apply(Testable::testAsInteger, testable)); () -> Failable.apply(Testable::testAsInteger, testable));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
final Error error = new OutOfMemoryError(); testable.setThrowable(ERROR);
testable.setThrowable(error);
e = assertThrows(OutOfMemoryError.class, () -> Failable.apply(Testable::testAsInteger, testable)); e = assertThrows(OutOfMemoryError.class, () -> Failable.apply(Testable::testAsInteger, testable));
assertSame(error, e); assertSame(ERROR, e);
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
testable.setThrowable(ioe); testable.setThrowable(ioe);
@ -568,16 +550,14 @@ void testAsCallable() {
@Test @Test
void testAsConsumer() { void testAsConsumer() {
final IllegalStateException ise = new IllegalStateException(); final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
final Testable<?, ?> testable = new Testable<>(ise);
final Consumer<Testable<?, ?>> consumer = Failable.asConsumer(Testable::test); final Consumer<Testable<?, ?>> consumer = Failable.asConsumer(Testable::test);
Throwable e = assertThrows(IllegalStateException.class, () -> consumer.accept(testable)); Throwable e = assertThrows(IllegalStateException.class, () -> consumer.accept(testable));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
final Error error = new OutOfMemoryError(); testable.setThrowable(ERROR);
testable.setThrowable(error);
e = assertThrows(OutOfMemoryError.class, () -> consumer.accept(testable)); e = assertThrows(OutOfMemoryError.class, () -> consumer.accept(testable));
assertSame(error, e); assertSame(ERROR, e);
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
testable.setThrowable(ioe); testable.setThrowable(ioe);
@ -618,20 +598,22 @@ public void testAsSupplier() {
} }
@Test @Test
void testBiConsumer() { void testBiConsumer() throws Throwable {
final IllegalStateException ise = new IllegalStateException();
final Testable<?, ?> testable = new Testable<>(null); final Testable<?, ?> testable = new Testable<>(null);
final FailableBiConsumer<Testable<?, ?>, Throwable, Throwable> failableBiConsumer = (t, th) -> { final FailableBiConsumer<Testable<?, ?>, Throwable, Throwable> failableBiConsumer = (t, th) -> {
t.setThrowable(th); t.setThrowable(th);
t.test(); t.test();
}; };
final BiConsumer<Testable<?, ?>, Throwable> consumer = Failable.asBiConsumer(failableBiConsumer); final BiConsumer<Testable<?, ?>, Throwable> consumer = Failable.asBiConsumer(failableBiConsumer);
Throwable e = assertThrows(IllegalStateException.class, () -> consumer.accept(testable, ise)); Throwable e = assertThrows(IllegalStateException.class,
assertSame(ise, e); () -> consumer.accept(testable, ILLEGAL_STATE_EXCEPTION));
assertSame(ILLEGAL_STATE_EXCEPTION, e);
final Error error = new OutOfMemoryError(); e = assertThrows(OutOfMemoryError.class, () -> consumer.accept(testable, ERROR));
e = assertThrows(OutOfMemoryError.class, () -> consumer.accept(testable, error)); assertSame(ERROR, e);
assertSame(error, e);
e = assertThrows(OutOfMemoryError.class, () -> failableBiConsumer.accept(testable, ERROR));
assertSame(ERROR, e);
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
testable.setThrowable(ioe); testable.setThrowable(ioe);
@ -643,9 +625,27 @@ void testBiConsumer() {
consumer.accept(testable, null); consumer.accept(testable, null);
} }
@Test
void testBiConsumerAndThen() throws Throwable {
final Testable<?, ?> testable = new Testable<>(null);
final FailableBiConsumer<Testable<?, ?>, Throwable, Throwable> failableBiConsumer = (t, th) -> {
t.setThrowable(th);
t.test();
};
Throwable e;
final FailableBiConsumer<Testable<?, ?>, Throwable, Throwable> nop = FailableBiConsumer.nop();
e = assertThrows(OutOfMemoryError.class, () -> nop.andThen(failableBiConsumer).accept(testable, ERROR));
assertSame(ERROR, e);
// Does not throw
nop.andThen(nop);
// Documented in Javadoc edge-case.
assertThrows(NullPointerException.class, () -> failableBiConsumer.andThen(null));
}
@Test @Test
public void testBiFunction() { public void testBiFunction() {
final IllegalStateException ise = new IllegalStateException(); final IllegalStateException ise = ILLEGAL_STATE_EXCEPTION;
final Testable<?, ?> testable = new Testable<>(ise); final Testable<?, ?> testable = new Testable<>(ise);
final FailableBiFunction<Testable<?, ?>, Throwable, Integer, Throwable> failableBiFunction = (t, th) -> { final FailableBiFunction<Testable<?, ?>, Throwable, Integer, Throwable> failableBiFunction = (t, th) -> {
t.setThrowable(th); t.setThrowable(th);
@ -655,10 +655,9 @@ public void testBiFunction() {
Throwable e = assertThrows(IllegalStateException.class, () -> biFunction.apply(testable, ise)); Throwable e = assertThrows(IllegalStateException.class, () -> biFunction.apply(testable, ise));
assertSame(ise, e); assertSame(ise, e);
final Error error = new OutOfMemoryError(); testable.setThrowable(ERROR);
testable.setThrowable(error); e = assertThrows(OutOfMemoryError.class, () -> biFunction.apply(testable, ERROR));
e = assertThrows(OutOfMemoryError.class, () -> biFunction.apply(testable, error)); assertSame(ERROR, e);
assertSame(error, e);
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
testable.setThrowable(ioe); testable.setThrowable(ioe);
@ -674,8 +673,8 @@ public void testBiFunction() {
@DisplayName("Test that asPredicate(FailableBiPredicate) is converted to -> BiPredicate ") @DisplayName("Test that asPredicate(FailableBiPredicate) is converted to -> BiPredicate ")
public void testBiPredicate() { public void testBiPredicate() {
FailureOnOddInvocations.invocations = 0; FailureOnOddInvocations.invocations = 0;
final FailableBiPredicate<Object, Object, Throwable> failableBiPredicate = (t1, final FailableBiPredicate<Object, Object, Throwable> failableBiPredicate = (t1, t2) -> FailureOnOddInvocations
t2) -> FailureOnOddInvocations.failingBool(); .failingBool();
final BiPredicate<?, ?> predicate = Failable.asBiPredicate(failableBiPredicate); final BiPredicate<?, ?> predicate = Failable.asBiPredicate(failableBiPredicate);
final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class,
() -> predicate.test(null, null)); () -> predicate.test(null, null));
@ -717,20 +716,18 @@ public void testDoublePredicate() throws Throwable {
@Test @Test
public void testFunction() { public void testFunction() {
final IllegalStateException ise = new IllegalStateException(); final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
final Testable<?, ?> testable = new Testable<>(ise);
final FailableFunction<Throwable, Integer, Throwable> failableFunction = th -> { final FailableFunction<Throwable, Integer, Throwable> failableFunction = th -> {
testable.setThrowable(th); testable.setThrowable(th);
return Integer.valueOf(testable.testAsInteger()); return Integer.valueOf(testable.testAsInteger());
}; };
final Function<Throwable, Integer> function = Failable.asFunction(failableFunction); final Function<Throwable, Integer> function = Failable.asFunction(failableFunction);
Throwable e = assertThrows(IllegalStateException.class, () -> function.apply(ise)); Throwable e = assertThrows(IllegalStateException.class, () -> function.apply(ILLEGAL_STATE_EXCEPTION));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
final Error error = new OutOfMemoryError(); testable.setThrowable(ERROR);
testable.setThrowable(error); e = assertThrows(OutOfMemoryError.class, () -> function.apply(ERROR));
e = assertThrows(OutOfMemoryError.class, () -> function.apply(error)); assertSame(ERROR, e);
assertSame(error, e);
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
testable.setThrowable(ioe); testable.setThrowable(ioe);
@ -744,16 +741,14 @@ public void testFunction() {
@Test @Test
public void testGetAsBooleanSupplier() { public void testGetAsBooleanSupplier() {
final IllegalStateException ise = new IllegalStateException(); final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
final Testable<?, ?> testable = new Testable<>(ise);
Throwable e = assertThrows(IllegalStateException.class, Throwable e = assertThrows(IllegalStateException.class,
() -> Failable.getAsBoolean(testable::testAsBooleanPrimitive)); () -> Failable.getAsBoolean(testable::testAsBooleanPrimitive));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
final Error error = new OutOfMemoryError(); testable.setThrowable(ERROR);
testable.setThrowable(error);
e = assertThrows(OutOfMemoryError.class, () -> Failable.getAsBoolean(testable::testAsBooleanPrimitive)); e = assertThrows(OutOfMemoryError.class, () -> Failable.getAsBoolean(testable::testAsBooleanPrimitive));
assertSame(error, e); assertSame(ERROR, e);
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
testable.setThrowable(ioe); testable.setThrowable(ioe);
@ -768,16 +763,14 @@ public void testGetAsBooleanSupplier() {
@Test @Test
public void testGetAsDoubleSupplier() { public void testGetAsDoubleSupplier() {
final IllegalStateException ise = new IllegalStateException(); final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
final Testable<?, ?> testable = new Testable<>(ise);
Throwable e = assertThrows(IllegalStateException.class, Throwable e = assertThrows(IllegalStateException.class,
() -> Failable.getAsDouble(testable::testAsDoublePrimitive)); () -> Failable.getAsDouble(testable::testAsDoublePrimitive));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
final Error error = new OutOfMemoryError(); testable.setThrowable(ERROR);
testable.setThrowable(error);
e = assertThrows(OutOfMemoryError.class, () -> Failable.getAsDouble(testable::testAsDoublePrimitive)); e = assertThrows(OutOfMemoryError.class, () -> Failable.getAsDouble(testable::testAsDoublePrimitive));
assertSame(error, e); assertSame(ERROR, e);
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
testable.setThrowable(ioe); testable.setThrowable(ioe);
@ -792,15 +785,13 @@ public void testGetAsDoubleSupplier() {
@Test @Test
public void testGetAsIntSupplier() { public void testGetAsIntSupplier() {
final IllegalStateException ise = new IllegalStateException(); final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
final Testable<?, ?> testable = new Testable<>(ise);
Throwable e = assertThrows(IllegalStateException.class, () -> Failable.getAsInt(testable::testAsIntPrimitive)); Throwable e = assertThrows(IllegalStateException.class, () -> Failable.getAsInt(testable::testAsIntPrimitive));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
final Error error = new OutOfMemoryError(); testable.setThrowable(ERROR);
testable.setThrowable(error);
e = assertThrows(OutOfMemoryError.class, () -> Failable.getAsInt(testable::testAsIntPrimitive)); e = assertThrows(OutOfMemoryError.class, () -> Failable.getAsInt(testable::testAsIntPrimitive));
assertSame(error, e); assertSame(ERROR, e);
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
testable.setThrowable(ioe); testable.setThrowable(ioe);
@ -816,16 +807,14 @@ public void testGetAsIntSupplier() {
@Test @Test
public void testGetAsLongSupplier() { public void testGetAsLongSupplier() {
final IllegalStateException ise = new IllegalStateException(); final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
final Testable<?, ?> testable = new Testable<>(ise);
Throwable e = assertThrows(IllegalStateException.class, Throwable e = assertThrows(IllegalStateException.class,
() -> Failable.getAsLong(testable::testAsLongPrimitive)); () -> Failable.getAsLong(testable::testAsLongPrimitive));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
final Error error = new OutOfMemoryError(); testable.setThrowable(ERROR);
testable.setThrowable(error);
e = assertThrows(OutOfMemoryError.class, () -> Failable.getAsLong(testable::testAsLongPrimitive)); e = assertThrows(OutOfMemoryError.class, () -> Failable.getAsLong(testable::testAsLongPrimitive));
assertSame(error, e); assertSame(ERROR, e);
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
testable.setThrowable(ioe); testable.setThrowable(ioe);
@ -854,15 +843,13 @@ public void testGetFromSupplier() {
@Test @Test
public void testGetSupplier() { public void testGetSupplier() {
final IllegalStateException ise = new IllegalStateException(); final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);
final Testable<?, ?> testable = new Testable<>(ise);
Throwable e = assertThrows(IllegalStateException.class, () -> Failable.get(testable::testAsInteger)); Throwable e = assertThrows(IllegalStateException.class, () -> Failable.get(testable::testAsInteger));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
final Error error = new OutOfMemoryError(); testable.setThrowable(ERROR);
testable.setThrowable(error);
e = assertThrows(OutOfMemoryError.class, () -> Failable.get(testable::testAsInteger)); e = assertThrows(OutOfMemoryError.class, () -> Failable.get(testable::testAsInteger));
assertSame(error, e); assertSame(ERROR, e);
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
testable.setThrowable(ioe); testable.setThrowable(ioe);
@ -897,8 +884,7 @@ public void testLongPredicate() throws Throwable {
@DisplayName("Test that asPredicate(FailablePredicate) is converted to -> Predicate ") @DisplayName("Test that asPredicate(FailablePredicate) is converted to -> Predicate ")
public void testPredicate() { public void testPredicate() {
FailureOnOddInvocations.invocations = 0; FailureOnOddInvocations.invocations = 0;
final FailablePredicate<Object, Throwable> failablePredicate = t -> FailureOnOddInvocations final FailablePredicate<Object, Throwable> failablePredicate = t -> FailureOnOddInvocations.failingBool();
.failingBool();
final Predicate<?> predicate = Failable.asPredicate(failablePredicate); final Predicate<?> predicate = Failable.asPredicate(failablePredicate);
final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class,
() -> predicate.test(null)); () -> predicate.test(null));
@ -1047,7 +1033,6 @@ public boolean getAsBoolean() throws IOException {
/////////////////////////////////////////////// ///////////////////////////////////////////////
/** /**
* Tests that our failable interface is properly defined to throw any exception. using the top level generic types * Tests that our failable interface is properly defined to throw any exception. using the top level generic types
* Object and Throwable. * Object and Throwable.
@ -2050,32 +2035,30 @@ public long applyAsLong(final String t) throws IOException {
@Test @Test
public void testTryWithResources() { public void testTryWithResources() {
final CloseableObject co = new CloseableObject(); final CloseableObject closeable = new CloseableObject();
final FailableConsumer<Throwable, ? extends Throwable> consumer = co::run; final FailableConsumer<Throwable, ? extends Throwable> consumer = closeable::run;
final IllegalStateException ise = new IllegalStateException();
Throwable e = assertThrows(IllegalStateException.class, Throwable e = assertThrows(IllegalStateException.class,
() -> Failable.tryWithResources(() -> consumer.accept(ise), co::close)); () -> Failable.tryWithResources(() -> consumer.accept(ILLEGAL_STATE_EXCEPTION), closeable::close));
assertSame(ise, e); assertSame(ILLEGAL_STATE_EXCEPTION, e);
assertTrue(co.isClosed()); assertTrue(closeable.isClosed());
co.reset(); closeable.reset();
final Error error = new OutOfMemoryError();
e = assertThrows(OutOfMemoryError.class, e = assertThrows(OutOfMemoryError.class,
() -> Failable.tryWithResources(() -> consumer.accept(error), co::close)); () -> Failable.tryWithResources(() -> consumer.accept(ERROR), closeable::close));
assertSame(error, e); assertSame(ERROR, e);
assertTrue(co.isClosed()); assertTrue(closeable.isClosed());
co.reset(); closeable.reset();
final IOException ioe = new IOException("Unknown I/O error"); final IOException ioe = new IOException("Unknown I/O error");
final UncheckedIOException uioe = assertThrows(UncheckedIOException.class, final UncheckedIOException uioe = assertThrows(UncheckedIOException.class,
() -> Failable.tryWithResources(() -> consumer.accept(ioe), co::close)); () -> Failable.tryWithResources(() -> consumer.accept(ioe), closeable::close));
final IOException cause = uioe.getCause(); final IOException cause = uioe.getCause();
assertSame(ioe, cause); assertSame(ioe, cause);
assertTrue(co.isClosed()); assertTrue(closeable.isClosed());
co.reset(); closeable.reset();
Failable.tryWithResources(() -> consumer.accept(null), co::close); Failable.tryWithResources(() -> consumer.accept(null), closeable::close);
assertTrue(co.isClosed()); assertTrue(closeable.isClosed());
} }
} }