Added: aries/trunk/async/promise-api/src/test/java/org/apache/aries/async/promise/test/FunctionTest.java URL: http://svn.apache.org/viewvc/aries/trunk/async/promise-api/src/test/java/org/apache/aries/async/promise/test/FunctionTest.java?rev=1678227&view=auto ============================================================================== --- aries/trunk/async/promise-api/src/test/java/org/apache/aries/async/promise/test/FunctionTest.java (added) +++ aries/trunk/async/promise-api/src/test/java/org/apache/aries/async/promise/test/FunctionTest.java Thu May 7 15:00:53 2015 @@ -0,0 +1,339 @@ +package org.apache.aries.async.promise.test; + +import org.junit.Test; +import org.osgi.util.function.Function; +import org.osgi.util.function.Predicate; +import org.osgi.util.promise.Deferred; +import org.osgi.util.promise.Promise; +import org.osgi.util.promise.Promises; + +import java.util.NoSuchElementException; +import java.util.concurrent.CountDownLatch; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class FunctionTest { + + @Test + public void testFilter() throws Exception { + testFilter("hello"); + testFilter("!reject"); + testFilter("fail"); + testFilter(null); + testFilter("already"); + testFilter("already!"); + } + + @Test + public void testMap() throws Exception { + testMap("hello"); + testMap("hello!"); + testMap("fail"); + testMap("fail!"); + } + + @Test + public void testFlatMap() throws Exception { + testFlatMap("hello"); + testFlatMap("hello!"); + testFlatMap("fail"); + } + + @Test + public void testRecover() throws Exception { + testRecover("hello"); + testRecover("fail"); + testRecover("null"); + testRecover(null); + } + + @Test + public void testRecoverWith() throws Exception { + testRecoverWith("hello"); + testRecoverWith("fail"); + testRecoverWith("null"); + testRecoverWith(null); + } + + @Test + public void testFallback() throws Exception { + testFallback("hello", "world"); + testFallback("fail", "world"); + testFallback("hello", "fail"); + testFallback("fail", "fail"); + } + + @Test + public void testFilter2() throws Exception { + String bigValue = new String("value"); + Promise<String> p1 = Promises.resolved(bigValue); + + Promise<String> p2 = p1.filter(new Predicate<String>() { + public boolean test(String t) { + return t.length() > 0; + } + }); + assertTrue("Filter2 resolved", p2.isDone()); + assertEquals("Value2 matches", bigValue, p2.getValue()); + + Promise<String> p3 = p1.filter(new Predicate<String>() { + public boolean test(String t) { + return t.length() == 0; + } + }); + assertTrue("Filter3 resolved", p3.isDone()); + assertTrue("Value3 fail matches", p3.getFailure() instanceof NoSuchElementException); + } + + public static class Nasty extends RuntimeException { + public Nasty(String msg) { + super(msg); + } + } + + private void testFilter(String r) throws Exception { + Deferred<String> def = new Deferred<String>(); + + Throwable fail = new Throwable("fail"); + boolean already = (r != null && r.startsWith("already")); + + if (already) { + if (r.contains("!")) { + def.fail(fail); + } else { + def.resolve(r); + } + } + + Promise<String> filter = def.getPromise().filter(new Predicate<String>() { + @Override + public boolean test(String s) { + if (s == null) { + throw new Nasty(null); + } + return !s.startsWith("!"); + } + }); + + if (!already) { + if ("fail".equals(r)) { + def.fail(fail); + } else { + def.resolve(r); + } + } + assertTrue("Filter resolved", filter.isDone()); + + @SuppressWarnings({"not thrown", "all"}) + Throwable failure = filter.getFailure(); + + if ("fail".equals(r)) { + assertEquals("Failure matches", fail, filter.getFailure()); + } else if (already && r.contains("!")) { + assertEquals("Failure matches", fail, filter.getFailure()); + } else if (r == null) { + assertTrue("Failure instance Nasty", failure instanceof Nasty); + } else if (r.startsWith("!")) { + assertTrue("Failure instanceof NoSuchElementException", failure instanceof NoSuchElementException); + } else { + assertEquals("Value matches", r, filter.getValue()); + } + } + + private void testMap(String r) throws Exception { + Deferred<String> def = new Deferred<String>(); + + Promise<String> result = def.getPromise().map(new Function<String, String>() { + @Override + public String apply(String s) { + if (s.contains("!")) + throw new Nasty(s); + return s + s.length(); + } + }); + + Throwable fail = new Throwable("fail"); + + if (r.startsWith("fail")) { + def.fail(fail); + } else { + def.resolve(r); + } + assertTrue("Map resolved", result.isDone()); + + @SuppressWarnings({"not thrown", "all"}) + Throwable failure = result.getFailure(); + if (r.startsWith("fail")) { + assertEquals("Failure matches", fail, failure); + } else if (r.contains("!")) { + assertTrue("Failure instance Nasty", failure instanceof Nasty); + } else { + assertEquals("Value matches", r + r.length(), result.getValue()); + } + } + + private void testFlatMap(String r) throws Exception { + Deferred<String> def = new Deferred<String>(); + + Promise<String> flatMap = def.getPromise().flatMap(new Function<String, Promise<? extends String>>() { + @Override + public Promise<String> apply(String s) { + if (s.contains("!")) + throw new Nasty(s); + return Promises.resolved(s + s.length()); + } + }); + + Throwable fail = new Throwable("fail"); + + if ("fail".equals(r)) { + def.fail(fail); + } else { + def.resolve(r); + } + assertTrue("FlatMap resolved", flatMap.isDone()); + + @SuppressWarnings({"not thrown", "all"}) + Throwable failure = flatMap.getFailure(); + + if ("fail".equals(r)) { + assertEquals("Failure matches", fail, failure); + } else if (r.contains("!")) { + assertTrue("Failure instance Nasty", failure instanceof Nasty); + } else { + // "the returned Promise will be resolved with the Promise from the specified Function, + // as applied to the value of this Promise" + assertEquals("Value matches", r + r.length(), flatMap.getValue()); + } + } + + private void testRecover(String r) throws Exception { + Deferred<String> def = new Deferred<String>(); + + Promise<String> recover = def.getPromise().recover(new Function<Promise<?>, String>() { + @Override + public String apply(Promise<?> promise) { + try { + @SuppressWarnings({"not thrown", "all"}) + String msg = promise.getFailure().getMessage(); + if (msg == null) { + throw new Nasty(null); + } + if (msg.equals("null")) { + return null; + } + return "recover:" + msg; + } catch (InterruptedException e) { + return null; + } + } + }); + + Throwable fail = new Throwable(r); + + if (null == r || "fail".equals(r) || "null".equals(r)) { + def.fail(fail); + } else { + def.resolve(r); + } + assertTrue("Recover resolved", recover.isDone()); + + if ("fail".equals(r)) { + // "recover Promise will be resolved with the recovery value" + assertEquals("Recovery value matches", "recover:" + r, recover.getValue()); + } else if ("null".equals(r)) { + // "recover Promise will be failed with the failure of this Promise" + assertEquals("Recovery failed matches", fail, recover.getFailure()); + } else if (r == null) { + @SuppressWarnings({"not thrown", "all"}) + Throwable failure = recover.getFailure(); + assertTrue("Failure instance Nasty", failure instanceof Nasty); + } else { + // "the returned Promise will be resolved with the value of this Promise" + assertEquals("Value matches", def.getPromise().getValue(), recover.getValue()); + } + } + + private void testRecoverWith(String r) throws Exception { + Deferred<String> def = new Deferred<String>(); + + Promise<? extends String> recover = def.getPromise().recoverWith( + new Function<Promise<?>, Promise<? extends String>>() { + @Override + public Promise<String> apply(Promise<?> promise) { + try { + @SuppressWarnings({"not thrown", "all"}) + String msg = promise.getFailure().getMessage(); + if (msg == null) { + throw new Nasty(null); + } + if (msg.equals("null")) { + return null; + } + return Promises.resolved("recover:" + msg); + + } catch (InterruptedException e) { + return null; + } + } + }); + + Throwable fail = new Throwable(r); + + if (null == r || "fail".equals(r) || "null".equals(r)) { + def.fail(fail); + } else { + def.resolve(r); + } + assertTrue("RecoverWith resolved", recover.isDone()); + + if ("fail".equals(r)) { + // "recover Promise will be resolved with the recovery value" + assertEquals("Recovery value matches", "recover:" + r, recover.getValue()); + } else if ("null".equals(r)) { + // "recover Promise will be failed with the failure of this Promise" + assertEquals("Recovery failed matches", fail, recover.getFailure()); + } else if (r == null) { + @SuppressWarnings({"not thrown", "all"}) + Throwable failure = recover.getFailure(); + assertTrue("Failure instance Nasty", failure instanceof Nasty); + } else { + // "the returned Promise will be resolved with the value of this Promise" + assertEquals("Value matches", def.getPromise().getValue(), recover.getValue()); + } + + } + + void testFallback(String r, String f) throws Exception { + Deferred<String> def = new Deferred<String>(); + Promise<String> promise = def.getPromise(); + Deferred<String> fallback = new Deferred<String>(); + Promise<String> result = promise.fallbackTo(fallback.getPromise()); + + Throwable fail = new Throwable(r); + Throwable fail2 = new Throwable(f + f); + + if ("fail".equals(r)) { + if ("fail".equals(f)) { + fallback.fail(fail2); + } else { + fallback.resolve(f); + } + def.fail(fail); + } else { + def.resolve(r); + } + assertTrue("result resolved", result.isDone()); + + if ("fail".equals(r)) { + if ("fail".equals(f)) { + assertEquals("Failure matches", fail, result.getFailure()); + } else { + assertEquals("Fallback matches", f, result.getValue()); + } + } else { + assertEquals("Value matches", r, result.getValue()); + } + } +}
Added: aries/trunk/async/promise-api/src/test/java/org/apache/aries/async/promise/test/PromisesTest.java URL: http://svn.apache.org/viewvc/aries/trunk/async/promise-api/src/test/java/org/apache/aries/async/promise/test/PromisesTest.java?rev=1678227&view=auto ============================================================================== --- aries/trunk/async/promise-api/src/test/java/org/apache/aries/async/promise/test/PromisesTest.java (added) +++ aries/trunk/async/promise-api/src/test/java/org/apache/aries/async/promise/test/PromisesTest.java Thu May 7 15:00:53 2015 @@ -0,0 +1,179 @@ +package org.apache.aries.async.promise.test; + +import org.osgi.util.promise.Deferred; +import org.osgi.util.promise.FailedPromisesException; +import org.osgi.util.promise.Promise; +import org.osgi.util.promise.Promises; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import static org.junit.Assert.*; + +public class PromisesTest { + + @Test + public void testResolved() throws Exception { + final Promise<String> promise = Promises.resolved("Resolved"); + assertTrue("Promise resolved", promise.isDone()); + assertEquals("Value matches", "Resolved", promise.getValue()); + } + + @Test + public void testFailed() throws Exception { + Exception failed = new Exception("Failed"); + final Promise<String> promise = Promises.failed(failed); + assertTrue("Promise resolved", promise.isDone()); + assertEquals("Value matches", failed, promise.getFailure()); + } + + @Test + public void testLatch() throws Exception { + testLatch(false, "hello", "world"); + testLatch(true, "hello", "world"); + testLatch(false, "goodbye", "!cruel", "world"); + testLatch(true, "goodbye", "!cruel", "world"); + testLatch(false, "goodbye", "!cruel", "!world"); + testLatch(false); + testLatch(1, 2); + testLatch(1, -2, 3); + testLatch(1, -2, 3, -4); + testLatch(new Integer[0]); + } + + // T = String + private void testLatch(boolean preResolve, String... rv) throws Exception { + @SuppressWarnings("unchecked") + Deferred<String>[] dv = new Deferred[rv.length]; + @SuppressWarnings("unchecked") + Promise<String>[] pv = new Promise[rv.length]; + + for (int i = 0; i < rv.length; i++) { + dv[i] = new Deferred<String>(); + pv[i] = dv[i].getPromise(); + } + + Promise<List<String>> latch = null; + if (!preResolve) { + @SuppressWarnings("unchecked") + Promise<List<String>> latch2 = Promises.all(pv); + latch = latch2; + + if (rv.length == 0) { + assertTrue("latch resolved", latch.isDone()); + return; + } + assertFalse("latch not resolved", latch.isDone()); + } + + int nFail = 0; + for (int i = 0; i < rv.length; i++) { + String res = rv[i]; + if (res.startsWith("!")) { + dv[i].fail(new Exception(res)); + nFail++; + } else { + dv[i].resolve(res); + } + } + + if (preResolve) { + @SuppressWarnings("unchecked") + Promise<List<String>> latch2 = Promises.all(pv); + latch = latch2; + } + + assertTrue("latch resolved", latch.isDone()); + + if (nFail > 0) { + @SuppressWarnings({"not thrown", "all"}) + Throwable failure = latch.getFailure(); + assertTrue("failure instanceof FailedPromisesException", failure instanceof FailedPromisesException); + Collection<Promise<?>> failedPromises = ((FailedPromisesException) failure).getFailedPromises(); + assertEquals("failedPromises size matches", nFail, failedPromises.size()); + + for (int i = 0; i < rv.length; i++) { + Promise<String> promise = pv[i]; + if (rv[i].startsWith("!")) { + assertTrue("failedPromises contains", failedPromises.contains(promise)); + } else { + assertFalse("failedPromises doesn't contain", failedPromises.contains(promise)); + } + } + } else { + List<String> list = latch.getValue(); + assertEquals("list size matches", rv.length, list.size()); + for (int i = 0; i < rv.length; i++) { + assertEquals("list[i] matches", rv[i], list.get(i)); + } + + // check list is modifiable + list.add(0, "new item"); + assertEquals("list modifiable", "new item", list.get(0)); + } + } + + // T = Number + // S = Integer + private void testLatch(Integer... rv) throws Exception { + @SuppressWarnings("unchecked") + Deferred<Integer>[] dv = new Deferred[rv.length]; + + List<Promise<Integer>> promises = new ArrayList<Promise<Integer>>(); + + for (int i = 0; i < rv.length; i++) { + dv[i] = new Deferred<Integer>(); + promises.add(dv[i].getPromise()); + } + + Promise<List<Number>> latch = Promises.all(promises); + if (rv.length == 0) { + assertTrue("latch resolved", latch.isDone()); + return; + } + assertFalse("latch not resolved", latch.isDone()); + + int nFail = 0; + for (int i = 0; i < rv.length; i++) { + Integer res = rv[i]; + if (res < 0) { + dv[i].fail(new Exception("fail" + res)); + nFail++; + } else { + dv[i].resolve(res); + } + } + assertTrue("latch resolved", latch.isDone()); + + if (nFail > 0) { + @SuppressWarnings({"not thrown", "all"}) + Throwable failure = latch.getFailure(); + assertTrue("failure instanceof FailedPromisesException", failure instanceof FailedPromisesException); + Collection<Promise<?>> failedPromises = ((FailedPromisesException) failure).getFailedPromises(); + assertEquals("failedPromises size matches", nFail, failedPromises.size()); + + for (int i = 0; i < rv.length; i++) { + Promise<Integer> promise = promises.get(i); + if (rv[i] < 0) { + assertTrue("failedPromises contains", failedPromises.contains(promise)); + } else { + assertFalse("failedPromises doesn't contain", failedPromises.contains(promise)); + } + } + } else { + List<Number> list = latch.getValue(); + assertEquals("list size matches", rv.length, list.size()); + for (int i = 0; i < rv.length; i++) { + assertEquals("list[i] matches", rv[i], list.get(i)); + } + + // check list is modifiable + list.add(0, 3.14); + assertEquals("list modifiable", 3.14, list.get(0)); + } + } + + +}
