package io.futuristic;
import junit.framework.TestCase;
import org.junit.Test;
import java.io.InvalidClassException;
import java.util.InvalidPropertiesFormatException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public class FutureWithExceptionTest extends TestCase {
@Test
public void testConsumeDoesNotGetCalled() {
AtomicBoolean consumed = new AtomicBoolean(false);
Exception expectedException = new RuntimeException();
FutureWithException futureWithException = new FutureWithException(expectedException);
try {
futureWithException.consume(o -> consumed.set(true)).await();
fail("An exception should have been thrown");
} catch (Exception e) {
assertEquals(expectedException, e);
assertFalse(consumed.get());
}
}
@Test
public void testMapDoesNotGetCalled() {
AtomicBoolean consumed = new AtomicBoolean(false);
Exception expectedException = new RuntimeException();
FutureWithException futureWithException = new FutureWithException(expectedException);
try {
futureWithException.map(o -> {
consumed.set(true);
return o;
}).await();
fail("An exception should have been thrown");
} catch (Exception e) {
assertEquals(expectedException, e);
assertFalse(consumed.get());
}
}
@Test
public void testMapFutureDoesNotGetCalled() {
AtomicBoolean consumed = new AtomicBoolean(false);
Exception expectedException = new RuntimeException();
FutureWithException futureWithException = new FutureWithException(expectedException);
try {
futureWithException.mapFuture(o -> {
consumed.set(true);
return Futures.withValue(o);
}).await();
fail("An exception should have been thrown");
} catch (Exception e) {
assertEquals(expectedException, e);
assertFalse(consumed.get());
}
}
@Test
public void testTrapOnlyCallsOnce() {
AtomicInteger trapCount = new AtomicInteger();
Exception expectedException = new RuntimeException();
FutureWithException futureWithException = new FutureWithException(expectedException);
try {
futureWithException
.trap(RuntimeException.class, e -> {
trapCount.incrementAndGet();
return null;
}).trap(RuntimeException.class, e -> {
trapCount.incrementAndGet();
return null;
}).await();
assertEquals(1, trapCount.get());
} catch (Exception e) {
fail("No exception should have been thrown");
}
}
@Test
public void testTrapCorrectType() {
AtomicInteger trapCount = new AtomicInteger();
Exception expectedException = new RuntimeException();
FutureWithException futureWithException = new FutureWithException(expectedException);
try {
futureWithException
.trap(InvalidClassException.class, e -> {
trapCount.decrementAndGet();
return null;
})
.trap(RuntimeException.class, e -> {
trapCount.incrementAndGet();
return null;
}).await();
assertEquals(1, trapCount.get());
} catch (Exception e) {
fail("No exception should have been thrown");
}
}
@Test
public void testTrapCorrectType_invertedChain() {
AtomicInteger trapCount = new AtomicInteger();
Exception expectedException = new RuntimeException();
FutureWithException futureWithException = new FutureWithException(expectedException);
try {
futureWithException
.trap(RuntimeException.class, e -> {
trapCount.incrementAndGet();
return null;
})
.trap(InvalidClassException.class, e -> {
trapCount.decrementAndGet();
return null;
}).await();
assertEquals(1, trapCount.get());
} catch (Exception e) {
fail("No exception should have been thrown");
}
}
@Test
public void testTrapCorrectType_noTrapping() {
AtomicInteger trapCount = new AtomicInteger();
Exception expectedException = new RuntimeException();
FutureWithException futureWithException = new FutureWithException(expectedException);
try {
futureWithException
.trap(InvalidPropertiesFormatException.class, e -> {
trapCount.incrementAndGet();
return null;
})
.trap(InvalidClassException.class, e -> {
trapCount.incrementAndGet();
return null;
}).await();
fail("An exception should have been thrown");
} catch (Exception e) {
assertEquals(expectedException, e);
assertEquals(0, trapCount.get());
}
}
@Test
public void testTrapCorrectType_supperClass() {
AtomicInteger trapCount = new AtomicInteger();
Exception expectedException = new RuntimeException();
FutureWithException futureWithException = new FutureWithException(expectedException);
try {
futureWithException
.trap(Throwable.class, e -> {
trapCount.incrementAndGet();
return null;
})
.trap(InvalidClassException.class, e -> {
trapCount.decrementAndGet();
return null;
}).await();
assertEquals(1, trapCount.get());
} catch (Exception e) {
fail("No exception should have been thrown");
}
}
@Test
public void test_bigChain() {
AtomicInteger successCount = new AtomicInteger();
AtomicInteger trapCount = new AtomicInteger();
Exception expectedException = new RuntimeException();
FutureWithException futureWithException = new FutureWithException(expectedException);
try {
futureWithException
.consume(v -> successCount.incrementAndGet())
.consume(v -> successCount.incrementAndGet())
.map(v -> successCount.incrementAndGet())
.mapFuture(v -> Futures.withValue(successCount.incrementAndGet()))
.trap(RuntimeException.class, e -> {
trapCount.incrementAndGet();
return null;
})
.trap(InvalidClassException.class, e -> {
trapCount.decrementAndGet();
return null;
})
.consume(v -> successCount.incrementAndGet())
.map(v -> successCount.incrementAndGet())
.await();
assertEquals(2, successCount.get());
assertEquals(1, trapCount.get());
} catch (Exception e) {
fail("No exception should have been thrown");
}
}
}