package io.trane.future;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
import java.time.Duration;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.Test;
public class ValueFutureTest {
private <T> T get(Future<T> future) throws CheckedFutureException {
return future.get(Duration.ZERO);
}
/*** map ***/
@Test
public void map() throws CheckedFutureException {
Future<Integer> future = Future.value(1).map(i -> i + 1);
assertEquals(new Integer(2), get(future));
}
@Test(expected = ArithmeticException.class)
public void mapException() throws CheckedFutureException {
Future<Integer> future = Future.value(1).map(i -> i / 0);
get(future);
}
/*** flatMap ***/
@Test
public void flatMap() throws CheckedFutureException {
Future<Integer> future = Future.value(1).flatMap(i -> Future.value(i + 1));
assertEquals(new Integer(2), get(future));
}
@Test(expected = ArithmeticException.class)
public void flatMapException() throws CheckedFutureException {
Future<Integer> future = Future.value(1).flatMap(i -> Future.value(i / 0));
get(future);
}
/*** transform ***/
@Test
public void transform() throws CheckedFutureException {
Transformer<Integer, Integer> t = new Transformer<Integer, Integer>() {
@Override
public Integer onException(Throwable ex) {
return null;
}
@Override
public Integer onValue(Integer value) {
assertEquals(new Integer(1), value);
return value + 1;
}
};
assertEquals(new Integer(2), get(Future.value(1).transform(t)));
}
@Test(expected = TestException.class)
public void transformException() throws CheckedFutureException {
Transformer<Integer, Integer> t = new Transformer<Integer, Integer>() {
@Override
public Integer onException(Throwable ex) {
return null;
}
@Override
public Integer onValue(Integer value) {
assertEquals(new Integer(1), value);
throw new TestException();
}
};
get(Future.value(1).transform(t));
}
/*** transformWith ***/
@Test
public void transformWith() throws CheckedFutureException {
Transformer<Integer, Future<Integer>> t = new Transformer<Integer, Future<Integer>>() {
@Override
public Future<Integer> onException(Throwable ex) {
return null;
}
@Override
public Future<Integer> onValue(Integer value) {
assertEquals(new Integer(1), value);
return Future.value(value + 1);
}
};
assertEquals(new Integer(2), get(Future.value(1).transformWith(t)));
}
@Test(expected = TestException.class)
public void transformWithException() throws CheckedFutureException {
Transformer<Integer, Future<Integer>> t = new Transformer<Integer, Future<Integer>>() {
@Override
public Future<Integer> onException(Throwable ex) {
return null;
}
@Override
public Future<Integer> onValue(Integer value) {
assertEquals(new Integer(1), value);
throw new TestException();
}
};
get(Future.value(1).transformWith(t));
}
/*** biMap ***/
@Test
public void biMap() throws CheckedFutureException {
Future<Integer> f = Future.value(1).biMap(Future.value(2), (a, b) -> a + b);
assertEquals(new Integer(3), get(f));
}
@Test(expected = ArithmeticException.class)
public void biMapException() throws CheckedFutureException {
Future<Integer> f = Future.value(1).biMap(Future.value(2), (a, b) -> 1 / 0);
get(f);
}
/*** biFlatMap ***/
@Test
public void biFlatMap() throws CheckedFutureException {
Future<Integer> f = Future.value(1).biFlatMap(Future.value(2), (a, b) -> Future.value(a + b));
assertEquals(new Integer(3), get(f));
}
@Test(expected = ArithmeticException.class)
public void biFlatMapException() throws CheckedFutureException {
Future<Integer> f = Future.value(1).biFlatMap(Future.value(2), (a, b) -> Future.apply(() -> 1 / 0));
get(f);
}
/*** onSuccess ***/
@Test
public void onSuccess() throws CheckedFutureException {
AtomicInteger result = new AtomicInteger(0);
Future<Integer> future = Future.value(1).onSuccess(i -> result.set(i));
assertEquals(1, result.get());
assertEquals(new Integer(1), get(future));
}
@Test
public void onSuccessException() throws CheckedFutureException {
Future<Integer> future = Future.value(1).onSuccess(i -> {
throw new RuntimeException();
});
assertEquals(new Integer(1), get(future));
}
/*** onFailure ***/
@Test
public void onFailure() throws CheckedFutureException {
AtomicReference<Throwable> exception = new AtomicReference<>();
Future<Integer> future = Future.value(1).onFailure(exception::set);
assertEquals(null, exception.get());
assertEquals(new Integer(1), get(future));
}
@Test
public void onFailureException() throws CheckedFutureException {
Future<Integer> future = Future.value(1).onFailure(ex -> {
throw new RuntimeException();
});
assertEquals(new Integer(1), get(future));
}
/*** respond ***/
@Test
public void respond() throws CheckedFutureException {
AtomicInteger result = new AtomicInteger(-1);
AtomicBoolean failure = new AtomicBoolean(false);
final Responder<Integer> r = new Responder<Integer>() {
@Override
public void onException(Throwable ex) {
failure.set(true);
}
@Override
public void onValue(Integer value) {
result.set(value);
}
};
Future<Integer> f = Future.value(1).respond(r);
assertEquals(new Integer(1), get(f));
assertEquals(1, result.get());
assertFalse(failure.get());
}
@Test
public void respondException() throws CheckedFutureException {
AtomicInteger result = new AtomicInteger(-1);
AtomicBoolean failure = new AtomicBoolean(false);
final Responder<Integer> r = new Responder<Integer>() {
@Override
public void onException(Throwable ex) {
failure.set(true);
throw new NullPointerException();
}
@Override
public void onValue(Integer value) {
result.set(value);
throw new NullPointerException();
}
};
Future.value(1).respond(r);
assertEquals(1, result.get());
assertFalse(failure.get());
}
/*** rescue ***/
@Test
public void rescue() {
Future<Integer> future = Future.value(1);
assertEquals(future, future.rescue(t -> Future.value(2)));
}
/*** voided ***/
@Test
public void voided() throws CheckedFutureException {
Future<Void> future = Future.value(1).voided();
assertNull(get(future));
}
/*** get ***/
@Test
public void get() throws CheckedFutureException {
Future<Integer> future = Future.value(1);
assertEquals(new Integer(1), future.get(Duration.ofMillis(1)));
}
@Test
public void getZeroTimeout() throws CheckedFutureException {
Future<Integer> future = Future.value(1);
assertEquals(new Integer(1), future.get(Duration.ZERO));
}
@Test
public void getNegativeTimeout() throws CheckedFutureException {
Future<Integer> future = Future.value(1);
assertEquals(new Integer(1), future.get(Duration.ofMillis(-1)));
}
/*** toString ***/
@Test
public void toStringInt() {
String s = Future.value(1).toString();
assertEquals("ValueFuture(1)", s);
}
@Test
public void toStringNull() {
String s = Future.value(null).toString();
assertEquals("ValueFuture(null)", s);
}
/*** hashCode ***/
@Test
public void testHashCode() {
assertEquals(Future.value(1).hashCode(), Future.value(1).hashCode());
}
@Test
public void testHashCodeNotEquals() {
assertNotEquals(Future.value(1).hashCode(), Future.value(2).hashCode());
}
@Test
public void testHashCodeNull() {
assertEquals(Future.value(null).hashCode(), Future.value(null).hashCode());
}
@Test
public void testHashCodeNullNotEquals() {
assertNotEquals(Future.value(null).hashCode(), Future.value(1).hashCode());
}
/*** equals ***/
@Test
public void testEquals() {
assertEquals(Future.value(1), Future.value(1));
}
@Test
public void testEqualsNotEquals() {
assertNotEquals(Future.value(1), Future.value(2));
}
@Test
public void testEqualsNotEqualsNull() {
assertNotEquals(Future.value(1), null);
}
@Test
public void testEqualsNotEqualsOtherClass() {
assertNotEquals(Future.value(1), "s");
}
@Test
public void testEqualsNull() {
assertEquals(Future.value(null), Future.value(null));
}
@Test
public void testEqualsNullNotEquals() {
assertNotEquals(Future.value(null), Future.value(1));
}
}