ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/CompletableFutureTest.java
(Generate patch)

Comparing jsr166/src/test/tck/CompletableFutureTest.java (file contents):
Revision 1.129 by jsr166, Sun Nov 15 01:33:02 2015 UTC vs.
Revision 1.134 by jsr166, Sun Nov 15 19:55:38 2015 UTC

# Line 982 | Line 982 | public class CompletableFutureTest exten
982       * If a whenComplete action throws an exception when triggered by
983       * a normal completion, it completes exceptionally
984       */
985 <    public void testWhenComplete_actionFailed() {
985 >    public void testWhenComplete_sourceCompletedNormallyActionFailed() {
986          for (boolean createIncomplete : new boolean[] { true, false })
987          for (ExecutionMode m : ExecutionMode.values())
988          for (Integer v1 : new Integer[] { 1, null })
# Line 1010 | Line 1010 | public class CompletableFutureTest exten
1010      /**
1011       * If a whenComplete action throws an exception when triggered by
1012       * a source completion that also throws an exception, the source
1013 <     * exception takes precedence.
1013 >     * exception takes precedence (unlike handle)
1014       */
1015 <    public void testWhenComplete_actionFailedSourceFailed() {
1015 >    public void testWhenComplete_sourceFailedActionFailed() {
1016          for (boolean createIncomplete : new boolean[] { true, false })
1017          for (ExecutionMode m : ExecutionMode.values())
1018      {
# Line 1125 | Line 1125 | public class CompletableFutureTest exten
1125      }}
1126  
1127      /**
1128 <     * handle result completes exceptionally if action does
1128 >     * If a "handle action" throws an exception when triggered by
1129 >     * a normal completion, it completes exceptionally
1130       */
1131 <    public void testHandle_sourceFailedActionFailed() {
1131 >    public void testHandle_sourceCompletedNormallyActionFailed() {
1132          for (ExecutionMode m : ExecutionMode.values())
1133          for (boolean createIncomplete : new boolean[] { true, false })
1134 +        for (Integer v1 : new Integer[] { 1, null })
1135      {
1136          final CompletableFuture<Integer> f = new CompletableFuture<>();
1137          final AtomicInteger a = new AtomicInteger(0);
1138 <        final CFException ex1 = new CFException();
1139 <        final CFException ex2 = new CFException();
1138 <        if (!createIncomplete) f.completeExceptionally(ex1);
1138 >        final CFException ex = new CFException();
1139 >        if (!createIncomplete) assertTrue(f.complete(v1));
1140          final CompletableFuture<Integer> g = m.handle
1141              (f,
1142               (Integer x, Throwable t) -> {
1143                  m.checkExecutionMode();
1144 <                threadAssertNull(x);
1145 <                threadAssertSame(ex1, t);
1144 >                threadAssertSame(x, v1);
1145 >                threadAssertNull(t);
1146                  a.getAndIncrement();
1147 <                throw ex2;
1147 >                throw ex;
1148              });
1149 <        if (createIncomplete) f.completeExceptionally(ex1);
1149 >        if (createIncomplete) assertTrue(f.complete(v1));
1150  
1151 <        checkCompletedWithWrappedException(g, ex2);
1152 <        checkCompletedExceptionally(f, ex1);
1151 >        checkCompletedWithWrappedException(g, ex);
1152 >        checkCompletedNormally(f, v1);
1153          assertEquals(1, a.get());
1154      }}
1155  
1156 <    public void testHandle_sourceCompletedNormallyActionFailed() {
1157 <        for (ExecutionMode m : ExecutionMode.values())
1156 >    /**
1157 >     * If a "handle action" throws an exception when triggered by
1158 >     * a source completion that also throws an exception, the action
1159 >     * exception takes precedence (unlike whenComplete)
1160 >     */
1161 >    public void testHandle_sourceFailedActionFailed() {
1162          for (boolean createIncomplete : new boolean[] { true, false })
1163 <        for (Integer v1 : new Integer[] { 1, null })
1163 >        for (ExecutionMode m : ExecutionMode.values())
1164      {
1160        final CompletableFuture<Integer> f = new CompletableFuture<>();
1165          final AtomicInteger a = new AtomicInteger(0);
1166 <        final CFException ex = new CFException();
1167 <        if (!createIncomplete) assertTrue(f.complete(v1));
1166 >        final CFException ex1 = new CFException();
1167 >        final CFException ex2 = new CFException();
1168 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1169 >
1170 >        if (!createIncomplete) f.completeExceptionally(ex1);
1171          final CompletableFuture<Integer> g = m.handle
1172              (f,
1173               (Integer x, Throwable t) -> {
1174                  m.checkExecutionMode();
1175 <                threadAssertSame(x, v1);
1176 <                threadAssertNull(t);
1175 >                threadAssertNull(x);
1176 >                threadAssertSame(ex1, t);
1177                  a.getAndIncrement();
1178 <                throw ex;
1178 >                throw ex2;
1179              });
1180 <        if (createIncomplete) assertTrue(f.complete(v1));
1180 >        if (createIncomplete) f.completeExceptionally(ex1);
1181  
1182 <        checkCompletedWithWrappedException(g, ex);
1183 <        checkCompletedNormally(f, v1);
1182 >        checkCompletedWithWrappedException(g, ex2);
1183 >        checkCompletedExceptionally(f, ex1);
1184          assertEquals(1, a.get());
1185      }}
1186  
# Line 3764 | Line 3771 | public class CompletableFutureTest exten
3771      }
3772  
3773      static class Monad {
3774 <        static class MonadError extends Error {
3775 <            public MonadError() { super("monadic zero"); }
3774 >        static class ZeroException extends RuntimeException {
3775 >            public ZeroException() { super("monadic zero"); }
3776          }
3777          // "return", "unit"
3778          static <T> CompletableFuture<T> unit(T value) {
# Line 3773 | Line 3780 | public class CompletableFutureTest exten
3780          }
3781          // monadic zero ?
3782          static <T> CompletableFuture<T> zero() {
3783 <            return failedFuture(new MonadError());
3783 >            return failedFuture(new ZeroException());
3784          }
3785          // >=>
3786          static <T,U,V> Function<T, CompletableFuture<V>> compose
# Line 3787 | Line 3794 | public class CompletableFutureTest exten
3794                  f.getNow(null);
3795                  throw new AssertionFailedError("should throw");
3796              } catch (CompletionException success) {
3797 <                assertTrue(success.getCause() instanceof MonadError);
3797 >                assertTrue(success.getCause() instanceof ZeroException);
3798              }
3799          }
3800  
# Line 3819 | Line 3826 | public class CompletableFutureTest exten
3826                                               CompletableFuture<? extends T> g) {
3827              PlusFuture<T> plus = new PlusFuture<T>();
3828              BiConsumer<T, Throwable> action = (T result, Throwable ex) -> {
3829 <                if (result != null) {
3829 >                if (ex == null) {
3830                      if (plus.complete(result))
3831                          if (plus.firstFailure.get() != null)
3832                              plus.firstFailure.set(null);
# Line 3827 | Line 3834 | public class CompletableFutureTest exten
3834                  else if (plus.firstFailure.compareAndSet(null, ex)) {
3835                      if (plus.isDone())
3836                          plus.firstFailure.set(null);
3837 <                } else {
3838 <                    if (plus.completeExceptionally(ex))
3839 <                        plus.firstFailure.set(null);
3837 >                }
3838 >                else {
3839 >                    // first failure has precedence
3840 >                    Throwable first = plus.firstFailure.getAndSet(null);
3841 >
3842 >                    // may fail with "Self-suppression not permitted"
3843 >                    try { first.addSuppressed(ex); }
3844 >                    catch (Exception ignored) {}
3845 >
3846 >                    plus.completeExceptionally(first);
3847                  }
3848              };
3849              f.whenComplete(action);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines