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.6 by jsr166, Fri Mar 22 16:10:19 2013 UTC vs.
Revision 1.21 by jsr166, Mon Apr 8 16:58:17 2013 UTC

# Line 53 | Line 53 | public class CompletableFutureTest exten
53          catch (Throwable fail) { threadUnexpectedException(fail); }
54      }
55  
56 <    void checkCompletedNormally(CompletableFuture<?> f, Object value) {
56 >    <T> void checkCompletedNormally(CompletableFuture<T> f, T value) {
57 >        try {
58 >            assertEquals(value, f.get(LONG_DELAY_MS, MILLISECONDS));
59 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
60          try {
61              assertEquals(value, f.join());
62          } catch (Throwable fail) { threadUnexpectedException(fail); }
# Line 63 | Line 66 | public class CompletableFutureTest exten
66          try {
67              assertEquals(value, f.get());
68          } catch (Throwable fail) { threadUnexpectedException(fail); }
66        try {
67            assertEquals(value, f.get(0L, SECONDS));
68        } catch (Throwable fail) { threadUnexpectedException(fail); }
69          assertTrue(f.isDone());
70          assertFalse(f.isCancelled());
71          assertTrue(f.toString().contains("[Completed normally]"));
# Line 73 | Line 73 | public class CompletableFutureTest exten
73  
74      void checkCompletedWithWrappedCFException(CompletableFuture<?> f) {
75          try {
76 +            f.get(LONG_DELAY_MS, MILLISECONDS);
77 +            shouldThrow();
78 +        } catch (ExecutionException success) {
79 +            assertTrue(success.getCause() instanceof CFException);
80 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
81 +        try {
82              f.join();
83              shouldThrow();
84 <        } catch (Throwable ex) {
85 <            assertTrue(ex instanceof CompletionException &&
80 <                       ((CompletionException)ex).getCause() instanceof CFException);
84 >        } catch (CompletionException success) {
85 >            assertTrue(success.getCause() instanceof CFException);
86          }
87          try {
88              f.getNow(null);
89              shouldThrow();
90 <        } catch (Throwable ex) {
91 <            assertTrue(ex instanceof CompletionException &&
87 <                       ((CompletionException)ex).getCause() instanceof CFException);
90 >        } catch (CompletionException success) {
91 >            assertTrue(success.getCause() instanceof CFException);
92          }
93          try {
94              f.get();
95              shouldThrow();
96 <        } catch (Throwable ex) {
97 <            assertTrue(ex instanceof ExecutionException &&
98 <                       ((ExecutionException)ex).getCause() instanceof CFException);
95 <        }
96 <        try {
97 <            f.get(0L, SECONDS);
98 <            shouldThrow();
99 <        } catch (Throwable ex) {
100 <            assertTrue(ex instanceof ExecutionException &&
101 <                       ((ExecutionException)ex).getCause() instanceof CFException);
102 <        }
96 >        } catch (ExecutionException success) {
97 >            assertTrue(success.getCause() instanceof CFException);
98 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
99          assertTrue(f.isDone());
100          assertFalse(f.isCancelled());
101 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
102      }
103  
104      void checkCancelled(CompletableFuture<?> f) {
105          try {
106 +            f.get(LONG_DELAY_MS, MILLISECONDS);
107 +            shouldThrow();
108 +        } catch (CancellationException success) {
109 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
110 +        try {
111              f.join();
112              shouldThrow();
113 <        } catch (Throwable ex) {
112 <            assertTrue(ex instanceof CancellationException);
113 <        }
113 >        } catch (CancellationException success) {}
114          try {
115              f.getNow(null);
116              shouldThrow();
117 <        } catch (Throwable ex) {
118 <            assertTrue(ex instanceof CancellationException);
119 <        }
117 >        } catch (CancellationException success) {}
118          try {
119              f.get();
120              shouldThrow();
121 <        } catch (Throwable ex) {
122 <            assertTrue(ex instanceof CancellationException);
125 <        }
126 <        try {
127 <            f.get(0L, SECONDS);
128 <            shouldThrow();
129 <        } catch (Throwable ex) {
130 <            assertTrue(ex instanceof CancellationException);
131 <        }
121 >        } catch (CancellationException success) {
122 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
123          assertTrue(f.isDone());
124          assertTrue(f.isCancelled());
125 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
126      }
127  
128      void checkCompletedWithWrappedCancellationException(CompletableFuture<?> f) {
129          try {
130 +            f.get(LONG_DELAY_MS, MILLISECONDS);
131 +            shouldThrow();
132 +        } catch (ExecutionException success) {
133 +            assertTrue(success.getCause() instanceof CancellationException);
134 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
135 +        try {
136              f.join();
137              shouldThrow();
138 <        } catch (Throwable ex) {
139 <            assertTrue(ex instanceof CompletionException &&
142 <                       ((CompletionException)ex).getCause() instanceof CancellationException);
138 >        } catch (CompletionException success) {
139 >            assertTrue(success.getCause() instanceof CancellationException);
140          }
141          try {
142              f.getNow(null);
143              shouldThrow();
144 <        } catch (Throwable ex) {
145 <            assertTrue(ex instanceof CompletionException &&
149 <                       ((CompletionException)ex).getCause() instanceof CancellationException);
144 >        } catch (CompletionException success) {
145 >            assertTrue(success.getCause() instanceof CancellationException);
146          }
147          try {
148              f.get();
149              shouldThrow();
150 <        } catch (Throwable ex) {
151 <            assertTrue(ex instanceof ExecutionException &&
152 <                       ((ExecutionException)ex).getCause() instanceof CancellationException);
157 <        }
158 <        try {
159 <            f.get(0L, SECONDS);
160 <            shouldThrow();
161 <        } catch (Throwable ex) {
162 <            assertTrue(ex instanceof ExecutionException &&
163 <                       ((ExecutionException)ex).getCause() instanceof CancellationException);
164 <        }
150 >        } catch (ExecutionException success) {
151 >            assertTrue(success.getCause() instanceof CancellationException);
152 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
153          assertTrue(f.isDone());
154          assertFalse(f.isCancelled());
155 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
156      }
157  
158      /**
# Line 285 | Line 274 | public class CompletableFutureTest exten
274          assertTrue(f.toString().contains("[Completed exceptionally]"));
275      }
276  
277 +    /**
278 +     * completedFuture returns a completed CompletableFuture with given value
279 +     */
280 +    public void testCompletedFuture() {
281 +        CompletableFuture<String> f = CompletableFuture.completedFuture("test");
282 +        checkCompletedNormally(f, "test");
283 +    }
284 +
285 +    // Choose non-commutative actions for better coverage
286 +
287      static final Supplier<Integer> supplyOne =
288          () -> Integer.valueOf(1);
289      static final Function<Integer, Integer> inc =
290          (Integer x) -> Integer.valueOf(x.intValue() + 1);
291 <    static final BiFunction<Integer, Integer, Integer> add =
292 <        (Integer x, Integer y) -> Integer.valueOf(x.intValue() + y.intValue());
291 >    static final BiFunction<Integer, Integer, Integer> subtract =
292 >        (Integer x, Integer y) -> Integer.valueOf(x.intValue() - y.intValue());
293      static final class IncAction implements Consumer<Integer> {
294          int value;
295          public void accept(Integer x) { value = x.intValue() + 1; }
# Line 331 | Line 330 | public class CompletableFutureTest exten
330          public void run() { ran = true; throw new CFException(); }
331      }
332  
333 <    static final class CompletableFutureInc implements Function<Integer, CompletableFuture<Integer>> {
333 >    static final class CompletableFutureInc
334 >        implements Function<Integer, CompletableFuture<Integer>> {
335 >        boolean ran;
336          public CompletableFuture<Integer> apply(Integer x) {
337 +            ran = true;
338              CompletableFuture<Integer> f = new CompletableFuture<Integer>();
339              f.complete(Integer.valueOf(x.intValue() + 1));
340              return f;
341          }
342      }
343  
344 <    static final class FailingCompletableFutureFunction implements Function<Integer, CompletableFuture<Integer>> {
344 >    static final class FailingCompletableFutureFunction
345 >        implements Function<Integer, CompletableFuture<Integer>> {
346          boolean ran;
347          public CompletableFuture<Integer> apply(Integer x) {
348              ran = true; throw new CFException();
# Line 348 | Line 351 | public class CompletableFutureTest exten
351  
352      // Used for explicit executor tests
353      static final class ThreadExecutor implements Executor {
354 +        AtomicInteger count = new AtomicInteger(0);
355 +
356          public void execute(Runnable r) {
357 +            count.getAndIncrement();
358              new Thread(r).start();
359          }
360      }
# Line 358 | Line 364 | public class CompletableFutureTest exten
364      }
365  
366      static final class IntegerHandler implements BiFunction<Integer, Throwable, Integer> {
367 +        boolean ran;
368          public Integer apply(Integer x, Throwable t) {
369 +            ran = true;
370              return (t == null) ? two : three;
371          }
372      }
# Line 387 | Line 395 | public class CompletableFutureTest exten
395       * normal or exceptional completion of source
396       */
397      public void testHandle() {
398 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
399 <        IntegerHandler r = new IntegerHandler();
400 <        CompletableFuture<Integer> g = f.handle(r);
398 >        CompletableFuture<Integer> f, g;
399 >        IntegerHandler r;
400 >
401 >        f = new CompletableFuture<Integer>();
402          f.completeExceptionally(new CFException());
403 +        g = f.handle(r = new IntegerHandler());
404 +        assertTrue(r.ran);
405          checkCompletedNormally(g, three);
406  
407          f = new CompletableFuture<Integer>();
408 <        r = new IntegerHandler();
409 <        g = f.handle(r);
408 >        g = f.handle(r = new IntegerHandler());
409 >        assertFalse(r.ran);
410 >        f.completeExceptionally(new CFException());
411 >        checkCompletedNormally(g, three);
412 >        assertTrue(r.ran);
413 >
414 >        f = new CompletableFuture<Integer>();
415 >        f.complete(one);
416 >        g = f.handle(r = new IntegerHandler());
417 >        assertTrue(r.ran);
418 >        checkCompletedNormally(g, two);
419 >
420 >        f = new CompletableFuture<Integer>();
421 >        g = f.handle(r = new IntegerHandler());
422 >        assertFalse(r.ran);
423          f.complete(one);
424 +        assertTrue(r.ran);
425          checkCompletedNormally(g, two);
426      }
427  
# Line 408 | Line 433 | public class CompletableFutureTest exten
433          CompletableFuture<Void> f = CompletableFuture.runAsync(r);
434          assertNull(f.join());
435          assertTrue(r.ran);
436 +        checkCompletedNormally(f, null);
437      }
438  
439      /**
# Line 415 | Line 441 | public class CompletableFutureTest exten
441       */
442      public void testRunAsync2() {
443          Noop r = new Noop();
444 <        CompletableFuture<Void> f = CompletableFuture.runAsync(r, new ThreadExecutor());
444 >        ThreadExecutor exec = new ThreadExecutor();
445 >        CompletableFuture<Void> f = CompletableFuture.runAsync(r, exec);
446          assertNull(f.join());
447          assertTrue(r.ran);
448 +        checkCompletedNormally(f, null);
449 +        assertEquals(1, exec.count.get());
450      }
451  
452      /**
# Line 434 | Line 463 | public class CompletableFutureTest exten
463       * supplyAsync completes with result of supplier
464       */
465      public void testSupplyAsync() {
466 <        CompletableFuture<Integer> f = CompletableFuture.supplyAsync(supplyOne);
466 >        CompletableFuture<Integer> f;
467 >        f = CompletableFuture.supplyAsync(supplyOne);
468          assertEquals(f.join(), one);
469 +        checkCompletedNormally(f, one);
470      }
471  
472      /**
473       * supplyAsync with executor completes with result of supplier
474       */
475      public void testSupplyAsync2() {
476 <        CompletableFuture<Integer> f = CompletableFuture.supplyAsync(supplyOne, new ThreadExecutor());
476 >        CompletableFuture<Integer> f;
477 >        f = CompletableFuture.supplyAsync(supplyOne, new ThreadExecutor());
478          assertEquals(f.join(), one);
479 +        checkCompletedNormally(f, one);
480      }
481  
482      /**
# Line 456 | Line 489 | public class CompletableFutureTest exten
489          assertTrue(r.ran);
490      }
491  
492 <    // seq conmpletion methods
492 >    // seq completion methods
493  
494      /**
495       * thenRun result completes normally after normal completion of source
# Line 599 | Line 632 | public class CompletableFutureTest exten
632  
633  
634      /**
635 <     * thenCombine result completes normally after normal completion of sources
635 >     * thenCombine result completes normally after normal completion
636 >     * of sources
637       */
638      public void testThenCombine() {
639 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
606 <        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
607 <        CompletableFuture<Integer> g = f.thenCombine(f2, add);
608 <        f.complete(one);
609 <        checkIncomplete(g);
610 <        f2.complete(two);
611 <        checkCompletedNormally(g, three);
639 >        CompletableFuture<Integer> f, g, h;
640  
641          f = new CompletableFuture<Integer>();
642 <        f.complete(one);
643 <        f2 = new CompletableFuture<Integer>();
644 <        g = f.thenCombine(f2, add);
645 <        checkIncomplete(g);
646 <        f2.complete(two);
647 <        checkCompletedNormally(g, three);
642 >        g = new CompletableFuture<Integer>();
643 >        h = f.thenCombine(g, subtract);
644 >        f.complete(3);
645 >        checkIncomplete(h);
646 >        g.complete(1);
647 >        checkCompletedNormally(h, 2);
648 >
649 >        f = new CompletableFuture<Integer>();
650 >        g = new CompletableFuture<Integer>();
651 >        h = f.thenCombine(g, subtract);
652 >        g.complete(1);
653 >        checkIncomplete(h);
654 >        f.complete(3);
655 >        checkCompletedNormally(h, 2);
656 >
657 >        f = new CompletableFuture<Integer>();
658 >        g = new CompletableFuture<Integer>();
659 >        g.complete(1);
660 >        f.complete(3);
661 >        h = f.thenCombine(g, subtract);
662 >        checkCompletedNormally(h, 2);
663      }
664  
665      /**
# Line 624 | Line 667 | public class CompletableFutureTest exten
667       * completion of either source
668       */
669      public void testThenCombine2() {
670 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
671 <        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
672 <        CompletableFuture<Integer> g = f.thenCombine(f2, add);
670 >        CompletableFuture<Integer> f, g, h;
671 >
672 >        f = new CompletableFuture<Integer>();
673 >        g = new CompletableFuture<Integer>();
674 >        h = f.thenCombine(g, subtract);
675          f.completeExceptionally(new CFException());
676 <        f2.complete(two);
677 <        checkCompletedWithWrappedCFException(g);
676 >        checkIncomplete(h);
677 >        g.complete(1);
678 >        checkCompletedWithWrappedCFException(h);
679  
680          f = new CompletableFuture<Integer>();
681 <        f.complete(one);
682 <        f2 = new CompletableFuture<Integer>();
683 <        g = f.thenCombine(f2, add);
684 <        f2.completeExceptionally(new CFException());
685 <        checkCompletedWithWrappedCFException(g);
681 >        g = new CompletableFuture<Integer>();
682 >        h = f.thenCombine(g, subtract);
683 >        g.completeExceptionally(new CFException());
684 >        checkIncomplete(h);
685 >        f.complete(3);
686 >        checkCompletedWithWrappedCFException(h);
687 >
688 >        f = new CompletableFuture<Integer>();
689 >        g = new CompletableFuture<Integer>();
690 >        f.complete(3);
691 >        g.completeExceptionally(new CFException());
692 >        h = f.thenCombine(g, subtract);
693 >        checkCompletedWithWrappedCFException(h);
694 >
695 >        f = new CompletableFuture<Integer>();
696 >        g = new CompletableFuture<Integer>();
697 >        f.completeExceptionally(new CFException());
698 >        g.complete(3);
699 >        h = f.thenCombine(g, subtract);
700 >        checkCompletedWithWrappedCFException(h);
701      }
702  
703      /**
# Line 649 | Line 710 | public class CompletableFutureTest exten
710          CompletableFuture<Integer> g = f.thenCombine(f2, r);
711          f.complete(one);
712          checkIncomplete(g);
713 +        assertFalse(r.ran);
714          f2.complete(two);
715          checkCompletedWithWrappedCFException(g);
716 +        assertTrue(r.ran);
717      }
718  
719      /**
720       * thenCombine result completes exceptionally if either source cancelled
721       */
722      public void testThenCombine4() {
723 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
724 <        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
725 <        CompletableFuture<Integer> g = f.thenCombine(f2, add);
723 >        CompletableFuture<Integer> f, g, h;
724 >
725 >        f = new CompletableFuture<Integer>();
726 >        g = new CompletableFuture<Integer>();
727 >        h = f.thenCombine(g, subtract);
728          assertTrue(f.cancel(true));
729 <        f2.complete(two);
730 <        checkCompletedWithWrappedCancellationException(g);
729 >        checkIncomplete(h);
730 >        g.complete(1);
731 >        checkCompletedWithWrappedCancellationException(h);
732 >
733          f = new CompletableFuture<Integer>();
734 <        f2 = new CompletableFuture<Integer>();
735 <        g = f.thenCombine(f2, add);
736 <        f.complete(one);
737 <        assertTrue(f2.cancel(true));
738 <        checkCompletedWithWrappedCancellationException(g);
734 >        g = new CompletableFuture<Integer>();
735 >        h = f.thenCombine(g, subtract);
736 >        assertTrue(g.cancel(true));
737 >        checkIncomplete(h);
738 >        f.complete(3);
739 >        checkCompletedWithWrappedCancellationException(h);
740 >
741 >        f = new CompletableFuture<Integer>();
742 >        g = new CompletableFuture<Integer>();
743 >        assertTrue(f.cancel(true));
744 >        assertTrue(g.cancel(true));
745 >        h = f.thenCombine(g, subtract);
746 >        checkCompletedWithWrappedCancellationException(h);
747      }
748  
749      /**
# Line 1052 | Line 1127 | public class CompletableFutureTest exten
1127       * thenCompose result completes normally after normal completion of source
1128       */
1129      public void testThenCompose() {
1130 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1131 <        CompletableFutureInc r = new CompletableFutureInc();
1132 <        CompletableFuture<Integer> g = f.thenCompose(r);
1130 >        CompletableFuture<Integer> f, g;
1131 >        CompletableFutureInc r;
1132 >
1133 >        f = new CompletableFuture<Integer>();
1134 >        g = f.thenCompose(r = new CompletableFutureInc());
1135 >        f.complete(one);
1136 >        checkCompletedNormally(g, two);
1137 >        assertTrue(r.ran);
1138 >
1139 >        f = new CompletableFuture<Integer>();
1140          f.complete(one);
1141 +        g = f.thenCompose(r = new CompletableFutureInc());
1142          checkCompletedNormally(g, two);
1143 +        assertTrue(r.ran);
1144      }
1145  
1146      /**
# Line 1064 | Line 1148 | public class CompletableFutureTest exten
1148       * completion of source
1149       */
1150      public void testThenCompose2() {
1151 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1152 <        CompletableFutureInc r = new CompletableFutureInc();
1153 <        CompletableFuture<Integer> g = f.thenCompose(r);
1151 >        CompletableFuture<Integer> f, g;
1152 >        CompletableFutureInc r;
1153 >
1154 >        f = new CompletableFuture<Integer>();
1155 >        g = f.thenCompose(r = new CompletableFutureInc());
1156          f.completeExceptionally(new CFException());
1157          checkCompletedWithWrappedCFException(g);
1158 +
1159 +        f = new CompletableFuture<Integer>();
1160 +        f.completeExceptionally(new CFException());
1161 +        g = f.thenCompose(r = new CompletableFutureInc());
1162 +        checkCompletedWithWrappedCFException(g);
1163      }
1164  
1165      /**
1166       * thenCompose result completes exceptionally if action does
1167       */
1168      public void testThenCompose3() {
1169 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1170 <        FailingCompletableFutureFunction r = new FailingCompletableFutureFunction();
1171 <        CompletableFuture<Integer> g = f.thenCompose(r);
1169 >        CompletableFuture<Integer> f, g;
1170 >        FailingCompletableFutureFunction r;
1171 >
1172 >        f = new CompletableFuture<Integer>();
1173 >        g = f.thenCompose(r = new FailingCompletableFutureFunction());
1174 >        f.complete(one);
1175 >        checkCompletedWithWrappedCFException(g);
1176 >
1177 >        f = new CompletableFuture<Integer>();
1178          f.complete(one);
1179 +        g = f.thenCompose(r = new FailingCompletableFutureFunction());
1180          checkCompletedWithWrappedCFException(g);
1181      }
1182  
# Line 1086 | Line 1184 | public class CompletableFutureTest exten
1184       * thenCompose result completes exceptionally if source cancelled
1185       */
1186      public void testThenCompose4() {
1187 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1188 <        CompletableFutureInc r = new CompletableFutureInc();
1189 <        CompletableFuture<Integer> g = f.thenCompose(r);
1187 >        CompletableFuture<Integer> f, g;
1188 >        CompletableFutureInc r;
1189 >
1190 >        f = new CompletableFuture<Integer>();
1191 >        g = f.thenCompose(r = new CompletableFutureInc());
1192 >        assertTrue(f.cancel(true));
1193 >        checkCompletedWithWrappedCancellationException(g);
1194 >
1195 >        f = new CompletableFuture<Integer>();
1196          assertTrue(f.cancel(true));
1197 +        g = f.thenCompose(r = new CompletableFutureInc());
1198          checkCompletedWithWrappedCancellationException(g);
1199      }
1200  
# Line 1241 | Line 1346 | public class CompletableFutureTest exten
1346          assertTrue(f.cancel(true));
1347          checkCompletedWithWrappedCancellationException(g);
1348      }
1349 +
1350      /**
1351       * thenCombineAsync result completes normally after normal
1352       * completion of sources
1353       */
1354      public void testThenCombineAsync() {
1355 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1356 <        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1357 <        CompletableFuture<Integer> g = f.thenCombineAsync(f2, add);
1358 <        f.complete(one);
1359 <        checkIncomplete(g);
1360 <        f2.complete(two);
1361 <        checkCompletedNormally(g, three);
1355 >        CompletableFuture<Integer> f, g, h;
1356 >
1357 >        f = new CompletableFuture<Integer>();
1358 >        g = new CompletableFuture<Integer>();
1359 >        h = f.thenCombineAsync(g, subtract);
1360 >        f.complete(3);
1361 >        checkIncomplete(h);
1362 >        g.complete(1);
1363 >        checkCompletedNormally(h, 2);
1364 >
1365 >        f = new CompletableFuture<Integer>();
1366 >        g = new CompletableFuture<Integer>();
1367 >        h = f.thenCombineAsync(g, subtract);
1368 >        g.complete(1);
1369 >        checkIncomplete(h);
1370 >        f.complete(3);
1371 >        checkCompletedNormally(h, 2);
1372 >
1373 >        f = new CompletableFuture<Integer>();
1374 >        g = new CompletableFuture<Integer>();
1375 >        g.complete(1);
1376 >        f.complete(3);
1377 >        h = f.thenCombineAsync(g, subtract);
1378 >        checkCompletedNormally(h, 2);
1379      }
1380  
1381      /**
1382       * thenCombineAsync result completes exceptionally after exceptional
1383 <     * completion of source
1383 >     * completion of either source
1384       */
1385      public void testThenCombineAsync2() {
1386 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1387 <        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1388 <        CompletableFuture<Integer> g = f.thenCombineAsync(f2, add);
1386 >        CompletableFuture<Integer> f, g, h;
1387 >
1388 >        f = new CompletableFuture<Integer>();
1389 >        g = new CompletableFuture<Integer>();
1390 >        h = f.thenCombineAsync(g, subtract);
1391          f.completeExceptionally(new CFException());
1392 <        f2.complete(two);
1393 <        checkCompletedWithWrappedCFException(g);
1392 >        checkIncomplete(h);
1393 >        g.complete(1);
1394 >        checkCompletedWithWrappedCFException(h);
1395  
1396          f = new CompletableFuture<Integer>();
1397 <        f2 = new CompletableFuture<Integer>();
1398 <        g = f.thenCombineAsync(f2, add);
1399 <        f.complete(one);
1400 <        f2.completeExceptionally(new CFException());
1401 <        checkCompletedWithWrappedCFException(g);
1397 >        g = new CompletableFuture<Integer>();
1398 >        h = f.thenCombineAsync(g, subtract);
1399 >        g.completeExceptionally(new CFException());
1400 >        checkIncomplete(h);
1401 >        f.complete(3);
1402 >        checkCompletedWithWrappedCFException(h);
1403 >
1404 >        f = new CompletableFuture<Integer>();
1405 >        g = new CompletableFuture<Integer>();
1406 >        g.completeExceptionally(new CFException());
1407 >        f.complete(3);
1408 >        h = f.thenCombineAsync(g, subtract);
1409 >        checkCompletedWithWrappedCFException(h);
1410      }
1411  
1412      /**
# Line 1285 | Line 1419 | public class CompletableFutureTest exten
1419          CompletableFuture<Integer> g = f.thenCombineAsync(f2, r);
1420          f.complete(one);
1421          checkIncomplete(g);
1422 +        assertFalse(r.ran);
1423          f2.complete(two);
1424          checkCompletedWithWrappedCFException(g);
1425 +        assertTrue(r.ran);
1426      }
1427  
1428      /**
1429       * thenCombineAsync result completes exceptionally if either source cancelled
1430       */
1431      public void testThenCombineAsync4() {
1432 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1433 <        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1434 <        CompletableFuture<Integer> g = f.thenCombineAsync(f2, add);
1432 >        CompletableFuture<Integer> f, g, h;
1433 >
1434 >        f = new CompletableFuture<Integer>();
1435 >        g = new CompletableFuture<Integer>();
1436 >        h = f.thenCombineAsync(g, subtract);
1437          assertTrue(f.cancel(true));
1438 <        f2.complete(two);
1439 <        checkCompletedWithWrappedCancellationException(g);
1438 >        checkIncomplete(h);
1439 >        g.complete(1);
1440 >        checkCompletedWithWrappedCancellationException(h);
1441  
1442          f = new CompletableFuture<Integer>();
1443 <        f2 = new CompletableFuture<Integer>();
1444 <        g = f.thenCombineAsync(f2, add);
1445 <        f.complete(one);
1446 <        assertTrue(f2.cancel(true));
1447 <        checkCompletedWithWrappedCancellationException(g);
1443 >        g = new CompletableFuture<Integer>();
1444 >        h = f.thenCombineAsync(g, subtract);
1445 >        assertTrue(g.cancel(true));
1446 >        checkIncomplete(h);
1447 >        f.complete(3);
1448 >        checkCompletedWithWrappedCancellationException(h);
1449 >
1450 >        f = new CompletableFuture<Integer>();
1451 >        g = new CompletableFuture<Integer>();
1452 >        g.complete(3);
1453 >        assertTrue(f.cancel(true));
1454 >        h = f.thenCombineAsync(g, subtract);
1455 >        checkCompletedWithWrappedCancellationException(h);
1456 >
1457 >        f = new CompletableFuture<Integer>();
1458 >        g = new CompletableFuture<Integer>();
1459 >        f.complete(3);
1460 >        assertTrue(g.cancel(true));
1461 >        h = f.thenCombineAsync(g, subtract);
1462 >        checkCompletedWithWrappedCancellationException(h);
1463      }
1464  
1465      /**
# Line 1671 | Line 1825 | public class CompletableFutureTest exten
1825      }
1826  
1827      /**
1828 <     * thenCompse result completes normally after normal completion of source
1828 >     * thenComposeAsync result completes normally after normal
1829 >     * completion of source
1830       */
1831      public void testThenComposeAsync() {
1832 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1833 <        CompletableFutureInc r = new CompletableFutureInc();
1834 <        CompletableFuture<Integer> g = f.thenComposeAsync(r);
1832 >        CompletableFuture<Integer> f, g;
1833 >        CompletableFutureInc r;
1834 >
1835 >        f = new CompletableFuture<Integer>();
1836 >        g = f.thenComposeAsync(r = new CompletableFutureInc());
1837          f.complete(one);
1838          checkCompletedNormally(g, two);
1839 +
1840 +        f = new CompletableFuture<Integer>();
1841 +        f.complete(one);
1842 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
1843 +        checkCompletedNormally(g, two);
1844      }
1845  
1846      /**
1847 <     * thenComposeAsync result completes exceptionally after exceptional
1848 <     * completion of source
1847 >     * thenComposeAsync result completes exceptionally after
1848 >     * exceptional completion of source
1849       */
1850      public void testThenComposeAsync2() {
1851 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1852 <        CompletableFutureInc r = new CompletableFutureInc();
1853 <        CompletableFuture<Integer> g = f.thenComposeAsync(r);
1851 >        CompletableFuture<Integer> f, g;
1852 >        CompletableFutureInc r;
1853 >
1854 >        f = new CompletableFuture<Integer>();
1855 >        g = f.thenComposeAsync(r = new CompletableFutureInc());
1856          f.completeExceptionally(new CFException());
1857          checkCompletedWithWrappedCFException(g);
1858 +        assertFalse(r.ran);
1859 +
1860 +        f = new CompletableFuture<Integer>();
1861 +        f.completeExceptionally(new CFException());
1862 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
1863 +        checkCompletedWithWrappedCFException(g);
1864 +        assertFalse(r.ran);
1865      }
1866  
1867      /**
1868       * thenComposeAsync result completes exceptionally if action does
1869       */
1870      public void testThenComposeAsync3() {
1871 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1872 <        FailingCompletableFutureFunction r = new FailingCompletableFutureFunction();
1873 <        CompletableFuture<Integer> g = f.thenComposeAsync(r);
1871 >        CompletableFuture<Integer> f, g;
1872 >        FailingCompletableFutureFunction r;
1873 >
1874 >        f = new CompletableFuture<Integer>();
1875 >        g = f.thenComposeAsync(r = new FailingCompletableFutureFunction());
1876          f.complete(one);
1877          checkCompletedWithWrappedCFException(g);
1878 +
1879 +        f = new CompletableFuture<Integer>();
1880 +        f.complete(one);
1881 +        g = f.thenComposeAsync(r = new FailingCompletableFutureFunction());
1882 +        checkCompletedWithWrappedCFException(g);
1883      }
1884  
1885      /**
1886       * thenComposeAsync result completes exceptionally if source cancelled
1887       */
1888      public void testThenComposeAsync4() {
1889 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1890 <        CompletableFutureInc r = new CompletableFutureInc();
1891 <        CompletableFuture<Integer> g = f.thenComposeAsync(r);
1889 >        CompletableFuture<Integer> f, g;
1890 >        CompletableFutureInc r;
1891 >
1892 >        f = new CompletableFuture<Integer>();
1893 >        g = f.thenComposeAsync(r = new CompletableFutureInc());
1894          assertTrue(f.cancel(true));
1895          checkCompletedWithWrappedCancellationException(g);
1896 +
1897 +        f = new CompletableFuture<Integer>();
1898 +        assertTrue(f.cancel(true));
1899 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
1900 +        checkCompletedWithWrappedCancellationException(g);
1901      }
1902  
1903  
1904 <    // aaync with explicit executors
1904 >    // async with explicit executors
1905  
1906      /**
1907       * thenRunAsync result completes normally after normal completion of source
# Line 1863 | Line 2048 | public class CompletableFutureTest exten
2048          assertTrue(f.cancel(true));
2049          checkCompletedWithWrappedCancellationException(g);
2050      }
2051 +
2052      /**
2053       * thenCombineAsync result completes normally after normal
2054       * completion of sources
2055       */
2056      public void testThenCombineAsyncE() {
2057 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2058 <        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2059 <        CompletableFuture<Integer> g = f.thenCombineAsync(f2, add, new ThreadExecutor());
2060 <        f.complete(one);
2061 <        checkIncomplete(g);
2062 <        f2.complete(two);
2063 <        checkCompletedNormally(g, three);
2057 >        CompletableFuture<Integer> f, g, h;
2058 >        ThreadExecutor e = new ThreadExecutor();
2059 >        int count = 0;
2060 >
2061 >        f = new CompletableFuture<Integer>();
2062 >        g = new CompletableFuture<Integer>();
2063 >        h = f.thenCombineAsync(g, subtract, e);
2064 >        f.complete(3);
2065 >        checkIncomplete(h);
2066 >        g.complete(1);
2067 >        checkCompletedNormally(h, 2);
2068 >        assertEquals(++count, e.count.get());
2069 >
2070 >        f = new CompletableFuture<Integer>();
2071 >        g = new CompletableFuture<Integer>();
2072 >        h = f.thenCombineAsync(g, subtract, e);
2073 >        g.complete(1);
2074 >        checkIncomplete(h);
2075 >        f.complete(3);
2076 >        checkCompletedNormally(h, 2);
2077 >        assertEquals(++count, e.count.get());
2078 >
2079 >        f = new CompletableFuture<Integer>();
2080 >        g = new CompletableFuture<Integer>();
2081 >        g.complete(1);
2082 >        f.complete(3);
2083 >        h = f.thenCombineAsync(g, subtract, e);
2084 >        checkCompletedNormally(h, 2);
2085 >        assertEquals(++count, e.count.get());
2086      }
2087  
2088      /**
2089       * thenCombineAsync result completes exceptionally after exceptional
2090 <     * completion of source
2090 >     * completion of either source
2091       */
2092      public void testThenCombineAsync2E() {
2093 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2094 <        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2095 <        CompletableFuture<Integer> g = f.thenCombineAsync(f2, add, new ThreadExecutor());
2093 >        CompletableFuture<Integer> f, g, h;
2094 >        ThreadExecutor e = new ThreadExecutor();
2095 >        int count = 0;
2096 >
2097 >        f = new CompletableFuture<Integer>();
2098 >        g = new CompletableFuture<Integer>();
2099 >        h = f.thenCombineAsync(g, subtract, e);
2100          f.completeExceptionally(new CFException());
2101 <        f2.complete(two);
2102 <        checkCompletedWithWrappedCFException(g);
2101 >        checkIncomplete(h);
2102 >        g.complete(1);
2103 >        checkCompletedWithWrappedCFException(h);
2104  
2105          f = new CompletableFuture<Integer>();
2106 <        f2 = new CompletableFuture<Integer>();
2107 <        g = f.thenCombineAsync(f2, add, new ThreadExecutor());
2108 <        f.complete(one);
2109 <        f2.completeExceptionally(new CFException());
2110 <        checkCompletedWithWrappedCFException(g);
2106 >        g = new CompletableFuture<Integer>();
2107 >        h = f.thenCombineAsync(g, subtract, e);
2108 >        g.completeExceptionally(new CFException());
2109 >        checkIncomplete(h);
2110 >        f.complete(3);
2111 >        checkCompletedWithWrappedCFException(h);
2112 >
2113 >        f = new CompletableFuture<Integer>();
2114 >        g = new CompletableFuture<Integer>();
2115 >        g.completeExceptionally(new CFException());
2116 >        h = f.thenCombineAsync(g, subtract, e);
2117 >        checkIncomplete(h);
2118 >        f.complete(3);
2119 >        checkCompletedWithWrappedCFException(h);
2120 >
2121 >        assertEquals(0, e.count.get());
2122      }
2123  
2124      /**
# Line 1907 | Line 2131 | public class CompletableFutureTest exten
2131          CompletableFuture<Integer> g = f.thenCombineAsync(f2, r, new ThreadExecutor());
2132          f.complete(one);
2133          checkIncomplete(g);
2134 +        assertFalse(r.ran);
2135          f2.complete(two);
2136          checkCompletedWithWrappedCFException(g);
2137 +        assertTrue(r.ran);
2138      }
2139  
2140      /**
2141       * thenCombineAsync result completes exceptionally if either source cancelled
2142       */
2143      public void testThenCombineAsync4E() {
2144 <        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2145 <        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2146 <        CompletableFuture<Integer> g = f.thenCombineAsync(f2, add, new ThreadExecutor());
2144 >        CompletableFuture<Integer> f, g, h;
2145 >        ThreadExecutor e = new ThreadExecutor();
2146 >
2147 >        f = new CompletableFuture<Integer>();
2148 >        g = new CompletableFuture<Integer>();
2149 >        h = f.thenCombineAsync(g, subtract, e);
2150          assertTrue(f.cancel(true));
2151 <        f2.complete(two);
2152 <        checkCompletedWithWrappedCancellationException(g);
2151 >        checkIncomplete(h);
2152 >        g.complete(1);
2153 >        checkCompletedWithWrappedCancellationException(h);
2154  
2155          f = new CompletableFuture<Integer>();
2156 <        f2 = new CompletableFuture<Integer>();
2157 <        g = f.thenCombineAsync(f2, add, new ThreadExecutor());
2158 <        f.complete(one);
2159 <        assertTrue(f2.cancel(true));
2160 <        checkCompletedWithWrappedCancellationException(g);
2156 >        g = new CompletableFuture<Integer>();
2157 >        h = f.thenCombineAsync(g, subtract, e);
2158 >        assertTrue(g.cancel(true));
2159 >        checkIncomplete(h);
2160 >        f.complete(3);
2161 >        checkCompletedWithWrappedCancellationException(h);
2162 >
2163 >        f = new CompletableFuture<Integer>();
2164 >        g = new CompletableFuture<Integer>();
2165 >        assertTrue(g.cancel(true));
2166 >        h = f.thenCombineAsync(g, subtract, e);
2167 >        checkIncomplete(h);
2168 >        f.complete(3);
2169 >        checkCompletedWithWrappedCancellationException(h);
2170 >
2171 >        f = new CompletableFuture<Integer>();
2172 >        g = new CompletableFuture<Integer>();
2173 >        assertTrue(f.cancel(true));
2174 >        assertTrue(g.cancel(true));
2175 >        h = f.thenCombineAsync(g, subtract, e);
2176 >        checkCompletedWithWrappedCancellationException(h);
2177 >
2178 >        assertEquals(0, e.count.get());
2179      }
2180  
2181      /**
# Line 2293 | Line 2541 | public class CompletableFutureTest exten
2541      }
2542  
2543      /**
2544 <     * thenCompse result completes normally after normal completion of source
2544 >     * thenComposeAsync result completes normally after normal
2545 >     * completion of source
2546       */
2547      public void testThenComposeAsyncE() {
2548          CompletableFuture<Integer> f = new CompletableFuture<Integer>();
# Line 2304 | Line 2553 | public class CompletableFutureTest exten
2553      }
2554  
2555      /**
2556 <     * thenComposeAsync result completes exceptionally after exceptional
2557 <     * completion of source
2556 >     * thenComposeAsync result completes exceptionally after
2557 >     * exceptional completion of source
2558       */
2559      public void testThenComposeAsync2E() {
2560          CompletableFuture<Integer> f = new CompletableFuture<Integer>();
# Line 2356 | Line 2605 | public class CompletableFutureTest exten
2605              CompletableFuture[] fs = new CompletableFuture[k];
2606              for (int i = 0; i < k; ++i)
2607                  fs[i] = new CompletableFuture<Integer>();
2608 <            CompletableFuture<?> f = CompletableFuture.allOf(fs);
2608 >            CompletableFuture<Void> f = CompletableFuture.allOf(fs);
2609              for (int i = 0; i < k; ++i) {
2610                  checkIncomplete(f);
2611                  fs[i].complete(one);
2612              }
2613 <            assertTrue(f.isDone());
2365 <            assertFalse(f.isCancelled());
2613 >            checkCompletedNormally(f, null);
2614          }
2615      }
2616  
# Line 2375 | Line 2623 | public class CompletableFutureTest exten
2623      }
2624  
2625      /**
2626 <     * allOf returns a future completed when any components complete
2626 >     * anyOf returns a future completed when any components complete
2627       */
2628      public void testAnyOf() throws Exception {
2629          for (int k = 1; k < 20; ++k) {
2630              CompletableFuture[] fs = new CompletableFuture[k];
2631              for (int i = 0; i < k; ++i)
2632                  fs[i] = new CompletableFuture<Integer>();
2633 <            CompletableFuture<?> f = CompletableFuture.anyOf(fs);
2633 >            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
2634              checkIncomplete(f);
2635              for (int i = 0; i < k; ++i) {
2636                  fs[i].complete(one);
2637 <                assertTrue(f.isDone());
2637 >                checkCompletedNormally(f, one);
2638              }
2639          }
2640      }
# Line 2397 | Line 2645 | public class CompletableFutureTest exten
2645      public void testNPE() {
2646          CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2647          CompletableFuture<Integer> g = new CompletableFuture<Integer>();
2648 <        CompletableFuture h;
2649 <        try { h = f.thenApply(null); } catch (NullPointerException ok) {}
2650 <        try { h = f.thenAccept(null); } catch (NullPointerException ok) {}
2651 <        try { h = f.thenRun(null); } catch (NullPointerException ok) {}
2652 <        try { h = f.thenCombine(g, null); } catch (NullPointerException ok) {}
2653 <        try { h = f.thenCombine(null, null); } catch (NullPointerException ok) {}
2654 <        try { h = f.applyToEither(g, null); } catch (NullPointerException ok) {}
2655 <        try { h = f.applyToEither(null, null); } catch (NullPointerException ok) {}
2656 <        try { h = f.thenAcceptBoth(g, null); } catch (NullPointerException ok) {}
2657 <        try { h = f.thenAcceptBoth(null, null); } catch (NullPointerException ok) {}
2658 <        try { h = f.runAfterEither(g, null); } catch (NullPointerException ok) {}
2659 <        try { h = f.runAfterEither(null, null); } catch (NullPointerException ok) {}
2660 <        try { h = f.runAfterBoth(g, null); } catch (NullPointerException ok) {}
2661 <        try { h = f.runAfterBoth(null, null); } catch (NullPointerException ok) {}
2662 <        try { h = f.exceptionally(null); } catch (NullPointerException ok) {}
2663 <        try { h = f.handle(null); } catch (NullPointerException ok) {}
2664 <        try { h = f.thenCompose(null); } catch (NullPointerException ok) {}
2665 <
2666 <        try { h = f.thenApplyAsync(null); } catch (NullPointerException ok) {}
2667 <        try { h = f.thenAcceptAsync(null); } catch (NullPointerException ok) {}
2668 <        try { h = f.thenRunAsync(null); } catch (NullPointerException ok) {}
2669 <        try { h = f.thenCombineAsync(g, null); } catch (NullPointerException ok) {}
2670 <        try { h = f.thenCombineAsync(null, null); } catch (NullPointerException ok) {}
2671 <        try { h = f.applyToEitherAsync(g, null); } catch (NullPointerException ok) {}
2672 <        try { h = f.applyToEitherAsync(null, null); } catch (NullPointerException ok) {}
2673 <        try { h = f.thenAcceptBothAsync(g, null); } catch (NullPointerException ok) {}
2674 <        try { h = f.thenAcceptBothAsync(null, null); } catch (NullPointerException ok) {}
2675 <        try { h = f.runAfterEitherAsync(g, null); } catch (NullPointerException ok) {}
2676 <        try { h = f.runAfterEitherAsync(null, null); } catch (NullPointerException ok) {}
2677 <        try { h = f.runAfterBothAsync(g, null); } catch (NullPointerException ok) {}
2678 <        try { h = f.runAfterBothAsync(null, null); } catch (NullPointerException ok) {}
2648 >        CompletableFuture<Integer> nullFuture = (CompletableFuture<Integer>)null;
2649 >        CompletableFuture<?> h;
2650 >        ThreadExecutor exec = new ThreadExecutor();
2651 >
2652 >        Runnable[] throwingActions = {
2653 >            () -> { CompletableFuture.supplyAsync(null); },
2654 >            () -> { CompletableFuture.supplyAsync(null, exec); },
2655 >            () -> { CompletableFuture.supplyAsync(supplyOne, null); },
2656 >
2657 >            () -> { CompletableFuture.runAsync(null); },
2658 >            () -> { CompletableFuture.runAsync(null, exec); },
2659 >            () -> { CompletableFuture.runAsync(() -> {}, null); },
2660 >
2661 >            () -> { f.completeExceptionally(null); },
2662 >
2663 >            () -> { f.thenApply(null); },
2664 >            () -> { f.thenApplyAsync(null); },
2665 >            () -> { f.thenApplyAsync((x) -> x, null); },
2666 >            () -> { f.thenApplyAsync(null, exec); },
2667 >
2668 >            () -> { f.thenAccept(null); },
2669 >            () -> { f.thenAcceptAsync(null); },
2670 >            () -> { f.thenAcceptAsync((x) -> { ; }, null); },
2671 >            () -> { f.thenAcceptAsync(null, exec); },
2672 >
2673 >            () -> { f.thenRun(null); },
2674 >            () -> { f.thenRunAsync(null); },
2675 >            () -> { f.thenRunAsync(() -> { ; }, null); },
2676 >            () -> { f.thenRunAsync(null, exec); },
2677 >
2678 >            () -> { f.thenCombine(g, null); },
2679 >            () -> { f.thenCombineAsync(g, null); },
2680 >            () -> { f.thenCombineAsync(g, null, exec); },
2681 >            () -> { f.thenCombine(nullFuture, (x, y) -> x); },
2682 >            () -> { f.thenCombineAsync(nullFuture, (x, y) -> x); },
2683 >            () -> { f.thenCombineAsync(nullFuture, (x, y) -> x, exec); },
2684 >            () -> { f.thenCombineAsync(g, (x, y) -> x, null); },
2685 >
2686 >            () -> { f.thenAcceptBoth(g, null); },
2687 >            () -> { f.thenAcceptBothAsync(g, null); },
2688 >            () -> { f.thenAcceptBothAsync(g, null, exec); },
2689 >            () -> { f.thenAcceptBoth(nullFuture, (x, y) -> {}); },
2690 >            () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}); },
2691 >            () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec); },
2692 >            () -> { f.thenAcceptBothAsync(g, (x, y) -> {}, null); },
2693 >
2694 >            () -> { f.runAfterBoth(g, null); },
2695 >            () -> { f.runAfterBothAsync(g, null); },
2696 >            () -> { f.runAfterBothAsync(g, null, exec); },
2697 >            () -> { f.runAfterBoth(nullFuture, () -> {}); },
2698 >            () -> { f.runAfterBothAsync(nullFuture, () -> {}); },
2699 >            () -> { f.runAfterBothAsync(nullFuture, () -> {}, exec); },
2700 >            () -> { f.runAfterBothAsync(g, () -> {}, null); },
2701 >
2702 >            () -> { f.applyToEither(g, null); },
2703 >            () -> { f.applyToEitherAsync(g, null); },
2704 >            () -> { f.applyToEitherAsync(g, null, exec); },
2705 >            () -> { f.applyToEither(nullFuture, (x) -> x); },
2706 >            () -> { f.applyToEitherAsync(nullFuture, (x) -> x); },
2707 >            () -> { f.applyToEitherAsync(nullFuture, (x) -> x, exec); },
2708 >            () -> { f.applyToEitherAsync(g, (x) -> x, null); },
2709 >
2710 >            () -> { f.acceptEither(g, null); },
2711 >            () -> { f.acceptEitherAsync(g, null); },
2712 >            () -> { f.acceptEitherAsync(g, null, exec); },
2713 >            () -> { f.acceptEither(nullFuture, (x) -> {}); },
2714 >            () -> { f.acceptEitherAsync(nullFuture, (x) -> {}); },
2715 >            () -> { f.acceptEitherAsync(nullFuture, (x) -> {}, exec); },
2716 >            () -> { f.acceptEitherAsync(g, (x) -> {}, null); },
2717 >
2718 >            () -> { f.runAfterEither(g, null); },
2719 >            () -> { f.runAfterEitherAsync(g, null); },
2720 >            () -> { f.runAfterEitherAsync(g, null, exec); },
2721 >            () -> { f.runAfterEither(nullFuture, () -> {}); },
2722 >            () -> { f.runAfterEitherAsync(nullFuture, () -> {}); },
2723 >            () -> { f.runAfterEitherAsync(nullFuture, () -> {}, exec); },
2724 >            () -> { f.runAfterEitherAsync(g, () -> {}, null); },
2725 >
2726 >            () -> { f.thenCompose(null); },
2727 >            () -> { f.thenComposeAsync(null); },
2728 >            () -> { f.thenComposeAsync(new CompletableFutureInc(), null); },
2729 >            () -> { f.thenComposeAsync(null, exec); },
2730 >
2731 >            () -> { f.exceptionally(null); },
2732 >
2733 >            () -> { f.handle(null); },
2734 >
2735 >            () -> { CompletableFuture.allOf((CompletableFuture<?>)null); },
2736 >            () -> { CompletableFuture.allOf((CompletableFuture<?>[])null); },
2737 >            () -> { CompletableFuture.allOf(f, null); },
2738 >            () -> { CompletableFuture.allOf(null, f); },
2739 >
2740 >            () -> { CompletableFuture.anyOf((CompletableFuture<?>)null); },
2741 >            () -> { CompletableFuture.anyOf((CompletableFuture<?>[])null); },
2742 >            () -> { CompletableFuture.anyOf(f, null); },
2743 >            () -> { CompletableFuture.anyOf(null, f); },
2744 >        };
2745  
2746 +        assertThrows(NullPointerException.class, throwingActions);
2747 +        assertEquals(0, exec.count.get());
2748      }
2749  
2434
2750   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines