| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.commons.lang3; |
| |
| import static org.junit.jupiter.api.Assertions.assertEquals; |
| import static org.junit.jupiter.api.Assertions.assertNotNull; |
| import static org.junit.jupiter.api.Assertions.assertNull; |
| import static org.junit.jupiter.api.Assertions.assertSame; |
| import static org.junit.jupiter.api.Assertions.assertThrows; |
| import static org.junit.jupiter.api.Assertions.assertTrue; |
| |
| import java.io.IOException; |
| import java.io.UncheckedIOException; |
| import java.lang.reflect.UndeclaredThrowableException; |
| import java.util.concurrent.Callable; |
| import java.util.function.BiConsumer; |
| import java.util.function.BiFunction; |
| import java.util.function.BiPredicate; |
| import java.util.function.Consumer; |
| import java.util.function.Function; |
| import java.util.function.Predicate; |
| import java.util.function.Supplier; |
| |
| import org.apache.commons.lang3.Functions.FailableBiConsumer; |
| import org.apache.commons.lang3.Functions.FailableBiFunction; |
| import org.apache.commons.lang3.Functions.FailableCallable; |
| import org.apache.commons.lang3.Functions.FailableConsumer; |
| import org.apache.commons.lang3.Functions.FailableFunction; |
| import org.apache.commons.lang3.Functions.FailableSupplier; |
| import org.junit.jupiter.api.DisplayName; |
| import org.junit.jupiter.api.Test; |
| |
| public class FunctionsTest extends AbstractLangTest { |
| |
| public static class CloseableObject { |
| private boolean closed; |
| |
| public void close() { |
| closed = true; |
| } |
| |
| public boolean isClosed() { |
| return closed; |
| } |
| |
| public void reset() { |
| closed = false; |
| } |
| |
| public void run(final Throwable pTh) throws Throwable { |
| if (pTh != null) { |
| throw pTh; |
| } |
| } |
| } |
| |
| public static class FailureOnOddInvocations { |
| private static int invocations; |
| |
| static boolean failingBool() throws SomeException { |
| throwOnOdd(); |
| return true; |
| } |
| |
| static boolean testDouble(final double value) throws SomeException { |
| throwOnOdd(); |
| return true; |
| } |
| |
| static boolean testInt(final int value) throws SomeException { |
| throwOnOdd(); |
| return true; |
| } |
| |
| static boolean testLong(final long value) throws SomeException { |
| throwOnOdd(); |
| return true; |
| } |
| |
| private static void throwOnOdd() throws SomeException { |
| final int i = ++invocations; |
| if (i % 2 == 1) { |
| throw new SomeException("Odd Invocation: " + i); |
| } |
| } |
| |
| FailureOnOddInvocations() throws SomeException { |
| throwOnOdd(); |
| } |
| |
| boolean getAsBoolean() throws SomeException { |
| throwOnOdd(); |
| return true; |
| } |
| } |
| |
| public static class SomeException extends Exception { |
| |
| private static final long serialVersionUID = -4965704778119283411L; |
| |
| private Throwable t; |
| |
| SomeException(final String message) { |
| super(message); |
| } |
| |
| public void setThrowable(final Throwable throwable) { |
| t = throwable; |
| } |
| |
| public void test() throws Throwable { |
| if (t != null) { |
| throw t; |
| } |
| } |
| } |
| |
| public static class Testable<T, P> { |
| private T acceptedObject; |
| private P acceptedPrimitiveObject1; |
| private P acceptedPrimitiveObject2; |
| private Throwable throwable; |
| |
| Testable(final Throwable throwable) { |
| this.throwable = throwable; |
| } |
| |
| public T getAcceptedObject() { |
| return acceptedObject; |
| } |
| |
| public P getAcceptedPrimitiveObject1() { |
| return acceptedPrimitiveObject1; |
| } |
| |
| public P getAcceptedPrimitiveObject2() { |
| return acceptedPrimitiveObject2; |
| } |
| |
| public void setThrowable(final Throwable throwable) { |
| this.throwable = throwable; |
| } |
| |
| public void test() throws Throwable { |
| test(throwable); |
| } |
| |
| public Object test(final Object input1, final Object input2) throws Throwable { |
| test(throwable); |
| return acceptedObject; |
| } |
| |
| public void test(final Throwable throwable) throws Throwable { |
| if (throwable != null) { |
| throw throwable; |
| } |
| } |
| |
| public boolean testAsBooleanPrimitive() throws Throwable { |
| return testAsBooleanPrimitive(throwable); |
| } |
| |
| public boolean testAsBooleanPrimitive(final Throwable throwable) throws Throwable { |
| if (throwable != null) { |
| throw throwable; |
| } |
| return false; |
| } |
| |
| public double testAsDoublePrimitive() throws Throwable { |
| return testAsDoublePrimitive(throwable); |
| } |
| |
| public double testAsDoublePrimitive(final Throwable throwable) throws Throwable { |
| if (throwable != null) { |
| throw throwable; |
| } |
| return 0; |
| } |
| |
| public Integer testAsInteger() throws Throwable { |
| return testAsInteger(throwable); |
| } |
| |
| public Integer testAsInteger(final Throwable throwable) throws Throwable { |
| if (throwable != null) { |
| throw throwable; |
| } |
| return 0; |
| } |
| |
| public int testAsIntPrimitive() throws Throwable { |
| return testAsIntPrimitive(throwable); |
| } |
| |
| public int testAsIntPrimitive(final Throwable throwable) throws Throwable { |
| if (throwable != null) { |
| throw throwable; |
| } |
| return 0; |
| } |
| |
| public long testAsLongPrimitive() throws Throwable { |
| return testAsLongPrimitive(throwable); |
| } |
| |
| public long testAsLongPrimitive(final Throwable throwable) throws Throwable { |
| if (throwable != null) { |
| throw throwable; |
| } |
| return 0; |
| } |
| |
| public void testDouble(final double i) throws Throwable { |
| test(throwable); |
| acceptedPrimitiveObject1 = (P) ((Double) i); |
| } |
| |
| public double testDoubleDouble(final double i, final double j) throws Throwable { |
| test(throwable); |
| acceptedPrimitiveObject1 = (P) ((Double) i); |
| acceptedPrimitiveObject2 = (P) ((Double) j); |
| return 3d; |
| } |
| |
| public void testInt(final int i) throws Throwable { |
| test(throwable); |
| acceptedPrimitiveObject1 = (P) ((Integer) i); |
| } |
| |
| public void testLong(final long i) throws Throwable { |
| test(throwable); |
| acceptedPrimitiveObject1 = (P) ((Long) i); |
| } |
| |
| public void testObjDouble(final T object, final double i) throws Throwable { |
| test(throwable); |
| acceptedObject = object; |
| acceptedPrimitiveObject1 = (P) ((Double) i); |
| } |
| |
| public void testObjInt(final T object, final int i) throws Throwable { |
| test(throwable); |
| acceptedObject = object; |
| acceptedPrimitiveObject1 = (P) ((Integer) i); |
| } |
| |
| public void testObjLong(final T object, final long i) throws Throwable { |
| test(throwable); |
| acceptedObject = object; |
| acceptedPrimitiveObject1 = (P) ((Long) i); |
| } |
| } |
| |
| @Test |
| public void testAcceptBiConsumer() { |
| final IllegalStateException ise = new IllegalStateException(); |
| final Testable<?, ?> testable = new Testable<>(null); |
| Throwable e = assertThrows(IllegalStateException.class, () -> Functions.accept(Testable::test, testable, ise)); |
| assertSame(ise, e); |
| |
| final Error error = new OutOfMemoryError(); |
| e = assertThrows(OutOfMemoryError.class, () -> Functions.accept(Testable::test, testable, error)); |
| assertSame(error, e); |
| |
| final IOException ioe = new IOException("Unknown I/O error"); |
| testable.setThrowable(ioe); |
| e = assertThrows(UncheckedIOException.class, () -> Functions.accept(Testable::test, testable, ioe)); |
| final Throwable t = e.getCause(); |
| assertNotNull(t); |
| assertSame(ioe, t); |
| |
| testable.setThrowable(null); |
| Functions.accept(Testable::test, testable, (Throwable) null); |
| } |
| |
| @Test |
| public void testAcceptConsumer() { |
| final IllegalStateException ise = new IllegalStateException(); |
| final Testable<?, ?> testable = new Testable<>(ise); |
| Throwable e = assertThrows(IllegalStateException.class, () -> Functions.accept(Testable::test, testable)); |
| assertSame(ise, e); |
| |
| final Error error = new OutOfMemoryError(); |
| testable.setThrowable(error); |
| e = assertThrows(OutOfMemoryError.class, () -> Functions.accept(Testable::test, testable)); |
| assertSame(error, e); |
| |
| final IOException ioe = new IOException("Unknown I/O error"); |
| testable.setThrowable(ioe); |
| e = assertThrows(UncheckedIOException.class, () -> Functions.accept(Testable::test, testable)); |
| final Throwable t = e.getCause(); |
| assertNotNull(t); |
| assertSame(ioe, t); |
| |
| testable.setThrowable(null); |
| Functions.accept(Testable::test, testable); |
| } |
| |
| @Test |
| public void testAcceptDoubleConsumer() { |
| final IllegalStateException ise = new IllegalStateException(); |
| final Testable<?, Double> testable = new Testable<>(ise); |
| Throwable e = assertThrows(IllegalStateException.class, () -> Functions.accept(testable::testDouble, 1d)); |
| assertSame(ise, e); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| final Error error = new OutOfMemoryError(); |
| testable.setThrowable(error); |
| e = assertThrows(OutOfMemoryError.class, () -> Functions.accept(testable::testDouble, 1d)); |
| assertSame(error, e); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| final IOException ioe = new IOException("Unknown I/O error"); |
| testable.setThrowable(ioe); |
| e = assertThrows(UncheckedIOException.class, () -> Functions.accept(testable::testDouble, 1d)); |
| final Throwable t = e.getCause(); |
| assertNotNull(t); |
| assertSame(ioe, t); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| testable.setThrowable(null); |
| Functions.accept(testable::testDouble, 1d); |
| assertEquals(1, testable.getAcceptedPrimitiveObject1()); |
| } |
| |
| @Test |
| public void testAcceptIntConsumer() { |
| final IllegalStateException ise = new IllegalStateException(); |
| final Testable<?, Integer> testable = new Testable<>(ise); |
| Throwable e = assertThrows(IllegalStateException.class, () -> Functions.accept(testable::testInt, 1)); |
| assertSame(ise, e); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| final Error error = new OutOfMemoryError(); |
| testable.setThrowable(error); |
| e = assertThrows(OutOfMemoryError.class, () -> Functions.accept(testable::testInt, 1)); |
| assertSame(error, e); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| final IOException ioe = new IOException("Unknown I/O error"); |
| testable.setThrowable(ioe); |
| e = assertThrows(UncheckedIOException.class, () -> Functions.accept(testable::testInt, 1)); |
| final Throwable t = e.getCause(); |
| assertNotNull(t); |
| assertSame(ioe, t); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| testable.setThrowable(null); |
| Functions.accept(testable::testInt, 1); |
| assertEquals(1, testable.getAcceptedPrimitiveObject1()); |
| } |
| |
| @Test |
| public void testAcceptLongConsumer() { |
| final IllegalStateException ise = new IllegalStateException(); |
| final Testable<?, Long> testable = new Testable<>(ise); |
| Throwable e = assertThrows(IllegalStateException.class, () -> Functions.accept(testable::testLong, 1L)); |
| assertSame(ise, e); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| final Error error = new OutOfMemoryError(); |
| testable.setThrowable(error); |
| e = assertThrows(OutOfMemoryError.class, () -> Functions.accept(testable::testLong, 1L)); |
| assertSame(error, e); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| final IOException ioe = new IOException("Unknown I/O error"); |
| testable.setThrowable(ioe); |
| e = assertThrows(UncheckedIOException.class, () -> Functions.accept(testable::testLong, 1L)); |
| final Throwable t = e.getCause(); |
| assertNotNull(t); |
| assertSame(ioe, t); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| testable.setThrowable(null); |
| Functions.accept(testable::testLong, 1L); |
| assertEquals(1, testable.getAcceptedPrimitiveObject1()); |
| } |
| |
| @Test |
| public void testAcceptObjDoubleConsumer() { |
| final IllegalStateException ise = new IllegalStateException(); |
| final Testable<String, Double> testable = new Testable<>(ise); |
| Throwable e = assertThrows(IllegalStateException.class, |
| () -> Functions.accept(testable::testObjDouble, "X", 1d)); |
| assertSame(ise, e); |
| assertNull(testable.getAcceptedObject()); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| final Error error = new OutOfMemoryError(); |
| testable.setThrowable(error); |
| e = assertThrows(OutOfMemoryError.class, () -> Functions.accept(testable::testObjDouble, "X", 1d)); |
| assertSame(error, e); |
| assertNull(testable.getAcceptedObject()); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| final IOException ioe = new IOException("Unknown I/O error"); |
| testable.setThrowable(ioe); |
| e = assertThrows(UncheckedIOException.class, () -> Functions.accept(testable::testObjDouble, "X", 1d)); |
| final Throwable t = e.getCause(); |
| assertNotNull(t); |
| assertSame(ioe, t); |
| assertNull(testable.getAcceptedObject()); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| testable.setThrowable(null); |
| Functions.accept(testable::testObjDouble, "X", 1d); |
| assertEquals("X", testable.getAcceptedObject()); |
| assertEquals(1d, testable.getAcceptedPrimitiveObject1()); |
| } |
| |
| @Test |
| public void testAcceptObjIntConsumer() { |
| final IllegalStateException ise = new IllegalStateException(); |
| final Testable<String, Integer> testable = new Testable<>(ise); |
| Throwable e = assertThrows(IllegalStateException.class, () -> Functions.accept(testable::testObjInt, "X", 1)); |
| assertSame(ise, e); |
| assertNull(testable.getAcceptedObject()); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| final Error error = new OutOfMemoryError(); |
| testable.setThrowable(error); |
| e = assertThrows(OutOfMemoryError.class, () -> Functions.accept(testable::testObjInt, "X", 1)); |
| assertSame(error, e); |
| assertNull(testable.getAcceptedObject()); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| final IOException ioe = new IOException("Unknown I/O error"); |
| testable.setThrowable(ioe); |
| e = assertThrows(UncheckedIOException.class, () -> Functions.accept(testable::testObjInt, "X", 1)); |
| final Throwable t = e.getCause(); |
| assertNotNull(t); |
| assertSame(ioe, t); |
| assertNull(testable.getAcceptedObject()); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| testable.setThrowable(null); |
| Functions.accept(testable::testObjInt, "X", 1); |
| assertEquals("X", testable.getAcceptedObject()); |
| assertEquals(1, testable.getAcceptedPrimitiveObject1()); |
| } |
| |
| @Test |
| public void testAcceptObjLongConsumer() { |
| final IllegalStateException ise = new IllegalStateException(); |
| final Testable<String, Long> testable = new Testable<>(ise); |
| Throwable e = assertThrows(IllegalStateException.class, () -> Functions.accept(testable::testObjLong, "X", 1L)); |
| assertSame(ise, e); |
| assertNull(testable.getAcceptedObject()); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| final Error error = new OutOfMemoryError(); |
| testable.setThrowable(error); |
| e = assertThrows(OutOfMemoryError.class, () -> Functions.accept(testable::testObjLong, "X", 1L)); |
| assertSame(error, e); |
| assertNull(testable.getAcceptedObject()); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| final IOException ioe = new IOException("Unknown I/O error"); |
| testable.setThrowable(ioe); |
| e = assertThrows(UncheckedIOException.class, () -> Functions.accept(testable::testObjLong, "X", 1L)); |
| final Throwable t = e.getCause(); |
| assertNotNull(t); |
| assertSame(ioe, t); |
| assertNull(testable.getAcceptedObject()); |
| assertNull(testable.getAcceptedPrimitiveObject1()); |
| |
| testable.setThrowable(null); |
| Functions.accept(testable::testObjLong, "X", 1L); |
| assertEquals("X", testable.getAcceptedObject()); |
| assertEquals(1L, testable.getAcceptedPrimitiveObject1()); |
| } |
| |
| @Test |
| public void testApplyBiFunction() { |
| final IllegalStateException ise = new IllegalStateException(); |
| final Testable<?, ?> testable = new Testable<>(null); |
| Throwable e = assertThrows(IllegalStateException.class, |
| () -> Functions.apply(Testable::testAsInteger, testable, ise)); |
| assertSame(ise, e); |
| |
| final Error error = new OutOfMemoryError(); |
| e = assertThrows(OutOfMemoryError.class, () -> Functions.apply(Testable::testAsInteger, testable, error)); |
| assertSame(error, e); |
| |
| final IOException ioe = new IOException("Unknown I/O error"); |
| e = assertThrows(UncheckedIOException.class, () -> Functions.apply(Testable::testAsInteger, testable, ioe)); |
| final Throwable t = e.getCause(); |
| assertNotNull(t); |
| assertSame(ioe, t); |
| |
| final Integer i = Functions.apply(Testable::testAsInteger, testable, (Throwable) null); |
| assertNotNull(i); |
| assertEquals(0, i.intValue()); |
| } |
| |
| @Test |
| public void testApplyFunction() { |
| final IllegalStateException ise = new IllegalStateException(); |
| final Testable<?, ?> testable = new Testable<>(ise); |
| Throwable e = assertThrows(IllegalStateException.class, |
| () -> Functions.apply(Testable::testAsInteger, testable)); |
| assertSame(ise, e); |
| |
| final Error error = new OutOfMemoryError(); |
| testable.setThrowable(error); |
| e = assertThrows(OutOfMemoryError.class, () -> Functions.apply(Testable::testAsInteger, testable)); |
| assertSame(error, e); |
| |
| final IOException ioe = new IOException("Unknown I/O error"); |
| testable.setThrowable(ioe); |
| e = assertThrows(UncheckedIOException.class, () -> Functions.apply(Testable::testAsInteger, testable)); |
| final Throwable t = e.getCause(); |
| assertNotNull(t); |
| assertSame(ioe, t); |
| |
| testable.setThrowable(null); |
| final Integer i = Functions.apply(Testable::testAsInteger, testable); |
| assertNotNull(i); |
| assertEquals(0, i.intValue()); |
| } |
| |
| @Test |
| public void testAsCallable() { |
| FailureOnOddInvocations.invocations = 0; |
| final FailableCallable<FailureOnOddInvocations, SomeException> failableCallable = FailureOnOddInvocations::new; |
| final Callable<FailureOnOddInvocations> callable = Functions.asCallable(failableCallable); |
| final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, callable::call); |
| final Throwable cause = e.getCause(); |
| assertNotNull(cause); |
| assertTrue(cause instanceof SomeException); |
| assertEquals("Odd Invocation: 1", cause.getMessage()); |
| final FailureOnOddInvocations instance; |
| try { |
| instance = callable.call(); |
| } catch (final Exception ex) { |
| throw Functions.rethrow(ex); |
| } |
| assertNotNull(instance); |
| } |
| |
| @Test |
| public void testAsConsumer() { |
| final IllegalStateException ise = new IllegalStateException(); |
| final Testable<?, ?> testable = new Testable<>(ise); |
| final Consumer<Testable<?, ?>> consumer = Functions.asConsumer(Testable::test); |
| Throwable e = assertThrows(IllegalStateException.class, () -> consumer.accept(testable)); |
| assertSame(ise, e); |
| |
| final Error error = new OutOfMemoryError(); |
| testable.setThrowable(error); |
| e = assertThrows(OutOfMemoryError.class, () -> consumer.accept(testable)); |
| assertSame(error, e); |
| |
| final IOException ioe = new IOException("Unknown I/O error"); |
| testable.setThrowable(ioe); |
| e = assertThrows(UncheckedIOException.class, () -> consumer.accept(testable)); |
| final Throwable t = e.getCause(); |
| assertNotNull(t); |
| assertSame(ioe, t); |
| |
| testable.setThrowable(null); |
| Functions.accept(Testable::test, testable); |
| } |
| |
| @Test |
| public void testAsRunnable() { |
| FailureOnOddInvocations.invocations = 0; |
| final Runnable runnable = Functions.asRunnable(FailureOnOddInvocations::new); |
| final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, runnable::run); |
| final Throwable cause = e.getCause(); |
| assertNotNull(cause); |
| assertTrue(cause instanceof SomeException); |
| assertEquals("Odd Invocation: 1", cause.getMessage()); |
| |
| // Even invocations, should not throw an exception |
| runnable.run(); |
| } |
| |
| @Test |
| public void testAsSupplier() { |
| FailureOnOddInvocations.invocations = 0; |
| final FailableSupplier<FailureOnOddInvocations, Throwable> failableSupplier = FailureOnOddInvocations::new; |
| final Supplier<FailureOnOddInvocations> supplier = Functions.asSupplier(failableSupplier); |
| final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, supplier::get); |
| final Throwable cause = e.getCause(); |
| assertNotNull(cause); |
| assertTrue(cause instanceof SomeException); |
| assertEquals("Odd Invocation: 1", cause.getMessage()); |
| assertNotNull(supplier.get()); |
| } |
| |
| @Test |
| public void testBiConsumer() { |
| final IllegalStateException ise = new IllegalStateException(); |
| final Testable<?, ?> testable = new Testable<>(null); |
| final FailableBiConsumer<Testable<?, ?>, Throwable, Throwable> failableBiConsumer = (t, th) -> { |
| t.setThrowable(th); |
| t.test(); |
| }; |
| final BiConsumer<Testable<?, ?>, Throwable> consumer = Functions.asBiConsumer(failableBiConsumer); |
| Throwable e = assertThrows(IllegalStateException.class, () -> consumer.accept(testable, ise)); |
| assertSame(ise, e); |
| |
| final Error error = new OutOfMemoryError(); |
| e = assertThrows(OutOfMemoryError.class, () -> consumer.accept(testable, error)); |
| assertSame(error, e); |
| |
| final IOException ioe = new IOException("Unknown I/O error"); |
| testable.setThrowable(ioe); |
| e = assertThrows(UncheckedIOException.class, () -> consumer.accept(testable, ioe)); |
| final Throwable t = e.getCause(); |
| assertNotNull(t); |
| assertSame(ioe, t); |
| |
| consumer.accept(testable, null); |
| } |
| |
| @Test |
| public void testBiFunction() { |
| final IllegalStateException ise = new IllegalStateException(); |
| final Testable<?, ?> testable = new Testable<>(ise); |
| final FailableBiFunction<Testable<?, ?>, Throwable, Integer, Throwable> failableBiFunction = (t, th) -> { |
| t.setThrowable(th); |
| return Integer.valueOf(t.testAsInteger()); |
| }; |
| final BiFunction<Testable<?, ?>, Throwable, Integer> biFunction = Functions.asBiFunction(failableBiFunction); |
| Throwable e = assertThrows(IllegalStateException.class, () -> biFunction.apply(testable, ise)); |
| assertSame(ise, e); |
| |
| final Error error = new OutOfMemoryError(); |
| testable.setThrowable(error); |
| e = assertThrows(OutOfMemoryError.class, () -> biFunction.apply(testable, error)); |
| assertSame(error, e); |
| |
| final IOException ioe = new IOException("Unknown I/O error"); |
| testable.setThrowable(ioe); |
| e = assertThrows(UncheckedIOException.class, () -> biFunction.apply(testable, ioe)); |
| final Throwable t = e.getCause(); |
| assertNotNull(t); |
| assertSame(ioe, t); |
| |
| assertEquals(0, biFunction.apply(testable, null).intValue()); |
| } |
| |
| @Test |
| @DisplayName("Test that asPredicate(FailableBiPredicate) is converted to -> BiPredicate ") |
| public void testBiPredicate() { |
| FailureOnOddInvocations.invocations = 0; |
| final Functions.FailableBiPredicate<Object, Object, Throwable> failableBiPredicate = (t1, |
| t2) -> FailureOnOddInvocations.failingBool(); |
| final BiPredicate<?, ?> predicate = Functions.asBiPredicate(failableBiPredicate); |
| final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, |
| () -> predicate.test(null, null)); |
| final Throwable cause = e.getCause(); |
| assertNotNull(cause); |
| assertTrue(cause instanceof SomeException); |
| assertEquals("Odd Invocation: 1", cause.getMessage()); |
| final boolean instance = predicate.test(null, null); |
| assertNotNull(instance); |
| } |
| |
| @Test |
| public void testCallable() { |
| FailureOnOddInvocations.invocations = 0; |
| final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, |
| () -> Functions.run(FailureOnOddInvocations::new)); |
| final Throwable cause = e.getCause(); |
| assertNotNull(cause); |
| assertTrue(cause instanceof SomeException); |
| assertEquals("Odd Invocation: 1", cause.getMessage()); |
| final FailureOnOddInvocations instance = Functions.call(FailureOnOddInvocations::new); |
| assertNotNull(instance); |
| } |
| |
| @Test |
| public void testConstructor() { |
| // We allow this, which must have been an omission to make the ctor private. |
| // We could make the ctor private in 4.0. |
| new Functions(); |
| } |
| |
| @Test |
| public void testFunction() { |
| final IllegalStateException ise = new IllegalStateException(); |
| final Testable<?, ?> testable = new Testable<>(ise); |
| final FailableFunction<Throwable, Integer, Throwable> failableFunction = th -> { |
| testable.setThrowable(th); |
| return Integer.valueOf(testable.testAsInteger()); |
| }; |
| final Function<Throwable, Integer> function = Functions.asFunction(failableFunction); |
| Throwable e = assertThrows(IllegalStateException.class, () -> function.apply(ise)); |
| assertSame(ise, e); |
| |
| final Error error = new OutOfMemoryError(); |
| testable.setThrowable(error); |
| e = assertThrows(OutOfMemoryError.class, () -> function.apply(error)); |
| assertSame(error, e); |
| |
| final IOException ioe = new IOException("Unknown I/O error"); |
| testable.setThrowable(ioe); |
| e = assertThrows(UncheckedIOException.class, () -> function.apply(ioe)); |
| final Throwable t = e.getCause(); |
| assertNotNull(t); |
| assertSame(ioe, t); |
| |
| assertEquals(0, function.apply(null).intValue()); |
| } |
| |
| @Test |
| public void testGetFromSupplier() { |
| FailureOnOddInvocations.invocations = 0; |
| final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, |
| () -> Functions.run(FailureOnOddInvocations::new)); |
| final Throwable cause = e.getCause(); |
| assertNotNull(cause); |
| assertTrue(cause instanceof SomeException); |
| assertEquals("Odd Invocation: 1", cause.getMessage()); |
| final FailureOnOddInvocations instance = Functions.call(FailureOnOddInvocations::new); |
| assertNotNull(instance); |
| } |
| |
| @Test |
| public void testGetSupplier() { |
| final IllegalStateException ise = new IllegalStateException(); |
| final Testable<?, ?> testable = new Testable<>(ise); |
| Throwable e = assertThrows(IllegalStateException.class, () -> Functions.get(testable::testAsInteger)); |
| assertSame(ise, e); |
| |
| final Error error = new OutOfMemoryError(); |
| testable.setThrowable(error); |
| e = assertThrows(OutOfMemoryError.class, () -> Functions.get(testable::testAsInteger)); |
| assertSame(error, e); |
| |
| final IOException ioe = new IOException("Unknown I/O error"); |
| testable.setThrowable(ioe); |
| e = assertThrows(UncheckedIOException.class, () -> Functions.get(testable::testAsInteger)); |
| final Throwable t = e.getCause(); |
| assertNotNull(t); |
| assertSame(ioe, t); |
| |
| testable.setThrowable(null); |
| final Integer i = Functions.apply(Testable::testAsInteger, testable); |
| assertNotNull(i); |
| assertEquals(0, i.intValue()); |
| } |
| |
| @Test |
| @DisplayName("Test that asPredicate(FailablePredicate) is converted to -> Predicate ") |
| public void testPredicate() { |
| FailureOnOddInvocations.invocations = 0; |
| final Functions.FailablePredicate<Object, Throwable> failablePredicate = t -> FailureOnOddInvocations |
| .failingBool(); |
| final Predicate<?> predicate = Functions.asPredicate(failablePredicate); |
| final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, |
| () -> predicate.test(null)); |
| final Throwable cause = e.getCause(); |
| assertNotNull(cause); |
| assertTrue(cause instanceof SomeException); |
| assertEquals("Odd Invocation: 1", cause.getMessage()); |
| final boolean instance = predicate.test(null); |
| assertNotNull(instance); |
| } |
| |
| @Test |
| public void testRunnable() { |
| FailureOnOddInvocations.invocations = 0; |
| final UndeclaredThrowableException e = assertThrows(UndeclaredThrowableException.class, |
| () -> Functions.run(FailureOnOddInvocations::new)); |
| final Throwable cause = e.getCause(); |
| assertNotNull(cause); |
| assertTrue(cause instanceof SomeException); |
| assertEquals("Odd Invocation: 1", cause.getMessage()); |
| |
| // Even invocations, should not throw an exception |
| Functions.run(FailureOnOddInvocations::new); |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception. using the top level generic types |
| * Object and Throwable. |
| */ |
| @Test |
| public void testThrows_FailableBiConsumer_Object_Throwable() { |
| new Functions.FailableBiConsumer<Object, Object, Throwable>() { |
| |
| @Override |
| public void accept(final Object object1, final Object object2) throws Throwable { |
| throw new IOException("test"); |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as |
| * generic test types. |
| */ |
| @Test |
| public void testThrows_FailableBiConsumer_String_IOException() { |
| new Functions.FailableBiConsumer<String, String, IOException>() { |
| |
| @Override |
| public void accept(final String object1, final String object2) throws IOException { |
| throw new IOException("test"); |
| |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception. using the top level generic types |
| * Object and Throwable. |
| */ |
| @Test |
| public void testThrows_FailableBiFunction_Object_Throwable() { |
| new Functions.FailableBiFunction<Object, Object, Object, Throwable>() { |
| |
| @Override |
| public Object apply(final Object input1, final Object input2) throws Throwable { |
| throw new IOException("test"); |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as |
| * generic test types. |
| */ |
| @Test |
| public void testThrows_FailableBiFunction_String_IOException() { |
| new Functions.FailableBiFunction<String, String, String, IOException>() { |
| |
| @Override |
| public String apply(final String input1, final String input2) throws IOException { |
| throw new IOException("test"); |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception. using the top level generic types |
| * Object and Throwable. |
| */ |
| @Test |
| public void testThrows_FailableBiPredicate_Object_Throwable() { |
| new Functions.FailableBiPredicate<Object, Object, Throwable>() { |
| |
| @Override |
| public boolean test(final Object object1, final Object object2) throws Throwable { |
| throw new IOException("test"); |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as |
| * generic test types. |
| */ |
| @Test |
| public void testThrows_FailableBiPredicate_String_IOException() { |
| new Functions.FailableBiPredicate<String, String, IOException>() { |
| |
| @Override |
| public boolean test(final String object1, final String object2) throws IOException { |
| throw new IOException("test"); |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception. using the top level generic types |
| * Object and Throwable. |
| */ |
| @Test |
| public void testThrows_FailableCallable_Object_Throwable() { |
| new Functions.FailableCallable<Object, Throwable>() { |
| |
| @Override |
| public Object call() throws Throwable { |
| throw new IOException("test"); |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as |
| * generic test types. |
| */ |
| @Test |
| public void testThrows_FailableCallable_String_IOException() { |
| new Functions.FailableCallable<String, IOException>() { |
| |
| @Override |
| public String call() throws IOException { |
| throw new IOException("test"); |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception. using the top level generic types |
| * Object and Throwable. |
| */ |
| @Test |
| public void testThrows_FailableConsumer_Object_Throwable() { |
| new Functions.FailableConsumer<Object, Throwable>() { |
| |
| @Override |
| public void accept(final Object object) throws Throwable { |
| throw new IOException("test"); |
| |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as |
| * generic test types. |
| */ |
| @Test |
| public void testThrows_FailableConsumer_String_IOException() { |
| new Functions.FailableConsumer<String, IOException>() { |
| |
| @Override |
| public void accept(final String object) throws IOException { |
| throw new IOException("test"); |
| |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception. using the top level generic types |
| * Object and Throwable. |
| */ |
| @Test |
| public void testThrows_FailableFunction_Object_Throwable() { |
| new Functions.FailableFunction<Object, Object, Throwable>() { |
| |
| @Override |
| public Object apply(final Object input) throws Throwable { |
| throw new IOException("test"); |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as |
| * generic test types. |
| */ |
| @Test |
| public void testThrows_FailableFunction_String_IOException() { |
| new Functions.FailableFunction<String, String, IOException>() { |
| |
| @Override |
| public String apply(final String input) throws IOException { |
| throw new IOException("test"); |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception. using the top level generic types |
| * Object and Throwable. |
| */ |
| @Test |
| public void testThrows_FailablePredicate_Object_Throwable() { |
| new Functions.FailablePredicate<Object, Throwable>() { |
| |
| @Override |
| public boolean test(final Object object) throws Throwable { |
| throw new IOException("test"); |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as |
| * generic test types. |
| */ |
| @Test |
| public void testThrows_FailablePredicate_String_IOException() { |
| new Functions.FailablePredicate<String, IOException>() { |
| |
| @Override |
| public boolean test(final String object) throws IOException { |
| throw new IOException("test"); |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception. using the top level generic types |
| * Object and Throwable. |
| */ |
| @Test |
| public void testThrows_FailableRunnable_Object_Throwable() { |
| new Functions.FailableRunnable<Throwable>() { |
| |
| @Override |
| public void run() throws Throwable { |
| throw new IOException("test"); |
| |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as |
| * generic test types. |
| */ |
| @Test |
| public void testThrows_FailableRunnable_String_IOException() { |
| new Functions.FailableRunnable<IOException>() { |
| |
| @Override |
| public void run() throws IOException { |
| throw new IOException("test"); |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception. using the top level generic types |
| * Object and Throwable. |
| */ |
| @Test |
| public void testThrows_FailableSupplier_Object_Throwable() { |
| new Functions.FailableSupplier<Object, Throwable>() { |
| |
| @Override |
| public Object get() throws Throwable { |
| throw new IOException("test"); |
| } |
| }; |
| } |
| |
| /** |
| * Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as |
| * generic test types. |
| */ |
| @Test |
| public void testThrows_FailableSupplier_String_IOException() { |
| new Functions.FailableSupplier<String, IOException>() { |
| |
| @Override |
| public String get() throws IOException { |
| throw new IOException("test"); |
| } |
| }; |
| } |
| |
| @Test |
| public void testTryWithResources() { |
| final CloseableObject co = new CloseableObject(); |
| final FailableConsumer<Throwable, ? extends Throwable> consumer = co::run; |
| final IllegalStateException ise = new IllegalStateException(); |
| Throwable e = assertThrows(IllegalStateException.class, |
| () -> Functions.tryWithResources(() -> consumer.accept(ise), co::close)); |
| assertSame(ise, e); |
| |
| assertTrue(co.isClosed()); |
| co.reset(); |
| final Error error = new OutOfMemoryError(); |
| e = assertThrows(OutOfMemoryError.class, |
| () -> Functions.tryWithResources(() -> consumer.accept(error), co::close)); |
| assertSame(error, e); |
| |
| assertTrue(co.isClosed()); |
| co.reset(); |
| final IOException ioe = new IOException("Unknown I/O error"); |
| final UncheckedIOException uioe = assertThrows(UncheckedIOException.class, |
| () -> Functions.tryWithResources(() -> consumer.accept(ioe), co::close)); |
| final IOException cause = uioe.getCause(); |
| assertSame(ioe, cause); |
| |
| assertTrue(co.isClosed()); |
| co.reset(); |
| Functions.tryWithResources(() -> consumer.accept(null), co::close); |
| assertTrue(co.isClosed()); |
| } |
| } |