package akka.dispatch; import org.junit.Test; import static org.junit.Assert.*; import java.util.concurrent.Callable; import java.util.LinkedList; import java.lang.Iterable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import akka.japi.Function; import akka.japi.Function2; import akka.japi.Procedure; import scala.Some; import scala.Right; import static akka.dispatch.Futures.*; public class JavaFutureTests { @Test public void mustBeAbleToMapAFuture() { Future f1 = future(new Callable() { public String call() { return "Hello"; } }); Future f2 = f1.map(new Function() { public String apply(String s) { return s + " World"; } }); assertEquals("Hello World", f2.get()); } @Test public void mustBeAbleToExecuteAnOnResultCallback() throws Throwable { final CountDownLatch latch = new CountDownLatch(1); Promise cf = new akka.dispatch.DefaultPromise(1000, TimeUnit.MILLISECONDS, Dispatchers.defaultGlobalDispatcher()); Future f = cf; f.onResult(new Procedure() { public void apply(String result) { if(result.equals("foo")) latch.countDown(); } }); cf.completeWithResult("foo"); assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); assertEquals(f.get(), "foo"); } @Test public void mustBeAbleToExecuteAnOnExceptionCallback() throws Throwable { final CountDownLatch latch = new CountDownLatch(1); Promise cf = new akka.dispatch.DefaultPromise(1000, TimeUnit.MILLISECONDS, Dispatchers.defaultGlobalDispatcher()); Future f = cf; f.onException(new Procedure() { public void apply(Throwable t) { if(t instanceof NullPointerException) latch.countDown(); } }); Throwable exception = new NullPointerException(); cf.completeWithException(exception); assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); assertEquals(f.exception().get(), exception); } @Test public void mustBeAbleToExecuteAnOnTimeoutCallback() throws Throwable { final CountDownLatch latch = new CountDownLatch(1); Promise cf = new akka.dispatch.DefaultPromise(1000, TimeUnit.MILLISECONDS, Dispatchers.defaultGlobalDispatcher()); Future f = cf; f.onTimeout(new Procedure>() { public void apply(Future future) { latch.countDown(); } }); assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); assertTrue(f.value().isEmpty()); } @Test public void mustBeAbleToExecuteAnOnCompleteCallback() throws Throwable { final CountDownLatch latch = new CountDownLatch(1); Promise cf = new akka.dispatch.DefaultPromise(1000, TimeUnit.MILLISECONDS, Dispatchers.defaultGlobalDispatcher()); Future f = cf; f.onComplete(new Procedure>() { public void apply(akka.dispatch.Future future) { latch.countDown(); } }); cf.completeWithResult("foo"); assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); assertEquals(f.get(), "foo"); } @Test public void mustBeAbleToForeachAFuture() throws Throwable { final CountDownLatch latch = new CountDownLatch(1); Promise cf = new akka.dispatch.DefaultPromise(1000, TimeUnit.MILLISECONDS, Dispatchers.defaultGlobalDispatcher()); Future f = cf; f.foreach(new Procedure() { public void apply(String future) { latch.countDown(); } }); cf.completeWithResult("foo"); assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); assertEquals(f.get(), "foo"); } @Test public void mustBeAbleToFlatMapAFuture() throws Throwable { final CountDownLatch latch = new CountDownLatch(1); Promise cf = new akka.dispatch.DefaultPromise(1000, TimeUnit.MILLISECONDS, Dispatchers.defaultGlobalDispatcher()); cf.completeWithResult("1000"); Future f = cf; Future r = f.flatMap(new Function>() { public Future apply(String r) { latch.countDown(); Promise cf = new akka.dispatch.DefaultPromise(1000, TimeUnit.MILLISECONDS, Dispatchers.defaultGlobalDispatcher()); cf.completeWithResult(Integer.parseInt(r)); return cf; } }); assertEquals(f.get(), "1000"); assertEquals(r.get().intValue(), 1000); assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); } @Test public void mustBeAbleToFilterAFuture() throws Throwable { final CountDownLatch latch = new CountDownLatch(1); Promise cf = new akka.dispatch.DefaultPromise(1000, TimeUnit.MILLISECONDS, Dispatchers.defaultGlobalDispatcher()); Future f = cf; Future r = f.filter(new Function() { public Boolean apply(String r) { latch.countDown(); return r.equals("foo"); } }); cf.completeWithResult("foo"); assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); assertEquals(f.get(), "foo"); assertEquals(r.get(), "foo"); } // TODO: Improve this test, perhaps with an Actor @Test public void mustSequenceAFutureList() { LinkedList> listFutures = new LinkedList>(); LinkedList listExpected = new LinkedList(); for (int i = 0; i < 10; i++) { listExpected.add("test"); listFutures.add(future(new Callable() { public String call() { return "test"; } })); } Future> futureList = sequence(listFutures); assertEquals(futureList.get(), listExpected); } // TODO: Improve this test, perhaps with an Actor @Test public void foldForJavaApiMustWork() { LinkedList> listFutures = new LinkedList>(); StringBuilder expected = new StringBuilder(); for (int i = 0; i < 10; i++) { expected.append("test"); listFutures.add(future(new Callable() { public String call() { return "test"; } })); } Future result = fold("", 15000,listFutures, new Function2(){ public String apply(String r, String t) { return r + t; } }); assertEquals(result.get(), expected.toString()); } @Test public void reduceForJavaApiMustWork() { LinkedList> listFutures = new LinkedList>(); StringBuilder expected = new StringBuilder(); for (int i = 0; i < 10; i++) { expected.append("test"); listFutures.add(future(new Callable() { public String call() { return "test"; } })); } Future result = reduce(listFutures, 15000, new Function2(){ public String apply(String r, String t) { return r + t; } }); assertEquals(result.get(), expected.toString()); } @Test public void traverseForJavaApiMustWork() { LinkedList listStrings = new LinkedList(); LinkedList expectedStrings = new LinkedList(); for (int i = 0; i < 10; i++) { expectedStrings.add("TEST"); listStrings.add("test"); } Future> result = traverse(listStrings, new Function>(){ public Future apply(final String r) { return future(new Callable() { public String call() { return r.toUpperCase(); } }); } }); assertEquals(result.get(), expectedStrings); } }