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.35 by jsr166, Sun Jun 1 22:22:49 2014 UTC vs.
Revision 1.40 by jsr166, Mon Jun 2 01:11:53 2014 UTC

# Line 318 | Line 318 | public class CompletableFutureTest exten
318  
319      // Choose non-commutative actions for better coverage
320  
321 +    // A non-commutative function that handles and produces null values as well.
322 +    static Integer subtract(Integer x, Integer y) {
323 +        return (x == null && y == null) ? null :
324 +            ((x == null) ? 42 : x.intValue())
325 +            - ((y == null) ? 99 : y.intValue());
326 +    }
327 +
328 +    // A function that handles and produces null values as well.
329 +    static Integer inc(Integer x) {
330 +        return (x == null) ? null : x + 1;
331 +    }
332 +
333      static final Supplier<Integer> supplyOne =
334          () -> Integer.valueOf(1);
335      static final Function<Integer, Integer> inc =
336          (Integer x) -> Integer.valueOf(x.intValue() + 1);
337      static final BiFunction<Integer, Integer, Integer> subtract =
338 <        (Integer x, Integer y) -> Integer.valueOf(x.intValue() - y.intValue());
338 >        (Integer x, Integer y) -> subtract(x, y);
339      static final class IncAction implements Consumer<Integer> {
340 <        int value;
341 <        public void accept(Integer x) { value = x.intValue() + 1; }
340 >        int invocationCount = 0;
341 >        Integer value;
342 >        public boolean ran() { return invocationCount == 1; }
343 >        public void accept(Integer x) {
344 >            invocationCount++;
345 >            value = inc(x);
346 >        }
347      }
348 <    static final class SubtractAction implements BiConsumer<Integer, Integer> {
349 <        // Handle null values as well
350 <        public int subtract(Integer x, Integer y) {
351 <            return ((x == null) ? 42 : x.intValue())
352 <                - ((y == null) ? 99 : y.intValue());
348 >    static final class IncFunction implements Function<Integer,Integer> {
349 >        int invocationCount = 0;
350 >        Integer value;
351 >        public boolean ran() { return invocationCount == 1; }
352 >        public Integer apply(Integer x) {
353 >            invocationCount++;
354 >            return value = inc(x);
355          }
356 <        int value;
357 <        public boolean ran() { return value != 0; }
356 >    }
357 >    static final class SubtractAction implements BiConsumer<Integer, Integer> {
358 >        int invocationCount = 0;
359 >        Integer value;
360 >        // Check this action was invoked exactly once when result is computed.
361 >        public boolean ran() { return invocationCount == 1; }
362          public void accept(Integer x, Integer y) {
363 +            invocationCount++;
364              value = subtract(x, y);
365          }
366      }
367 +    static final class SubtractFunction implements BiFunction<Integer, Integer, Integer> {
368 +        int invocationCount = 0;
369 +        Integer value;
370 +        // Check this action was invoked exactly once when result is computed.
371 +        public boolean ran() { return invocationCount == 1; }
372 +        public Integer apply(Integer x, Integer y) {
373 +            invocationCount++;
374 +            return value = subtract(x, y);
375 +        }
376 +    }
377      static final class Noop implements Runnable {
378          boolean ran;
379          public void run() { ran = true; }
# Line 427 | Line 461 | public class CompletableFutureTest exten
461                   BiConsumer<? super T,? super U> a) {
462                  return f.thenAcceptBoth(g, a);
463              }
464 +            public <T,U,V> CompletableFuture<V> thenCombine
465 +                (CompletableFuture<T> f,
466 +                 CompletionStage<? extends U> g,
467 +                 BiFunction<? super T,? super U,? extends V> a) {
468 +                return f.thenCombine(g, a);
469 +            }
470 +            public <T,U> CompletableFuture<U> applyToEither
471 +                (CompletableFuture<T> f,
472 +                 CompletionStage<? extends T> g,
473 +                 Function<? super T,U> a) {
474 +                return f.applyToEither(g, a);
475 +            }
476 +            public <T> CompletableFuture<Void> acceptEither
477 +                (CompletableFuture<T> f,
478 +                 CompletionStage<? extends T> g,
479 +                 Consumer<? super T> a) {
480 +                return f.acceptEither(g, a);
481 +            }
482 +            public <T> CompletableFuture<Void> runAfterEither
483 +                (CompletableFuture<T> f,
484 +                 CompletionStage<?> g,
485 +                 java.lang.Runnable a) {
486 +                return f.runAfterEither(g, a);
487 +            }
488 +            public <T,U> CompletableFuture<U> thenCompose
489 +                (CompletableFuture<T> f,
490 +                 Function<? super T,? extends CompletionStage<U>> a) {
491 +                return f.thenCompose(a);
492 +            }
493 +            public <T> CompletableFuture<T> whenComplete
494 +                (CompletableFuture<T> f,
495 +                 BiConsumer<? super T,? super Throwable> a) {
496 +                return f.whenComplete(a);
497 +            }
498          },
499  
500   //             /** Experimental way to do more testing */
# Line 454 | Line 522 | public class CompletableFutureTest exten
522                   BiConsumer<? super T,? super U> a) {
523                  return f.thenAcceptBothAsync(g, a);
524              }
525 +            public <T,U,V> CompletableFuture<V> thenCombine
526 +                (CompletableFuture<T> f,
527 +                 CompletionStage<? extends U> g,
528 +                 BiFunction<? super T,? super U,? extends V> a) {
529 +                return f.thenCombineAsync(g, a);
530 +            }
531 +            public <T,U> CompletableFuture<U> applyToEither
532 +                (CompletableFuture<T> f,
533 +                 CompletionStage<? extends T> g,
534 +                 Function<? super T,U> a) {
535 +                return f.applyToEitherAsync(g, a);
536 +            }
537 +            public <T> CompletableFuture<Void> acceptEither
538 +                (CompletableFuture<T> f,
539 +                 CompletionStage<? extends T> g,
540 +                 Consumer<? super T> a) {
541 +                return f.acceptEitherAsync(g, a);
542 +            }
543 +            public <T> CompletableFuture<Void> runAfterEither
544 +                (CompletableFuture<T> f,
545 +                 CompletionStage<?> g,
546 +                 java.lang.Runnable a) {
547 +                return f.runAfterEitherAsync(g, a);
548 +            }
549 +            public <T,U> CompletableFuture<U> thenCompose
550 +                (CompletableFuture<T> f,
551 +                 Function<? super T,? extends CompletionStage<U>> a) {
552 +                return f.thenComposeAsync(a);
553 +            }
554 +            public <T> CompletableFuture<T> whenComplete
555 +                (CompletableFuture<T> f,
556 +                 BiConsumer<? super T,? super Throwable> a) {
557 +                return f.whenCompleteAsync(a);
558 +            }
559          },
560  
561   //         REVERSE_DEFAULT_ASYNC {
# Line 480 | Line 582 | public class CompletableFutureTest exten
582                   BiConsumer<? super T,? super U> a) {
583                  return f.thenAcceptBothAsync(g, a, new ThreadExecutor());
584              }
585 +            public <T,U,V> CompletableFuture<V> thenCombine
586 +                (CompletableFuture<T> f,
587 +                 CompletionStage<? extends U> g,
588 +                 BiFunction<? super T,? super U,? extends V> a) {
589 +                return f.thenCombineAsync(g, a, new ThreadExecutor());
590 +            }
591 +            public <T,U> CompletableFuture<U> applyToEither
592 +                (CompletableFuture<T> f,
593 +                 CompletionStage<? extends T> g,
594 +                 Function<? super T,U> a) {
595 +                return f.applyToEitherAsync(g, a, new ThreadExecutor());
596 +            }
597 +            public <T> CompletableFuture<Void> acceptEither
598 +                (CompletableFuture<T> f,
599 +                 CompletionStage<? extends T> g,
600 +                 Consumer<? super T> a) {
601 +                return f.acceptEitherAsync(g, a, new ThreadExecutor());
602 +            }
603 +            public <T> CompletableFuture<Void> runAfterEither
604 +                (CompletableFuture<T> f,
605 +                 CompletionStage<?> g,
606 +                 java.lang.Runnable a) {
607 +                return f.runAfterEitherAsync(g, a, new ThreadExecutor());
608 +            }
609 +            public <T,U> CompletableFuture<U> thenCompose
610 +                (CompletableFuture<T> f,
611 +                 Function<? super T,? extends CompletionStage<U>> a) {
612 +                return f.thenComposeAsync(a, new ThreadExecutor());
613 +            }
614 +            public <T> CompletableFuture<T> whenComplete
615 +                (CompletableFuture<T> f,
616 +                 BiConsumer<? super T,? super Throwable> a) {
617 +                return f.whenCompleteAsync(a, new ThreadExecutor());
618 +            }
619          };
620  
621          public abstract <T,U> CompletableFuture<Void> runAfterBoth
# Line 488 | Line 624 | public class CompletableFutureTest exten
624              (CompletableFuture<T> f,
625               CompletionStage<? extends U> g,
626               BiConsumer<? super T,? super U> a);
627 +        public abstract <T,U,V> CompletableFuture<V> thenCombine
628 +            (CompletableFuture<T> f,
629 +             CompletionStage<? extends U> g,
630 +             BiFunction<? super T,? super U,? extends V> a);
631 +        public abstract <T,U> CompletableFuture<U> applyToEither
632 +            (CompletableFuture<T> f,
633 +             CompletionStage<? extends T> g,
634 +             Function<? super T,U> a);
635 +        public abstract <T> CompletableFuture<Void> acceptEither
636 +            (CompletableFuture<T> f,
637 +             CompletionStage<? extends T> g,
638 +             Consumer<? super T> a);
639 +        public abstract <T> CompletableFuture<Void> runAfterEither
640 +            (CompletableFuture<T> f,
641 +             CompletionStage<?> g,
642 +             java.lang.Runnable a);
643 +        public abstract <T,U> CompletableFuture<U> thenCompose
644 +            (CompletableFuture<T> f,
645 +             Function<? super T,? extends CompletionStage<U>> a);
646 +        public abstract <T> CompletableFuture<T> whenComplete
647 +            (CompletableFuture<T> f,
648 +             BiConsumer<? super T,? super Throwable> a);
649 +
650 +
651      }
652  
653      /**
# Line 740 | Line 900 | public class CompletableFutureTest exten
900          CompletableFuture<Void> g = f.thenAccept(r);
901          f.complete(one);
902          checkCompletedNormally(g, null);
903 <        assertEquals(r.value, 2);
903 >        assertEquals(r.value, (Integer) 2);
904      }
905  
906      /**
# Line 782 | Line 942 | public class CompletableFutureTest exten
942       * thenCombine result completes normally after normal completion
943       * of sources
944       */
945 <    public void testThenCombine() {
946 <        CompletableFuture<Integer> f, g, h;
945 >    public void testThenCombine_normalCompletion1() {
946 >        for (ExecutionMode m : ExecutionMode.values())
947 >        for (Integer v1 : new Integer[] { 1, null })
948 >        for (Integer v2 : new Integer[] { 2, null }) {
949  
950 <        f = new CompletableFuture<>();
951 <        g = new CompletableFuture<>();
952 <        h = f.thenCombine(g, subtract);
953 <        f.complete(3);
950 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
951 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
952 >        final SubtractFunction r = new SubtractFunction();
953 >        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
954 >
955 >        f.complete(v1);
956          checkIncomplete(h);
957 <        g.complete(1);
958 <        checkCompletedNormally(h, 2);
957 >        assertFalse(r.ran());
958 >        g.complete(v2);
959  
960 <        f = new CompletableFuture<>();
961 <        g = new CompletableFuture<>();
962 <        h = f.thenCombine(g, subtract);
963 <        g.complete(1);
960 >        checkCompletedNormally(h, subtract(v1, v2));
961 >        checkCompletedNormally(f, v1);
962 >        checkCompletedNormally(g, v2);
963 >        }
964 >    }
965 >
966 >    public void testThenCombine_normalCompletion2() {
967 >        for (ExecutionMode m : ExecutionMode.values())
968 >        for (Integer v1 : new Integer[] { 1, null })
969 >        for (Integer v2 : new Integer[] { 2, null }) {
970 >
971 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
972 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
973 >        final SubtractFunction r = new SubtractFunction();
974 >        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
975 >
976 >        g.complete(v2);
977          checkIncomplete(h);
978 <        f.complete(3);
979 <        checkCompletedNormally(h, 2);
978 >        assertFalse(r.ran());
979 >        f.complete(v1);
980  
981 <        f = new CompletableFuture<>();
982 <        g = new CompletableFuture<>();
983 <        g.complete(1);
984 <        f.complete(3);
985 <        h = f.thenCombine(g, subtract);
986 <        checkCompletedNormally(h, 2);
981 >        checkCompletedNormally(h, subtract(v1, v2));
982 >        checkCompletedNormally(f, v1);
983 >        checkCompletedNormally(g, v2);
984 >        }
985 >    }
986 >
987 >    public void testThenCombine_normalCompletion3() {
988 >        for (ExecutionMode m : ExecutionMode.values())
989 >        for (Integer v1 : new Integer[] { 1, null })
990 >        for (Integer v2 : new Integer[] { 2, null }) {
991 >
992 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
993 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
994 >        final SubtractFunction r = new SubtractFunction();
995 >
996 >        g.complete(v2);
997 >        f.complete(v1);
998 >        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
999 >
1000 >        checkCompletedNormally(h, subtract(v1, v2));
1001 >        checkCompletedNormally(f, v1);
1002 >        checkCompletedNormally(g, v2);
1003 >        }
1004 >    }
1005 >
1006 >    public void testThenCombine_normalCompletion4() {
1007 >        for (ExecutionMode m : ExecutionMode.values())
1008 >        for (Integer v1 : new Integer[] { 1, null })
1009 >        for (Integer v2 : new Integer[] { 2, null }) {
1010 >
1011 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1012 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1013 >        final SubtractFunction r = new SubtractFunction();
1014 >
1015 >        f.complete(v1);
1016 >        g.complete(v2);
1017 >        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1018 >
1019 >        checkCompletedNormally(h, subtract(v1, v2));
1020 >        checkCompletedNormally(f, v1);
1021 >        checkCompletedNormally(g, v2);
1022 >        }
1023      }
1024  
1025      /**
1026       * thenCombine result completes exceptionally after exceptional
1027       * completion of either source
1028       */
1029 <    public void testThenCombine2() {
1030 <        CompletableFuture<Integer> f, g, h;
1029 >    public void testThenCombine_exceptionalCompletion1() {
1030 >        for (ExecutionMode m : ExecutionMode.values())
1031 >        for (Integer v1 : new Integer[] { 1, null }) {
1032  
1033 <        f = new CompletableFuture<>();
1034 <        g = new CompletableFuture<>();
1035 <        h = f.thenCombine(g, subtract);
1036 <        f.completeExceptionally(new CFException());
1033 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1034 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1035 >        final SubtractFunction r = new SubtractFunction();
1036 >        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1037 >        final CFException ex = new CFException();
1038 >
1039 >        f.completeExceptionally(ex);
1040          checkIncomplete(h);
1041 <        g.complete(1);
825 <        checkCompletedWithWrappedCFException(h);
1041 >        g.complete(v1);
1042  
1043 <        f = new CompletableFuture<>();
1044 <        g = new CompletableFuture<>();
1045 <        h = f.thenCombine(g, subtract);
1046 <        g.completeExceptionally(new CFException());
1043 >        checkCompletedWithWrappedCFException(h, ex);
1044 >        checkCompletedWithWrappedCFException(f, ex);
1045 >        assertFalse(r.ran());
1046 >        checkCompletedNormally(g, v1);
1047 >        }
1048 >    }
1049 >
1050 >    public void testThenCombine_exceptionalCompletion2() {
1051 >        for (ExecutionMode m : ExecutionMode.values())
1052 >        for (Integer v1 : new Integer[] { 1, null }) {
1053 >
1054 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1055 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1056 >        final SubtractFunction r = new SubtractFunction();
1057 >        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1058 >        final CFException ex = new CFException();
1059 >
1060 >        g.completeExceptionally(ex);
1061          checkIncomplete(h);
1062 <        f.complete(3);
833 <        checkCompletedWithWrappedCFException(h);
1062 >        f.complete(v1);
1063  
1064 <        f = new CompletableFuture<>();
1065 <        g = new CompletableFuture<>();
1066 <        f.complete(3);
1067 <        g.completeExceptionally(new CFException());
1068 <        h = f.thenCombine(g, subtract);
1069 <        checkCompletedWithWrappedCFException(h);
1064 >        checkCompletedWithWrappedCFException(h, ex);
1065 >        checkCompletedWithWrappedCFException(g, ex);
1066 >        assertFalse(r.ran());
1067 >        checkCompletedNormally(f, v1);
1068 >        }
1069 >    }
1070  
1071 <        f = new CompletableFuture<>();
1072 <        g = new CompletableFuture<>();
1073 <        f.completeExceptionally(new CFException());
1074 <        g.complete(3);
1075 <        h = f.thenCombine(g, subtract);
1076 <        checkCompletedWithWrappedCFException(h);
1071 >    public void testThenCombine_exceptionalCompletion3() {
1072 >        for (ExecutionMode m : ExecutionMode.values())
1073 >        for (Integer v1 : new Integer[] { 1, null }) {
1074 >
1075 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1076 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1077 >        final SubtractFunction r = new SubtractFunction();
1078 >        final CFException ex = new CFException();
1079 >
1080 >        g.completeExceptionally(ex);
1081 >        f.complete(v1);
1082 >        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1083 >
1084 >        checkCompletedWithWrappedCFException(h, ex);
1085 >        checkCompletedWithWrappedCFException(g, ex);
1086 >        assertFalse(r.ran());
1087 >        checkCompletedNormally(f, v1);
1088 >        }
1089 >    }
1090 >
1091 >    public void testThenCombine_exceptionalCompletion4() {
1092 >        for (ExecutionMode m : ExecutionMode.values())
1093 >        for (Integer v1 : new Integer[] { 1, null }) {
1094 >
1095 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1096 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1097 >        final SubtractFunction r = new SubtractFunction();
1098 >        final CFException ex = new CFException();
1099 >
1100 >        f.completeExceptionally(ex);
1101 >        g.complete(v1);
1102 >        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1103 >
1104 >        checkCompletedWithWrappedCFException(h, ex);
1105 >        checkCompletedWithWrappedCFException(f, ex);
1106 >        assertFalse(r.ran());
1107 >        checkCompletedNormally(g, v1);
1108 >        }
1109      }
1110  
1111      /**
1112       * thenCombine result completes exceptionally if action does
1113       */
1114 <    public void testThenCombine3() {
1115 <        CompletableFuture<Integer> f = new CompletableFuture<>();
1116 <        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1117 <        FailingBiFunction r = new FailingBiFunction();
1118 <        CompletableFuture<Integer> g = f.thenCombine(f2, r);
1119 <        f.complete(one);
1120 <        checkIncomplete(g);
1121 <        assertFalse(r.ran);
1122 <        f2.complete(two);
1123 <        checkCompletedWithWrappedCFException(g);
1124 <        assertTrue(r.ran);
1114 >    public void testThenCombine_actionFailed1() {
1115 >        for (ExecutionMode m : ExecutionMode.values())
1116 >        for (Integer v1 : new Integer[] { 1, null })
1117 >        for (Integer v2 : new Integer[] { 2, null }) {
1118 >
1119 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1120 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1121 >        final FailingBiFunction r = new FailingBiFunction();
1122 >        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1123 >
1124 >        f.complete(v1);
1125 >        checkIncomplete(h);
1126 >        g.complete(v2);
1127 >
1128 >        checkCompletedWithWrappedCFException(h);
1129 >        checkCompletedNormally(f, v1);
1130 >        checkCompletedNormally(g, v2);
1131 >        }
1132 >    }
1133 >
1134 >    public void testThenCombine_actionFailed2() {
1135 >        for (ExecutionMode m : ExecutionMode.values())
1136 >        for (Integer v1 : new Integer[] { 1, null })
1137 >        for (Integer v2 : new Integer[] { 2, null }) {
1138 >
1139 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1140 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1141 >        final FailingBiFunction r = new FailingBiFunction();
1142 >        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1143 >
1144 >        g.complete(v2);
1145 >        checkIncomplete(h);
1146 >        f.complete(v1);
1147 >
1148 >        checkCompletedWithWrappedCFException(h);
1149 >        checkCompletedNormally(f, v1);
1150 >        checkCompletedNormally(g, v2);
1151 >        }
1152      }
1153  
1154      /**
1155       * thenCombine result completes exceptionally if either source cancelled
1156       */
1157 <    public void testThenCombine4() {
1158 <        CompletableFuture<Integer> f, g, h;
1157 >    public void testThenCombine_sourceCancelled1() {
1158 >        for (ExecutionMode m : ExecutionMode.values())
1159 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1160 >        for (Integer v1 : new Integer[] { 1, null }) {
1161  
1162 <        f = new CompletableFuture<>();
1163 <        g = new CompletableFuture<>();
1164 <        h = f.thenCombine(g, subtract);
1165 <        assertTrue(f.cancel(true));
1162 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1163 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1164 >        final SubtractFunction r = new SubtractFunction();
1165 >        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1166 >
1167 >        assertTrue(f.cancel(mayInterruptIfRunning));
1168          checkIncomplete(h);
1169 <        g.complete(1);
1169 >        g.complete(v1);
1170 >
1171          checkCompletedWithWrappedCancellationException(h);
1172 +        checkCancelled(f);
1173 +        assertFalse(r.ran());
1174 +        checkCompletedNormally(g, v1);
1175 +        }
1176 +    }
1177  
1178 <        f = new CompletableFuture<>();
1179 <        g = new CompletableFuture<>();
1180 <        h = f.thenCombine(g, subtract);
1181 <        assertTrue(g.cancel(true));
1178 >    public void testThenCombine_sourceCancelled2() {
1179 >        for (ExecutionMode m : ExecutionMode.values())
1180 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1181 >        for (Integer v1 : new Integer[] { 1, null }) {
1182 >
1183 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1184 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1185 >        final SubtractFunction r = new SubtractFunction();
1186 >        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1187 >
1188 >        assertTrue(g.cancel(mayInterruptIfRunning));
1189          checkIncomplete(h);
1190 <        f.complete(3);
1190 >        f.complete(v1);
1191 >
1192          checkCompletedWithWrappedCancellationException(h);
1193 +        checkCancelled(g);
1194 +        assertFalse(r.ran());
1195 +        checkCompletedNormally(f, v1);
1196 +        }
1197 +    }
1198 +
1199 +    public void testThenCombine_sourceCancelled3() {
1200 +        for (ExecutionMode m : ExecutionMode.values())
1201 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1202 +        for (Integer v1 : new Integer[] { 1, null }) {
1203 +
1204 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1205 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1206 +        final SubtractFunction r = new SubtractFunction();
1207 +
1208 +        assertTrue(g.cancel(mayInterruptIfRunning));
1209 +        f.complete(v1);
1210 +        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1211  
888        f = new CompletableFuture<>();
889        g = new CompletableFuture<>();
890        assertTrue(f.cancel(true));
891        assertTrue(g.cancel(true));
892        h = f.thenCombine(g, subtract);
1212          checkCompletedWithWrappedCancellationException(h);
1213 +        checkCancelled(g);
1214 +        assertFalse(r.ran());
1215 +        checkCompletedNormally(f, v1);
1216 +        }
1217 +    }
1218 +
1219 +    public void testThenCombine_sourceCancelled4() {
1220 +        for (ExecutionMode m : ExecutionMode.values())
1221 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1222 +        for (Integer v1 : new Integer[] { 1, null }) {
1223 +
1224 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1225 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1226 +        final SubtractFunction r = new SubtractFunction();
1227 +
1228 +        assertTrue(f.cancel(mayInterruptIfRunning));
1229 +        g.complete(v1);
1230 +        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1231 +
1232 +        checkCompletedWithWrappedCancellationException(h);
1233 +        checkCancelled(f);
1234 +        assertFalse(r.ran());
1235 +        checkCompletedNormally(g, v1);
1236 +        }
1237      }
1238  
1239      /**
# Line 909 | Line 1252 | public class CompletableFutureTest exten
1252  
1253          f.complete(v1);
1254          checkIncomplete(h);
1255 <        assertEquals(r.value, 0);
1255 >        assertFalse(r.ran());
1256          g.complete(v2);
1257  
1258          checkCompletedNormally(h, null);
1259 <        assertEquals(r.value, r.subtract(v1, v2));
1259 >        assertEquals(r.value, subtract(v1, v2));
1260          checkCompletedNormally(f, v1);
1261          checkCompletedNormally(g, v2);
1262          }
# Line 931 | Line 1274 | public class CompletableFutureTest exten
1274  
1275          g.complete(v2);
1276          checkIncomplete(h);
1277 <        assertEquals(r.value, 0);
1277 >        assertFalse(r.ran());
1278          f.complete(v1);
1279  
1280          checkCompletedNormally(h, null);
1281 <        assertEquals(r.value, r.subtract(v1, v2));
1281 >        assertEquals(r.value, subtract(v1, v2));
1282          checkCompletedNormally(f, v1);
1283          checkCompletedNormally(g, v2);
1284          }
# Line 955 | Line 1298 | public class CompletableFutureTest exten
1298          final CompletableFuture<Void> h = m.thenAcceptBoth(f, g, r);
1299  
1300          checkCompletedNormally(h, null);
1301 <        assertEquals(r.value, r.subtract(v1, v2));
1301 >        assertEquals(r.value, subtract(v1, v2));
1302          checkCompletedNormally(f, v1);
1303          checkCompletedNormally(g, v2);
1304          }
# Line 975 | Line 1318 | public class CompletableFutureTest exten
1318          final CompletableFuture<Void> h = m.thenAcceptBoth(f, g, r);
1319  
1320          checkCompletedNormally(h, null);
1321 <        assertEquals(r.value, r.subtract(v1, v2));
1321 >        assertEquals(r.value, subtract(v1, v2));
1322          checkCompletedNormally(f, v1);
1323          checkCompletedNormally(g, v2);
1324          }
# Line 1501 | Line 1844 | public class CompletableFutureTest exten
1844       * applyToEither result completes normally after normal completion
1845       * of either source
1846       */
1847 <    public void testApplyToEither() {
1848 <        CompletableFuture<Integer> f = new CompletableFuture<>();
1849 <        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1850 <        CompletableFuture<Integer> g = f.applyToEither(f2, inc);
1508 <        f.complete(one);
1509 <        checkCompletedNormally(g, two);
1510 <        f2.complete(one);
1511 <        checkCompletedNormally(g, two);
1847 >    public void testApplyToEither_normalCompletion1() {
1848 >        for (ExecutionMode m : ExecutionMode.values())
1849 >        for (Integer v1 : new Integer[] { 1, null })
1850 >        for (Integer v2 : new Integer[] { 2, null }) {
1851  
1852 <        f = new CompletableFuture<>();
1853 <        f.complete(one);
1854 <        f2 = new CompletableFuture<>();
1855 <        g = f.applyToEither(f2, inc);
1856 <        checkCompletedNormally(g, two);
1852 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1853 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1854 >        final IncFunction r = new IncFunction();
1855 >        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
1856 >
1857 >        f.complete(v1);
1858 >        checkCompletedNormally(h, inc(v1));
1859 >        g.complete(v2);
1860 >
1861 >        checkCompletedNormally(f, v1);
1862 >        checkCompletedNormally(g, v2);
1863 >        checkCompletedNormally(h, inc(v1));
1864 >        }
1865 >    }
1866 >
1867 >    public void testApplyToEither_normalCompletion2() {
1868 >        for (ExecutionMode m : ExecutionMode.values())
1869 >        for (Integer v1 : new Integer[] { 1, null })
1870 >        for (Integer v2 : new Integer[] { 2, null }) {
1871 >
1872 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1873 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1874 >        final IncFunction r = new IncFunction();
1875 >        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
1876 >
1877 >        g.complete(v2);
1878 >        checkCompletedNormally(h, inc(v2));
1879 >        f.complete(v1);
1880 >
1881 >        checkCompletedNormally(f, v1);
1882 >        checkCompletedNormally(g, v2);
1883 >        checkCompletedNormally(h, inc(v2));
1884 >        }
1885 >    }
1886 >    public void testApplyToEither_normalCompletion3() {
1887 >        for (ExecutionMode m : ExecutionMode.values())
1888 >        for (Integer v1 : new Integer[] { 1, null })
1889 >        for (Integer v2 : new Integer[] { 2, null }) {
1890 >
1891 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1892 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1893 >        final IncFunction r = new IncFunction();
1894 >
1895 >        f.complete(v1);
1896 >        g.complete(v2);
1897 >        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
1898 >
1899 >        checkCompletedNormally(f, v1);
1900 >        checkCompletedNormally(g, v2);
1901 >
1902 >        // unspecified behavior
1903 >        assertTrue(Objects.equals(h.join(), inc(v1)) ||
1904 >                   Objects.equals(h.join(), inc(v2)));
1905 >        }
1906      }
1907  
1908      /**
1909       * applyToEither result completes exceptionally after exceptional
1910       * completion of either source
1911       */
1912 <    public void testApplyToEither2() {
1913 <        CompletableFuture<Integer> f = new CompletableFuture<>();
1914 <        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1527 <        CompletableFuture<Integer> g = f.applyToEither(f2, inc);
1528 <        f.completeExceptionally(new CFException());
1529 <        f2.complete(one);
1530 <        checkCompletedWithWrappedCFException(g);
1912 >    public void testApplyToEither_exceptionalCompletion1() {
1913 >        for (ExecutionMode m : ExecutionMode.values())
1914 >        for (Integer v1 : new Integer[] { 1, null }) {
1915  
1916 <        f = new CompletableFuture<>();
1917 <        f2 = new CompletableFuture<>();
1918 <        f2.completeExceptionally(new CFException());
1919 <        g = f.applyToEither(f2, inc);
1920 <        checkCompletedWithWrappedCFException(g);
1916 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1917 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1918 >        final IncFunction r = new IncFunction();
1919 >        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
1920 >        final CFException ex = new CFException();
1921 >
1922 >        f.completeExceptionally(ex);
1923 >        checkCompletedWithWrappedCFException(h, ex);
1924 >        g.complete(v1);
1925 >
1926 >        assertFalse(r.ran());
1927 >        checkCompletedNormally(g, v1);
1928 >        checkCompletedWithWrappedCFException(f, ex);
1929 >        checkCompletedWithWrappedCFException(h, ex);
1930 >        }
1931 >    }
1932 >
1933 >    public void testApplyToEither_exceptionalCompletion2() {
1934 >        for (ExecutionMode m : ExecutionMode.values())
1935 >        for (Integer v1 : new Integer[] { 1, null }) {
1936 >
1937 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1938 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1939 >        final IncFunction r = new IncFunction();
1940 >        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
1941 >        final CFException ex = new CFException();
1942 >
1943 >        g.completeExceptionally(ex);
1944 >        checkCompletedWithWrappedCFException(h, ex);
1945 >        f.complete(v1);
1946 >
1947 >        assertFalse(r.ran());
1948 >        checkCompletedNormally(f, v1);
1949 >        checkCompletedWithWrappedCFException(g, ex);
1950 >        checkCompletedWithWrappedCFException(h, ex);
1951 >        }
1952 >    }
1953 >
1954 >    public void testApplyToEither_exceptionalCompletion3() {
1955 >        for (ExecutionMode m : ExecutionMode.values())
1956 >        for (Integer v1 : new Integer[] { 1, null }) {
1957 >
1958 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1959 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1960 >        final IncFunction r = new IncFunction();
1961 >        final CFException ex = new CFException();
1962 >
1963 >        g.completeExceptionally(ex);
1964 >        f.complete(v1);
1965 >        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
1966 >
1967 >        // unspecified behavior
1968 >        Integer v;
1969 >        try {
1970 >            assertEquals(h.join(), inc(v1));
1971 >            assertTrue(r.ran());
1972 >        } catch (CompletionException ok) {
1973 >            checkCompletedWithWrappedCFException(h, ex);
1974 >            assertFalse(r.ran());
1975 >        }
1976 >
1977 >        checkCompletedWithWrappedCFException(g, ex);
1978 >        checkCompletedNormally(f, v1);
1979 >        }
1980 >    }
1981 >
1982 >    public void testApplyToEither_exceptionalCompletion4() {
1983 >        for (ExecutionMode m : ExecutionMode.values())
1984 >        for (Integer v1 : new Integer[] { 1, null }) {
1985 >
1986 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1987 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1988 >        final IncFunction r = new IncFunction();
1989 >        final CFException ex = new CFException();
1990 >
1991 >        f.completeExceptionally(ex);
1992 >        g.complete(v1);
1993 >        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
1994 >
1995 >        // unspecified behavior
1996 >        Integer v;
1997 >        try {
1998 >            assertEquals(h.join(), inc(v1));
1999 >            assertTrue(r.ran());
2000 >        } catch (CompletionException ok) {
2001 >            checkCompletedWithWrappedCFException(h, ex);
2002 >            assertFalse(r.ran());
2003 >        }
2004 >
2005 >        checkCompletedWithWrappedCFException(f, ex);
2006 >        assertFalse(r.ran());
2007 >        checkCompletedNormally(g, v1);
2008 >        }
2009      }
2010  
2011      /**
2012       * applyToEither result completes exceptionally if action does
2013       */
2014 <    public void testApplyToEither3() {
2015 <        CompletableFuture<Integer> f = new CompletableFuture<>();
2016 <        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2017 <        FailingFunction r = new FailingFunction();
2018 <        CompletableFuture<Integer> g = f.applyToEither(f2, r);
2019 <        f2.complete(two);
2020 <        checkCompletedWithWrappedCFException(g);
2014 >    public void testApplyToEither_actionFailed1() {
2015 >        for (ExecutionMode m : ExecutionMode.values())
2016 >        for (Integer v1 : new Integer[] { 1, null })
2017 >        for (Integer v2 : new Integer[] { 2, null }) {
2018 >
2019 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2020 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2021 >        final FailingFunction r = new FailingFunction();
2022 >        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
2023 >
2024 >        f.complete(v1);
2025 >        checkCompletedWithWrappedCFException(h);
2026 >        g.complete(v2);
2027 >        checkCompletedNormally(f, v1);
2028 >        checkCompletedNormally(g, v2);
2029 >        }
2030 >    }
2031 >
2032 >    public void testApplyToEither_actionFailed2() {
2033 >        for (ExecutionMode m : ExecutionMode.values())
2034 >        for (Integer v1 : new Integer[] { 1, null })
2035 >        for (Integer v2 : new Integer[] { 2, null }) {
2036 >
2037 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2038 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2039 >        final FailingFunction r = new FailingFunction();
2040 >        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
2041 >
2042 >        g.complete(v2);
2043 >        checkCompletedWithWrappedCFException(h);
2044 >        f.complete(v1);
2045 >        checkCompletedNormally(f, v1);
2046 >        checkCompletedNormally(g, v2);
2047 >        }
2048      }
2049  
2050      /**
2051       * applyToEither result completes exceptionally if either source cancelled
2052       */
2053 <    public void testApplyToEither4() {
2054 <        CompletableFuture<Integer> f = new CompletableFuture<>();
2055 <        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2056 <        CompletableFuture<Integer> g = f.applyToEither(f2, inc);
2057 <        assertTrue(f.cancel(true));
2058 <        checkCompletedWithWrappedCancellationException(g);
2059 <        f = new CompletableFuture<>();
2060 <        f2 = new CompletableFuture<>();
2061 <        assertTrue(f2.cancel(true));
2062 <        checkCompletedWithWrappedCancellationException(g);
2053 >    public void testApplyToEither_sourceCancelled1() {
2054 >        for (ExecutionMode m : ExecutionMode.values())
2055 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2056 >        for (Integer v1 : new Integer[] { 1, null }) {
2057 >
2058 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2059 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2060 >        final IncFunction r = new IncFunction();
2061 >        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
2062 >
2063 >        assertTrue(f.cancel(mayInterruptIfRunning));
2064 >        checkCompletedWithWrappedCancellationException(h);
2065 >        g.complete(v1);
2066 >
2067 >        checkCancelled(f);
2068 >        assertFalse(r.ran());
2069 >        checkCompletedNormally(g, v1);
2070 >        checkCompletedWithWrappedCancellationException(h);
2071 >        }
2072 >    }
2073 >
2074 >    public void testApplyToEither_sourceCancelled2() {
2075 >        for (ExecutionMode m : ExecutionMode.values())
2076 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2077 >        for (Integer v1 : new Integer[] { 1, null }) {
2078 >
2079 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2080 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2081 >        final IncFunction r = new IncFunction();
2082 >        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
2083 >
2084 >        assertTrue(g.cancel(mayInterruptIfRunning));
2085 >        checkCompletedWithWrappedCancellationException(h);
2086 >        f.complete(v1);
2087 >
2088 >        checkCancelled(g);
2089 >        assertFalse(r.ran());
2090 >        checkCompletedNormally(f, v1);
2091 >        checkCompletedWithWrappedCancellationException(h);
2092 >        }
2093 >    }
2094 >
2095 >    public void testApplyToEither_sourceCancelled3() {
2096 >        for (ExecutionMode m : ExecutionMode.values())
2097 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2098 >        for (Integer v1 : new Integer[] { 1, null }) {
2099 >
2100 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2101 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2102 >        final IncFunction r = new IncFunction();
2103 >
2104 >        assertTrue(g.cancel(mayInterruptIfRunning));
2105 >        f.complete(v1);
2106 >        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
2107 >
2108 >        // unspecified behavior
2109 >        Integer v;
2110 >        try {
2111 >            assertEquals(h.join(), inc(v1));
2112 >            assertTrue(r.ran());
2113 >        } catch (CompletionException ok) {
2114 >            checkCompletedWithWrappedCancellationException(h);
2115 >            assertFalse(r.ran());
2116 >        }
2117 >
2118 >        checkCancelled(g);
2119 >        checkCompletedNormally(f, v1);
2120 >        }
2121 >    }
2122 >
2123 >    public void testApplyToEither_sourceCancelled4() {
2124 >        for (ExecutionMode m : ExecutionMode.values())
2125 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2126 >        for (Integer v1 : new Integer[] { 1, null }) {
2127 >
2128 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2129 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2130 >        final IncFunction r = new IncFunction();
2131 >
2132 >        assertTrue(f.cancel(mayInterruptIfRunning));
2133 >        g.complete(v1);
2134 >        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
2135 >
2136 >        // unspecified behavior
2137 >        Integer v;
2138 >        try {
2139 >            assertEquals(h.join(), inc(v1));
2140 >            assertTrue(r.ran());
2141 >        } catch (CompletionException ok) {
2142 >            checkCompletedWithWrappedCancellationException(h);
2143 >            assertFalse(r.ran());
2144 >        }
2145 >
2146 >        checkCancelled(f);
2147 >        checkCompletedNormally(g, v1);
2148 >        }
2149      }
2150  
2151      /**
2152       * acceptEither result completes normally after normal completion
2153       * of either source
2154       */
2155 <    public void testAcceptEither() {
2156 <        CompletableFuture<Integer> f = new CompletableFuture<>();
2157 <        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2158 <        IncAction r = new IncAction();
1574 <        CompletableFuture<Void> g = f.acceptEither(f2, r);
1575 <        f.complete(one);
1576 <        checkCompletedNormally(g, null);
1577 <        f2.complete(one);
1578 <        checkCompletedNormally(g, null);
1579 <        assertEquals(r.value, 2);
2155 >    public void testAcceptEither_normalCompletion1() {
2156 >        for (ExecutionMode m : ExecutionMode.values())
2157 >        for (Integer v1 : new Integer[] { 1, null })
2158 >        for (Integer v2 : new Integer[] { 2, null }) {
2159  
2160 <        r = new IncAction();
2161 <        f = new CompletableFuture<>();
2162 <        f.complete(one);
2163 <        f2 = new CompletableFuture<>();
2164 <        g = f.acceptEither(f2, r);
2165 <        checkCompletedNormally(g, null);
2166 <        assertEquals(r.value, 2);
2160 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2161 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2162 >        final IncAction r = new IncAction();
2163 >        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2164 >
2165 >        f.complete(v1);
2166 >        checkCompletedNormally(h, null);
2167 >        assertEquals(r.value, inc(v1));
2168 >        g.complete(v2);
2169 >
2170 >        checkCompletedNormally(f, v1);
2171 >        checkCompletedNormally(g, v2);
2172 >        checkCompletedNormally(h, null);
2173 >        }
2174 >    }
2175 >
2176 >    public void testAcceptEither_normalCompletion2() {
2177 >        for (ExecutionMode m : ExecutionMode.values())
2178 >        for (Integer v1 : new Integer[] { 1, null })
2179 >        for (Integer v2 : new Integer[] { 2, null }) {
2180 >
2181 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2182 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2183 >        final IncAction r = new IncAction();
2184 >        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2185 >
2186 >        g.complete(v2);
2187 >        checkCompletedNormally(h, null);
2188 >        assertEquals(r.value, inc(v2));
2189 >        f.complete(v1);
2190 >
2191 >        checkCompletedNormally(f, v1);
2192 >        checkCompletedNormally(g, v2);
2193 >        checkCompletedNormally(h, null);
2194 >        }
2195 >    }
2196 >    public void testAcceptEither_normalCompletion3() {
2197 >        for (ExecutionMode m : ExecutionMode.values())
2198 >        for (Integer v1 : new Integer[] { 1, null })
2199 >        for (Integer v2 : new Integer[] { 2, null }) {
2200 >
2201 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2202 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2203 >        final IncAction r = new IncAction();
2204 >
2205 >        f.complete(v1);
2206 >        g.complete(v2);
2207 >        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2208 >
2209 >        checkCompletedNormally(h, null);
2210 >        checkCompletedNormally(f, v1);
2211 >        checkCompletedNormally(g, v2);
2212 >
2213 >        // unspecified behavior
2214 >        assertTrue(Objects.equals(r.value, inc(v1)) ||
2215 >                   Objects.equals(r.value, inc(v2)));
2216 >        }
2217      }
2218  
2219      /**
2220       * acceptEither result completes exceptionally after exceptional
2221       * completion of either source
2222       */
2223 <    public void testAcceptEither2() {
2224 <        CompletableFuture<Integer> f = new CompletableFuture<>();
2225 <        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1597 <        IncAction r = new IncAction();
1598 <        CompletableFuture<Void> g = f.acceptEither(f2, r);
1599 <        f.completeExceptionally(new CFException());
1600 <        f2.complete(one);
1601 <        checkCompletedWithWrappedCFException(g);
2223 >    public void testAcceptEither_exceptionalCompletion1() {
2224 >        for (ExecutionMode m : ExecutionMode.values())
2225 >        for (Integer v1 : new Integer[] { 1, null }) {
2226  
2227 <        r = new IncAction();
2228 <        f = new CompletableFuture<>();
2229 <        f2 = new CompletableFuture<>();
2230 <        f2.completeExceptionally(new CFException());
2231 <        g = f.acceptEither(f2, r);
2232 <        checkCompletedWithWrappedCFException(g);
2227 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2228 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2229 >        final IncAction r = new IncAction();
2230 >        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2231 >        final CFException ex = new CFException();
2232 >
2233 >        f.completeExceptionally(ex);
2234 >        checkCompletedWithWrappedCFException(h, ex);
2235 >        g.complete(v1);
2236 >
2237 >        assertFalse(r.ran());
2238 >        checkCompletedNormally(g, v1);
2239 >        checkCompletedWithWrappedCFException(f, ex);
2240 >        checkCompletedWithWrappedCFException(h, ex);
2241 >        }
2242 >    }
2243 >
2244 >    public void testAcceptEither_exceptionalCompletion2() {
2245 >        for (ExecutionMode m : ExecutionMode.values())
2246 >        for (Integer v1 : new Integer[] { 1, null }) {
2247 >
2248 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2249 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2250 >        final IncAction r = new IncAction();
2251 >        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2252 >        final CFException ex = new CFException();
2253 >
2254 >        g.completeExceptionally(ex);
2255 >        checkCompletedWithWrappedCFException(h, ex);
2256 >        f.complete(v1);
2257 >
2258 >        assertFalse(r.ran());
2259 >        checkCompletedNormally(f, v1);
2260 >        checkCompletedWithWrappedCFException(g, ex);
2261 >        checkCompletedWithWrappedCFException(h, ex);
2262 >        }
2263 >    }
2264 >
2265 >    public void testAcceptEither_exceptionalCompletion3() {
2266 >        for (ExecutionMode m : ExecutionMode.values())
2267 >        for (Integer v1 : new Integer[] { 1, null }) {
2268 >
2269 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2270 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2271 >        final IncAction r = new IncAction();
2272 >        final CFException ex = new CFException();
2273 >
2274 >        g.completeExceptionally(ex);
2275 >        f.complete(v1);
2276 >        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2277 >
2278 >        // unspecified behavior
2279 >        Integer v;
2280 >        try {
2281 >            assertEquals(h.join(), null);
2282 >            assertTrue(r.ran());
2283 >            assertEquals(inc(v1), r.value);
2284 >        } catch (CompletionException ok) {
2285 >            checkCompletedWithWrappedCFException(h, ex);
2286 >            assertFalse(r.ran());
2287 >        }
2288 >
2289 >        checkCompletedWithWrappedCFException(g, ex);
2290 >        checkCompletedNormally(f, v1);
2291 >        }
2292 >    }
2293 >
2294 >    public void testAcceptEither_exceptionalCompletion4() {
2295 >        for (ExecutionMode m : ExecutionMode.values())
2296 >        for (Integer v1 : new Integer[] { 1, null }) {
2297 >
2298 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2299 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2300 >        final IncAction r = new IncAction();
2301 >        final CFException ex = new CFException();
2302 >
2303 >        f.completeExceptionally(ex);
2304 >        g.complete(v1);
2305 >        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2306 >
2307 >        // unspecified behavior
2308 >        Integer v;
2309 >        try {
2310 >            assertEquals(h.join(), null);
2311 >            assertTrue(r.ran());
2312 >            assertEquals(inc(v1), r.value);
2313 >        } catch (CompletionException ok) {
2314 >            checkCompletedWithWrappedCFException(h, ex);
2315 >            assertFalse(r.ran());
2316 >        }
2317 >
2318 >        checkCompletedWithWrappedCFException(f, ex);
2319 >        assertFalse(r.ran());
2320 >        checkCompletedNormally(g, v1);
2321 >        }
2322      }
2323  
2324      /**
2325       * acceptEither result completes exceptionally if action does
2326       */
2327 <    public void testAcceptEither3() {
2328 <        CompletableFuture<Integer> f = new CompletableFuture<>();
2329 <        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2330 <        FailingConsumer r = new FailingConsumer();
2331 <        CompletableFuture<Void> g = f.acceptEither(f2, r);
2332 <        f2.complete(two);
2333 <        checkCompletedWithWrappedCFException(g);
2327 >    public void testAcceptEither_actionFailed1() {
2328 >        for (ExecutionMode m : ExecutionMode.values())
2329 >        for (Integer v1 : new Integer[] { 1, null })
2330 >        for (Integer v2 : new Integer[] { 2, null }) {
2331 >
2332 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2333 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2334 >        final FailingConsumer r = new FailingConsumer();
2335 >        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2336 >
2337 >        f.complete(v1);
2338 >        checkCompletedWithWrappedCFException(h);
2339 >        g.complete(v2);
2340 >        checkCompletedNormally(f, v1);
2341 >        checkCompletedNormally(g, v2);
2342 >        }
2343 >    }
2344 >
2345 >    public void testAcceptEither_actionFailed2() {
2346 >        for (ExecutionMode m : ExecutionMode.values())
2347 >        for (Integer v1 : new Integer[] { 1, null })
2348 >        for (Integer v2 : new Integer[] { 2, null }) {
2349 >
2350 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2351 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2352 >        final FailingConsumer r = new FailingConsumer();
2353 >        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2354 >
2355 >        g.complete(v2);
2356 >        checkCompletedWithWrappedCFException(h);
2357 >        f.complete(v1);
2358 >        checkCompletedNormally(f, v1);
2359 >        checkCompletedNormally(g, v2);
2360 >        }
2361      }
2362  
2363      /**
2364       * acceptEither result completes exceptionally if either source cancelled
2365       */
2366 <    public void testAcceptEither4() {
2367 <        CompletableFuture<Integer> f = new CompletableFuture<>();
2368 <        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2369 <        IncAction r = new IncAction();
2370 <        CompletableFuture<Void> g = f.acceptEither(f2, r);
2371 <        assertTrue(f.cancel(true));
2372 <        checkCompletedWithWrappedCancellationException(g);
2373 <        f = new CompletableFuture<>();
2374 <        f2 = new CompletableFuture<>();
2375 <        assertTrue(f2.cancel(true));
2376 <        checkCompletedWithWrappedCancellationException(g);
2366 >    public void testAcceptEither_sourceCancelled1() {
2367 >        for (ExecutionMode m : ExecutionMode.values())
2368 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2369 >        for (Integer v1 : new Integer[] { 1, null }) {
2370 >
2371 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2372 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2373 >        final IncAction r = new IncAction();
2374 >        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2375 >
2376 >        assertTrue(f.cancel(mayInterruptIfRunning));
2377 >        checkCompletedWithWrappedCancellationException(h);
2378 >        g.complete(v1);
2379 >
2380 >        checkCancelled(f);
2381 >        assertFalse(r.ran());
2382 >        checkCompletedNormally(g, v1);
2383 >        checkCompletedWithWrappedCancellationException(h);
2384 >        }
2385 >    }
2386 >
2387 >    public void testAcceptEither_sourceCancelled2() {
2388 >        for (ExecutionMode m : ExecutionMode.values())
2389 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2390 >        for (Integer v1 : new Integer[] { 1, null }) {
2391 >
2392 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2393 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2394 >        final IncAction r = new IncAction();
2395 >        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2396 >
2397 >        assertTrue(g.cancel(mayInterruptIfRunning));
2398 >        checkCompletedWithWrappedCancellationException(h);
2399 >        f.complete(v1);
2400 >
2401 >        checkCancelled(g);
2402 >        assertFalse(r.ran());
2403 >        checkCompletedNormally(f, v1);
2404 >        checkCompletedWithWrappedCancellationException(h);
2405 >        }
2406 >    }
2407 >
2408 >    public void testAcceptEither_sourceCancelled3() {
2409 >        for (ExecutionMode m : ExecutionMode.values())
2410 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2411 >        for (Integer v1 : new Integer[] { 1, null }) {
2412 >
2413 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2414 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2415 >        final IncAction r = new IncAction();
2416 >
2417 >        assertTrue(g.cancel(mayInterruptIfRunning));
2418 >        f.complete(v1);
2419 >        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2420 >
2421 >        // unspecified behavior
2422 >        Integer v;
2423 >        try {
2424 >            assertEquals(h.join(), null);
2425 >            assertTrue(r.ran());
2426 >            assertEquals(inc(v1), r.value);
2427 >        } catch (CompletionException ok) {
2428 >            checkCompletedWithWrappedCancellationException(h);
2429 >            assertFalse(r.ran());
2430 >        }
2431 >
2432 >        checkCancelled(g);
2433 >        checkCompletedNormally(f, v1);
2434 >        }
2435 >    }
2436 >
2437 >    public void testAcceptEither_sourceCancelled4() {
2438 >        for (ExecutionMode m : ExecutionMode.values())
2439 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2440 >        for (Integer v1 : new Integer[] { 1, null }) {
2441 >
2442 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
2443 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
2444 >        final IncAction r = new IncAction();
2445 >
2446 >        assertTrue(f.cancel(mayInterruptIfRunning));
2447 >        g.complete(v1);
2448 >        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2449 >
2450 >        // unspecified behavior
2451 >        Integer v;
2452 >        try {
2453 >            assertEquals(h.join(), null);
2454 >            assertTrue(r.ran());
2455 >            assertEquals(inc(v1), r.value);
2456 >        } catch (CompletionException ok) {
2457 >            checkCompletedWithWrappedCancellationException(h);
2458 >            assertFalse(r.ran());
2459 >        }
2460 >
2461 >        checkCancelled(f);
2462 >        checkCompletedNormally(g, v1);
2463 >        }
2464      }
2465  
2466      /**
# Line 1894 | Line 2721 | public class CompletableFutureTest exten
2721          CompletableFuture<Void> g = f.thenAcceptAsync(r);
2722          f.complete(one);
2723          checkCompletedNormally(g, null);
2724 <        assertEquals(r.value, 2);
2724 >        assertEquals(r.value, (Integer) 2);
2725      }
2726  
2727      /**
# Line 1932 | Line 2759 | public class CompletableFutureTest exten
2759      }
2760  
2761      /**
1935     * thenCombineAsync result completes normally after normal
1936     * completion of sources
1937     */
1938    public void testThenCombineAsync() {
1939        CompletableFuture<Integer> f, g, h;
1940
1941        f = new CompletableFuture<>();
1942        g = new CompletableFuture<>();
1943        h = f.thenCombineAsync(g, subtract);
1944        f.complete(3);
1945        checkIncomplete(h);
1946        g.complete(1);
1947        checkCompletedNormally(h, 2);
1948
1949        f = new CompletableFuture<>();
1950        g = new CompletableFuture<>();
1951        h = f.thenCombineAsync(g, subtract);
1952        g.complete(1);
1953        checkIncomplete(h);
1954        f.complete(3);
1955        checkCompletedNormally(h, 2);
1956
1957        f = new CompletableFuture<>();
1958        g = new CompletableFuture<>();
1959        g.complete(1);
1960        f.complete(3);
1961        h = f.thenCombineAsync(g, subtract);
1962        checkCompletedNormally(h, 2);
1963    }
1964
1965    /**
1966     * thenCombineAsync result completes exceptionally after exceptional
1967     * completion of either source
1968     */
1969    public void testThenCombineAsync2() {
1970        CompletableFuture<Integer> f, g, h;
1971
1972        f = new CompletableFuture<>();
1973        g = new CompletableFuture<>();
1974        h = f.thenCombineAsync(g, subtract);
1975        f.completeExceptionally(new CFException());
1976        checkIncomplete(h);
1977        g.complete(1);
1978        checkCompletedWithWrappedCFException(h);
1979
1980        f = new CompletableFuture<>();
1981        g = new CompletableFuture<>();
1982        h = f.thenCombineAsync(g, subtract);
1983        g.completeExceptionally(new CFException());
1984        checkIncomplete(h);
1985        f.complete(3);
1986        checkCompletedWithWrappedCFException(h);
1987
1988        f = new CompletableFuture<>();
1989        g = new CompletableFuture<>();
1990        g.completeExceptionally(new CFException());
1991        f.complete(3);
1992        h = f.thenCombineAsync(g, subtract);
1993        checkCompletedWithWrappedCFException(h);
1994    }
1995
1996    /**
1997     * thenCombineAsync result completes exceptionally if action does
1998     */
1999    public void testThenCombineAsync3() {
2000        CompletableFuture<Integer> f = new CompletableFuture<>();
2001        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2002        FailingBiFunction r = new FailingBiFunction();
2003        CompletableFuture<Integer> g = f.thenCombineAsync(f2, r);
2004        f.complete(one);
2005        checkIncomplete(g);
2006        assertFalse(r.ran);
2007        f2.complete(two);
2008        checkCompletedWithWrappedCFException(g);
2009        assertTrue(r.ran);
2010    }
2011
2012    /**
2013     * thenCombineAsync result completes exceptionally if either source cancelled
2014     */
2015    public void testThenCombineAsync4() {
2016        CompletableFuture<Integer> f, g, h;
2017
2018        f = new CompletableFuture<>();
2019        g = new CompletableFuture<>();
2020        h = f.thenCombineAsync(g, subtract);
2021        assertTrue(f.cancel(true));
2022        checkIncomplete(h);
2023        g.complete(1);
2024        checkCompletedWithWrappedCancellationException(h);
2025
2026        f = new CompletableFuture<>();
2027        g = new CompletableFuture<>();
2028        h = f.thenCombineAsync(g, subtract);
2029        assertTrue(g.cancel(true));
2030        checkIncomplete(h);
2031        f.complete(3);
2032        checkCompletedWithWrappedCancellationException(h);
2033
2034        f = new CompletableFuture<>();
2035        g = new CompletableFuture<>();
2036        g.complete(3);
2037        assertTrue(f.cancel(true));
2038        h = f.thenCombineAsync(g, subtract);
2039        checkCompletedWithWrappedCancellationException(h);
2040
2041        f = new CompletableFuture<>();
2042        g = new CompletableFuture<>();
2043        f.complete(3);
2044        assertTrue(g.cancel(true));
2045        h = f.thenCombineAsync(g, subtract);
2046        checkCompletedWithWrappedCancellationException(h);
2047    }
2048
2049    /**
2050     * applyToEitherAsync result completes normally after normal
2051     * completion of sources
2052     */
2053    public void testApplyToEitherAsync() {
2054        CompletableFuture<Integer> f = new CompletableFuture<>();
2055        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2056        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc);
2057        f.complete(one);
2058        checkCompletedNormally(g, two);
2059
2060        f = new CompletableFuture<>();
2061        f.complete(one);
2062        f2 = new CompletableFuture<>();
2063        g = f.applyToEitherAsync(f2, inc);
2064        checkCompletedNormally(g, two);
2065    }
2066
2067    /**
2068     * applyToEitherAsync result completes exceptionally after exceptional
2069     * completion of source
2070     */
2071    public void testApplyToEitherAsync2() {
2072        CompletableFuture<Integer> f = new CompletableFuture<>();
2073        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2074        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc);
2075        f.completeExceptionally(new CFException());
2076        checkCompletedWithWrappedCFException(g);
2077
2078        f = new CompletableFuture<>();
2079        f2 = new CompletableFuture<>();
2080        f2.completeExceptionally(new CFException());
2081        g = f.applyToEitherAsync(f2, inc);
2082        f.complete(one);
2083        checkCompletedWithWrappedCFException(g);
2084    }
2085
2086    /**
2087     * applyToEitherAsync result completes exceptionally if action does
2088     */
2089    public void testApplyToEitherAsync3() {
2090        CompletableFuture<Integer> f = new CompletableFuture<>();
2091        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2092        FailingFunction r = new FailingFunction();
2093        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, r);
2094        f.complete(one);
2095        checkCompletedWithWrappedCFException(g);
2096    }
2097
2098    /**
2099     * applyToEitherAsync result completes exceptionally if either source cancelled
2100     */
2101    public void testApplyToEitherAsync4() {
2102        CompletableFuture<Integer> f = new CompletableFuture<>();
2103        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2104        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc);
2105        assertTrue(f.cancel(true));
2106        checkCompletedWithWrappedCancellationException(g);
2107
2108        f = new CompletableFuture<>();
2109        f2 = new CompletableFuture<>();
2110        assertTrue(f2.cancel(true));
2111        g = f.applyToEitherAsync(f2, inc);
2112        checkCompletedWithWrappedCancellationException(g);
2113    }
2114
2115    /**
2116     * acceptEitherAsync result completes normally after normal
2117     * completion of sources
2118     */
2119    public void testAcceptEitherAsync() {
2120        CompletableFuture<Integer> f = new CompletableFuture<>();
2121        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2122        IncAction r = new IncAction();
2123        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
2124        f.complete(one);
2125        checkCompletedNormally(g, null);
2126        assertEquals(r.value, 2);
2127
2128        r = new IncAction();
2129        f = new CompletableFuture<>();
2130        f.complete(one);
2131        f2 = new CompletableFuture<>();
2132        g = f.acceptEitherAsync(f2, r);
2133        checkCompletedNormally(g, null);
2134        assertEquals(r.value, 2);
2135    }
2136
2137    /**
2138     * acceptEitherAsync result completes exceptionally after exceptional
2139     * completion of source
2140     */
2141    public void testAcceptEitherAsync2() {
2142        CompletableFuture<Integer> f = new CompletableFuture<>();
2143        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2144        IncAction r = new IncAction();
2145        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
2146        f.completeExceptionally(new CFException());
2147        checkCompletedWithWrappedCFException(g);
2148
2149        r = new IncAction();
2150        f = new CompletableFuture<>();
2151        f2 = new CompletableFuture<>();
2152        f2.completeExceptionally(new CFException());
2153        g = f.acceptEitherAsync(f2, r);
2154        f.complete(one);
2155        checkCompletedWithWrappedCFException(g);
2156    }
2157
2158    /**
2159     * acceptEitherAsync result completes exceptionally if action does
2160     */
2161    public void testAcceptEitherAsync3() {
2162        CompletableFuture<Integer> f = new CompletableFuture<>();
2163        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2164        FailingConsumer r = new FailingConsumer();
2165        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
2166        f.complete(one);
2167        checkCompletedWithWrappedCFException(g);
2168    }
2169
2170    /**
2171     * acceptEitherAsync result completes exceptionally if either
2172     * source cancelled
2173     */
2174    public void testAcceptEitherAsync4() {
2175        CompletableFuture<Integer> f = new CompletableFuture<>();
2176        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2177        IncAction r = new IncAction();
2178        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
2179        assertTrue(f.cancel(true));
2180        checkCompletedWithWrappedCancellationException(g);
2181
2182        r = new IncAction();
2183        f = new CompletableFuture<>();
2184        f2 = new CompletableFuture<>();
2185        assertTrue(f2.cancel(true));
2186        g = f.acceptEitherAsync(f2, r);
2187        checkCompletedWithWrappedCancellationException(g);
2188    }
2189
2190    /**
2762       * runAfterEitherAsync result completes normally after normal
2763       * completion of sources
2764       */
# Line 2448 | Line 3019 | public class CompletableFutureTest exten
3019          CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
3020          f.complete(one);
3021          checkCompletedNormally(g, null);
3022 <        assertEquals(r.value, 2);
3022 >        assertEquals(r.value, (Integer) 2);
3023      }
3024  
3025      /**
# Line 2485 | Line 3056 | public class CompletableFutureTest exten
3056          checkCompletedWithWrappedCancellationException(g);
3057      }
3058  
2488    /**
2489     * thenCombineAsync result completes normally after normal
2490     * completion of sources
2491     */
2492    public void testThenCombineAsyncE() {
2493        CompletableFuture<Integer> f, g, h;
2494        ThreadExecutor e = new ThreadExecutor();
2495        int count = 0;
2496
2497        f = new CompletableFuture<>();
2498        g = new CompletableFuture<>();
2499        h = f.thenCombineAsync(g, subtract, e);
2500        f.complete(3);
2501        checkIncomplete(h);
2502        g.complete(1);
2503        checkCompletedNormally(h, 2);
2504        assertEquals(++count, e.count.get());
2505
2506        f = new CompletableFuture<>();
2507        g = new CompletableFuture<>();
2508        h = f.thenCombineAsync(g, subtract, e);
2509        g.complete(1);
2510        checkIncomplete(h);
2511        f.complete(3);
2512        checkCompletedNormally(h, 2);
2513        assertEquals(++count, e.count.get());
2514
2515        f = new CompletableFuture<>();
2516        g = new CompletableFuture<>();
2517        g.complete(1);
2518        f.complete(3);
2519        h = f.thenCombineAsync(g, subtract, e);
2520        checkCompletedNormally(h, 2);
2521        assertEquals(++count, e.count.get());
2522    }
2523
2524    /**
2525     * thenCombineAsync result completes exceptionally after exceptional
2526     * completion of either source
2527     */
2528    public void testThenCombineAsync2E() {
2529        CompletableFuture<Integer> f, g, h;
2530        ThreadExecutor e = new ThreadExecutor();
2531        int count = 0;
2532
2533        f = new CompletableFuture<>();
2534        g = new CompletableFuture<>();
2535        h = f.thenCombineAsync(g, subtract, e);
2536        f.completeExceptionally(new CFException());
2537        checkIncomplete(h);
2538        g.complete(1);
2539        checkCompletedWithWrappedCFException(h);
2540
2541        f = new CompletableFuture<>();
2542        g = new CompletableFuture<>();
2543        h = f.thenCombineAsync(g, subtract, e);
2544        g.completeExceptionally(new CFException());
2545        checkIncomplete(h);
2546        f.complete(3);
2547        checkCompletedWithWrappedCFException(h);
2548
2549        f = new CompletableFuture<>();
2550        g = new CompletableFuture<>();
2551        g.completeExceptionally(new CFException());
2552        h = f.thenCombineAsync(g, subtract, e);
2553        checkIncomplete(h);
2554        f.complete(3);
2555        checkCompletedWithWrappedCFException(h);
2556
2557        assertEquals(0, e.count.get());
2558    }
2559
2560    /**
2561     * thenCombineAsync result completes exceptionally if action does
2562     */
2563    public void testThenCombineAsync3E() {
2564        CompletableFuture<Integer> f = new CompletableFuture<>();
2565        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2566        FailingBiFunction r = new FailingBiFunction();
2567        CompletableFuture<Integer> g = f.thenCombineAsync(f2, r, new ThreadExecutor());
2568        f.complete(one);
2569        checkIncomplete(g);
2570        assertFalse(r.ran);
2571        f2.complete(two);
2572        checkCompletedWithWrappedCFException(g);
2573        assertTrue(r.ran);
2574    }
2575
2576    /**
2577     * thenCombineAsync result completes exceptionally if either source cancelled
2578     */
2579    public void testThenCombineAsync4E() {
2580        CompletableFuture<Integer> f, g, h;
2581        ThreadExecutor e = new ThreadExecutor();
2582
2583        f = new CompletableFuture<>();
2584        g = new CompletableFuture<>();
2585        h = f.thenCombineAsync(g, subtract, e);
2586        assertTrue(f.cancel(true));
2587        checkIncomplete(h);
2588        g.complete(1);
2589        checkCompletedWithWrappedCancellationException(h);
2590
2591        f = new CompletableFuture<>();
2592        g = new CompletableFuture<>();
2593        h = f.thenCombineAsync(g, subtract, e);
2594        assertTrue(g.cancel(true));
2595        checkIncomplete(h);
2596        f.complete(3);
2597        checkCompletedWithWrappedCancellationException(h);
2598
2599        f = new CompletableFuture<>();
2600        g = new CompletableFuture<>();
2601        assertTrue(g.cancel(true));
2602        h = f.thenCombineAsync(g, subtract, e);
2603        checkIncomplete(h);
2604        f.complete(3);
2605        checkCompletedWithWrappedCancellationException(h);
2606
2607        f = new CompletableFuture<>();
2608        g = new CompletableFuture<>();
2609        assertTrue(f.cancel(true));
2610        assertTrue(g.cancel(true));
2611        h = f.thenCombineAsync(g, subtract, e);
2612        checkCompletedWithWrappedCancellationException(h);
2613
2614        assertEquals(0, e.count.get());
2615    }
2616
2617    /**
2618     * applyToEitherAsync result completes normally after normal
2619     * completion of sources
2620     */
2621    public void testApplyToEitherAsyncE() {
2622        CompletableFuture<Integer> f = new CompletableFuture<>();
2623        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2624        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2625        f.complete(one);
2626        checkCompletedNormally(g, two);
2627
2628        f = new CompletableFuture<>();
2629        f.complete(one);
2630        f2 = new CompletableFuture<>();
2631        g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2632        checkCompletedNormally(g, two);
2633    }
2634
2635    /**
2636     * applyToEitherAsync result completes exceptionally after exceptional
2637     * completion of source
2638     */
2639    public void testApplyToEitherAsync2E() {
2640        CompletableFuture<Integer> f = new CompletableFuture<>();
2641        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2642        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2643        f.completeExceptionally(new CFException());
2644        checkCompletedWithWrappedCFException(g);
2645
2646        f = new CompletableFuture<>();
2647        f2 = new CompletableFuture<>();
2648        f2.completeExceptionally(new CFException());
2649        g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2650        f.complete(one);
2651        checkCompletedWithWrappedCFException(g);
2652    }
2653
2654    /**
2655     * applyToEitherAsync result completes exceptionally if action does
2656     */
2657    public void testApplyToEitherAsync3E() {
2658        CompletableFuture<Integer> f = new CompletableFuture<>();
2659        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2660        FailingFunction r = new FailingFunction();
2661        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, r, new ThreadExecutor());
2662        f.complete(one);
2663        checkCompletedWithWrappedCFException(g);
2664    }
2665
2666    /**
2667     * applyToEitherAsync result completes exceptionally if either source cancelled
2668     */
2669    public void testApplyToEitherAsync4E() {
2670        CompletableFuture<Integer> f = new CompletableFuture<>();
2671        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2672        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2673        assertTrue(f.cancel(true));
2674        checkCompletedWithWrappedCancellationException(g);
2675
2676        f = new CompletableFuture<>();
2677        f2 = new CompletableFuture<>();
2678        assertTrue(f2.cancel(true));
2679        g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2680        checkCompletedWithWrappedCancellationException(g);
2681    }
2682
2683    /**
2684     * acceptEitherAsync result completes normally after normal
2685     * completion of sources
2686     */
2687    public void testAcceptEitherAsyncE() {
2688        CompletableFuture<Integer> f = new CompletableFuture<>();
2689        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2690        IncAction r = new IncAction();
2691        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2692        f.complete(one);
2693        checkCompletedNormally(g, null);
2694        assertEquals(r.value, 2);
2695
2696        r = new IncAction();
2697        f = new CompletableFuture<>();
2698        f.complete(one);
2699        f2 = new CompletableFuture<>();
2700        g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2701        checkCompletedNormally(g, null);
2702        assertEquals(r.value, 2);
2703    }
2704
2705    /**
2706     * acceptEitherAsync result completes exceptionally after exceptional
2707     * completion of source
2708     */
2709    public void testAcceptEitherAsync2E() {
2710        CompletableFuture<Integer> f = new CompletableFuture<>();
2711        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2712        IncAction r = new IncAction();
2713        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2714        f.completeExceptionally(new CFException());
2715        checkCompletedWithWrappedCFException(g);
2716
2717        r = new IncAction();
2718        f = new CompletableFuture<>();
2719        f2 = new CompletableFuture<>();
2720        f2.completeExceptionally(new CFException());
2721        g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2722        f.complete(one);
2723        checkCompletedWithWrappedCFException(g);
2724    }
2725
2726    /**
2727     * acceptEitherAsync result completes exceptionally if action does
2728     */
2729    public void testAcceptEitherAsync3E() {
2730        CompletableFuture<Integer> f = new CompletableFuture<>();
2731        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2732        FailingConsumer r = new FailingConsumer();
2733        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2734        f.complete(one);
2735        checkCompletedWithWrappedCFException(g);
2736    }
2737
2738    /**
2739     * acceptEitherAsync result completes exceptionally if either
2740     * source cancelled
2741     */
2742    public void testAcceptEitherAsync4E() {
2743        CompletableFuture<Integer> f = new CompletableFuture<>();
2744        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2745        IncAction r = new IncAction();
2746        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2747        assertTrue(f.cancel(true));
2748        checkCompletedWithWrappedCancellationException(g);
2749
2750        r = new IncAction();
2751        f = new CompletableFuture<>();
2752        f2 = new CompletableFuture<>();
2753        assertTrue(f2.cancel(true));
2754        g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2755        checkCompletedWithWrappedCancellationException(g);
2756    }
2757
3059      /**
3060       * runAfterEitherAsync result completes normally after normal
3061       * completion of sources

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines