package io.futuristic;
import io.futuristic.util.DummyExceptions;
import io.futuristic.util.Triggerer;
import org.junit.Test;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import static org.junit.Assert.*;
/**
* @autor: julio
*/
public class FutureWithTriggerTest {
@Test
public void testGetSync() throws Exception {
FutureWithTrigger futureWithTrigger = new FutureWithTrigger();
Object test = new Object();
Triggerer.triggerValue(test, futureWithTrigger);
Object result = futureWithTrigger.getFuture().await();
assertEquals(test, result);
}
@Test
public void testGetAsync() throws Exception {
FutureWithTrigger futureWithTrigger = new FutureWithTrigger();
Object test = new Object();
Triggerer.triggerValueAsync(10, test, futureWithTrigger);
Object result = futureWithTrigger.getFuture().await();
assertEquals(test, result);
}
@Test
public void testConsumeSync(){
FutureWithTrigger<AtomicBoolean> futureWithTrigger = new FutureWithTrigger<>();
futureWithTrigger.getFuture().consume(b->b.set(true));
AtomicBoolean test = new AtomicBoolean(false);
Triggerer.triggerValue(test, futureWithTrigger);
assertTrue(test.get());
}
@Test
public void testConsumeAsync() throws Exception {
FutureWithTrigger<AtomicBoolean> futureWithTrigger = new FutureWithTrigger<>();
futureWithTrigger.getFuture().consume(b->b.set(true));
AtomicBoolean test = new AtomicBoolean(false);
Triggerer.triggerValueAsync(10, test, futureWithTrigger);
AtomicBoolean result = futureWithTrigger.getFuture().consume(b->b.set(true)).await();
assertEquals(test, result);
assertTrue(test.get());
}
@Test
public void testMapSync() throws Exception {
FutureWithTrigger<Integer> futureWithTrigger = new FutureWithTrigger<>();
int test = 1;
Triggerer.triggerValue(test, futureWithTrigger);
int result = futureWithTrigger.getFuture().map(i->i+1).await();
assertEquals(test + 1, result);
}
@Test
public void testMapAsync() throws Exception {
FutureWithTrigger<Integer> futureWithTrigger = new FutureWithTrigger<>();
int test = 1;
Triggerer.triggerValueAsync(10, test, futureWithTrigger);
int result = futureWithTrigger.getFuture().map(i->i+1).await();
assertEquals(test + 1, result);
}
@Test
public void testMapFutureSync() throws Exception {
FutureWithTrigger<Integer> futureWithTrigger = new FutureWithTrigger<>();
int test = 1;
Triggerer.triggerValue(test, futureWithTrigger);
int result = futureWithTrigger.getFuture().mapFuture(i -> {
FutureWithTrigger<Integer> next = new FutureWithTrigger<>();
Triggerer.triggerValue(test + 1, next);
return next.getFuture();
}).await();
assertEquals(test + 1, result);
}
@Test
public void testMapFutureAsync() throws Exception {
FutureWithTrigger<Integer> futureWithTrigger = new FutureWithTrigger<>();
int test = 1;
Triggerer.triggerValueAsync(10, test, futureWithTrigger);
int result = futureWithTrigger.getFuture().mapFuture(i -> {
FutureWithTrigger<Integer> next = new FutureWithTrigger<>();
Triggerer.triggerValueAsync(10, test + 1, next);
return next.getFuture();
}).await();
assertEquals(test + 1, result);
}
@Test
public void testChaining() throws Exception {
FutureWithTrigger<Integer> futureWithTrigger = new FutureWithTrigger<>();
int initialValue = 1;
Triggerer.triggerValueAsync(10, initialValue, futureWithTrigger);
String result = futureWithTrigger.getFuture().mapFuture(i -> {
//This will increase by one the test variable, after 10 milliseconds
//Result should be 2
FutureWithTrigger<Integer> next = new FutureWithTrigger<>();
Triggerer.triggerValueAsync(10, initialValue + 1, next);
return next.getFuture();
}).map(
//This will create a StringBuilder with the integer returned from the previous step
//Result should be "2"
i -> new StringBuilder(Integer.toString(i))
).consume(
//This appends a "c" to the builder
//Result should be "2c"
s -> s.append("c")
).await().toString();
//Proof that all was executed in sequence
assertEquals("2c", result);
}
@Test
public void testErrorCatching() {
FutureWithTrigger<Object> futureWithTrigger = new FutureWithTrigger<>();
RuntimeException exception = new RuntimeException();
AtomicReference<RuntimeException> exceptionReference = new AtomicReference<>();
Triggerer.triggerValue(new Object(), futureWithTrigger);
try {
futureWithTrigger.getFuture().consume(v -> {
throw exception;
}).trap(RuntimeException.class, e -> {
exceptionReference.set(e);
throw e;
}).await();
fail("Exception should have been thrown");
} catch (Exception catchedException) {
assertEquals(exception, exceptionReference.get());
assertEquals(exception, catchedException);
}
}
@Test
public void testErrorCatchingFuture() {
FutureWithTrigger<Object> futureWithTrigger = new FutureWithTrigger<>();
RuntimeException exception = new RuntimeException();
AtomicReference<RuntimeException> exceptionReference = new AtomicReference<>();
Triggerer.triggerValue(new Object(), futureWithTrigger);
try {
futureWithTrigger.getFuture().consume(v -> {
throw exception;
}).trapFuture(RuntimeException.class, e -> {
exceptionReference.set(e);
throw e;
}).await();
fail("Exception should have been thrown");
} catch (Exception catchedException) {
assertEquals(exception, exceptionReference.get());
assertEquals(exception, catchedException);
}
}
@Test
public void testErrorCatchingRightType() {
FutureWithTrigger<Object> futureWithTrigger = new FutureWithTrigger<>();
DummyExceptions.DummyException1 exception = new DummyExceptions.DummyException1();
AtomicReference<DummyExceptions.DummyException1> exceptionReference1 = new AtomicReference<>();
AtomicReference<DummyExceptions.DummyException2> exceptionReference2 = new AtomicReference<>();
Object test = new Object();
Triggerer.triggerValue(test, futureWithTrigger);
try {
futureWithTrigger.getFuture().consume(v -> {
throw exception;
}).trap(DummyExceptions.DummyException2.class, e -> {
exceptionReference2.set(e); //This should never be called
throw e;
}).trap(DummyExceptions.DummyException1.class, e -> {
exceptionReference1.set(e); //This should be called because of the type
throw e;
}).await();
fail("Exception should have been thrown");
} catch (Exception catchedException) {
assertEquals(exception, exceptionReference1.get());
assertNull(exceptionReference2.get());
assertEquals(exception, catchedException);
}
}
@Test
public void testErrorThrowingSync() {
FutureWithTrigger<Object> futureWithTrigger = new FutureWithTrigger<>();
RuntimeException exception = new RuntimeException();
AtomicReference<RuntimeException> exceptionReference = new AtomicReference<>();
Triggerer.triggerError(exception, futureWithTrigger);
try {
futureWithTrigger.getFuture().trap(RuntimeException.class, e -> {
exceptionReference.set(e);
throw e;
}).await();
fail("Exception should have been thrown");
} catch (Exception catchedException) {
assertEquals(exception, exceptionReference.get());
assertEquals(exception, catchedException);
}
}
@Test
public void testErrorThrowingAsync() {
FutureWithTrigger<Object> futureWithTrigger = new FutureWithTrigger<>();
RuntimeException exception = new RuntimeException();
AtomicReference<RuntimeException> exceptionReference = new AtomicReference<>();
Triggerer.triggerErrorAsync(10, exception, futureWithTrigger);
try {
futureWithTrigger.getFuture().trap(RuntimeException.class, e -> {
exceptionReference.set(e);
throw e;
}).await();
fail("Exception should have been thrown");
} catch (Exception catchedException) {
assertEquals(exception, exceptionReference.get());
assertEquals(exception, catchedException);
}
}
@Test
public void testErrorRecovering() {
FutureWithTrigger<Integer> futureWithTrigger = new FutureWithTrigger<>();
RuntimeException exception = new RuntimeException();
AtomicReference<RuntimeException> exceptionReference = new AtomicReference<>();
Triggerer.triggerErrorAsync(10, exception, futureWithTrigger);
try {
int value = futureWithTrigger.getFuture().trap(RuntimeException.class, e -> {
exceptionReference.set(e);
return 1;
}).await();
assertEquals(1, value);
assertEquals(exception, exceptionReference.get());
} catch (Exception catchedException) {
fail("No error should have been thrown");
}
}
@Test
public void testErrorRecoveringFuture() {
FutureWithTrigger<Integer> futureWithTrigger = new FutureWithTrigger<>();
RuntimeException exception = new RuntimeException();
AtomicReference<RuntimeException> exceptionReference = new AtomicReference<>();
Triggerer.triggerErrorAsync(10, exception, futureWithTrigger);
try {
int value = futureWithTrigger.getFuture().trapFuture(RuntimeException.class, e -> {
exceptionReference.set(e);
return Futures.withValue(1);
}).await();
assertEquals(1, value);
assertEquals(exception, exceptionReference.get());
} catch (Exception catchedException) {
fail("No error should have been thrown");
}
}
}