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.1 by jsr166, Wed Feb 6 19:55:06 2013 UTC vs.
Revision 1.22 by jsr166, Mon Apr 8 20:46:59 2013 UTC

# Line 1 | Line 1
1   /*
2 < * Written by Doug Lea with assistance from members of JCP JSR-166
3 < * Expert Group and released to the public domain, as explained at
2 > * Written by Doug Lea and Martin Buchholz with assistance from
3 > * members of JCP JSR-166 Expert Group and released to the public
4 > * domain, as explained at
5   * http://creativecommons.org/publicdomain/zero/1.0/
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
6   */
7  
8   import junit.framework.*;
9   import java.util.concurrent.Callable;
10 + import java.util.concurrent.Executor;
11 + import java.util.concurrent.ExecutorService;
12 + import java.util.concurrent.Executors;
13   import java.util.concurrent.CancellationException;
14   import java.util.concurrent.CountDownLatch;
15   import java.util.concurrent.ExecutionException;
16   import java.util.concurrent.Future;
17   import java.util.concurrent.CompletableFuture;
18 + import java.util.concurrent.CompletionException;
19   import java.util.concurrent.TimeoutException;
20   import java.util.concurrent.atomic.AtomicInteger;
21   import static java.util.concurrent.TimeUnit.MILLISECONDS;
22   import static java.util.concurrent.TimeUnit.SECONDS;
23   import java.util.*;
24 + import java.util.function.Supplier;
25 + import java.util.function.Consumer;
26 + import java.util.function.BiConsumer;
27 + import java.util.function.Function;
28 + import java.util.function.BiFunction;
29  
30   public class CompletableFutureTest extends JSR166TestCase {
31  
# Line 28 | Line 36 | public class CompletableFutureTest exten
36          return new TestSuite(CompletableFutureTest.class);
37      }
38  
39 +    static class CFException extends RuntimeException {}
40 +
41 +    void checkIncomplete(CompletableFuture<?> f) {
42 +        assertFalse(f.isDone());
43 +        assertFalse(f.isCancelled());
44 +        assertTrue(f.toString().contains("[Not completed]"));
45 +        try {
46 +            assertNull(f.getNow(null));
47 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
48 +        try {
49 +            f.get(0L, SECONDS);
50 +            shouldThrow();
51 +        }
52 +        catch (TimeoutException success) {}
53 +        catch (Throwable fail) { threadUnexpectedException(fail); }
54 +    }
55 +
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); }
63 +        try {
64 +            assertEquals(value, f.getNow(null));
65 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
66 +        try {
67 +            assertEquals(value, f.get());
68 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
69 +        assertTrue(f.isDone());
70 +        assertFalse(f.isCancelled());
71 +        assertTrue(f.toString().contains("[Completed normally]"));
72 +    }
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 (CompletionException success) {
85 +            assertTrue(success.getCause() instanceof CFException);
86 +        }
87 +        try {
88 +            f.getNow(null);
89 +            shouldThrow();
90 +        } catch (CompletionException success) {
91 +            assertTrue(success.getCause() instanceof CFException);
92 +        }
93 +        try {
94 +            f.get();
95 +            shouldThrow();
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 (CancellationException success) {}
114 +        try {
115 +            f.getNow(null);
116 +            shouldThrow();
117 +        } catch (CancellationException success) {}
118 +        try {
119 +            f.get();
120 +            shouldThrow();
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 (CompletionException success) {
139 +            assertTrue(success.getCause() instanceof CancellationException);
140 +        }
141 +        try {
142 +            f.getNow(null);
143 +            shouldThrow();
144 +        } catch (CompletionException success) {
145 +            assertTrue(success.getCause() instanceof CancellationException);
146 +        }
147 +        try {
148 +            f.get();
149 +            shouldThrow();
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 +    /**
159 +     * A newly constructed CompletableFuture is incomplete, as indicated
160 +     * by methods isDone, isCancelled, and getNow
161 +     */
162 +    public void testConstructor() {
163 +        CompletableFuture<Integer> f = new CompletableFuture<>();
164 +        checkIncomplete(f);
165 +    }
166 +
167 +    /**
168 +     * complete completes normally, as indicated by methods isDone,
169 +     * isCancelled, join, get, and getNow
170 +     */
171 +    public void testComplete() {
172 +        CompletableFuture<Integer> f = new CompletableFuture<>();
173 +        checkIncomplete(f);
174 +        f.complete(one);
175 +        checkCompletedNormally(f, one);
176 +    }
177 +
178 +    /**
179 +     * completeExceptionally completes exceptionally, as indicated by
180 +     * methods isDone, isCancelled, join, get, and getNow
181 +     */
182 +    public void testCompleteExceptionally() {
183 +        CompletableFuture<Integer> f = new CompletableFuture<>();
184 +        checkIncomplete(f);
185 +        f.completeExceptionally(new CFException());
186 +        checkCompletedWithWrappedCFException(f);
187 +    }
188 +
189 +    /**
190 +     * cancel completes exceptionally and reports cancelled, as indicated by
191 +     * methods isDone, isCancelled, join, get, and getNow
192 +     */
193 +    public void testCancel() {
194 +        CompletableFuture<Integer> f = new CompletableFuture<>();
195 +        checkIncomplete(f);
196 +        assertTrue(f.cancel(true));
197 +        checkCancelled(f);
198 +    }
199 +
200 +    /**
201 +     * obtrudeValue forces completion with given value
202 +     */
203 +    public void testObtrudeValue() {
204 +        CompletableFuture<Integer> f = new CompletableFuture<>();
205 +        checkIncomplete(f);
206 +        f.complete(one);
207 +        checkCompletedNormally(f, one);
208 +        f.obtrudeValue(three);
209 +        checkCompletedNormally(f, three);
210 +        f.obtrudeValue(two);
211 +        checkCompletedNormally(f, two);
212 +        f = new CompletableFuture<>();
213 +        f.obtrudeValue(three);
214 +        checkCompletedNormally(f, three);
215 +        f = new CompletableFuture<>();
216 +        f.completeExceptionally(new CFException());
217 +        f.obtrudeValue(four);
218 +        checkCompletedNormally(f, four);
219 +    }
220 +
221 +    /**
222 +     * obtrudeException forces completion with given exception
223 +     */
224 +    public void testObtrudeException() {
225 +        CompletableFuture<Integer> f = new CompletableFuture<>();
226 +        checkIncomplete(f);
227 +        f.complete(one);
228 +        checkCompletedNormally(f, one);
229 +        f.obtrudeException(new CFException());
230 +        checkCompletedWithWrappedCFException(f);
231 +        f = new CompletableFuture<>();
232 +        f.obtrudeException(new CFException());
233 +        checkCompletedWithWrappedCFException(f);
234 +        f = new CompletableFuture<>();
235 +        f.completeExceptionally(new CFException());
236 +        f.obtrudeValue(four);
237 +        checkCompletedNormally(f, four);
238 +        f.obtrudeException(new CFException());
239 +        checkCompletedWithWrappedCFException(f);
240 +    }
241 +
242 +    /**
243 +     * getNumberOfDependents returns number of dependent tasks
244 +     */
245 +    public void testGetNumberOfDependents() {
246 +        CompletableFuture<Integer> f = new CompletableFuture<>();
247 +        assertEquals(f.getNumberOfDependents(), 0);
248 +        CompletableFuture g = f.thenRun(new Noop());
249 +        assertEquals(f.getNumberOfDependents(), 1);
250 +        assertEquals(g.getNumberOfDependents(), 0);
251 +        CompletableFuture h = f.thenRun(new Noop());
252 +        assertEquals(f.getNumberOfDependents(), 2);
253 +        f.complete(1);
254 +        checkCompletedNormally(g, null);
255 +        assertEquals(f.getNumberOfDependents(), 0);
256 +        assertEquals(g.getNumberOfDependents(), 0);
257 +    }
258 +
259 +
260 +    /**
261 +     * toString indicates current completion state
262 +     */
263      public void testToString() {
264          CompletableFuture<String> f;
265 <        assertTrue(new CompletableFuture<String>().toString()
34 <                   .contains("[Not completed]"));
265 >
266          f = new CompletableFuture<String>();
267 +        assertTrue(f.toString().contains("[Not completed]"));
268 +
269          f.complete("foo");
270          assertTrue(f.toString().contains("[Completed normally]"));
271 +
272          f = new CompletableFuture<String>();
273          f.completeExceptionally(new IndexOutOfBoundsException());
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> 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; }
296 +    }
297 +    static final class SubtractAction implements BiConsumer<Integer, Integer> {
298 +        int value;
299 +        public void accept(Integer x, Integer y) {
300 +            value = x.intValue() - y.intValue();
301 +        }
302 +    }
303 +    static final class Noop implements Runnable {
304 +        boolean ran;
305 +        public void run() { ran = true; }
306 +    }
307 +
308 +    static final class FailingSupplier implements Supplier<Integer> {
309 +        boolean ran;
310 +        public Integer get() { ran = true; throw new CFException(); }
311 +    }
312 +    static final class FailingConsumer implements Consumer<Integer> {
313 +        boolean ran;
314 +        public void accept(Integer x) { ran = true; throw new CFException(); }
315 +    }
316 +    static final class FailingBiConsumer implements BiConsumer<Integer, Integer> {
317 +        boolean ran;
318 +        public void accept(Integer x, Integer y) { ran = true; throw new CFException(); }
319 +    }
320 +    static final class FailingFunction implements Function<Integer, Integer> {
321 +        boolean ran;
322 +        public Integer apply(Integer x) { ran = true; throw new CFException(); }
323 +    }
324 +    static final class FailingBiFunction implements BiFunction<Integer, Integer, Integer> {
325 +        boolean ran;
326 +        public Integer apply(Integer x, Integer y) { ran = true; throw new CFException(); }
327 +    }
328 +    static final class FailingNoop implements Runnable {
329 +        boolean ran;
330 +        public void run() { ran = true; throw new CFException(); }
331 +    }
332 +
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<>();
339 +            f.complete(Integer.valueOf(x.intValue() + 1));
340 +            return f;
341 +        }
342 +    }
343 +
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();
349 +        }
350 +    }
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 +    }
361 +
362 +    static final class ExceptionToInteger implements Function<Throwable, Integer> {
363 +        public Integer apply(Throwable x) { return Integer.valueOf(3); }
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 +    }
373 +
374 +
375 +    /**
376 +     * exceptionally action completes with function value on source
377 +     * exception;  otherwise with source value
378 +     */
379 +    public void testExceptionally() {
380 +        CompletableFuture<Integer> f = new CompletableFuture<>();
381 +        ExceptionToInteger r = new ExceptionToInteger();
382 +        CompletableFuture<Integer> g = f.exceptionally(r);
383 +        f.completeExceptionally(new CFException());
384 +        checkCompletedNormally(g, three);
385 +
386 +        f = new CompletableFuture<>();
387 +        r = new ExceptionToInteger();
388 +        g = f.exceptionally(r);
389 +        f.complete(one);
390 +        checkCompletedNormally(g, one);
391 +    }
392 +
393 +    /**
394 +     * handle action completes normally with function value on either
395 +     * normal or exceptional completion of source
396 +     */
397 +    public void testHandle() {
398 +        CompletableFuture<Integer> f, g;
399 +        IntegerHandler r;
400 +
401 +        f = new CompletableFuture<>();
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<>();
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<>();
415 +        f.complete(one);
416 +        g = f.handle(r = new IntegerHandler());
417 +        assertTrue(r.ran);
418 +        checkCompletedNormally(g, two);
419 +
420 +        f = new CompletableFuture<>();
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 +
428 +    /**
429 +     * runAsync completes after running Runnable
430 +     */
431 +    public void testRunAsync() {
432 +        Noop r = new Noop();
433 +        CompletableFuture<Void> f = CompletableFuture.runAsync(r);
434 +        assertNull(f.join());
435 +        assertTrue(r.ran);
436 +        checkCompletedNormally(f, null);
437 +    }
438 +
439 +    /**
440 +     * runAsync with executor completes after running Runnable
441 +     */
442 +    public void testRunAsync2() {
443 +        Noop r = new Noop();
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 +    /**
453 +     * failing runAsync completes exceptionally after running Runnable
454 +     */
455 +    public void testRunAsync3() {
456 +        FailingNoop r = new FailingNoop();
457 +        CompletableFuture<Void> f = CompletableFuture.runAsync(r);
458 +        checkCompletedWithWrappedCFException(f);
459 +        assertTrue(r.ran);
460 +    }
461 +
462 +    /**
463 +     * supplyAsync completes with result of supplier
464 +     */
465 +    public void testSupplyAsync() {
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;
477 +        f = CompletableFuture.supplyAsync(supplyOne, new ThreadExecutor());
478 +        assertEquals(f.join(), one);
479 +        checkCompletedNormally(f, one);
480 +    }
481 +
482 +    /**
483 +     * Failing supplyAsync completes exceptionally
484 +     */
485 +    public void testSupplyAsync3() {
486 +        FailingSupplier r = new FailingSupplier();
487 +        CompletableFuture<Integer> f = CompletableFuture.supplyAsync(r);
488 +        checkCompletedWithWrappedCFException(f);
489 +        assertTrue(r.ran);
490 +    }
491 +
492 +    // seq completion methods
493 +
494 +    /**
495 +     * thenRun result completes normally after normal completion of source
496 +     */
497 +    public void testThenRun() {
498 +        CompletableFuture<Integer> f = new CompletableFuture<>();
499 +        Noop r = new Noop();
500 +        CompletableFuture<Void> g = f.thenRun(r);
501 +        f.complete(null);
502 +        checkCompletedNormally(g, null);
503 +        // reordered version
504 +        f = new CompletableFuture<>();
505 +        f.complete(null);
506 +        r = new Noop();
507 +        g = f.thenRun(r);
508 +        checkCompletedNormally(g, null);
509 +    }
510 +
511 +    /**
512 +     * thenRun result completes exceptionally after exceptional
513 +     * completion of source
514 +     */
515 +    public void testThenRun2() {
516 +        CompletableFuture<Integer> f = new CompletableFuture<>();
517 +        Noop r = new Noop();
518 +        CompletableFuture<Void> g = f.thenRun(r);
519 +        f.completeExceptionally(new CFException());
520 +        checkCompletedWithWrappedCFException(g);
521 +    }
522 +
523 +    /**
524 +     * thenRun result completes exceptionally if action does
525 +     */
526 +    public void testThenRun3() {
527 +        CompletableFuture<Integer> f = new CompletableFuture<>();
528 +        FailingNoop r = new FailingNoop();
529 +        CompletableFuture<Void> g = f.thenRun(r);
530 +        f.complete(null);
531 +        checkCompletedWithWrappedCFException(g);
532 +    }
533 +
534 +    /**
535 +     * thenRun result completes exceptionally if source cancelled
536 +     */
537 +    public void testThenRun4() {
538 +        CompletableFuture<Integer> f = new CompletableFuture<>();
539 +        Noop r = new Noop();
540 +        CompletableFuture<Void> g = f.thenRun(r);
541 +        assertTrue(f.cancel(true));
542 +        checkCompletedWithWrappedCancellationException(g);
543 +    }
544 +
545 +    /**
546 +     * thenApply result completes normally after normal completion of source
547 +     */
548 +    public void testThenApply() {
549 +        CompletableFuture<Integer> f = new CompletableFuture<>();
550 +        CompletableFuture<Integer> g = f.thenApply(inc);
551 +        f.complete(one);
552 +        checkCompletedNormally(g, two);
553 +    }
554 +
555 +    /**
556 +     * thenApply result completes exceptionally after exceptional
557 +     * completion of source
558 +     */
559 +    public void testThenApply2() {
560 +        CompletableFuture<Integer> f = new CompletableFuture<>();
561 +        CompletableFuture<Integer> g = f.thenApply(inc);
562 +        f.completeExceptionally(new CFException());
563 +        checkCompletedWithWrappedCFException(g);
564 +    }
565 +
566 +    /**
567 +     * thenApply result completes exceptionally if action does
568 +     */
569 +    public void testThenApply3() {
570 +        CompletableFuture<Integer> f = new CompletableFuture<>();
571 +        CompletableFuture<Integer> g = f.thenApply(new FailingFunction());
572 +        f.complete(one);
573 +        checkCompletedWithWrappedCFException(g);
574 +    }
575 +
576 +    /**
577 +     * thenApply result completes exceptionally if source cancelled
578 +     */
579 +    public void testThenApply4() {
580 +        CompletableFuture<Integer> f = new CompletableFuture<>();
581 +        CompletableFuture<Integer> g = f.thenApply(inc);
582 +        assertTrue(f.cancel(true));
583 +        checkCompletedWithWrappedCancellationException(g);
584 +    }
585 +
586 +    /**
587 +     * thenAccept result completes normally after normal completion of source
588 +     */
589 +    public void testThenAccept() {
590 +        CompletableFuture<Integer> f = new CompletableFuture<>();
591 +        IncAction r = new IncAction();
592 +        CompletableFuture<Void> g = f.thenAccept(r);
593 +        f.complete(one);
594 +        checkCompletedNormally(g, null);
595 +        assertEquals(r.value, 2);
596 +    }
597 +
598 +    /**
599 +     * thenAccept result completes exceptionally after exceptional
600 +     * completion of source
601 +     */
602 +    public void testThenAccept2() {
603 +        CompletableFuture<Integer> f = new CompletableFuture<>();
604 +        IncAction r = new IncAction();
605 +        CompletableFuture<Void> g = f.thenAccept(r);
606 +        f.completeExceptionally(new CFException());
607 +        checkCompletedWithWrappedCFException(g);
608 +    }
609 +
610 +    /**
611 +     * thenAccept result completes exceptionally if action does
612 +     */
613 +    public void testThenAccept3() {
614 +        CompletableFuture<Integer> f = new CompletableFuture<>();
615 +        FailingConsumer r = new FailingConsumer();
616 +        CompletableFuture<Void> g = f.thenAccept(r);
617 +        f.complete(one);
618 +        checkCompletedWithWrappedCFException(g);
619 +        assertTrue(r.ran);
620 +    }
621 +
622 +    /**
623 +     * thenAccept result completes exceptionally if source cancelled
624 +     */
625 +    public void testThenAccept4() {
626 +        CompletableFuture<Integer> f = new CompletableFuture<>();
627 +        IncAction r = new IncAction();
628 +        CompletableFuture<Void> g = f.thenAccept(r);
629 +        assertTrue(f.cancel(true));
630 +        checkCompletedWithWrappedCancellationException(g);
631 +    }
632 +
633 +
634 +    /**
635 +     * thenCombine result completes normally after normal completion
636 +     * of sources
637 +     */
638 +    public void testThenCombine() {
639 +        CompletableFuture<Integer> f, g, h;
640 +
641 +        f = new CompletableFuture<>();
642 +        g = new CompletableFuture<>();
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<>();
650 +        g = new CompletableFuture<>();
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<>();
658 +        g = new CompletableFuture<>();
659 +        g.complete(1);
660 +        f.complete(3);
661 +        h = f.thenCombine(g, subtract);
662 +        checkCompletedNormally(h, 2);
663 +    }
664 +
665 +    /**
666 +     * thenCombine result completes exceptionally after exceptional
667 +     * completion of either source
668 +     */
669 +    public void testThenCombine2() {
670 +        CompletableFuture<Integer> f, g, h;
671 +
672 +        f = new CompletableFuture<>();
673 +        g = new CompletableFuture<>();
674 +        h = f.thenCombine(g, subtract);
675 +        f.completeExceptionally(new CFException());
676 +        checkIncomplete(h);
677 +        g.complete(1);
678 +        checkCompletedWithWrappedCFException(h);
679 +
680 +        f = new CompletableFuture<>();
681 +        g = new CompletableFuture<>();
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<>();
689 +        g = new CompletableFuture<>();
690 +        f.complete(3);
691 +        g.completeExceptionally(new CFException());
692 +        h = f.thenCombine(g, subtract);
693 +        checkCompletedWithWrappedCFException(h);
694 +
695 +        f = new CompletableFuture<>();
696 +        g = new CompletableFuture<>();
697 +        f.completeExceptionally(new CFException());
698 +        g.complete(3);
699 +        h = f.thenCombine(g, subtract);
700 +        checkCompletedWithWrappedCFException(h);
701 +    }
702 +
703 +    /**
704 +     * thenCombine result completes exceptionally if action does
705 +     */
706 +    public void testThenCombine3() {
707 +        CompletableFuture<Integer> f = new CompletableFuture<>();
708 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
709 +        FailingBiFunction r = new FailingBiFunction();
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, g, h;
724 +
725 +        f = new CompletableFuture<>();
726 +        g = new CompletableFuture<>();
727 +        h = f.thenCombine(g, subtract);
728 +        assertTrue(f.cancel(true));
729 +        checkIncomplete(h);
730 +        g.complete(1);
731 +        checkCompletedWithWrappedCancellationException(h);
732 +
733 +        f = new CompletableFuture<>();
734 +        g = new CompletableFuture<>();
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<>();
742 +        g = new CompletableFuture<>();
743 +        assertTrue(f.cancel(true));
744 +        assertTrue(g.cancel(true));
745 +        h = f.thenCombine(g, subtract);
746 +        checkCompletedWithWrappedCancellationException(h);
747 +    }
748 +
749 +    /**
750 +     * thenAcceptBoth result completes normally after normal
751 +     * completion of sources
752 +     */
753 +    public void testThenAcceptBoth() {
754 +        CompletableFuture<Integer> f, g;
755 +        CompletableFuture<Void> h;
756 +        SubtractAction r;
757 +
758 +        f = new CompletableFuture<>();
759 +        g = new CompletableFuture<>();
760 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
761 +        f.complete(3);
762 +        checkIncomplete(h);
763 +        g.complete(1);
764 +        checkCompletedNormally(h, null);
765 +        assertEquals(r.value, 2);
766 +
767 +        f = new CompletableFuture<>();
768 +        g = new CompletableFuture<>();
769 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
770 +        g.complete(1);
771 +        checkIncomplete(h);
772 +        f.complete(3);
773 +        checkCompletedNormally(h, null);
774 +        assertEquals(r.value, 2);
775 +
776 +        f = new CompletableFuture<>();
777 +        g = new CompletableFuture<>();
778 +        g.complete(1);
779 +        f.complete(3);
780 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
781 +        checkCompletedNormally(h, null);
782 +        assertEquals(r.value, 2);
783 +    }
784 +
785 +    /**
786 +     * thenAcceptBoth result completes exceptionally after exceptional
787 +     * completion of either source
788 +     */
789 +    public void testThenAcceptBoth2() {
790 +        CompletableFuture<Integer> f, g;
791 +        CompletableFuture<Void> h;
792 +        SubtractAction r;
793 +
794 +        f = new CompletableFuture<>();
795 +        g = new CompletableFuture<>();
796 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
797 +        f.completeExceptionally(new CFException());
798 +        checkIncomplete(h);
799 +        g.complete(1);
800 +        checkCompletedWithWrappedCFException(h);
801 +
802 +        f = new CompletableFuture<>();
803 +        g = new CompletableFuture<>();
804 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
805 +        g.completeExceptionally(new CFException());
806 +        checkIncomplete(h);
807 +        f.complete(3);
808 +        checkCompletedWithWrappedCFException(h);
809 +
810 +        f = new CompletableFuture<>();
811 +        g = new CompletableFuture<>();
812 +        f.complete(3);
813 +        g.completeExceptionally(new CFException());
814 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
815 +        checkCompletedWithWrappedCFException(h);
816 +
817 +        f = new CompletableFuture<>();
818 +        g = new CompletableFuture<>();
819 +        f.completeExceptionally(new CFException());
820 +        g.complete(3);
821 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
822 +        checkCompletedWithWrappedCFException(h);
823 +    }
824 +
825 +    /**
826 +     * thenAcceptBoth result completes exceptionally if action does
827 +     */
828 +    public void testThenAcceptBoth3() {
829 +        CompletableFuture<Integer> f, g;
830 +        CompletableFuture<Void> h;
831 +        FailingBiConsumer r;
832 +
833 +        f = new CompletableFuture<>();
834 +        g = new CompletableFuture<>();
835 +        h = f.thenAcceptBoth(g, r = new FailingBiConsumer());
836 +        f.complete(3);
837 +        checkIncomplete(h);
838 +        g.complete(1);
839 +        checkCompletedWithWrappedCFException(h);
840 +
841 +        f = new CompletableFuture<>();
842 +        g = new CompletableFuture<>();
843 +        f.complete(3);
844 +        g.complete(1);
845 +        h = f.thenAcceptBoth(g, r = new FailingBiConsumer());
846 +        checkCompletedWithWrappedCFException(h);
847 +    }
848 +
849 +    /**
850 +     * thenAcceptBoth result completes exceptionally if either source cancelled
851 +     */
852 +    public void testThenAcceptBoth4() {
853 +        CompletableFuture<Integer> f, g;
854 +        CompletableFuture<Void> h;
855 +        SubtractAction r;
856 +
857 +        f = new CompletableFuture<>();
858 +        g = new CompletableFuture<>();
859 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
860 +        assertTrue(f.cancel(true));
861 +        checkIncomplete(h);
862 +        g.complete(1);
863 +        checkCompletedWithWrappedCancellationException(h);
864 +
865 +        f = new CompletableFuture<>();
866 +        g = new CompletableFuture<>();
867 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
868 +        assertTrue(g.cancel(true));
869 +        checkIncomplete(h);
870 +        f.complete(3);
871 +        checkCompletedWithWrappedCancellationException(h);
872 +
873 +        f = new CompletableFuture<>();
874 +        g = new CompletableFuture<>();
875 +        f.complete(3);
876 +        assertTrue(g.cancel(true));
877 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
878 +        checkCompletedWithWrappedCancellationException(h);
879 +
880 +        f = new CompletableFuture<>();
881 +        g = new CompletableFuture<>();
882 +        assertTrue(f.cancel(true));
883 +        g.complete(3);
884 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
885 +        checkCompletedWithWrappedCancellationException(h);
886 +    }
887 +
888 +    /**
889 +     * runAfterBoth result completes normally after normal
890 +     * completion of sources
891 +     */
892 +    public void testRunAfterBoth() {
893 +        CompletableFuture<Integer> f, g;
894 +        CompletableFuture<Void> h;
895 +        Noop r;
896 +
897 +        f = new CompletableFuture<>();
898 +        g = new CompletableFuture<>();
899 +        h = f.runAfterBoth(g, r = new Noop());
900 +        f.complete(3);
901 +        checkIncomplete(h);
902 +        g.complete(1);
903 +        checkCompletedNormally(h, null);
904 +        assertTrue(r.ran);
905 +
906 +        f = new CompletableFuture<>();
907 +        g = new CompletableFuture<>();
908 +        h = f.runAfterBoth(g, r = new Noop());
909 +        g.complete(1);
910 +        checkIncomplete(h);
911 +        f.complete(3);
912 +        checkCompletedNormally(h, null);
913 +        assertTrue(r.ran);
914 +
915 +        f = new CompletableFuture<>();
916 +        g = new CompletableFuture<>();
917 +        g.complete(1);
918 +        f.complete(3);
919 +        h = f.runAfterBoth(g, r = new Noop());
920 +        checkCompletedNormally(h, null);
921 +        assertTrue(r.ran);
922 +    }
923 +
924 +    /**
925 +     * runAfterBoth result completes exceptionally after exceptional
926 +     * completion of either source
927 +     */
928 +    public void testRunAfterBoth2() {
929 +        CompletableFuture<Integer> f, g;
930 +        CompletableFuture<Void> h;
931 +        Noop r;
932 +
933 +        f = new CompletableFuture<>();
934 +        g = new CompletableFuture<>();
935 +        h = f.runAfterBoth(g, r = new Noop());
936 +        f.completeExceptionally(new CFException());
937 +        checkIncomplete(h);
938 +        g.complete(1);
939 +        checkCompletedWithWrappedCFException(h);
940 +        assertFalse(r.ran);
941 +
942 +        f = new CompletableFuture<>();
943 +        g = new CompletableFuture<>();
944 +        h = f.runAfterBoth(g, r = new Noop());
945 +        g.completeExceptionally(new CFException());
946 +        checkIncomplete(h);
947 +        f.complete(3);
948 +        checkCompletedWithWrappedCFException(h);
949 +        assertFalse(r.ran);
950 +
951 +        f = new CompletableFuture<>();
952 +        g = new CompletableFuture<>();
953 +        g.completeExceptionally(new CFException());
954 +        f.complete(3);
955 +        h = f.runAfterBoth(g, r = new Noop());
956 +        checkCompletedWithWrappedCFException(h);
957 +        assertFalse(r.ran);
958 +
959 +        f = new CompletableFuture<>();
960 +        g = new CompletableFuture<>();
961 +        f.completeExceptionally(new CFException());
962 +        g.complete(1);
963 +        h = f.runAfterBoth(g, r = new Noop());
964 +        checkCompletedWithWrappedCFException(h);
965 +        assertFalse(r.ran);
966 +    }
967 +
968 +    /**
969 +     * runAfterBoth result completes exceptionally if action does
970 +     */
971 +    public void testRunAfterBoth3() {
972 +        CompletableFuture<Integer> f = new CompletableFuture<>();
973 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
974 +        FailingNoop r = new FailingNoop();
975 +        CompletableFuture<Void> g = f.runAfterBoth(f2, r);
976 +        f.complete(one);
977 +        checkIncomplete(g);
978 +        f2.complete(two);
979 +        checkCompletedWithWrappedCFException(g);
980 +    }
981 +
982 +    /**
983 +     * runAfterBoth result completes exceptionally if either source cancelled
984 +     */
985 +    public void testRunAfterBoth4() {
986 +        CompletableFuture<Integer> f = new CompletableFuture<>();
987 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
988 +        Noop r = new Noop();
989 +        CompletableFuture<Void> g = f.runAfterBoth(f2, r);
990 +        assertTrue(f.cancel(true));
991 +        f2.complete(two);
992 +        checkCompletedWithWrappedCancellationException(g);
993 +        f = new CompletableFuture<>();
994 +        f2 = new CompletableFuture<>();
995 +        r = new Noop();
996 +        g = f.runAfterBoth(f2, r);
997 +        f.complete(one);
998 +        assertTrue(f2.cancel(true));
999 +        checkCompletedWithWrappedCancellationException(g);
1000 +    }
1001 +
1002 +    /**
1003 +     * applyToEither result completes normally after normal completion
1004 +     * of either source
1005 +     */
1006 +    public void testApplyToEither() {
1007 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1008 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1009 +        CompletableFuture<Integer> g = f.applyToEither(f2, inc);
1010 +        f.complete(one);
1011 +        checkCompletedNormally(g, two);
1012 +        f2.complete(one);
1013 +        checkCompletedNormally(g, two);
1014 +
1015 +        f = new CompletableFuture<>();
1016 +        f.complete(one);
1017 +        f2 = new CompletableFuture<>();
1018 +        g = f.applyToEither(f2, inc);
1019 +        checkCompletedNormally(g, two);
1020 +    }
1021 +
1022 +    /**
1023 +     * applyToEither result completes exceptionally after exceptional
1024 +     * completion of either source
1025 +     */
1026 +    public void testApplyToEither2() {
1027 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1028 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1029 +        CompletableFuture<Integer> g = f.applyToEither(f2, inc);
1030 +        f.completeExceptionally(new CFException());
1031 +        f2.complete(one);
1032 +        checkCompletedWithWrappedCFException(g);
1033 +
1034 +        f = new CompletableFuture<>();
1035 +        f2 = new CompletableFuture<>();
1036 +        f2.completeExceptionally(new CFException());
1037 +        g = f.applyToEither(f2, inc);
1038 +        checkCompletedWithWrappedCFException(g);
1039 +    }
1040 +
1041 +    /**
1042 +     * applyToEither result completes exceptionally if action does
1043 +     */
1044 +    public void testApplyToEither3() {
1045 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1046 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1047 +        FailingFunction r = new FailingFunction();
1048 +        CompletableFuture<Integer> g = f.applyToEither(f2, r);
1049 +        f2.complete(two);
1050 +        checkCompletedWithWrappedCFException(g);
1051 +    }
1052 +
1053 +    /**
1054 +     * applyToEither result completes exceptionally if either source cancelled
1055 +     */
1056 +    public void testApplyToEither4() {
1057 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1058 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1059 +        CompletableFuture<Integer> g = f.applyToEither(f2, inc);
1060 +        assertTrue(f.cancel(true));
1061 +        checkCompletedWithWrappedCancellationException(g);
1062 +        f = new CompletableFuture<>();
1063 +        f2 = new CompletableFuture<>();
1064 +        assertTrue(f2.cancel(true));
1065 +        checkCompletedWithWrappedCancellationException(g);
1066 +    }
1067 +
1068 +    /**
1069 +     * acceptEither result completes normally after normal completion
1070 +     * of either source
1071 +     */
1072 +    public void testAcceptEither() {
1073 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1074 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1075 +        IncAction r = new IncAction();
1076 +        CompletableFuture<Void> g = f.acceptEither(f2, r);
1077 +        f.complete(one);
1078 +        checkCompletedNormally(g, null);
1079 +        f2.complete(one);
1080 +        checkCompletedNormally(g, null);
1081 +        assertEquals(r.value, 2);
1082 +
1083 +        r = new IncAction();
1084 +        f = new CompletableFuture<>();
1085 +        f.complete(one);
1086 +        f2 = new CompletableFuture<>();
1087 +        g = f.acceptEither(f2, r);
1088 +        checkCompletedNormally(g, null);
1089 +        assertEquals(r.value, 2);
1090 +    }
1091 +
1092 +    /**
1093 +     * acceptEither result completes exceptionally after exceptional
1094 +     * completion of either source
1095 +     */
1096 +    public void testAcceptEither2() {
1097 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1098 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1099 +        IncAction r = new IncAction();
1100 +        CompletableFuture<Void> g = f.acceptEither(f2, r);
1101 +        f.completeExceptionally(new CFException());
1102 +        f2.complete(one);
1103 +        checkCompletedWithWrappedCFException(g);
1104 +
1105 +        r = new IncAction();
1106 +        f = new CompletableFuture<>();
1107 +        f2 = new CompletableFuture<>();
1108 +        f2.completeExceptionally(new CFException());
1109 +        g = f.acceptEither(f2, r);
1110 +        checkCompletedWithWrappedCFException(g);
1111 +    }
1112 +
1113 +    /**
1114 +     * acceptEither result completes exceptionally if action does
1115 +     */
1116 +    public void testAcceptEither3() {
1117 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1118 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1119 +        FailingConsumer r = new FailingConsumer();
1120 +        CompletableFuture<Void> g = f.acceptEither(f2, r);
1121 +        f2.complete(two);
1122 +        checkCompletedWithWrappedCFException(g);
1123 +    }
1124 +
1125 +    /**
1126 +     * acceptEither result completes exceptionally if either source cancelled
1127 +     */
1128 +    public void testAcceptEither4() {
1129 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1130 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1131 +        IncAction r = new IncAction();
1132 +        CompletableFuture<Void> g = f.acceptEither(f2, r);
1133 +        assertTrue(f.cancel(true));
1134 +        checkCompletedWithWrappedCancellationException(g);
1135 +        f = new CompletableFuture<>();
1136 +        f2 = new CompletableFuture<>();
1137 +        assertTrue(f2.cancel(true));
1138 +        checkCompletedWithWrappedCancellationException(g);
1139 +    }
1140 +
1141 +
1142 +    /**
1143 +     * runAfterEither result completes normally after normal completion
1144 +     * of either source
1145 +     */
1146 +    public void testRunAfterEither() {
1147 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1148 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1149 +        Noop r = new Noop();
1150 +        CompletableFuture<Void> g = f.runAfterEither(f2, r);
1151 +        f.complete(one);
1152 +        checkCompletedNormally(g, null);
1153 +        f2.complete(one);
1154 +        checkCompletedNormally(g, null);
1155 +        assertTrue(r.ran);
1156 +
1157 +        r = new Noop();
1158 +        f = new CompletableFuture<>();
1159 +        f.complete(one);
1160 +        f2 = new CompletableFuture<>();
1161 +        g = f.runAfterEither(f2, r);
1162 +        checkCompletedNormally(g, null);
1163 +        assertTrue(r.ran);
1164 +    }
1165 +
1166 +    /**
1167 +     * runAfterEither result completes exceptionally after exceptional
1168 +     * completion of either source
1169 +     */
1170 +    public void testRunAfterEither2() {
1171 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1172 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1173 +        Noop r = new Noop();
1174 +        CompletableFuture<Void> g = f.runAfterEither(f2, r);
1175 +        f.completeExceptionally(new CFException());
1176 +        f2.complete(one);
1177 +        checkCompletedWithWrappedCFException(g);
1178 +
1179 +        r = new Noop();
1180 +        f = new CompletableFuture<>();
1181 +        f2 = new CompletableFuture<>();
1182 +        f2.completeExceptionally(new CFException());
1183 +        g = f.runAfterEither(f2, r);
1184 +        checkCompletedWithWrappedCFException(g);
1185 +    }
1186 +
1187 +    /**
1188 +     * runAfterEither result completes exceptionally if action does
1189 +     */
1190 +    public void testRunAfterEither3() {
1191 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1192 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1193 +        FailingNoop r = new FailingNoop();
1194 +        CompletableFuture<Void> g = f.runAfterEither(f2, r);
1195 +        f2.complete(two);
1196 +        checkCompletedWithWrappedCFException(g);
1197 +    }
1198 +
1199 +    /**
1200 +     * runAfterEither result completes exceptionally if either source cancelled
1201 +     */
1202 +    public void testRunAfterEither4() {
1203 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1204 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1205 +        Noop r = new Noop();
1206 +        CompletableFuture<Void> g = f.runAfterEither(f2, r);
1207 +        assertTrue(f.cancel(true));
1208 +        checkCompletedWithWrappedCancellationException(g);
1209 +        f = new CompletableFuture<>();
1210 +        f2 = new CompletableFuture<>();
1211 +        assertTrue(f2.cancel(true));
1212 +        checkCompletedWithWrappedCancellationException(g);
1213 +    }
1214 +
1215 +    /**
1216 +     * thenCompose result completes normally after normal completion of source
1217 +     */
1218 +    public void testThenCompose() {
1219 +        CompletableFuture<Integer> f, g;
1220 +        CompletableFutureInc r;
1221 +
1222 +        f = new CompletableFuture<>();
1223 +        g = f.thenCompose(r = new CompletableFutureInc());
1224 +        f.complete(one);
1225 +        checkCompletedNormally(g, two);
1226 +        assertTrue(r.ran);
1227 +
1228 +        f = new CompletableFuture<>();
1229 +        f.complete(one);
1230 +        g = f.thenCompose(r = new CompletableFutureInc());
1231 +        checkCompletedNormally(g, two);
1232 +        assertTrue(r.ran);
1233 +    }
1234 +
1235 +    /**
1236 +     * thenCompose result completes exceptionally after exceptional
1237 +     * completion of source
1238 +     */
1239 +    public void testThenCompose2() {
1240 +        CompletableFuture<Integer> f, g;
1241 +        CompletableFutureInc r;
1242 +
1243 +        f = new CompletableFuture<>();
1244 +        g = f.thenCompose(r = new CompletableFutureInc());
1245 +        f.completeExceptionally(new CFException());
1246 +        checkCompletedWithWrappedCFException(g);
1247 +
1248 +        f = new CompletableFuture<>();
1249 +        f.completeExceptionally(new CFException());
1250 +        g = f.thenCompose(r = new CompletableFutureInc());
1251 +        checkCompletedWithWrappedCFException(g);
1252 +    }
1253 +
1254 +    /**
1255 +     * thenCompose result completes exceptionally if action does
1256 +     */
1257 +    public void testThenCompose3() {
1258 +        CompletableFuture<Integer> f, g;
1259 +        FailingCompletableFutureFunction r;
1260 +
1261 +        f = new CompletableFuture<>();
1262 +        g = f.thenCompose(r = new FailingCompletableFutureFunction());
1263 +        f.complete(one);
1264 +        checkCompletedWithWrappedCFException(g);
1265 +
1266 +        f = new CompletableFuture<>();
1267 +        f.complete(one);
1268 +        g = f.thenCompose(r = new FailingCompletableFutureFunction());
1269 +        checkCompletedWithWrappedCFException(g);
1270 +    }
1271 +
1272 +    /**
1273 +     * thenCompose result completes exceptionally if source cancelled
1274 +     */
1275 +    public void testThenCompose4() {
1276 +        CompletableFuture<Integer> f, g;
1277 +        CompletableFutureInc r;
1278 +
1279 +        f = new CompletableFuture<>();
1280 +        g = f.thenCompose(r = new CompletableFutureInc());
1281 +        assertTrue(f.cancel(true));
1282 +        checkCompletedWithWrappedCancellationException(g);
1283 +
1284 +        f = new CompletableFuture<>();
1285 +        assertTrue(f.cancel(true));
1286 +        g = f.thenCompose(r = new CompletableFutureInc());
1287 +        checkCompletedWithWrappedCancellationException(g);
1288 +    }
1289 +
1290 +
1291 +    // asyncs
1292 +
1293 +    /**
1294 +     * thenRunAsync result completes normally after normal completion of source
1295 +     */
1296 +    public void testThenRunAsync() {
1297 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1298 +        Noop r = new Noop();
1299 +        CompletableFuture<Void> g = f.thenRunAsync(r);
1300 +        f.complete(null);
1301 +        checkCompletedNormally(g, null);
1302 +
1303 +        // reordered version
1304 +        f = new CompletableFuture<>();
1305 +        f.complete(null);
1306 +        r = new Noop();
1307 +        g = f.thenRunAsync(r);
1308 +        checkCompletedNormally(g, null);
1309 +    }
1310 +
1311 +    /**
1312 +     * thenRunAsync result completes exceptionally after exceptional
1313 +     * completion of source
1314 +     */
1315 +    public void testThenRunAsync2() {
1316 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1317 +        Noop r = new Noop();
1318 +        CompletableFuture<Void> g = f.thenRunAsync(r);
1319 +        f.completeExceptionally(new CFException());
1320 +        try {
1321 +            g.join();
1322 +            shouldThrow();
1323 +        } catch (Exception ok) {
1324 +        }
1325 +        checkCompletedWithWrappedCFException(g);
1326 +    }
1327 +
1328 +    /**
1329 +     * thenRunAsync result completes exceptionally if action does
1330 +     */
1331 +    public void testThenRunAsync3() {
1332 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1333 +        FailingNoop r = new FailingNoop();
1334 +        CompletableFuture<Void> g = f.thenRunAsync(r);
1335 +        f.complete(null);
1336 +        checkCompletedWithWrappedCFException(g);
1337 +    }
1338 +
1339 +    /**
1340 +     * thenRunAsync result completes exceptionally if source cancelled
1341 +     */
1342 +    public void testThenRunAsync4() {
1343 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1344 +        Noop r = new Noop();
1345 +        CompletableFuture<Void> g = f.thenRunAsync(r);
1346 +        assertTrue(f.cancel(true));
1347 +        checkCompletedWithWrappedCancellationException(g);
1348 +    }
1349 +
1350 +    /**
1351 +     * thenApplyAsync result completes normally after normal completion of source
1352 +     */
1353 +    public void testThenApplyAsync() {
1354 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1355 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc);
1356 +        f.complete(one);
1357 +        checkCompletedNormally(g, two);
1358 +    }
1359 +
1360 +    /**
1361 +     * thenApplyAsync result completes exceptionally after exceptional
1362 +     * completion of source
1363 +     */
1364 +    public void testThenApplyAsync2() {
1365 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1366 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc);
1367 +        f.completeExceptionally(new CFException());
1368 +        checkCompletedWithWrappedCFException(g);
1369 +    }
1370 +
1371 +    /**
1372 +     * thenApplyAsync result completes exceptionally if action does
1373 +     */
1374 +    public void testThenApplyAsync3() {
1375 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1376 +        FailingFunction r = new FailingFunction();
1377 +        CompletableFuture<Integer> g = f.thenApplyAsync(r);
1378 +        f.complete(null);
1379 +        checkCompletedWithWrappedCFException(g);
1380 +    }
1381 +
1382 +    /**
1383 +     * thenApplyAsync result completes exceptionally if source cancelled
1384 +     */
1385 +    public void testThenApplyAsync4() {
1386 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1387 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc);
1388 +        assertTrue(f.cancel(true));
1389 +        checkCompletedWithWrappedCancellationException(g);
1390 +    }
1391 +
1392 +    /**
1393 +     * thenAcceptAsync result completes normally after normal
1394 +     * completion of source
1395 +     */
1396 +    public void testThenAcceptAsync() {
1397 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1398 +        IncAction r = new IncAction();
1399 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
1400 +        f.complete(one);
1401 +        checkCompletedNormally(g, null);
1402 +        assertEquals(r.value, 2);
1403 +    }
1404 +
1405 +    /**
1406 +     * thenAcceptAsync result completes exceptionally after exceptional
1407 +     * completion of source
1408 +     */
1409 +    public void testThenAcceptAsync2() {
1410 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1411 +        IncAction r = new IncAction();
1412 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
1413 +        f.completeExceptionally(new CFException());
1414 +        checkCompletedWithWrappedCFException(g);
1415 +    }
1416 +
1417 +    /**
1418 +     * thenAcceptAsync result completes exceptionally if action does
1419 +     */
1420 +    public void testThenAcceptAsync3() {
1421 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1422 +        FailingConsumer r = new FailingConsumer();
1423 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
1424 +        f.complete(null);
1425 +        checkCompletedWithWrappedCFException(g);
1426 +    }
1427 +
1428 +    /**
1429 +     * thenAcceptAsync result completes exceptionally if source cancelled
1430 +     */
1431 +    public void testThenAcceptAsync4() {
1432 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1433 +        IncAction r = new IncAction();
1434 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
1435 +        assertTrue(f.cancel(true));
1436 +        checkCompletedWithWrappedCancellationException(g);
1437 +    }
1438 +
1439 +    /**
1440 +     * thenCombineAsync result completes normally after normal
1441 +     * completion of sources
1442 +     */
1443 +    public void testThenCombineAsync() {
1444 +        CompletableFuture<Integer> f, g, h;
1445 +
1446 +        f = new CompletableFuture<>();
1447 +        g = new CompletableFuture<>();
1448 +        h = f.thenCombineAsync(g, subtract);
1449 +        f.complete(3);
1450 +        checkIncomplete(h);
1451 +        g.complete(1);
1452 +        checkCompletedNormally(h, 2);
1453 +
1454 +        f = new CompletableFuture<>();
1455 +        g = new CompletableFuture<>();
1456 +        h = f.thenCombineAsync(g, subtract);
1457 +        g.complete(1);
1458 +        checkIncomplete(h);
1459 +        f.complete(3);
1460 +        checkCompletedNormally(h, 2);
1461 +
1462 +        f = new CompletableFuture<>();
1463 +        g = new CompletableFuture<>();
1464 +        g.complete(1);
1465 +        f.complete(3);
1466 +        h = f.thenCombineAsync(g, subtract);
1467 +        checkCompletedNormally(h, 2);
1468 +    }
1469 +
1470 +    /**
1471 +     * thenCombineAsync result completes exceptionally after exceptional
1472 +     * completion of either source
1473 +     */
1474 +    public void testThenCombineAsync2() {
1475 +        CompletableFuture<Integer> f, g, h;
1476 +
1477 +        f = new CompletableFuture<>();
1478 +        g = new CompletableFuture<>();
1479 +        h = f.thenCombineAsync(g, subtract);
1480 +        f.completeExceptionally(new CFException());
1481 +        checkIncomplete(h);
1482 +        g.complete(1);
1483 +        checkCompletedWithWrappedCFException(h);
1484 +
1485 +        f = new CompletableFuture<>();
1486 +        g = new CompletableFuture<>();
1487 +        h = f.thenCombineAsync(g, subtract);
1488 +        g.completeExceptionally(new CFException());
1489 +        checkIncomplete(h);
1490 +        f.complete(3);
1491 +        checkCompletedWithWrappedCFException(h);
1492 +
1493 +        f = new CompletableFuture<>();
1494 +        g = new CompletableFuture<>();
1495 +        g.completeExceptionally(new CFException());
1496 +        f.complete(3);
1497 +        h = f.thenCombineAsync(g, subtract);
1498 +        checkCompletedWithWrappedCFException(h);
1499 +    }
1500 +
1501 +    /**
1502 +     * thenCombineAsync result completes exceptionally if action does
1503 +     */
1504 +    public void testThenCombineAsync3() {
1505 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1506 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1507 +        FailingBiFunction r = new FailingBiFunction();
1508 +        CompletableFuture<Integer> g = f.thenCombineAsync(f2, r);
1509 +        f.complete(one);
1510 +        checkIncomplete(g);
1511 +        assertFalse(r.ran);
1512 +        f2.complete(two);
1513 +        checkCompletedWithWrappedCFException(g);
1514 +        assertTrue(r.ran);
1515 +    }
1516 +
1517 +    /**
1518 +     * thenCombineAsync result completes exceptionally if either source cancelled
1519 +     */
1520 +    public void testThenCombineAsync4() {
1521 +        CompletableFuture<Integer> f, g, h;
1522 +
1523 +        f = new CompletableFuture<>();
1524 +        g = new CompletableFuture<>();
1525 +        h = f.thenCombineAsync(g, subtract);
1526 +        assertTrue(f.cancel(true));
1527 +        checkIncomplete(h);
1528 +        g.complete(1);
1529 +        checkCompletedWithWrappedCancellationException(h);
1530 +
1531 +        f = new CompletableFuture<>();
1532 +        g = new CompletableFuture<>();
1533 +        h = f.thenCombineAsync(g, subtract);
1534 +        assertTrue(g.cancel(true));
1535 +        checkIncomplete(h);
1536 +        f.complete(3);
1537 +        checkCompletedWithWrappedCancellationException(h);
1538 +
1539 +        f = new CompletableFuture<>();
1540 +        g = new CompletableFuture<>();
1541 +        g.complete(3);
1542 +        assertTrue(f.cancel(true));
1543 +        h = f.thenCombineAsync(g, subtract);
1544 +        checkCompletedWithWrappedCancellationException(h);
1545 +
1546 +        f = new CompletableFuture<>();
1547 +        g = new CompletableFuture<>();
1548 +        f.complete(3);
1549 +        assertTrue(g.cancel(true));
1550 +        h = f.thenCombineAsync(g, subtract);
1551 +        checkCompletedWithWrappedCancellationException(h);
1552 +    }
1553 +
1554 +    /**
1555 +     * thenAcceptBothAsync result completes normally after normal
1556 +     * completion of sources
1557 +     */
1558 +    public void testThenAcceptBothAsync() {
1559 +        CompletableFuture<Integer> f, g;
1560 +        CompletableFuture<Void> h;
1561 +        SubtractAction r;
1562 +
1563 +        f = new CompletableFuture<>();
1564 +        g = new CompletableFuture<>();
1565 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1566 +        f.complete(3);
1567 +        checkIncomplete(h);
1568 +        g.complete(1);
1569 +        checkCompletedNormally(h, null);
1570 +        assertEquals(r.value, 2);
1571 +
1572 +        f = new CompletableFuture<>();
1573 +        g = new CompletableFuture<>();
1574 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1575 +        g.complete(1);
1576 +        checkIncomplete(h);
1577 +        f.complete(3);
1578 +        checkCompletedNormally(h, null);
1579 +        assertEquals(r.value, 2);
1580 +
1581 +        f = new CompletableFuture<>();
1582 +        g = new CompletableFuture<>();
1583 +        g.complete(1);
1584 +        f.complete(3);
1585 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1586 +        checkCompletedNormally(h, null);
1587 +        assertEquals(r.value, 2);
1588 +    }
1589 +
1590 +    /**
1591 +     * thenAcceptBothAsync result completes exceptionally after exceptional
1592 +     * completion of source
1593 +     */
1594 +    public void testThenAcceptBothAsync2() {
1595 +        CompletableFuture<Integer> f, g;
1596 +        CompletableFuture<Void> h;
1597 +        SubtractAction r;
1598 +
1599 +        f = new CompletableFuture<>();
1600 +        g = new CompletableFuture<>();
1601 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1602 +        f.completeExceptionally(new CFException());
1603 +        checkIncomplete(h);
1604 +        g.complete(1);
1605 +        checkCompletedWithWrappedCFException(h);
1606 +
1607 +        f = new CompletableFuture<>();
1608 +        g = new CompletableFuture<>();
1609 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1610 +        g.completeExceptionally(new CFException());
1611 +        checkIncomplete(h);
1612 +        f.complete(3);
1613 +        checkCompletedWithWrappedCFException(h);
1614 +
1615 +        f = new CompletableFuture<>();
1616 +        g = new CompletableFuture<>();
1617 +        f.complete(3);
1618 +        g.completeExceptionally(new CFException());
1619 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1620 +        checkCompletedWithWrappedCFException(h);
1621 +
1622 +        f = new CompletableFuture<>();
1623 +        g = new CompletableFuture<>();
1624 +        f.completeExceptionally(new CFException());
1625 +        g.complete(3);
1626 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1627 +        checkCompletedWithWrappedCFException(h);
1628 +    }
1629 +
1630 +    /**
1631 +     * thenAcceptBothAsync result completes exceptionally if action does
1632 +     */
1633 +    public void testThenAcceptBothAsync3() {
1634 +        CompletableFuture<Integer> f, g;
1635 +        CompletableFuture<Void> h;
1636 +        FailingBiConsumer r;
1637 +
1638 +        f = new CompletableFuture<>();
1639 +        g = new CompletableFuture<>();
1640 +        h = f.thenAcceptBothAsync(g, r = new FailingBiConsumer());
1641 +        f.complete(3);
1642 +        checkIncomplete(h);
1643 +        g.complete(1);
1644 +        checkCompletedWithWrappedCFException(h);
1645 +
1646 +        f = new CompletableFuture<>();
1647 +        g = new CompletableFuture<>();
1648 +        f.complete(3);
1649 +        g.complete(1);
1650 +        h = f.thenAcceptBothAsync(g, r = new FailingBiConsumer());
1651 +        checkCompletedWithWrappedCFException(h);
1652 +    }
1653 +
1654 +    /**
1655 +     * thenAcceptBothAsync result completes exceptionally if either source cancelled
1656 +     */
1657 +    public void testThenAcceptBothAsync4() {
1658 +        CompletableFuture<Integer> f, g;
1659 +        CompletableFuture<Void> h;
1660 +        SubtractAction r;
1661 +
1662 +        f = new CompletableFuture<>();
1663 +        g = new CompletableFuture<>();
1664 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1665 +        assertTrue(f.cancel(true));
1666 +        checkIncomplete(h);
1667 +        g.complete(1);
1668 +        checkCompletedWithWrappedCancellationException(h);
1669 +
1670 +        f = new CompletableFuture<>();
1671 +        g = new CompletableFuture<>();
1672 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1673 +        assertTrue(g.cancel(true));
1674 +        checkIncomplete(h);
1675 +        f.complete(3);
1676 +        checkCompletedWithWrappedCancellationException(h);
1677 +
1678 +        f = new CompletableFuture<>();
1679 +        g = new CompletableFuture<>();
1680 +        f.complete(3);
1681 +        assertTrue(g.cancel(true));
1682 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1683 +        checkCompletedWithWrappedCancellationException(h);
1684 +
1685 +        f = new CompletableFuture<>();
1686 +        g = new CompletableFuture<>();
1687 +        assertTrue(f.cancel(true));
1688 +        g.complete(3);
1689 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1690 +        checkCompletedWithWrappedCancellationException(h);
1691 +    }
1692 +
1693 +    /**
1694 +     * runAfterBothAsync result completes normally after normal
1695 +     * completion of sources
1696 +     */
1697 +    public void testRunAfterBothAsync() {
1698 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1699 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1700 +        Noop r = new Noop();
1701 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1702 +        f.complete(one);
1703 +        checkIncomplete(g);
1704 +        f2.complete(two);
1705 +        checkCompletedNormally(g, null);
1706 +        assertTrue(r.ran);
1707 +    }
1708 +
1709 +    /**
1710 +     * runAfterBothAsync result completes exceptionally after exceptional
1711 +     * completion of source
1712 +     */
1713 +    public void testRunAfterBothAsync2() {
1714 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1715 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1716 +        Noop r = new Noop();
1717 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1718 +        f.completeExceptionally(new CFException());
1719 +        f2.complete(two);
1720 +        checkCompletedWithWrappedCFException(g);
1721 +
1722 +        r = new Noop();
1723 +        f = new CompletableFuture<>();
1724 +        f2 = new CompletableFuture<>();
1725 +        g = f.runAfterBothAsync(f2, r);
1726 +        f.complete(one);
1727 +        f2.completeExceptionally(new CFException());
1728 +        checkCompletedWithWrappedCFException(g);
1729 +    }
1730 +
1731 +    /**
1732 +     * runAfterBothAsync result completes exceptionally if action does
1733 +     */
1734 +    public void testRunAfterBothAsync3() {
1735 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1736 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1737 +        FailingNoop r = new FailingNoop();
1738 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1739 +        f.complete(one);
1740 +        checkIncomplete(g);
1741 +        f2.complete(two);
1742 +        checkCompletedWithWrappedCFException(g);
1743 +    }
1744 +
1745 +    /**
1746 +     * runAfterBothAsync result completes exceptionally if either source cancelled
1747 +     */
1748 +    public void testRunAfterBothAsync4() {
1749 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1750 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1751 +        Noop r = new Noop();
1752 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1753 +        assertTrue(f.cancel(true));
1754 +        f2.complete(two);
1755 +        checkCompletedWithWrappedCancellationException(g);
1756 +
1757 +        r = new Noop();
1758 +        f = new CompletableFuture<>();
1759 +        f2 = new CompletableFuture<>();
1760 +        g = f.runAfterBothAsync(f2, r);
1761 +        f.complete(one);
1762 +        assertTrue(f2.cancel(true));
1763 +        checkCompletedWithWrappedCancellationException(g);
1764 +    }
1765 +
1766 +    /**
1767 +     * applyToEitherAsync result completes normally after normal
1768 +     * completion of sources
1769 +     */
1770 +    public void testApplyToEitherAsync() {
1771 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1772 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1773 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc);
1774 +        f.complete(one);
1775 +        checkCompletedNormally(g, two);
1776 +
1777 +        f = new CompletableFuture<>();
1778 +        f.complete(one);
1779 +        f2 = new CompletableFuture<>();
1780 +        g = f.applyToEitherAsync(f2, inc);
1781 +        checkCompletedNormally(g, two);
1782 +    }
1783 +
1784 +    /**
1785 +     * applyToEitherAsync result completes exceptionally after exceptional
1786 +     * completion of source
1787 +     */
1788 +    public void testApplyToEitherAsync2() {
1789 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1790 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1791 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc);
1792 +        f.completeExceptionally(new CFException());
1793 +        checkCompletedWithWrappedCFException(g);
1794 +
1795 +        f = new CompletableFuture<>();
1796 +        f2 = new CompletableFuture<>();
1797 +        f2.completeExceptionally(new CFException());
1798 +        g = f.applyToEitherAsync(f2, inc);
1799 +        f.complete(one);
1800 +        checkCompletedWithWrappedCFException(g);
1801 +    }
1802 +
1803 +    /**
1804 +     * applyToEitherAsync result completes exceptionally if action does
1805 +     */
1806 +    public void testApplyToEitherAsync3() {
1807 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1808 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1809 +        FailingFunction r = new FailingFunction();
1810 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, r);
1811 +        f.complete(one);
1812 +        checkCompletedWithWrappedCFException(g);
1813 +    }
1814 +
1815 +    /**
1816 +     * applyToEitherAsync result completes exceptionally if either source cancelled
1817 +     */
1818 +    public void testApplyToEitherAsync4() {
1819 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1820 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1821 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc);
1822 +        assertTrue(f.cancel(true));
1823 +        checkCompletedWithWrappedCancellationException(g);
1824 +
1825 +        f = new CompletableFuture<>();
1826 +        f2 = new CompletableFuture<>();
1827 +        assertTrue(f2.cancel(true));
1828 +        g = f.applyToEitherAsync(f2, inc);
1829 +        checkCompletedWithWrappedCancellationException(g);
1830 +    }
1831 +
1832 +    /**
1833 +     * acceptEitherAsync result completes normally after normal
1834 +     * completion of sources
1835 +     */
1836 +    public void testAcceptEitherAsync() {
1837 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1838 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1839 +        IncAction r = new IncAction();
1840 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
1841 +        f.complete(one);
1842 +        checkCompletedNormally(g, null);
1843 +        assertEquals(r.value, 2);
1844 +
1845 +        r = new IncAction();
1846 +        f = new CompletableFuture<>();
1847 +        f.complete(one);
1848 +        f2 = new CompletableFuture<>();
1849 +        g = f.acceptEitherAsync(f2, r);
1850 +        checkCompletedNormally(g, null);
1851 +        assertEquals(r.value, 2);
1852 +    }
1853 +
1854 +    /**
1855 +     * acceptEitherAsync result completes exceptionally after exceptional
1856 +     * completion of source
1857 +     */
1858 +    public void testAcceptEitherAsync2() {
1859 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1860 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1861 +        IncAction r = new IncAction();
1862 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
1863 +        f.completeExceptionally(new CFException());
1864 +        checkCompletedWithWrappedCFException(g);
1865 +
1866 +        r = new IncAction();
1867 +        f = new CompletableFuture<>();
1868 +        f2 = new CompletableFuture<>();
1869 +        f2.completeExceptionally(new CFException());
1870 +        g = f.acceptEitherAsync(f2, r);
1871 +        f.complete(one);
1872 +        checkCompletedWithWrappedCFException(g);
1873 +    }
1874 +
1875 +    /**
1876 +     * acceptEitherAsync result completes exceptionally if action does
1877 +     */
1878 +    public void testAcceptEitherAsync3() {
1879 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1880 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1881 +        FailingConsumer r = new FailingConsumer();
1882 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
1883 +        f.complete(one);
1884 +        checkCompletedWithWrappedCFException(g);
1885 +    }
1886 +
1887 +    /**
1888 +     * acceptEitherAsync result completes exceptionally if either
1889 +     * source cancelled
1890 +     */
1891 +    public void testAcceptEitherAsync4() {
1892 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1893 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1894 +        IncAction r = new IncAction();
1895 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
1896 +        assertTrue(f.cancel(true));
1897 +        checkCompletedWithWrappedCancellationException(g);
1898 +
1899 +        r = new IncAction();
1900 +        f = new CompletableFuture<>();
1901 +        f2 = new CompletableFuture<>();
1902 +        assertTrue(f2.cancel(true));
1903 +        g = f.acceptEitherAsync(f2, r);
1904 +        checkCompletedWithWrappedCancellationException(g);
1905 +    }
1906 +
1907 +    /**
1908 +     * runAfterEitherAsync result completes normally after normal
1909 +     * completion of sources
1910 +     */
1911 +    public void testRunAfterEitherAsync() {
1912 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1913 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1914 +        Noop r = new Noop();
1915 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r);
1916 +        f.complete(one);
1917 +        checkCompletedNormally(g, null);
1918 +        assertTrue(r.ran);
1919 +
1920 +        r = new Noop();
1921 +        f = new CompletableFuture<>();
1922 +        f.complete(one);
1923 +        f2 = new CompletableFuture<>();
1924 +        g = f.runAfterEitherAsync(f2, r);
1925 +        checkCompletedNormally(g, null);
1926 +        assertTrue(r.ran);
1927 +    }
1928 +
1929 +    /**
1930 +     * runAfterEitherAsync result completes exceptionally after exceptional
1931 +     * completion of source
1932 +     */
1933 +    public void testRunAfterEitherAsync2() {
1934 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1935 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1936 +        Noop r = new Noop();
1937 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r);
1938 +        f.completeExceptionally(new CFException());
1939 +        checkCompletedWithWrappedCFException(g);
1940 +
1941 +        r = new Noop();
1942 +        f = new CompletableFuture<>();
1943 +        f2 = new CompletableFuture<>();
1944 +        f2.completeExceptionally(new CFException());
1945 +        g = f.runAfterEitherAsync(f2, r);
1946 +        f.complete(one);
1947 +        checkCompletedWithWrappedCFException(g);
1948 +    }
1949 +
1950 +    /**
1951 +     * runAfterEitherAsync result completes exceptionally if action does
1952 +     */
1953 +    public void testRunAfterEitherAsync3() {
1954 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1955 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1956 +        FailingNoop r = new FailingNoop();
1957 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r);
1958 +        f.complete(one);
1959 +        checkCompletedWithWrappedCFException(g);
1960 +    }
1961 +
1962 +    /**
1963 +     * runAfterEitherAsync result completes exceptionally if either
1964 +     * source cancelled
1965 +     */
1966 +    public void testRunAfterEitherAsync4() {
1967 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1968 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1969 +        Noop r = new Noop();
1970 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r);
1971 +        assertTrue(f.cancel(true));
1972 +        checkCompletedWithWrappedCancellationException(g);
1973 +
1974 +        r = new Noop();
1975 +        f = new CompletableFuture<>();
1976 +        f2 = new CompletableFuture<>();
1977 +        assertTrue(f2.cancel(true));
1978 +        g = f.runAfterEitherAsync(f2, r);
1979 +        checkCompletedWithWrappedCancellationException(g);
1980 +    }
1981 +
1982 +    /**
1983 +     * thenComposeAsync result completes normally after normal
1984 +     * completion of source
1985 +     */
1986 +    public void testThenComposeAsync() {
1987 +        CompletableFuture<Integer> f, g;
1988 +        CompletableFutureInc r;
1989 +
1990 +        f = new CompletableFuture<>();
1991 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
1992 +        f.complete(one);
1993 +        checkCompletedNormally(g, two);
1994 +
1995 +        f = new CompletableFuture<>();
1996 +        f.complete(one);
1997 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
1998 +        checkCompletedNormally(g, two);
1999 +    }
2000 +
2001 +    /**
2002 +     * thenComposeAsync result completes exceptionally after
2003 +     * exceptional completion of source
2004 +     */
2005 +    public void testThenComposeAsync2() {
2006 +        CompletableFuture<Integer> f, g;
2007 +        CompletableFutureInc r;
2008 +
2009 +        f = new CompletableFuture<>();
2010 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
2011 +        f.completeExceptionally(new CFException());
2012 +        checkCompletedWithWrappedCFException(g);
2013 +        assertFalse(r.ran);
2014 +
2015 +        f = new CompletableFuture<>();
2016 +        f.completeExceptionally(new CFException());
2017 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
2018 +        checkCompletedWithWrappedCFException(g);
2019 +        assertFalse(r.ran);
2020 +    }
2021 +
2022 +    /**
2023 +     * thenComposeAsync result completes exceptionally if action does
2024 +     */
2025 +    public void testThenComposeAsync3() {
2026 +        CompletableFuture<Integer> f, g;
2027 +        FailingCompletableFutureFunction r;
2028 +
2029 +        f = new CompletableFuture<>();
2030 +        g = f.thenComposeAsync(r = new FailingCompletableFutureFunction());
2031 +        f.complete(one);
2032 +        checkCompletedWithWrappedCFException(g);
2033 +
2034 +        f = new CompletableFuture<>();
2035 +        f.complete(one);
2036 +        g = f.thenComposeAsync(r = new FailingCompletableFutureFunction());
2037 +        checkCompletedWithWrappedCFException(g);
2038 +    }
2039 +
2040 +    /**
2041 +     * thenComposeAsync result completes exceptionally if source cancelled
2042 +     */
2043 +    public void testThenComposeAsync4() {
2044 +        CompletableFuture<Integer> f, g;
2045 +        CompletableFutureInc r;
2046 +
2047 +        f = new CompletableFuture<>();
2048 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
2049 +        assertTrue(f.cancel(true));
2050 +        checkCompletedWithWrappedCancellationException(g);
2051 +
2052 +        f = new CompletableFuture<>();
2053 +        assertTrue(f.cancel(true));
2054 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
2055 +        checkCompletedWithWrappedCancellationException(g);
2056 +    }
2057 +
2058 +
2059 +    // async with explicit executors
2060 +
2061 +    /**
2062 +     * thenRunAsync result completes normally after normal completion of source
2063 +     */
2064 +    public void testThenRunAsyncE() {
2065 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2066 +        Noop r = new Noop();
2067 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
2068 +        f.complete(null);
2069 +        checkCompletedNormally(g, null);
2070 +
2071 +        // reordered version
2072 +        f = new CompletableFuture<>();
2073 +        f.complete(null);
2074 +        r = new Noop();
2075 +        g = f.thenRunAsync(r, new ThreadExecutor());
2076 +        checkCompletedNormally(g, null);
2077 +    }
2078 +
2079 +    /**
2080 +     * thenRunAsync result completes exceptionally after exceptional
2081 +     * completion of source
2082 +     */
2083 +    public void testThenRunAsync2E() {
2084 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2085 +        Noop r = new Noop();
2086 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
2087 +        f.completeExceptionally(new CFException());
2088 +        try {
2089 +            g.join();
2090 +            shouldThrow();
2091 +        } catch (Exception ok) {
2092 +        }
2093 +        checkCompletedWithWrappedCFException(g);
2094 +    }
2095 +
2096 +    /**
2097 +     * thenRunAsync result completes exceptionally if action does
2098 +     */
2099 +    public void testThenRunAsync3E() {
2100 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2101 +        FailingNoop r = new FailingNoop();
2102 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
2103 +        f.complete(null);
2104 +        checkCompletedWithWrappedCFException(g);
2105 +    }
2106 +
2107 +    /**
2108 +     * thenRunAsync result completes exceptionally if source cancelled
2109 +     */
2110 +    public void testThenRunAsync4E() {
2111 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2112 +        Noop r = new Noop();
2113 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
2114 +        assertTrue(f.cancel(true));
2115 +        checkCompletedWithWrappedCancellationException(g);
2116 +    }
2117 +
2118 +    /**
2119 +     * thenApplyAsync result completes normally after normal completion of source
2120 +     */
2121 +    public void testThenApplyAsyncE() {
2122 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2123 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc, new ThreadExecutor());
2124 +        f.complete(one);
2125 +        checkCompletedNormally(g, two);
2126 +    }
2127 +
2128 +    /**
2129 +     * thenApplyAsync result completes exceptionally after exceptional
2130 +     * completion of source
2131 +     */
2132 +    public void testThenApplyAsync2E() {
2133 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2134 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc, new ThreadExecutor());
2135 +        f.completeExceptionally(new CFException());
2136 +        checkCompletedWithWrappedCFException(g);
2137 +    }
2138 +
2139 +    /**
2140 +     * thenApplyAsync result completes exceptionally if action does
2141 +     */
2142 +    public void testThenApplyAsync3E() {
2143 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2144 +        FailingFunction r = new FailingFunction();
2145 +        CompletableFuture<Integer> g = f.thenApplyAsync(r, new ThreadExecutor());
2146 +        f.complete(null);
2147 +        checkCompletedWithWrappedCFException(g);
2148 +    }
2149 +
2150 +    /**
2151 +     * thenApplyAsync result completes exceptionally if source cancelled
2152 +     */
2153 +    public void testThenApplyAsync4E() {
2154 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2155 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc, new ThreadExecutor());
2156 +        assertTrue(f.cancel(true));
2157 +        checkCompletedWithWrappedCancellationException(g);
2158 +    }
2159 +
2160 +    /**
2161 +     * thenAcceptAsync result completes normally after normal
2162 +     * completion of source
2163 +     */
2164 +    public void testThenAcceptAsyncE() {
2165 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2166 +        IncAction r = new IncAction();
2167 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
2168 +        f.complete(one);
2169 +        checkCompletedNormally(g, null);
2170 +        assertEquals(r.value, 2);
2171 +    }
2172 +
2173 +    /**
2174 +     * thenAcceptAsync result completes exceptionally after exceptional
2175 +     * completion of source
2176 +     */
2177 +    public void testThenAcceptAsync2E() {
2178 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2179 +        IncAction r = new IncAction();
2180 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
2181 +        f.completeExceptionally(new CFException());
2182 +        checkCompletedWithWrappedCFException(g);
2183 +    }
2184 +
2185 +    /**
2186 +     * thenAcceptAsync result completes exceptionally if action does
2187 +     */
2188 +    public void testThenAcceptAsync3E() {
2189 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2190 +        FailingConsumer r = new FailingConsumer();
2191 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
2192 +        f.complete(null);
2193 +        checkCompletedWithWrappedCFException(g);
2194 +    }
2195 +
2196 +    /**
2197 +     * thenAcceptAsync result completes exceptionally if source cancelled
2198 +     */
2199 +    public void testThenAcceptAsync4E() {
2200 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2201 +        IncAction r = new IncAction();
2202 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
2203 +        assertTrue(f.cancel(true));
2204 +        checkCompletedWithWrappedCancellationException(g);
2205 +    }
2206 +
2207 +    /**
2208 +     * thenCombineAsync result completes normally after normal
2209 +     * completion of sources
2210 +     */
2211 +    public void testThenCombineAsyncE() {
2212 +        CompletableFuture<Integer> f, g, h;
2213 +        ThreadExecutor e = new ThreadExecutor();
2214 +        int count = 0;
2215 +
2216 +        f = new CompletableFuture<>();
2217 +        g = new CompletableFuture<>();
2218 +        h = f.thenCombineAsync(g, subtract, e);
2219 +        f.complete(3);
2220 +        checkIncomplete(h);
2221 +        g.complete(1);
2222 +        checkCompletedNormally(h, 2);
2223 +        assertEquals(++count, e.count.get());
2224 +
2225 +        f = new CompletableFuture<>();
2226 +        g = new CompletableFuture<>();
2227 +        h = f.thenCombineAsync(g, subtract, e);
2228 +        g.complete(1);
2229 +        checkIncomplete(h);
2230 +        f.complete(3);
2231 +        checkCompletedNormally(h, 2);
2232 +        assertEquals(++count, e.count.get());
2233 +
2234 +        f = new CompletableFuture<>();
2235 +        g = new CompletableFuture<>();
2236 +        g.complete(1);
2237 +        f.complete(3);
2238 +        h = f.thenCombineAsync(g, subtract, e);
2239 +        checkCompletedNormally(h, 2);
2240 +        assertEquals(++count, e.count.get());
2241 +    }
2242 +
2243 +    /**
2244 +     * thenCombineAsync result completes exceptionally after exceptional
2245 +     * completion of either source
2246 +     */
2247 +    public void testThenCombineAsync2E() {
2248 +        CompletableFuture<Integer> f, g, h;
2249 +        ThreadExecutor e = new ThreadExecutor();
2250 +        int count = 0;
2251 +
2252 +        f = new CompletableFuture<>();
2253 +        g = new CompletableFuture<>();
2254 +        h = f.thenCombineAsync(g, subtract, e);
2255 +        f.completeExceptionally(new CFException());
2256 +        checkIncomplete(h);
2257 +        g.complete(1);
2258 +        checkCompletedWithWrappedCFException(h);
2259 +
2260 +        f = new CompletableFuture<>();
2261 +        g = new CompletableFuture<>();
2262 +        h = f.thenCombineAsync(g, subtract, e);
2263 +        g.completeExceptionally(new CFException());
2264 +        checkIncomplete(h);
2265 +        f.complete(3);
2266 +        checkCompletedWithWrappedCFException(h);
2267 +
2268 +        f = new CompletableFuture<>();
2269 +        g = new CompletableFuture<>();
2270 +        g.completeExceptionally(new CFException());
2271 +        h = f.thenCombineAsync(g, subtract, e);
2272 +        checkIncomplete(h);
2273 +        f.complete(3);
2274 +        checkCompletedWithWrappedCFException(h);
2275 +
2276 +        assertEquals(0, e.count.get());
2277 +    }
2278 +
2279 +    /**
2280 +     * thenCombineAsync result completes exceptionally if action does
2281 +     */
2282 +    public void testThenCombineAsync3E() {
2283 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2284 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2285 +        FailingBiFunction r = new FailingBiFunction();
2286 +        CompletableFuture<Integer> g = f.thenCombineAsync(f2, r, new ThreadExecutor());
2287 +        f.complete(one);
2288 +        checkIncomplete(g);
2289 +        assertFalse(r.ran);
2290 +        f2.complete(two);
2291 +        checkCompletedWithWrappedCFException(g);
2292 +        assertTrue(r.ran);
2293 +    }
2294 +
2295 +    /**
2296 +     * thenCombineAsync result completes exceptionally if either source cancelled
2297 +     */
2298 +    public void testThenCombineAsync4E() {
2299 +        CompletableFuture<Integer> f, g, h;
2300 +        ThreadExecutor e = new ThreadExecutor();
2301 +
2302 +        f = new CompletableFuture<>();
2303 +        g = new CompletableFuture<>();
2304 +        h = f.thenCombineAsync(g, subtract, e);
2305 +        assertTrue(f.cancel(true));
2306 +        checkIncomplete(h);
2307 +        g.complete(1);
2308 +        checkCompletedWithWrappedCancellationException(h);
2309 +
2310 +        f = new CompletableFuture<>();
2311 +        g = new CompletableFuture<>();
2312 +        h = f.thenCombineAsync(g, subtract, e);
2313 +        assertTrue(g.cancel(true));
2314 +        checkIncomplete(h);
2315 +        f.complete(3);
2316 +        checkCompletedWithWrappedCancellationException(h);
2317 +
2318 +        f = new CompletableFuture<>();
2319 +        g = new CompletableFuture<>();
2320 +        assertTrue(g.cancel(true));
2321 +        h = f.thenCombineAsync(g, subtract, e);
2322 +        checkIncomplete(h);
2323 +        f.complete(3);
2324 +        checkCompletedWithWrappedCancellationException(h);
2325 +
2326 +        f = new CompletableFuture<>();
2327 +        g = new CompletableFuture<>();
2328 +        assertTrue(f.cancel(true));
2329 +        assertTrue(g.cancel(true));
2330 +        h = f.thenCombineAsync(g, subtract, e);
2331 +        checkCompletedWithWrappedCancellationException(h);
2332 +
2333 +        assertEquals(0, e.count.get());
2334 +    }
2335 +
2336 +    /**
2337 +     * thenAcceptBothAsync result completes normally after normal
2338 +     * completion of sources
2339 +     */
2340 +    public void testThenAcceptBothAsyncE() {
2341 +        CompletableFuture<Integer> f, g;
2342 +        CompletableFuture<Void> h;
2343 +        SubtractAction r;
2344 +        ThreadExecutor e = new ThreadExecutor();
2345 +
2346 +        f = new CompletableFuture<>();
2347 +        g = new CompletableFuture<>();
2348 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2349 +        f.complete(3);
2350 +        checkIncomplete(h);
2351 +        g.complete(1);
2352 +        checkCompletedNormally(h, null);
2353 +        assertEquals(r.value, 2);
2354 +
2355 +        f = new CompletableFuture<>();
2356 +        g = new CompletableFuture<>();
2357 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2358 +        g.complete(1);
2359 +        checkIncomplete(h);
2360 +        f.complete(3);
2361 +        checkCompletedNormally(h, null);
2362 +        assertEquals(r.value, 2);
2363 +
2364 +        f = new CompletableFuture<>();
2365 +        g = new CompletableFuture<>();
2366 +        g.complete(1);
2367 +        f.complete(3);
2368 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2369 +        checkCompletedNormally(h, null);
2370 +        assertEquals(r.value, 2);
2371 +
2372 +        assertEquals(3, e.count.get());
2373 +    }
2374 +
2375 +    /**
2376 +     * thenAcceptBothAsync result completes exceptionally after exceptional
2377 +     * completion of source
2378 +     */
2379 +    public void testThenAcceptBothAsync2E() {
2380 +        CompletableFuture<Integer> f, g;
2381 +        CompletableFuture<Void> h;
2382 +        SubtractAction r;
2383 +        ThreadExecutor e = new ThreadExecutor();
2384 +
2385 +        f = new CompletableFuture<>();
2386 +        g = new CompletableFuture<>();
2387 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2388 +        f.completeExceptionally(new CFException());
2389 +        checkIncomplete(h);
2390 +        g.complete(1);
2391 +        checkCompletedWithWrappedCFException(h);
2392 +
2393 +        f = new CompletableFuture<>();
2394 +        g = new CompletableFuture<>();
2395 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2396 +        g.completeExceptionally(new CFException());
2397 +        checkIncomplete(h);
2398 +        f.complete(3);
2399 +        checkCompletedWithWrappedCFException(h);
2400 +
2401 +        f = new CompletableFuture<>();
2402 +        g = new CompletableFuture<>();
2403 +        f.complete(3);
2404 +        g.completeExceptionally(new CFException());
2405 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2406 +        checkCompletedWithWrappedCFException(h);
2407 +
2408 +        f = new CompletableFuture<>();
2409 +        g = new CompletableFuture<>();
2410 +        f.completeExceptionally(new CFException());
2411 +        g.complete(3);
2412 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2413 +        checkCompletedWithWrappedCFException(h);
2414 +
2415 +        assertEquals(0, e.count.get());
2416 +    }
2417 +
2418 +    /**
2419 +     * thenAcceptBothAsync result completes exceptionally if action does
2420 +     */
2421 +    public void testThenAcceptBothAsync3E() {
2422 +        CompletableFuture<Integer> f, g;
2423 +        CompletableFuture<Void> h;
2424 +        FailingBiConsumer r;
2425 +        ThreadExecutor e = new ThreadExecutor();
2426 +
2427 +        f = new CompletableFuture<>();
2428 +        g = new CompletableFuture<>();
2429 +        h = f.thenAcceptBothAsync(g, r = new FailingBiConsumer(), e);
2430 +        f.complete(3);
2431 +        checkIncomplete(h);
2432 +        g.complete(1);
2433 +        checkCompletedWithWrappedCFException(h);
2434 +
2435 +        f = new CompletableFuture<>();
2436 +        g = new CompletableFuture<>();
2437 +        f.complete(3);
2438 +        g.complete(1);
2439 +        h = f.thenAcceptBothAsync(g, r = new FailingBiConsumer(), e);
2440 +        checkCompletedWithWrappedCFException(h);
2441 +
2442 +        assertEquals(2, e.count.get());
2443 +    }
2444 +
2445 +    /**
2446 +     * thenAcceptBothAsync result completes exceptionally if either source cancelled
2447 +     */
2448 +    public void testThenAcceptBothAsync4E() {
2449 +        CompletableFuture<Integer> f, g;
2450 +        CompletableFuture<Void> h;
2451 +        SubtractAction r;
2452 +        ThreadExecutor e = new ThreadExecutor();
2453 +
2454 +        f = new CompletableFuture<>();
2455 +        g = new CompletableFuture<>();
2456 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2457 +        assertTrue(f.cancel(true));
2458 +        checkIncomplete(h);
2459 +        g.complete(1);
2460 +        checkCompletedWithWrappedCancellationException(h);
2461 +
2462 +        f = new CompletableFuture<>();
2463 +        g = new CompletableFuture<>();
2464 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2465 +        assertTrue(g.cancel(true));
2466 +        checkIncomplete(h);
2467 +        f.complete(3);
2468 +        checkCompletedWithWrappedCancellationException(h);
2469 +
2470 +        f = new CompletableFuture<>();
2471 +        g = new CompletableFuture<>();
2472 +        f.complete(3);
2473 +        assertTrue(g.cancel(true));
2474 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2475 +        checkCompletedWithWrappedCancellationException(h);
2476 +
2477 +        f = new CompletableFuture<>();
2478 +        g = new CompletableFuture<>();
2479 +        assertTrue(f.cancel(true));
2480 +        g.complete(3);
2481 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2482 +        checkCompletedWithWrappedCancellationException(h);
2483 +
2484 +        assertEquals(0, e.count.get());
2485 +    }
2486 +
2487 +    /**
2488 +     * runAfterBothAsync result completes normally after normal
2489 +     * completion of sources
2490 +     */
2491 +    public void testRunAfterBothAsyncE() {
2492 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2493 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2494 +        Noop r = new Noop();
2495 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2496 +        f.complete(one);
2497 +        checkIncomplete(g);
2498 +        f2.complete(two);
2499 +        checkCompletedNormally(g, null);
2500 +        assertTrue(r.ran);
2501 +    }
2502 +
2503 +    /**
2504 +     * runAfterBothAsync result completes exceptionally after exceptional
2505 +     * completion of source
2506 +     */
2507 +    public void testRunAfterBothAsync2E() {
2508 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2509 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2510 +        Noop r = new Noop();
2511 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2512 +        f.completeExceptionally(new CFException());
2513 +        f2.complete(two);
2514 +        checkCompletedWithWrappedCFException(g);
2515 +
2516 +        r = new Noop();
2517 +        f = new CompletableFuture<>();
2518 +        f2 = new CompletableFuture<>();
2519 +        g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2520 +        f.complete(one);
2521 +        f2.completeExceptionally(new CFException());
2522 +        checkCompletedWithWrappedCFException(g);
2523 +    }
2524 +
2525 +    /**
2526 +     * runAfterBothAsync result completes exceptionally if action does
2527 +     */
2528 +    public void testRunAfterBothAsync3E() {
2529 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2530 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2531 +        FailingNoop r = new FailingNoop();
2532 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2533 +        f.complete(one);
2534 +        checkIncomplete(g);
2535 +        f2.complete(two);
2536 +        checkCompletedWithWrappedCFException(g);
2537 +    }
2538 +
2539 +    /**
2540 +     * runAfterBothAsync result completes exceptionally if either source cancelled
2541 +     */
2542 +    public void testRunAfterBothAsync4E() {
2543 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2544 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2545 +        Noop r = new Noop();
2546 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2547 +        assertTrue(f.cancel(true));
2548 +        f2.complete(two);
2549 +        checkCompletedWithWrappedCancellationException(g);
2550 +
2551 +        r = new Noop();
2552 +        f = new CompletableFuture<>();
2553 +        f2 = new CompletableFuture<>();
2554 +        g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2555 +        f.complete(one);
2556 +        assertTrue(f2.cancel(true));
2557 +        checkCompletedWithWrappedCancellationException(g);
2558 +    }
2559 +
2560 +    /**
2561 +     * applyToEitherAsync result completes normally after normal
2562 +     * completion of sources
2563 +     */
2564 +    public void testApplyToEitherAsyncE() {
2565 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2566 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2567 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2568 +        f.complete(one);
2569 +        checkCompletedNormally(g, two);
2570 +
2571 +        f = new CompletableFuture<>();
2572 +        f.complete(one);
2573 +        f2 = new CompletableFuture<>();
2574 +        g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2575 +        checkCompletedNormally(g, two);
2576 +    }
2577 +
2578 +    /**
2579 +     * applyToEitherAsync result completes exceptionally after exceptional
2580 +     * completion of source
2581 +     */
2582 +    public void testApplyToEitherAsync2E() {
2583 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2584 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2585 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2586 +        f.completeExceptionally(new CFException());
2587 +        checkCompletedWithWrappedCFException(g);
2588 +
2589 +        f = new CompletableFuture<>();
2590 +        f2 = new CompletableFuture<>();
2591 +        f2.completeExceptionally(new CFException());
2592 +        g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2593 +        f.complete(one);
2594 +        checkCompletedWithWrappedCFException(g);
2595 +    }
2596 +
2597 +    /**
2598 +     * applyToEitherAsync result completes exceptionally if action does
2599 +     */
2600 +    public void testApplyToEitherAsync3E() {
2601 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2602 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2603 +        FailingFunction r = new FailingFunction();
2604 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, r, new ThreadExecutor());
2605 +        f.complete(one);
2606 +        checkCompletedWithWrappedCFException(g);
2607 +    }
2608 +
2609 +    /**
2610 +     * applyToEitherAsync result completes exceptionally if either source cancelled
2611 +     */
2612 +    public void testApplyToEitherAsync4E() {
2613 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2614 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2615 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2616 +        assertTrue(f.cancel(true));
2617 +        checkCompletedWithWrappedCancellationException(g);
2618 +
2619 +        f = new CompletableFuture<>();
2620 +        f2 = new CompletableFuture<>();
2621 +        assertTrue(f2.cancel(true));
2622 +        g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2623 +        checkCompletedWithWrappedCancellationException(g);
2624 +    }
2625 +
2626 +    /**
2627 +     * acceptEitherAsync result completes normally after normal
2628 +     * completion of sources
2629 +     */
2630 +    public void testAcceptEitherAsyncE() {
2631 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2632 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2633 +        IncAction r = new IncAction();
2634 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2635 +        f.complete(one);
2636 +        checkCompletedNormally(g, null);
2637 +        assertEquals(r.value, 2);
2638 +
2639 +        r = new IncAction();
2640 +        f = new CompletableFuture<>();
2641 +        f.complete(one);
2642 +        f2 = new CompletableFuture<>();
2643 +        g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2644 +        checkCompletedNormally(g, null);
2645 +        assertEquals(r.value, 2);
2646 +    }
2647 +
2648 +    /**
2649 +     * acceptEitherAsync result completes exceptionally after exceptional
2650 +     * completion of source
2651 +     */
2652 +    public void testAcceptEitherAsync2E() {
2653 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2654 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2655 +        IncAction r = new IncAction();
2656 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2657 +        f.completeExceptionally(new CFException());
2658 +        checkCompletedWithWrappedCFException(g);
2659 +
2660 +        r = new IncAction();
2661 +        f = new CompletableFuture<>();
2662 +        f2 = new CompletableFuture<>();
2663 +        f2.completeExceptionally(new CFException());
2664 +        g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2665 +        f.complete(one);
2666 +        checkCompletedWithWrappedCFException(g);
2667 +    }
2668 +
2669 +    /**
2670 +     * acceptEitherAsync result completes exceptionally if action does
2671 +     */
2672 +    public void testAcceptEitherAsync3E() {
2673 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2674 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2675 +        FailingConsumer r = new FailingConsumer();
2676 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2677 +        f.complete(one);
2678 +        checkCompletedWithWrappedCFException(g);
2679 +    }
2680 +
2681 +    /**
2682 +     * acceptEitherAsync result completes exceptionally if either
2683 +     * source cancelled
2684 +     */
2685 +    public void testAcceptEitherAsync4E() {
2686 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2687 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2688 +        IncAction r = new IncAction();
2689 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2690 +        assertTrue(f.cancel(true));
2691 +        checkCompletedWithWrappedCancellationException(g);
2692 +
2693 +        r = new IncAction();
2694 +        f = new CompletableFuture<>();
2695 +        f2 = new CompletableFuture<>();
2696 +        assertTrue(f2.cancel(true));
2697 +        g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2698 +        checkCompletedWithWrappedCancellationException(g);
2699 +    }
2700 +
2701 +    /**
2702 +     * runAfterEitherAsync result completes normally after normal
2703 +     * completion of sources
2704 +     */
2705 +    public void testRunAfterEitherAsyncE() {
2706 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2707 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2708 +        Noop r = new Noop();
2709 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2710 +        f.complete(one);
2711 +        checkCompletedNormally(g, null);
2712 +        assertTrue(r.ran);
2713 +
2714 +        r = new Noop();
2715 +        f = new CompletableFuture<>();
2716 +        f.complete(one);
2717 +        f2 = new CompletableFuture<>();
2718 +        g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2719 +        checkCompletedNormally(g, null);
2720 +        assertTrue(r.ran);
2721 +    }
2722 +
2723 +    /**
2724 +     * runAfterEitherAsync result completes exceptionally after exceptional
2725 +     * completion of source
2726 +     */
2727 +    public void testRunAfterEitherAsync2E() {
2728 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2729 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2730 +        Noop r = new Noop();
2731 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2732 +        f.completeExceptionally(new CFException());
2733 +        checkCompletedWithWrappedCFException(g);
2734 +
2735 +        r = new Noop();
2736 +        f = new CompletableFuture<>();
2737 +        f2 = new CompletableFuture<>();
2738 +        f2.completeExceptionally(new CFException());
2739 +        g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2740 +        f.complete(one);
2741 +        checkCompletedWithWrappedCFException(g);
2742 +    }
2743 +
2744 +    /**
2745 +     * runAfterEitherAsync result completes exceptionally if action does
2746 +     */
2747 +    public void testRunAfterEitherAsync3E() {
2748 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2749 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2750 +        FailingNoop r = new FailingNoop();
2751 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2752 +        f.complete(one);
2753 +        checkCompletedWithWrappedCFException(g);
2754 +    }
2755 +
2756 +    /**
2757 +     * runAfterEitherAsync result completes exceptionally if either
2758 +     * source cancelled
2759 +     */
2760 +    public void testRunAfterEitherAsync4E() {
2761 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2762 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2763 +        Noop r = new Noop();
2764 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2765 +        assertTrue(f.cancel(true));
2766 +        checkCompletedWithWrappedCancellationException(g);
2767 +
2768 +        r = new Noop();
2769 +        f = new CompletableFuture<>();
2770 +        f2 = new CompletableFuture<>();
2771 +        assertTrue(f2.cancel(true));
2772 +        g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2773 +        checkCompletedWithWrappedCancellationException(g);
2774 +    }
2775 +
2776 +    /**
2777 +     * thenComposeAsync result completes normally after normal
2778 +     * completion of source
2779 +     */
2780 +    public void testThenComposeAsyncE() {
2781 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2782 +        CompletableFutureInc r = new CompletableFutureInc();
2783 +        CompletableFuture<Integer> g = f.thenComposeAsync(r, new ThreadExecutor());
2784 +        f.complete(one);
2785 +        checkCompletedNormally(g, two);
2786 +    }
2787 +
2788 +    /**
2789 +     * thenComposeAsync result completes exceptionally after
2790 +     * exceptional completion of source
2791 +     */
2792 +    public void testThenComposeAsync2E() {
2793 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2794 +        CompletableFutureInc r = new CompletableFutureInc();
2795 +        CompletableFuture<Integer> g = f.thenComposeAsync(r, new ThreadExecutor());
2796 +        f.completeExceptionally(new CFException());
2797 +        checkCompletedWithWrappedCFException(g);
2798 +    }
2799 +
2800 +    /**
2801 +     * thenComposeAsync result completes exceptionally if action does
2802 +     */
2803 +    public void testThenComposeAsync3E() {
2804 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2805 +        FailingCompletableFutureFunction r = new FailingCompletableFutureFunction();
2806 +        CompletableFuture<Integer> g = f.thenComposeAsync(r, new ThreadExecutor());
2807 +        f.complete(one);
2808 +        checkCompletedWithWrappedCFException(g);
2809 +    }
2810 +
2811 +    /**
2812 +     * thenComposeAsync result completes exceptionally if source cancelled
2813 +     */
2814 +    public void testThenComposeAsync4E() {
2815 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2816 +        CompletableFutureInc r = new CompletableFutureInc();
2817 +        CompletableFuture<Integer> g = f.thenComposeAsync(r, new ThreadExecutor());
2818 +        assertTrue(f.cancel(true));
2819 +        checkCompletedWithWrappedCancellationException(g);
2820 +    }
2821 +
2822 +    // other static methods
2823 +
2824 +    /**
2825 +     * allOf(no component futures) returns a future completed normally
2826 +     * with the value null
2827 +     */
2828 +    public void testAllOf_empty() throws Exception {
2829 +        CompletableFuture<?> f = CompletableFuture.allOf();
2830 +        checkCompletedNormally(f, null);
2831 +    }
2832 +
2833 +    /**
2834 +     * allOf returns a future completed when all components complete
2835 +     */
2836 +    public void testAllOf() throws Exception {
2837 +        for (int k = 1; k < 20; ++k) {
2838 +            CompletableFuture<Integer>[] fs = (CompletableFuture<Integer>[]) new CompletableFuture[k];
2839 +            for (int i = 0; i < k; ++i)
2840 +                fs[i] = new CompletableFuture<>();
2841 +            CompletableFuture<Void> f = CompletableFuture.allOf(fs);
2842 +            for (int i = 0; i < k; ++i) {
2843 +                checkIncomplete(f);
2844 +                fs[i].complete(one);
2845 +            }
2846 +            checkCompletedNormally(f, null);
2847 +        }
2848 +    }
2849 +
2850 +    /**
2851 +     * anyOf(no component futures) returns an incomplete future
2852 +     */
2853 +    public void testAnyOf_empty() throws Exception {
2854 +        CompletableFuture<?> f = CompletableFuture.anyOf();
2855 +        checkIncomplete(f);
2856 +    }
2857 +
2858 +    /**
2859 +     * anyOf returns a future completed when any components complete
2860 +     */
2861 +    public void testAnyOf() throws Exception {
2862 +        for (int k = 1; k < 20; ++k) {
2863 +            CompletableFuture[] fs = new CompletableFuture[k];
2864 +            for (int i = 0; i < k; ++i)
2865 +                fs[i] = new CompletableFuture<>();
2866 +            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
2867 +            checkIncomplete(f);
2868 +            for (int i = 0; i < k; ++i) {
2869 +                fs[i].complete(one);
2870 +                checkCompletedNormally(f, one);
2871 +            }
2872 +        }
2873 +    }
2874 +
2875 +    /**
2876 +     * Completion methods throw NullPointerException with null arguments
2877 +     */
2878 +    public void testNPE() {
2879 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2880 +        CompletableFuture<Integer> g = new CompletableFuture<>();
2881 +        CompletableFuture<Integer> nullFuture = (CompletableFuture<Integer>)null;
2882 +        CompletableFuture<?> h;
2883 +        ThreadExecutor exec = new ThreadExecutor();
2884 +
2885 +        Runnable[] throwingActions = {
2886 +            () -> { CompletableFuture.supplyAsync(null); },
2887 +            () -> { CompletableFuture.supplyAsync(null, exec); },
2888 +            () -> { CompletableFuture.supplyAsync(supplyOne, null); },
2889 +
2890 +            () -> { CompletableFuture.runAsync(null); },
2891 +            () -> { CompletableFuture.runAsync(null, exec); },
2892 +            () -> { CompletableFuture.runAsync(() -> {}, null); },
2893 +
2894 +            () -> { f.completeExceptionally(null); },
2895 +
2896 +            () -> { f.thenApply(null); },
2897 +            () -> { f.thenApplyAsync(null); },
2898 +            () -> { f.thenApplyAsync((x) -> x, null); },
2899 +            () -> { f.thenApplyAsync(null, exec); },
2900 +
2901 +            () -> { f.thenAccept(null); },
2902 +            () -> { f.thenAcceptAsync(null); },
2903 +            () -> { f.thenAcceptAsync((x) -> { ; }, null); },
2904 +            () -> { f.thenAcceptAsync(null, exec); },
2905 +
2906 +            () -> { f.thenRun(null); },
2907 +            () -> { f.thenRunAsync(null); },
2908 +            () -> { f.thenRunAsync(() -> { ; }, null); },
2909 +            () -> { f.thenRunAsync(null, exec); },
2910 +
2911 +            () -> { f.thenCombine(g, null); },
2912 +            () -> { f.thenCombineAsync(g, null); },
2913 +            () -> { f.thenCombineAsync(g, null, exec); },
2914 +            () -> { f.thenCombine(nullFuture, (x, y) -> x); },
2915 +            () -> { f.thenCombineAsync(nullFuture, (x, y) -> x); },
2916 +            () -> { f.thenCombineAsync(nullFuture, (x, y) -> x, exec); },
2917 +            () -> { f.thenCombineAsync(g, (x, y) -> x, null); },
2918 +
2919 +            () -> { f.thenAcceptBoth(g, null); },
2920 +            () -> { f.thenAcceptBothAsync(g, null); },
2921 +            () -> { f.thenAcceptBothAsync(g, null, exec); },
2922 +            () -> { f.thenAcceptBoth(nullFuture, (x, y) -> {}); },
2923 +            () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}); },
2924 +            () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec); },
2925 +            () -> { f.thenAcceptBothAsync(g, (x, y) -> {}, null); },
2926 +
2927 +            () -> { f.runAfterBoth(g, null); },
2928 +            () -> { f.runAfterBothAsync(g, null); },
2929 +            () -> { f.runAfterBothAsync(g, null, exec); },
2930 +            () -> { f.runAfterBoth(nullFuture, () -> {}); },
2931 +            () -> { f.runAfterBothAsync(nullFuture, () -> {}); },
2932 +            () -> { f.runAfterBothAsync(nullFuture, () -> {}, exec); },
2933 +            () -> { f.runAfterBothAsync(g, () -> {}, null); },
2934 +
2935 +            () -> { f.applyToEither(g, null); },
2936 +            () -> { f.applyToEitherAsync(g, null); },
2937 +            () -> { f.applyToEitherAsync(g, null, exec); },
2938 +            () -> { f.applyToEither(nullFuture, (x) -> x); },
2939 +            () -> { f.applyToEitherAsync(nullFuture, (x) -> x); },
2940 +            () -> { f.applyToEitherAsync(nullFuture, (x) -> x, exec); },
2941 +            () -> { f.applyToEitherAsync(g, (x) -> x, null); },
2942 +
2943 +            () -> { f.acceptEither(g, null); },
2944 +            () -> { f.acceptEitherAsync(g, null); },
2945 +            () -> { f.acceptEitherAsync(g, null, exec); },
2946 +            () -> { f.acceptEither(nullFuture, (x) -> {}); },
2947 +            () -> { f.acceptEitherAsync(nullFuture, (x) -> {}); },
2948 +            () -> { f.acceptEitherAsync(nullFuture, (x) -> {}, exec); },
2949 +            () -> { f.acceptEitherAsync(g, (x) -> {}, null); },
2950 +
2951 +            () -> { f.runAfterEither(g, null); },
2952 +            () -> { f.runAfterEitherAsync(g, null); },
2953 +            () -> { f.runAfterEitherAsync(g, null, exec); },
2954 +            () -> { f.runAfterEither(nullFuture, () -> {}); },
2955 +            () -> { f.runAfterEitherAsync(nullFuture, () -> {}); },
2956 +            () -> { f.runAfterEitherAsync(nullFuture, () -> {}, exec); },
2957 +            () -> { f.runAfterEitherAsync(g, () -> {}, null); },
2958 +
2959 +            () -> { f.thenCompose(null); },
2960 +            () -> { f.thenComposeAsync(null); },
2961 +            () -> { f.thenComposeAsync(new CompletableFutureInc(), null); },
2962 +            () -> { f.thenComposeAsync(null, exec); },
2963 +
2964 +            () -> { f.exceptionally(null); },
2965 +
2966 +            () -> { f.handle(null); },
2967 +
2968 +            () -> { CompletableFuture.allOf((CompletableFuture<?>)null); },
2969 +            () -> { CompletableFuture.allOf((CompletableFuture<?>[])null); },
2970 +            () -> { CompletableFuture.allOf(f, null); },
2971 +            () -> { CompletableFuture.allOf(null, f); },
2972 +
2973 +            () -> { CompletableFuture.anyOf((CompletableFuture<?>)null); },
2974 +            () -> { CompletableFuture.anyOf((CompletableFuture<?>[])null); },
2975 +            () -> { CompletableFuture.anyOf(f, null); },
2976 +            () -> { CompletableFuture.anyOf(null, f); },
2977 +        };
2978 +
2979 +        assertThrows(NullPointerException.class, throwingActions);
2980 +        assertEquals(0, exec.count.get());
2981 +    }
2982 +
2983   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines