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.4 by jsr166, Sun Feb 10 21:18:25 2013 UTC vs.
Revision 1.45 by jsr166, Mon Jun 2 06:07:34 2014 UTC

# Line 7 | Line 7
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.CompletionStage;
20   import java.util.concurrent.TimeoutException;
21   import java.util.concurrent.atomic.AtomicInteger;
22   import static java.util.concurrent.TimeUnit.MILLISECONDS;
23   import static java.util.concurrent.TimeUnit.SECONDS;
24   import java.util.*;
25 + import java.util.function.Supplier;
26 + import java.util.function.Consumer;
27 + import java.util.function.BiConsumer;
28 + import java.util.function.Function;
29 + import java.util.function.BiFunction;
30  
31   public class CompletableFutureTest extends JSR166TestCase {
32  
# Line 27 | Line 37 | public class CompletableFutureTest exten
37          return new TestSuite(CompletableFutureTest.class);
38      }
39  
40 +    static class CFException extends RuntimeException {}
41 +
42      void checkIncomplete(CompletableFuture<?> f) {
43          assertFalse(f.isDone());
44          assertFalse(f.isCancelled());
# Line 42 | Line 54 | public class CompletableFutureTest exten
54          catch (Throwable fail) { threadUnexpectedException(fail); }
55      }
56  
57 <    void checkCompletedNormally(CompletableFuture<?> f, Object value) {
57 >    <T> void checkCompletedNormally(CompletableFuture<T> f, T value) {
58 >        try {
59 >            assertEquals(value, f.get(LONG_DELAY_MS, MILLISECONDS));
60 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
61 >        try {
62 >            assertEquals(value, f.join());
63 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
64 >        try {
65 >            assertEquals(value, f.getNow(null));
66 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
67 >        try {
68 >            assertEquals(value, f.get());
69 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
70          assertTrue(f.isDone());
71          assertFalse(f.isCancelled());
72 +        assertFalse(f.isCompletedExceptionally());
73          assertTrue(f.toString().contains("[Completed normally]"));
74 +    }
75 +
76 +    void checkCompletedWithWrappedCFException(CompletableFuture<?> f) {
77          try {
78 <            assertSame(value, f.join());
78 >            f.get(LONG_DELAY_MS, MILLISECONDS);
79 >            shouldThrow();
80 >        } catch (ExecutionException success) {
81 >            assertTrue(success.getCause() instanceof CFException);
82          } catch (Throwable fail) { threadUnexpectedException(fail); }
83          try {
84 <            assertSame(value, f.getNow(null));
84 >            f.join();
85 >            shouldThrow();
86 >        } catch (CompletionException success) {
87 >            assertTrue(success.getCause() instanceof CFException);
88 >        }
89 >        try {
90 >            f.getNow(null);
91 >            shouldThrow();
92 >        } catch (CompletionException success) {
93 >            assertTrue(success.getCause() instanceof CFException);
94 >        }
95 >        try {
96 >            f.get();
97 >            shouldThrow();
98 >        } catch (ExecutionException success) {
99 >            assertTrue(success.getCause() instanceof CFException);
100          } catch (Throwable fail) { threadUnexpectedException(fail); }
101 +        assertTrue(f.isDone());
102 +        assertFalse(f.isCancelled());
103 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
104 +    }
105 +
106 +    void checkCompletedWithWrappedCFException(CompletableFuture<?> f,
107 +                                              CFException ex) {
108          try {
109 <            assertSame(value, f.get());
109 >            f.get(LONG_DELAY_MS, MILLISECONDS);
110 >            shouldThrow();
111 >        } catch (ExecutionException success) {
112 >            assertSame(ex, success.getCause());
113          } catch (Throwable fail) { threadUnexpectedException(fail); }
114          try {
115 <            assertSame(value, f.get(0L, SECONDS));
115 >            f.join();
116 >            shouldThrow();
117 >        } catch (CompletionException success) {
118 >            assertSame(ex, success.getCause());
119 >        }
120 >        try {
121 >            f.getNow(null);
122 >            shouldThrow();
123 >        } catch (CompletionException success) {
124 >            assertSame(ex, success.getCause());
125 >        }
126 >        try {
127 >            f.get();
128 >            shouldThrow();
129 >        } catch (ExecutionException success) {
130 >            assertSame(ex, success.getCause());
131          } catch (Throwable fail) { threadUnexpectedException(fail); }
132 +        assertTrue(f.isDone());
133 +        assertFalse(f.isCancelled());
134 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
135 +    }
136 +
137 +    void checkCancelled(CompletableFuture<?> f) {
138 +        try {
139 +            f.get(LONG_DELAY_MS, MILLISECONDS);
140 +            shouldThrow();
141 +        } catch (CancellationException success) {
142 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
143 +        try {
144 +            f.join();
145 +            shouldThrow();
146 +        } catch (CancellationException success) {}
147 +        try {
148 +            f.getNow(null);
149 +            shouldThrow();
150 +        } catch (CancellationException success) {}
151 +        try {
152 +            f.get();
153 +            shouldThrow();
154 +        } catch (CancellationException success) {
155 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
156 +        assertTrue(f.isDone());
157 +        assertTrue(f.isCompletedExceptionally());
158 +        assertTrue(f.isCancelled());
159 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
160      }
161  
162 <    // XXXX Just a skeleton implementation for now.
163 <    public void testTODO() {
164 <        fail("Please add some real tests!");
162 >    void checkCompletedWithWrappedCancellationException(CompletableFuture<?> f) {
163 >        try {
164 >            f.get(LONG_DELAY_MS, MILLISECONDS);
165 >            shouldThrow();
166 >        } catch (ExecutionException success) {
167 >            assertTrue(success.getCause() instanceof CancellationException);
168 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
169 >        try {
170 >            f.join();
171 >            shouldThrow();
172 >        } catch (CompletionException success) {
173 >            assertTrue(success.getCause() instanceof CancellationException);
174 >        }
175 >        try {
176 >            f.getNow(null);
177 >            shouldThrow();
178 >        } catch (CompletionException success) {
179 >            assertTrue(success.getCause() instanceof CancellationException);
180 >        }
181 >        try {
182 >            f.get();
183 >            shouldThrow();
184 >        } catch (ExecutionException success) {
185 >            assertTrue(success.getCause() instanceof CancellationException);
186 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
187 >        assertTrue(f.isDone());
188 >        assertFalse(f.isCancelled());
189 >        assertTrue(f.isCompletedExceptionally());
190 >        assertTrue(f.toString().contains("[Completed exceptionally]"));
191      }
192  
193 +    /**
194 +     * A newly constructed CompletableFuture is incomplete, as indicated
195 +     * by methods isDone, isCancelled, and getNow
196 +     */
197 +    public void testConstructor() {
198 +        CompletableFuture<Integer> f = new CompletableFuture<>();
199 +        checkIncomplete(f);
200 +    }
201 +
202 +    /**
203 +     * complete completes normally, as indicated by methods isDone,
204 +     * isCancelled, join, get, and getNow
205 +     */
206 +    public void testComplete() {
207 +        CompletableFuture<Integer> f = new CompletableFuture<>();
208 +        checkIncomplete(f);
209 +        f.complete(one);
210 +        checkCompletedNormally(f, one);
211 +    }
212 +
213 +    /**
214 +     * completeExceptionally completes exceptionally, as indicated by
215 +     * methods isDone, isCancelled, join, get, and getNow
216 +     */
217 +    public void testCompleteExceptionally() {
218 +        CompletableFuture<Integer> f = new CompletableFuture<>();
219 +        checkIncomplete(f);
220 +        f.completeExceptionally(new CFException());
221 +        checkCompletedWithWrappedCFException(f);
222 +    }
223 +
224 +    /**
225 +     * cancel completes exceptionally and reports cancelled, as indicated by
226 +     * methods isDone, isCancelled, join, get, and getNow
227 +     */
228 +    public void testCancel() {
229 +        CompletableFuture<Integer> f = new CompletableFuture<>();
230 +        checkIncomplete(f);
231 +        assertTrue(f.cancel(true));
232 +        checkCancelled(f);
233 +    }
234 +
235 +    /**
236 +     * obtrudeValue forces completion with given value
237 +     */
238 +    public void testObtrudeValue() {
239 +        CompletableFuture<Integer> f = new CompletableFuture<>();
240 +        checkIncomplete(f);
241 +        f.complete(one);
242 +        checkCompletedNormally(f, one);
243 +        f.obtrudeValue(three);
244 +        checkCompletedNormally(f, three);
245 +        f.obtrudeValue(two);
246 +        checkCompletedNormally(f, two);
247 +        f = new CompletableFuture<>();
248 +        f.obtrudeValue(three);
249 +        checkCompletedNormally(f, three);
250 +        f = new CompletableFuture<>();
251 +        f.completeExceptionally(new CFException());
252 +        f.obtrudeValue(four);
253 +        checkCompletedNormally(f, four);
254 +    }
255 +
256 +    /**
257 +     * obtrudeException forces completion with given exception
258 +     */
259 +    public void testObtrudeException() {
260 +        CompletableFuture<Integer> f = new CompletableFuture<>();
261 +        checkIncomplete(f);
262 +        f.complete(one);
263 +        checkCompletedNormally(f, one);
264 +        f.obtrudeException(new CFException());
265 +        checkCompletedWithWrappedCFException(f);
266 +        f = new CompletableFuture<>();
267 +        f.obtrudeException(new CFException());
268 +        checkCompletedWithWrappedCFException(f);
269 +        f = new CompletableFuture<>();
270 +        f.completeExceptionally(new CFException());
271 +        f.obtrudeValue(four);
272 +        checkCompletedNormally(f, four);
273 +        f.obtrudeException(new CFException());
274 +        checkCompletedWithWrappedCFException(f);
275 +    }
276 +
277 +    /**
278 +     * getNumberOfDependents returns number of dependent tasks
279 +     */
280 +    public void testGetNumberOfDependents() {
281 +        CompletableFuture<Integer> f = new CompletableFuture<>();
282 +        assertEquals(f.getNumberOfDependents(), 0);
283 +        CompletableFuture g = f.thenRun(new Noop());
284 +        assertEquals(f.getNumberOfDependents(), 1);
285 +        assertEquals(g.getNumberOfDependents(), 0);
286 +        CompletableFuture h = f.thenRun(new Noop());
287 +        assertEquals(f.getNumberOfDependents(), 2);
288 +        f.complete(1);
289 +        checkCompletedNormally(g, null);
290 +        assertEquals(f.getNumberOfDependents(), 0);
291 +        assertEquals(g.getNumberOfDependents(), 0);
292 +    }
293 +
294 +    /**
295 +     * toString indicates current completion state
296 +     */
297      public void testToString() {
298          CompletableFuture<String> f;
299  
# Line 80 | Line 309 | public class CompletableFutureTest exten
309      }
310  
311      /**
312 +     * completedFuture returns a completed CompletableFuture with given value
313 +     */
314 +    public void testCompletedFuture() {
315 +        CompletableFuture<String> f = CompletableFuture.completedFuture("test");
316 +        checkCompletedNormally(f, "test");
317 +    }
318 +
319 +    // Choose non-commutative actions for better coverage
320 +
321 +    // A non-commutative function that handles and produces null values as well.
322 +    static Integer subtract(Integer x, Integer y) {
323 +        return (x == null && y == null) ? null :
324 +            ((x == null) ? 42 : x.intValue())
325 +            - ((y == null) ? 99 : y.intValue());
326 +    }
327 +
328 +    // A function that handles and produces null values as well.
329 +    static Integer inc(Integer x) {
330 +        return (x == null) ? null : x + 1;
331 +    }
332 +
333 +    static final Supplier<Integer> supplyOne =
334 +        () -> Integer.valueOf(1);
335 +    static final Function<Integer, Integer> inc =
336 +        (Integer x) -> Integer.valueOf(x.intValue() + 1);
337 +    static final BiFunction<Integer, Integer, Integer> subtract =
338 +        (Integer x, Integer y) -> subtract(x, y);
339 +    static final class IncAction implements Consumer<Integer> {
340 +        int invocationCount = 0;
341 +        Integer value;
342 +        public void accept(Integer x) {
343 +            invocationCount++;
344 +            value = inc(x);
345 +        }
346 +    }
347 +    static final class IncFunction implements Function<Integer,Integer> {
348 +        int invocationCount = 0;
349 +        Integer value;
350 +        public Integer apply(Integer x) {
351 +            invocationCount++;
352 +            return value = inc(x);
353 +        }
354 +    }
355 +    static final class SubtractAction implements BiConsumer<Integer, Integer> {
356 +        int invocationCount = 0;
357 +        Integer value;
358 +        // Check this action was invoked exactly once when result is computed.
359 +        public void accept(Integer x, Integer y) {
360 +            invocationCount++;
361 +            value = subtract(x, y);
362 +        }
363 +    }
364 +    static final class SubtractFunction implements BiFunction<Integer, Integer, Integer> {
365 +        int invocationCount = 0;
366 +        Integer value;
367 +        // Check this action was invoked exactly once when result is computed.
368 +        public Integer apply(Integer x, Integer y) {
369 +            invocationCount++;
370 +            return value = subtract(x, y);
371 +        }
372 +    }
373 +    static final class Noop implements Runnable {
374 +        int invocationCount = 0;
375 +        public void run() {
376 +            invocationCount++;
377 +        }
378 +    }
379 +
380 +    static final class FailingSupplier implements Supplier<Integer> {
381 +        int invocationCount = 0;
382 +        public Integer get() {
383 +            invocationCount++;
384 +            throw new CFException();
385 +        }
386 +    }
387 +    static final class FailingConsumer implements Consumer<Integer> {
388 +        int invocationCount = 0;
389 +        public void accept(Integer x) {
390 +            invocationCount++;
391 +            throw new CFException();
392 +        }
393 +    }
394 +    static final class FailingBiConsumer implements BiConsumer<Integer, Integer> {
395 +        int invocationCount = 0;
396 +        public void accept(Integer x, Integer y) {
397 +            invocationCount++;
398 +            throw new CFException();
399 +        }
400 +    }
401 +    static final class FailingFunction implements Function<Integer, Integer> {
402 +        int invocationCount = 0;
403 +        public Integer apply(Integer x) {
404 +            invocationCount++;
405 +            throw new CFException();
406 +        }
407 +    }
408 +    static final class FailingBiFunction implements BiFunction<Integer, Integer, Integer> {
409 +        int invocationCount = 0;
410 +        public Integer apply(Integer x, Integer y) {
411 +            invocationCount++;
412 +            throw new CFException();
413 +        }
414 +    }
415 +    static final class FailingNoop implements Runnable {
416 +        int invocationCount = 0;
417 +        public void run() {
418 +            invocationCount++;
419 +            throw new CFException();
420 +        }
421 +    }
422 +
423 +    static final class CompletableFutureInc
424 +        implements Function<Integer, CompletableFuture<Integer>> {
425 +        int invocationCount = 0;
426 +        public CompletableFuture<Integer> apply(Integer x) {
427 +            invocationCount++;
428 +            CompletableFuture<Integer> f = new CompletableFuture<>();
429 +            f.complete(inc(x));
430 +            return f;
431 +        }
432 +    }
433 +
434 +    static final class FailingCompletableFutureFunction
435 +        implements Function<Integer, CompletableFuture<Integer>> {
436 +        int invocationCount = 0;
437 +        public CompletableFuture<Integer> apply(Integer x) {
438 +            invocationCount++;
439 +            throw new CFException();
440 +        }
441 +    }
442 +
443 +    // Used for explicit executor tests
444 +    static final class ThreadExecutor implements Executor {
445 +        AtomicInteger count = new AtomicInteger(0);
446 +
447 +        public void execute(Runnable r) {
448 +            count.getAndIncrement();
449 +            new Thread(r).start();
450 +        }
451 +    }
452 +
453 +    static final class ExceptionToInteger implements Function<Throwable, Integer> {
454 +        public Integer apply(Throwable x) { return Integer.valueOf(3); }
455 +    }
456 +
457 +    static final class IntegerHandler implements BiFunction<Integer, Throwable, Integer> {
458 +        int invocationCount = 0;
459 +        public Integer apply(Integer x, Throwable t) {
460 +            invocationCount++;
461 +            return (t == null) ? two : three;
462 +        }
463 +    }
464 +
465 +    /**
466 +     * Permits the testing of parallel code for the 3 different
467 +     * execution modes without repeating all the testing code.
468 +     */
469 +    enum ExecutionMode {
470 +        DEFAULT {
471 +            public <T,U> CompletableFuture<Void> runAfterBoth
472 +                (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
473 +                return f.runAfterBoth(g, a);
474 +            }
475 +            public <T,U> CompletableFuture<Void> thenAcceptBoth
476 +                (CompletableFuture<T> f,
477 +                 CompletionStage<? extends U> g,
478 +                 BiConsumer<? super T,? super U> a) {
479 +                return f.thenAcceptBoth(g, a);
480 +            }
481 +            public <T,U,V> CompletableFuture<V> thenCombine
482 +                (CompletableFuture<T> f,
483 +                 CompletionStage<? extends U> g,
484 +                 BiFunction<? super T,? super U,? extends V> a) {
485 +                return f.thenCombine(g, a);
486 +            }
487 +            public <T,U> CompletableFuture<U> applyToEither
488 +                (CompletableFuture<T> f,
489 +                 CompletionStage<? extends T> g,
490 +                 Function<? super T,U> a) {
491 +                return f.applyToEither(g, a);
492 +            }
493 +            public <T> CompletableFuture<Void> acceptEither
494 +                (CompletableFuture<T> f,
495 +                 CompletionStage<? extends T> g,
496 +                 Consumer<? super T> a) {
497 +                return f.acceptEither(g, a);
498 +            }
499 +            public <T> CompletableFuture<Void> runAfterEither
500 +                (CompletableFuture<T> f,
501 +                 CompletionStage<?> g,
502 +                 java.lang.Runnable a) {
503 +                return f.runAfterEither(g, a);
504 +            }
505 +            public <T,U> CompletableFuture<U> thenCompose
506 +                (CompletableFuture<T> f,
507 +                 Function<? super T,? extends CompletionStage<U>> a) {
508 +                return f.thenCompose(a);
509 +            }
510 +            public <T> CompletableFuture<T> whenComplete
511 +                (CompletableFuture<T> f,
512 +                 BiConsumer<? super T,? super Throwable> a) {
513 +                return f.whenComplete(a);
514 +            }
515 +        },
516 +
517 +        DEFAULT_ASYNC {
518 +            public <T,U> CompletableFuture<Void> runAfterBoth
519 +                (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
520 +                return f.runAfterBothAsync(g, a);
521 +            }
522 +            public <T,U> CompletableFuture<Void> thenAcceptBoth
523 +                (CompletableFuture<T> f,
524 +                 CompletionStage<? extends U> g,
525 +                 BiConsumer<? super T,? super U> a) {
526 +                return f.thenAcceptBothAsync(g, a);
527 +            }
528 +            public <T,U,V> CompletableFuture<V> thenCombine
529 +                (CompletableFuture<T> f,
530 +                 CompletionStage<? extends U> g,
531 +                 BiFunction<? super T,? super U,? extends V> a) {
532 +                return f.thenCombineAsync(g, a);
533 +            }
534 +            public <T,U> CompletableFuture<U> applyToEither
535 +                (CompletableFuture<T> f,
536 +                 CompletionStage<? extends T> g,
537 +                 Function<? super T,U> a) {
538 +                return f.applyToEitherAsync(g, a);
539 +            }
540 +            public <T> CompletableFuture<Void> acceptEither
541 +                (CompletableFuture<T> f,
542 +                 CompletionStage<? extends T> g,
543 +                 Consumer<? super T> a) {
544 +                return f.acceptEitherAsync(g, a);
545 +            }
546 +            public <T> CompletableFuture<Void> runAfterEither
547 +                (CompletableFuture<T> f,
548 +                 CompletionStage<?> g,
549 +                 java.lang.Runnable a) {
550 +                return f.runAfterEitherAsync(g, a);
551 +            }
552 +            public <T,U> CompletableFuture<U> thenCompose
553 +                (CompletableFuture<T> f,
554 +                 Function<? super T,? extends CompletionStage<U>> a) {
555 +                return f.thenComposeAsync(a);
556 +            }
557 +            public <T> CompletableFuture<T> whenComplete
558 +                (CompletableFuture<T> f,
559 +                 BiConsumer<? super T,? super Throwable> a) {
560 +                return f.whenCompleteAsync(a);
561 +            }
562 +        },
563 +
564 +        EXECUTOR {
565 +            public <T,U> CompletableFuture<Void> runAfterBoth
566 +                (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
567 +                return f.runAfterBothAsync(g, a, new ThreadExecutor());
568 +            }
569 +            public <T,U> CompletableFuture<Void> thenAcceptBoth
570 +                (CompletableFuture<T> f,
571 +                 CompletionStage<? extends U> g,
572 +                 BiConsumer<? super T,? super U> a) {
573 +                return f.thenAcceptBothAsync(g, a, new ThreadExecutor());
574 +            }
575 +            public <T,U,V> CompletableFuture<V> thenCombine
576 +                (CompletableFuture<T> f,
577 +                 CompletionStage<? extends U> g,
578 +                 BiFunction<? super T,? super U,? extends V> a) {
579 +                return f.thenCombineAsync(g, a, new ThreadExecutor());
580 +            }
581 +            public <T,U> CompletableFuture<U> applyToEither
582 +                (CompletableFuture<T> f,
583 +                 CompletionStage<? extends T> g,
584 +                 Function<? super T,U> a) {
585 +                return f.applyToEitherAsync(g, a, new ThreadExecutor());
586 +            }
587 +            public <T> CompletableFuture<Void> acceptEither
588 +                (CompletableFuture<T> f,
589 +                 CompletionStage<? extends T> g,
590 +                 Consumer<? super T> a) {
591 +                return f.acceptEitherAsync(g, a, new ThreadExecutor());
592 +            }
593 +            public <T> CompletableFuture<Void> runAfterEither
594 +                (CompletableFuture<T> f,
595 +                 CompletionStage<?> g,
596 +                 java.lang.Runnable a) {
597 +                return f.runAfterEitherAsync(g, a, new ThreadExecutor());
598 +            }
599 +            public <T,U> CompletableFuture<U> thenCompose
600 +                (CompletableFuture<T> f,
601 +                 Function<? super T,? extends CompletionStage<U>> a) {
602 +                return f.thenComposeAsync(a, new ThreadExecutor());
603 +            }
604 +            public <T> CompletableFuture<T> whenComplete
605 +                (CompletableFuture<T> f,
606 +                 BiConsumer<? super T,? super Throwable> a) {
607 +                return f.whenCompleteAsync(a, new ThreadExecutor());
608 +            }
609 +        };
610 +
611 +        public abstract <T,U> CompletableFuture<Void> runAfterBoth
612 +            (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a);
613 +        public abstract <T,U> CompletableFuture<Void> thenAcceptBoth
614 +            (CompletableFuture<T> f,
615 +             CompletionStage<? extends U> g,
616 +             BiConsumer<? super T,? super U> a);
617 +        public abstract <T,U,V> CompletableFuture<V> thenCombine
618 +            (CompletableFuture<T> f,
619 +             CompletionStage<? extends U> g,
620 +             BiFunction<? super T,? super U,? extends V> a);
621 +        public abstract <T,U> CompletableFuture<U> applyToEither
622 +            (CompletableFuture<T> f,
623 +             CompletionStage<? extends T> g,
624 +             Function<? super T,U> a);
625 +        public abstract <T> CompletableFuture<Void> acceptEither
626 +            (CompletableFuture<T> f,
627 +             CompletionStage<? extends T> g,
628 +             Consumer<? super T> a);
629 +        public abstract <T> CompletableFuture<Void> runAfterEither
630 +            (CompletableFuture<T> f,
631 +             CompletionStage<?> g,
632 +             java.lang.Runnable a);
633 +        public abstract <T,U> CompletableFuture<U> thenCompose
634 +            (CompletableFuture<T> f,
635 +             Function<? super T,? extends CompletionStage<U>> a);
636 +        public abstract <T> CompletableFuture<T> whenComplete
637 +            (CompletableFuture<T> f,
638 +             BiConsumer<? super T,? super Throwable> a);
639 +
640 +
641 +    }
642 +
643 +    /**
644 +     * exceptionally action completes with function value on source
645 +     * exception; otherwise with source value
646 +     */
647 +    public void testExceptionally() {
648 +        CompletableFuture<Integer> f = new CompletableFuture<>();
649 +        ExceptionToInteger r = new ExceptionToInteger();
650 +        CompletableFuture<Integer> g = f.exceptionally(r);
651 +        f.completeExceptionally(new CFException());
652 +        checkCompletedNormally(g, three);
653 +
654 +        f = new CompletableFuture<>();
655 +        r = new ExceptionToInteger();
656 +        g = f.exceptionally(r);
657 +        f.complete(one);
658 +        checkCompletedNormally(g, one);
659 +    }
660 +
661 +    /**
662 +     * handle action completes normally with function value on either
663 +     * normal or exceptional completion of source
664 +     */
665 +    public void testHandle() {
666 +        CompletableFuture<Integer> f, g;
667 +        IntegerHandler r;
668 +
669 +        f = new CompletableFuture<>();
670 +        f.completeExceptionally(new CFException());
671 +        g = f.handle(r = new IntegerHandler());
672 +        assertEquals(1, r.invocationCount);
673 +        assertEquals(1, r.invocationCount);
674 +        checkCompletedNormally(g, three);
675 +
676 +        f = new CompletableFuture<>();
677 +        g = f.handle(r = new IntegerHandler());
678 +        assertEquals(0, r.invocationCount);
679 +        f.completeExceptionally(new CFException());
680 +        checkCompletedNormally(g, three);
681 +        assertEquals(1, r.invocationCount);
682 +
683 +        f = new CompletableFuture<>();
684 +        f.complete(one);
685 +        g = f.handle(r = new IntegerHandler());
686 +        assertEquals(1, r.invocationCount);
687 +        checkCompletedNormally(g, two);
688 +
689 +        f = new CompletableFuture<>();
690 +        g = f.handle(r = new IntegerHandler());
691 +        assertEquals(0, r.invocationCount);
692 +        f.complete(one);
693 +        assertEquals(1, r.invocationCount);
694 +        checkCompletedNormally(g, two);
695 +    }
696 +
697 +    /**
698 +     * runAsync completes after running Runnable
699 +     */
700 +    public void testRunAsync() {
701 +        Noop r = new Noop();
702 +        CompletableFuture<Void> f = CompletableFuture.runAsync(r);
703 +        assertNull(f.join());
704 +        assertEquals(1, r.invocationCount);
705 +        checkCompletedNormally(f, null);
706 +    }
707 +
708 +    /**
709 +     * runAsync with executor completes after running Runnable
710 +     */
711 +    public void testRunAsync2() {
712 +        Noop r = new Noop();
713 +        ThreadExecutor exec = new ThreadExecutor();
714 +        CompletableFuture<Void> f = CompletableFuture.runAsync(r, exec);
715 +        assertNull(f.join());
716 +        assertEquals(1, r.invocationCount);
717 +        checkCompletedNormally(f, null);
718 +        assertEquals(1, exec.count.get());
719 +    }
720 +
721 +    /**
722 +     * failing runAsync completes exceptionally after running Runnable
723 +     */
724 +    public void testRunAsync3() {
725 +        FailingNoop r = new FailingNoop();
726 +        CompletableFuture<Void> f = CompletableFuture.runAsync(r);
727 +        checkCompletedWithWrappedCFException(f);
728 +        assertEquals(1, r.invocationCount);
729 +    }
730 +
731 +    /**
732 +     * supplyAsync completes with result of supplier
733 +     */
734 +    public void testSupplyAsync() {
735 +        CompletableFuture<Integer> f;
736 +        f = CompletableFuture.supplyAsync(supplyOne);
737 +        assertEquals(f.join(), one);
738 +        checkCompletedNormally(f, one);
739 +    }
740 +
741 +    /**
742 +     * supplyAsync with executor completes with result of supplier
743 +     */
744 +    public void testSupplyAsync2() {
745 +        CompletableFuture<Integer> f;
746 +        f = CompletableFuture.supplyAsync(supplyOne, new ThreadExecutor());
747 +        assertEquals(f.join(), one);
748 +        checkCompletedNormally(f, one);
749 +    }
750 +
751 +    /**
752 +     * Failing supplyAsync completes exceptionally
753 +     */
754 +    public void testSupplyAsync3() {
755 +        FailingSupplier r = new FailingSupplier();
756 +        CompletableFuture<Integer> f = CompletableFuture.supplyAsync(r);
757 +        checkCompletedWithWrappedCFException(f);
758 +        assertEquals(1, r.invocationCount);
759 +    }
760 +
761 +    // seq completion methods
762 +
763 +    /**
764 +     * thenRun result completes normally after normal completion of source
765 +     */
766 +    public void testThenRun() {
767 +        CompletableFuture<Integer> f;
768 +        CompletableFuture<Void> g;
769 +        Noop r;
770 +
771 +        f = new CompletableFuture<>();
772 +        g = f.thenRun(r = new Noop());
773 +        f.complete(null);
774 +        checkCompletedNormally(g, null);
775 +        assertEquals(1, r.invocationCount);
776 +
777 +        f = new CompletableFuture<>();
778 +        f.complete(null);
779 +        g = f.thenRun(r = new Noop());
780 +        checkCompletedNormally(g, null);
781 +        assertEquals(1, r.invocationCount);
782 +    }
783 +
784 +    /**
785 +     * thenRun result completes exceptionally after exceptional
786 +     * completion of source
787 +     */
788 +    public void testThenRun2() {
789 +        CompletableFuture<Integer> f;
790 +        CompletableFuture<Void> g;
791 +        Noop r;
792 +
793 +        f = new CompletableFuture<>();
794 +        g = f.thenRun(r = new Noop());
795 +        f.completeExceptionally(new CFException());
796 +        checkCompletedWithWrappedCFException(g);
797 +        assertEquals(0, r.invocationCount);
798 +
799 +        f = new CompletableFuture<>();
800 +        f.completeExceptionally(new CFException());
801 +        g = f.thenRun(r = new Noop());
802 +        checkCompletedWithWrappedCFException(g);
803 +        assertEquals(0, r.invocationCount);
804 +    }
805 +
806 +    /**
807 +     * thenRun result completes exceptionally if action does
808 +     */
809 +    public void testThenRun3() {
810 +        CompletableFuture<Integer> f;
811 +        CompletableFuture<Void> g;
812 +        FailingNoop r;
813 +
814 +        f = new CompletableFuture<>();
815 +        g = f.thenRun(r = new FailingNoop());
816 +        f.complete(null);
817 +        checkCompletedWithWrappedCFException(g);
818 +
819 +        f = new CompletableFuture<>();
820 +        f.complete(null);
821 +        g = f.thenRun(r = new FailingNoop());
822 +        checkCompletedWithWrappedCFException(g);
823 +    }
824 +
825 +    /**
826 +     * thenRun result completes exceptionally if source cancelled
827 +     */
828 +    public void testThenRun4() {
829 +        CompletableFuture<Integer> f;
830 +        CompletableFuture<Void> g;
831 +        Noop r;
832 +
833 +        f = new CompletableFuture<>();
834 +        g = f.thenRun(r = new Noop());
835 +        assertTrue(f.cancel(true));
836 +        checkCompletedWithWrappedCancellationException(g);
837 +
838 +        f = new CompletableFuture<>();
839 +        assertTrue(f.cancel(true));
840 +        g = f.thenRun(r = new Noop());
841 +        checkCompletedWithWrappedCancellationException(g);
842 +    }
843 +
844 +    /**
845 +     * thenApply result completes normally after normal completion of source
846 +     */
847 +    public void testThenApply() {
848 +        CompletableFuture<Integer> f = new CompletableFuture<>();
849 +        CompletableFuture<Integer> g = f.thenApply(inc);
850 +        f.complete(one);
851 +        checkCompletedNormally(g, two);
852 +    }
853 +
854 +    /**
855 +     * thenApply result completes exceptionally after exceptional
856 +     * completion of source
857 +     */
858 +    public void testThenApply2() {
859 +        CompletableFuture<Integer> f = new CompletableFuture<>();
860 +        CompletableFuture<Integer> g = f.thenApply(inc);
861 +        f.completeExceptionally(new CFException());
862 +        checkCompletedWithWrappedCFException(g);
863 +    }
864 +
865 +    /**
866 +     * thenApply result completes exceptionally if action does
867 +     */
868 +    public void testThenApply3() {
869 +        CompletableFuture<Integer> f = new CompletableFuture<>();
870 +        CompletableFuture<Integer> g = f.thenApply(new FailingFunction());
871 +        f.complete(one);
872 +        checkCompletedWithWrappedCFException(g);
873 +    }
874 +
875 +    /**
876 +     * thenApply result completes exceptionally if source cancelled
877 +     */
878 +    public void testThenApply4() {
879 +        CompletableFuture<Integer> f = new CompletableFuture<>();
880 +        CompletableFuture<Integer> g = f.thenApply(inc);
881 +        assertTrue(f.cancel(true));
882 +        checkCompletedWithWrappedCancellationException(g);
883 +    }
884 +
885 +    /**
886 +     * thenAccept result completes normally after normal completion of source
887 +     */
888 +    public void testThenAccept() {
889 +        CompletableFuture<Integer> f = new CompletableFuture<>();
890 +        IncAction r = new IncAction();
891 +        CompletableFuture<Void> g = f.thenAccept(r);
892 +        f.complete(one);
893 +        checkCompletedNormally(g, null);
894 +        assertEquals(r.value, (Integer) 2);
895 +    }
896 +
897 +    /**
898 +     * thenAccept result completes exceptionally after exceptional
899 +     * completion of source
900 +     */
901 +    public void testThenAccept2() {
902 +        CompletableFuture<Integer> f = new CompletableFuture<>();
903 +        IncAction r = new IncAction();
904 +        CompletableFuture<Void> g = f.thenAccept(r);
905 +        f.completeExceptionally(new CFException());
906 +        checkCompletedWithWrappedCFException(g);
907 +    }
908 +
909 +    /**
910 +     * thenAccept result completes exceptionally if action does
911 +     */
912 +    public void testThenAccept3() {
913 +        CompletableFuture<Integer> f = new CompletableFuture<>();
914 +        FailingConsumer r = new FailingConsumer();
915 +        CompletableFuture<Void> g = f.thenAccept(r);
916 +        f.complete(one);
917 +        checkCompletedWithWrappedCFException(g);
918 +        assertEquals(1, r.invocationCount);
919 +    }
920 +
921 +    /**
922 +     * thenAccept result completes exceptionally if source cancelled
923 +     */
924 +    public void testThenAccept4() {
925 +        CompletableFuture<Integer> f = new CompletableFuture<>();
926 +        IncAction r = new IncAction();
927 +        CompletableFuture<Void> g = f.thenAccept(r);
928 +        assertTrue(f.cancel(true));
929 +        checkCompletedWithWrappedCancellationException(g);
930 +    }
931 +
932 +    /**
933 +     * thenCombine result completes normally after normal completion
934 +     * of sources
935 +     */
936 +    public void testThenCombine_normalCompletion1() {
937 +        for (boolean createIncomplete : new boolean[] { true, false })
938 +        for (boolean fFirst : new boolean[] { true, false })
939 +        for (ExecutionMode m : ExecutionMode.values())
940 +        for (Integer v1 : new Integer[] { 1, null })
941 +        for (Integer v2 : new Integer[] { 2, null }) {
942 +
943 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
944 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
945 +        final SubtractFunction r = new SubtractFunction();
946 +        CompletableFuture<Integer> h = null;
947 +        if (createIncomplete) h = m.thenCombine(f, g, r);
948 +
949 +        if (fFirst)
950 +            f.complete(v1);
951 +        else
952 +            g.complete(v2);
953 +        if (createIncomplete) checkIncomplete(h);
954 +        assertEquals(0, r.invocationCount);
955 +        if (!fFirst)
956 +            f.complete(v1);
957 +        else
958 +            g.complete(v2);
959 +        if (!createIncomplete) h = m.thenCombine(f, g, r);
960 +
961 +        checkCompletedNormally(h, subtract(v1, v2));
962 +        checkCompletedNormally(f, v1);
963 +        checkCompletedNormally(g, v2);
964 +        assertEquals(1, r.invocationCount);
965 +        }
966 +    }
967 +
968 +    /**
969 +     * thenCombine result completes exceptionally after exceptional
970 +     * completion of either source
971 +     */
972 +    public void testThenCombine_exceptionalCompletion1() {
973 +        for (ExecutionMode m : ExecutionMode.values())
974 +        for (Integer v1 : new Integer[] { 1, null }) {
975 +
976 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
977 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
978 +        final SubtractFunction r = new SubtractFunction();
979 +        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
980 +        final CFException ex = new CFException();
981 +
982 +        f.completeExceptionally(ex);
983 +        checkIncomplete(h);
984 +        g.complete(v1);
985 +
986 +        checkCompletedWithWrappedCFException(h, ex);
987 +        checkCompletedWithWrappedCFException(f, ex);
988 +        assertEquals(0, r.invocationCount);
989 +        checkCompletedNormally(g, v1);
990 +        }
991 +    }
992 +
993 +    public void testThenCombine_exceptionalCompletion2() {
994 +        for (ExecutionMode m : ExecutionMode.values())
995 +        for (Integer v1 : new Integer[] { 1, null }) {
996 +
997 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
998 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
999 +        final SubtractFunction r = new SubtractFunction();
1000 +        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1001 +        final CFException ex = new CFException();
1002 +
1003 +        g.completeExceptionally(ex);
1004 +        checkIncomplete(h);
1005 +        f.complete(v1);
1006 +
1007 +        checkCompletedWithWrappedCFException(h, ex);
1008 +        checkCompletedWithWrappedCFException(g, ex);
1009 +        assertEquals(0, r.invocationCount);
1010 +        checkCompletedNormally(f, v1);
1011 +        }
1012 +    }
1013 +
1014 +    public void testThenCombine_exceptionalCompletion3() {
1015 +        for (ExecutionMode m : ExecutionMode.values())
1016 +        for (Integer v1 : new Integer[] { 1, null }) {
1017 +
1018 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1019 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1020 +        final SubtractFunction r = new SubtractFunction();
1021 +        final CFException ex = new CFException();
1022 +
1023 +        g.completeExceptionally(ex);
1024 +        f.complete(v1);
1025 +        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1026 +
1027 +        checkCompletedWithWrappedCFException(h, ex);
1028 +        checkCompletedWithWrappedCFException(g, ex);
1029 +        assertEquals(0, r.invocationCount);
1030 +        checkCompletedNormally(f, v1);
1031 +        }
1032 +    }
1033 +
1034 +    public void testThenCombine_exceptionalCompletion4() {
1035 +        for (ExecutionMode m : ExecutionMode.values())
1036 +        for (Integer v1 : new Integer[] { 1, null }) {
1037 +
1038 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1039 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1040 +        final SubtractFunction r = new SubtractFunction();
1041 +        final CFException ex = new CFException();
1042 +
1043 +        f.completeExceptionally(ex);
1044 +        g.complete(v1);
1045 +        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1046 +
1047 +        checkCompletedWithWrappedCFException(h, ex);
1048 +        checkCompletedWithWrappedCFException(f, ex);
1049 +        assertEquals(0, r.invocationCount);
1050 +        checkCompletedNormally(g, v1);
1051 +        }
1052 +    }
1053 +
1054 +    /**
1055 +     * thenCombine result completes exceptionally if action does
1056 +     */
1057 +    public void testThenCombine_actionFailed1() {
1058 +        for (ExecutionMode m : ExecutionMode.values())
1059 +        for (Integer v1 : new Integer[] { 1, null })
1060 +        for (Integer v2 : new Integer[] { 2, null }) {
1061 +
1062 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1063 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1064 +        final FailingBiFunction r = new FailingBiFunction();
1065 +        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1066 +
1067 +        f.complete(v1);
1068 +        checkIncomplete(h);
1069 +        g.complete(v2);
1070 +
1071 +        checkCompletedWithWrappedCFException(h);
1072 +        checkCompletedNormally(f, v1);
1073 +        checkCompletedNormally(g, v2);
1074 +        }
1075 +    }
1076 +
1077 +    public void testThenCombine_actionFailed2() {
1078 +        for (ExecutionMode m : ExecutionMode.values())
1079 +        for (Integer v1 : new Integer[] { 1, null })
1080 +        for (Integer v2 : new Integer[] { 2, null }) {
1081 +
1082 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1083 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1084 +        final FailingBiFunction r = new FailingBiFunction();
1085 +        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1086 +
1087 +        g.complete(v2);
1088 +        checkIncomplete(h);
1089 +        f.complete(v1);
1090 +
1091 +        checkCompletedWithWrappedCFException(h);
1092 +        checkCompletedNormally(f, v1);
1093 +        checkCompletedNormally(g, v2);
1094 +        }
1095 +    }
1096 +
1097 +    /**
1098 +     * thenCombine result completes exceptionally if either source cancelled
1099 +     */
1100 +    public void testThenCombine_sourceCancelled1() {
1101 +        for (ExecutionMode m : ExecutionMode.values())
1102 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1103 +        for (Integer v1 : new Integer[] { 1, null }) {
1104 +
1105 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1106 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1107 +        final SubtractFunction r = new SubtractFunction();
1108 +        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1109 +
1110 +        assertTrue(f.cancel(mayInterruptIfRunning));
1111 +        checkIncomplete(h);
1112 +        g.complete(v1);
1113 +
1114 +        checkCompletedWithWrappedCancellationException(h);
1115 +        checkCancelled(f);
1116 +        assertEquals(0, r.invocationCount);
1117 +        checkCompletedNormally(g, v1);
1118 +        }
1119 +    }
1120 +
1121 +    public void testThenCombine_sourceCancelled2() {
1122 +        for (ExecutionMode m : ExecutionMode.values())
1123 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1124 +        for (Integer v1 : new Integer[] { 1, null }) {
1125 +
1126 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1127 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1128 +        final SubtractFunction r = new SubtractFunction();
1129 +        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1130 +
1131 +        assertTrue(g.cancel(mayInterruptIfRunning));
1132 +        checkIncomplete(h);
1133 +        f.complete(v1);
1134 +
1135 +        checkCompletedWithWrappedCancellationException(h);
1136 +        checkCancelled(g);
1137 +        assertEquals(0, r.invocationCount);
1138 +        checkCompletedNormally(f, v1);
1139 +        }
1140 +    }
1141 +
1142 +    public void testThenCombine_sourceCancelled3() {
1143 +        for (ExecutionMode m : ExecutionMode.values())
1144 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1145 +        for (Integer v1 : new Integer[] { 1, null }) {
1146 +
1147 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1148 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1149 +        final SubtractFunction r = new SubtractFunction();
1150 +
1151 +        assertTrue(g.cancel(mayInterruptIfRunning));
1152 +        f.complete(v1);
1153 +        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1154 +
1155 +        checkCompletedWithWrappedCancellationException(h);
1156 +        checkCancelled(g);
1157 +        assertEquals(0, r.invocationCount);
1158 +        checkCompletedNormally(f, v1);
1159 +        }
1160 +    }
1161 +
1162 +    public void testThenCombine_sourceCancelled4() {
1163 +        for (ExecutionMode m : ExecutionMode.values())
1164 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1165 +        for (Integer v1 : new Integer[] { 1, null }) {
1166 +
1167 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1168 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1169 +        final SubtractFunction r = new SubtractFunction();
1170 +
1171 +        assertTrue(f.cancel(mayInterruptIfRunning));
1172 +        g.complete(v1);
1173 +        final CompletableFuture<Integer> h = m.thenCombine(f, g, r);
1174 +
1175 +        checkCompletedWithWrappedCancellationException(h);
1176 +        checkCancelled(f);
1177 +        assertEquals(0, r.invocationCount);
1178 +        checkCompletedNormally(g, v1);
1179 +        }
1180 +    }
1181 +
1182 +    /**
1183 +     * thenAcceptBoth result completes normally after normal
1184 +     * completion of sources
1185 +     */
1186 +    public void testThenAcceptBoth_normalCompletion1() {
1187 +        for (ExecutionMode m : ExecutionMode.values())
1188 +        for (Integer v1 : new Integer[] { 1, null })
1189 +        for (Integer v2 : new Integer[] { 2, null }) {
1190 +
1191 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1192 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1193 +        final SubtractAction r = new SubtractAction();
1194 +        final CompletableFuture<Void> h = m.thenAcceptBoth(f, g, r);
1195 +
1196 +        f.complete(v1);
1197 +        checkIncomplete(h);
1198 +        assertEquals(0, r.invocationCount);
1199 +        g.complete(v2);
1200 +
1201 +        checkCompletedNormally(h, null);
1202 +        assertEquals(r.value, subtract(v1, v2));
1203 +        checkCompletedNormally(f, v1);
1204 +        checkCompletedNormally(g, v2);
1205 +        }
1206 +    }
1207 +
1208 +    public void testThenAcceptBoth_normalCompletion2() {
1209 +        for (ExecutionMode m : ExecutionMode.values())
1210 +        for (Integer v1 : new Integer[] { 1, null })
1211 +        for (Integer v2 : new Integer[] { 2, null }) {
1212 +
1213 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1214 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1215 +        final SubtractAction r = new SubtractAction();
1216 +        final CompletableFuture<Void> h = m.thenAcceptBoth(f, g, r);
1217 +
1218 +        g.complete(v2);
1219 +        checkIncomplete(h);
1220 +        assertEquals(0, r.invocationCount);
1221 +        f.complete(v1);
1222 +
1223 +        checkCompletedNormally(h, null);
1224 +        assertEquals(r.value, subtract(v1, v2));
1225 +        checkCompletedNormally(f, v1);
1226 +        checkCompletedNormally(g, v2);
1227 +        }
1228 +    }
1229 +
1230 +    public void testThenAcceptBoth_normalCompletion3() {
1231 +        for (ExecutionMode m : ExecutionMode.values())
1232 +        for (Integer v1 : new Integer[] { 1, null })
1233 +        for (Integer v2 : new Integer[] { 2, null }) {
1234 +
1235 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1236 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1237 +        final SubtractAction r = new SubtractAction();
1238 +
1239 +        g.complete(v2);
1240 +        f.complete(v1);
1241 +        final CompletableFuture<Void> h = m.thenAcceptBoth(f, g, r);
1242 +
1243 +        checkCompletedNormally(h, null);
1244 +        assertEquals(r.value, subtract(v1, v2));
1245 +        checkCompletedNormally(f, v1);
1246 +        checkCompletedNormally(g, v2);
1247 +        }
1248 +    }
1249 +
1250 +    public void testThenAcceptBoth_normalCompletion4() {
1251 +        for (ExecutionMode m : ExecutionMode.values())
1252 +        for (Integer v1 : new Integer[] { 1, null })
1253 +        for (Integer v2 : new Integer[] { 2, null }) {
1254 +
1255 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1256 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1257 +        final SubtractAction r = new SubtractAction();
1258 +
1259 +        f.complete(v1);
1260 +        g.complete(v2);
1261 +        final CompletableFuture<Void> h = m.thenAcceptBoth(f, g, r);
1262 +
1263 +        checkCompletedNormally(h, null);
1264 +        assertEquals(r.value, subtract(v1, v2));
1265 +        checkCompletedNormally(f, v1);
1266 +        checkCompletedNormally(g, v2);
1267 +        }
1268 +    }
1269 +
1270 +    /**
1271 +     * thenAcceptBoth result completes exceptionally after exceptional
1272 +     * completion of either source
1273 +     */
1274 +    public void testThenAcceptBoth_exceptionalCompletion1() {
1275 +        for (ExecutionMode m : ExecutionMode.values())
1276 +        for (Integer v1 : new Integer[] { 1, null }) {
1277 +
1278 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1279 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1280 +        final SubtractAction r = new SubtractAction();
1281 +        final CompletableFuture<Void> h = m.thenAcceptBoth(f, g, r);
1282 +        final CFException ex = new CFException();
1283 +
1284 +        f.completeExceptionally(ex);
1285 +        checkIncomplete(h);
1286 +        g.complete(v1);
1287 +
1288 +        checkCompletedWithWrappedCFException(h, ex);
1289 +        checkCompletedWithWrappedCFException(f, ex);
1290 +        assertEquals(0, r.invocationCount);
1291 +        checkCompletedNormally(g, v1);
1292 +        }
1293 +    }
1294 +
1295 +    public void testThenAcceptBoth_exceptionalCompletion2() {
1296 +        for (ExecutionMode m : ExecutionMode.values())
1297 +        for (Integer v1 : new Integer[] { 1, null }) {
1298 +
1299 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1300 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1301 +        final SubtractAction r = new SubtractAction();
1302 +        final CompletableFuture<Void> h = m.thenAcceptBoth(f, g, r);
1303 +        final CFException ex = new CFException();
1304 +
1305 +        g.completeExceptionally(ex);
1306 +        checkIncomplete(h);
1307 +        f.complete(v1);
1308 +
1309 +        checkCompletedWithWrappedCFException(h, ex);
1310 +        checkCompletedWithWrappedCFException(g, ex);
1311 +        assertEquals(0, r.invocationCount);
1312 +        checkCompletedNormally(f, v1);
1313 +        }
1314 +    }
1315 +
1316 +    public void testThenAcceptBoth_exceptionalCompletion3() {
1317 +        for (ExecutionMode m : ExecutionMode.values())
1318 +        for (Integer v1 : new Integer[] { 1, null }) {
1319 +
1320 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1321 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1322 +        final SubtractAction r = new SubtractAction();
1323 +        final CFException ex = new CFException();
1324 +
1325 +        g.completeExceptionally(ex);
1326 +        f.complete(v1);
1327 +        final CompletableFuture<Void> h = m.thenAcceptBoth(f, g, r);
1328 +
1329 +        checkCompletedWithWrappedCFException(h, ex);
1330 +        checkCompletedWithWrappedCFException(g, ex);
1331 +        assertEquals(0, r.invocationCount);
1332 +        checkCompletedNormally(f, v1);
1333 +        }
1334 +    }
1335 +
1336 +    public void testThenAcceptBoth_exceptionalCompletion4() {
1337 +        for (ExecutionMode m : ExecutionMode.values())
1338 +        for (Integer v1 : new Integer[] { 1, null }) {
1339 +
1340 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1341 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1342 +        final SubtractAction r = new SubtractAction();
1343 +        final CFException ex = new CFException();
1344 +
1345 +        f.completeExceptionally(ex);
1346 +        g.complete(v1);
1347 +        final CompletableFuture<Void> h = m.thenAcceptBoth(f, g, r);
1348 +
1349 +        checkCompletedWithWrappedCFException(h, ex);
1350 +        checkCompletedWithWrappedCFException(f, ex);
1351 +        assertEquals(0, r.invocationCount);
1352 +        checkCompletedNormally(g, v1);
1353 +        }
1354 +    }
1355 +
1356 +    /**
1357 +     * thenAcceptBoth result completes exceptionally if action does
1358 +     */
1359 +    public void testThenAcceptBoth_actionFailed1() {
1360 +        for (ExecutionMode m : ExecutionMode.values())
1361 +        for (Integer v1 : new Integer[] { 1, null })
1362 +        for (Integer v2 : new Integer[] { 2, null }) {
1363 +
1364 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1365 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1366 +        final FailingBiConsumer r = new FailingBiConsumer();
1367 +        final CompletableFuture<Void> h = m.thenAcceptBoth(f, g, r);
1368 +
1369 +        f.complete(v1);
1370 +        checkIncomplete(h);
1371 +        g.complete(v2);
1372 +
1373 +        checkCompletedWithWrappedCFException(h);
1374 +        checkCompletedNormally(f, v1);
1375 +        checkCompletedNormally(g, v2);
1376 +        }
1377 +    }
1378 +
1379 +    public void testThenAcceptBoth_actionFailed2() {
1380 +        for (ExecutionMode m : ExecutionMode.values())
1381 +        for (Integer v1 : new Integer[] { 1, null })
1382 +        for (Integer v2 : new Integer[] { 2, null }) {
1383 +
1384 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1385 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1386 +        final FailingBiConsumer r = new FailingBiConsumer();
1387 +        final CompletableFuture<Void> h = m.thenAcceptBoth(f, g, r);
1388 +
1389 +        g.complete(v2);
1390 +        checkIncomplete(h);
1391 +        f.complete(v1);
1392 +
1393 +        checkCompletedWithWrappedCFException(h);
1394 +        checkCompletedNormally(f, v1);
1395 +        checkCompletedNormally(g, v2);
1396 +        }
1397 +    }
1398 +
1399 +    /**
1400 +     * thenAcceptBoth result completes exceptionally if either source cancelled
1401 +     */
1402 +    public void testThenAcceptBoth_sourceCancelled1() {
1403 +        for (ExecutionMode m : ExecutionMode.values())
1404 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1405 +        for (Integer v1 : new Integer[] { 1, null }) {
1406 +
1407 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1408 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1409 +        final SubtractAction r = new SubtractAction();
1410 +        final CompletableFuture<Void> h = m.thenAcceptBoth(f, g, r);
1411 +
1412 +        assertTrue(f.cancel(mayInterruptIfRunning));
1413 +        checkIncomplete(h);
1414 +        g.complete(v1);
1415 +
1416 +        checkCompletedWithWrappedCancellationException(h);
1417 +        checkCancelled(f);
1418 +        assertEquals(0, r.invocationCount);
1419 +        checkCompletedNormally(g, v1);
1420 +        }
1421 +    }
1422 +
1423 +    public void testThenAcceptBoth_sourceCancelled2() {
1424 +        for (ExecutionMode m : ExecutionMode.values())
1425 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1426 +        for (Integer v1 : new Integer[] { 1, null }) {
1427 +
1428 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1429 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1430 +        final SubtractAction r = new SubtractAction();
1431 +        final CompletableFuture<Void> h = m.thenAcceptBoth(f, g, r);
1432 +
1433 +        assertTrue(g.cancel(mayInterruptIfRunning));
1434 +        checkIncomplete(h);
1435 +        f.complete(v1);
1436 +
1437 +        checkCompletedWithWrappedCancellationException(h);
1438 +        checkCancelled(g);
1439 +        assertEquals(0, r.invocationCount);
1440 +        checkCompletedNormally(f, v1);
1441 +        }
1442 +    }
1443 +
1444 +    public void testThenAcceptBoth_sourceCancelled3() {
1445 +        for (ExecutionMode m : ExecutionMode.values())
1446 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1447 +        for (Integer v1 : new Integer[] { 1, null }) {
1448 +
1449 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1450 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1451 +        final SubtractAction r = new SubtractAction();
1452 +
1453 +        assertTrue(g.cancel(mayInterruptIfRunning));
1454 +        f.complete(v1);
1455 +        final CompletableFuture<Void> h = m.thenAcceptBoth(f, g, r);
1456 +
1457 +        checkCompletedWithWrappedCancellationException(h);
1458 +        checkCancelled(g);
1459 +        assertEquals(0, r.invocationCount);
1460 +        checkCompletedNormally(f, v1);
1461 +        }
1462 +    }
1463 +
1464 +    public void testThenAcceptBoth_sourceCancelled4() {
1465 +        for (ExecutionMode m : ExecutionMode.values())
1466 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1467 +        for (Integer v1 : new Integer[] { 1, null }) {
1468 +
1469 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1470 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1471 +        final SubtractAction r = new SubtractAction();
1472 +
1473 +        assertTrue(f.cancel(mayInterruptIfRunning));
1474 +        g.complete(v1);
1475 +        final CompletableFuture<Void> h = m.thenAcceptBoth(f, g, r);
1476 +
1477 +        checkCompletedWithWrappedCancellationException(h);
1478 +        checkCancelled(f);
1479 +        assertEquals(0, r.invocationCount);
1480 +        checkCompletedNormally(g, v1);
1481 +        }
1482 +    }
1483 +
1484 +    /**
1485 +     * runAfterBoth result completes normally after normal
1486 +     * completion of sources
1487 +     */
1488 +    public void testRunAfterBoth_normalCompletion1() {
1489 +        for (ExecutionMode m : ExecutionMode.values())
1490 +        for (Integer v1 : new Integer[] { 1, null })
1491 +        for (Integer v2 : new Integer[] { 2, null }) {
1492 +
1493 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1494 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1495 +        final Noop r = new Noop();
1496 +        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1497 +
1498 +        f.complete(v1);
1499 +        checkIncomplete(h);
1500 +        assertEquals(0, r.invocationCount);
1501 +        g.complete(v2);
1502 +
1503 +        checkCompletedNormally(h, null);
1504 +        assertEquals(1, r.invocationCount);
1505 +        checkCompletedNormally(f, v1);
1506 +        checkCompletedNormally(g, v2);
1507 +        }
1508 +    }
1509 +
1510 +    public void testRunAfterBoth_normalCompletion2() {
1511 +        for (ExecutionMode m : ExecutionMode.values())
1512 +        for (Integer v1 : new Integer[] { 1, null })
1513 +        for (Integer v2 : new Integer[] { 2, null }) {
1514 +
1515 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1516 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1517 +        final Noop r = new Noop();
1518 +        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1519 +
1520 +        g.complete(v2);
1521 +        checkIncomplete(h);
1522 +        assertEquals(0, r.invocationCount);
1523 +        f.complete(v1);
1524 +
1525 +        checkCompletedNormally(h, null);
1526 +        assertEquals(1, r.invocationCount);
1527 +        checkCompletedNormally(f, v1);
1528 +        checkCompletedNormally(g, v2);
1529 +        }
1530 +    }
1531 +
1532 +    public void testRunAfterBoth_normalCompletion3() {
1533 +        for (ExecutionMode m : ExecutionMode.values())
1534 +        for (Integer v1 : new Integer[] { 1, null })
1535 +        for (Integer v2 : new Integer[] { 2, null }) {
1536 +
1537 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1538 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1539 +        final Noop r = new Noop();
1540 +
1541 +        g.complete(v2);
1542 +        f.complete(v1);
1543 +        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1544 +
1545 +        checkCompletedNormally(h, null);
1546 +        assertEquals(1, r.invocationCount);
1547 +        checkCompletedNormally(f, v1);
1548 +        checkCompletedNormally(g, v2);
1549 +        }
1550 +    }
1551 +
1552 +    public void testRunAfterBoth_normalCompletion4() {
1553 +        for (ExecutionMode m : ExecutionMode.values())
1554 +        for (Integer v1 : new Integer[] { 1, null })
1555 +        for (Integer v2 : new Integer[] { 2, null }) {
1556 +
1557 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1558 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1559 +        final Noop r = new Noop();
1560 +
1561 +        f.complete(v1);
1562 +        g.complete(v2);
1563 +        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1564 +
1565 +        checkCompletedNormally(h, null);
1566 +        assertEquals(1, r.invocationCount);
1567 +        checkCompletedNormally(f, v1);
1568 +        checkCompletedNormally(g, v2);
1569 +        }
1570 +    }
1571 +
1572 +    /**
1573 +     * runAfterBoth result completes exceptionally after exceptional
1574 +     * completion of either source
1575 +     */
1576 +    public void testRunAfterBoth_exceptionalCompletion1() {
1577 +        for (ExecutionMode m : ExecutionMode.values())
1578 +        for (Integer v1 : new Integer[] { 1, null }) {
1579 +
1580 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1581 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1582 +        final Noop r = new Noop();
1583 +        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1584 +        final CFException ex = new CFException();
1585 +
1586 +        f.completeExceptionally(ex);
1587 +        checkIncomplete(h);
1588 +        g.complete(v1);
1589 +
1590 +        checkCompletedWithWrappedCFException(h, ex);
1591 +        checkCompletedWithWrappedCFException(f, ex);
1592 +        assertEquals(0, r.invocationCount);
1593 +        checkCompletedNormally(g, v1);
1594 +        }
1595 +    }
1596 +
1597 +    public void testRunAfterBoth_exceptionalCompletion2() {
1598 +        for (ExecutionMode m : ExecutionMode.values())
1599 +        for (Integer v1 : new Integer[] { 1, null }) {
1600 +
1601 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1602 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1603 +        final Noop r = new Noop();
1604 +        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1605 +        final CFException ex = new CFException();
1606 +
1607 +        g.completeExceptionally(ex);
1608 +        checkIncomplete(h);
1609 +        f.complete(v1);
1610 +
1611 +        checkCompletedWithWrappedCFException(h, ex);
1612 +        checkCompletedWithWrappedCFException(g, ex);
1613 +        assertEquals(0, r.invocationCount);
1614 +        checkCompletedNormally(f, v1);
1615 +        }
1616 +    }
1617 +
1618 +    public void testRunAfterBoth_exceptionalCompletion3() {
1619 +        for (ExecutionMode m : ExecutionMode.values())
1620 +        for (Integer v1 : new Integer[] { 1, null }) {
1621 +
1622 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1623 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1624 +        final Noop r = new Noop();
1625 +        final CFException ex = new CFException();
1626 +
1627 +        g.completeExceptionally(ex);
1628 +        f.complete(v1);
1629 +        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1630 +
1631 +        checkCompletedWithWrappedCFException(h, ex);
1632 +        checkCompletedWithWrappedCFException(g, ex);
1633 +        assertEquals(0, r.invocationCount);
1634 +        checkCompletedNormally(f, v1);
1635 +        }
1636 +    }
1637 +
1638 +    public void testRunAfterBoth_exceptionalCompletion4() {
1639 +        for (ExecutionMode m : ExecutionMode.values())
1640 +        for (Integer v1 : new Integer[] { 1, null }) {
1641 +
1642 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1643 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1644 +        final Noop r = new Noop();
1645 +        final CFException ex = new CFException();
1646 +
1647 +        f.completeExceptionally(ex);
1648 +        g.complete(v1);
1649 +        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1650 +
1651 +        checkCompletedWithWrappedCFException(h, ex);
1652 +        checkCompletedWithWrappedCFException(f, ex);
1653 +        assertEquals(0, r.invocationCount);
1654 +        checkCompletedNormally(g, v1);
1655 +        }
1656 +    }
1657 +
1658 +    /**
1659 +     * runAfterBoth result completes exceptionally if action does
1660 +     */
1661 +    public void testRunAfterBoth_actionFailed1() {
1662 +        for (ExecutionMode m : ExecutionMode.values())
1663 +        for (Integer v1 : new Integer[] { 1, null })
1664 +        for (Integer v2 : new Integer[] { 2, null }) {
1665 +
1666 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1667 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1668 +        final FailingNoop r = new FailingNoop();
1669 +        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1670 +
1671 +        f.complete(v1);
1672 +        checkIncomplete(h);
1673 +        g.complete(v2);
1674 +
1675 +        checkCompletedWithWrappedCFException(h);
1676 +        checkCompletedNormally(f, v1);
1677 +        checkCompletedNormally(g, v2);
1678 +        }
1679 +    }
1680 +
1681 +    public void testRunAfterBoth_actionFailed2() {
1682 +        for (ExecutionMode m : ExecutionMode.values())
1683 +        for (Integer v1 : new Integer[] { 1, null })
1684 +        for (Integer v2 : new Integer[] { 2, null }) {
1685 +
1686 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1687 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1688 +        final FailingNoop r = new FailingNoop();
1689 +        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1690 +
1691 +        g.complete(v2);
1692 +        checkIncomplete(h);
1693 +        f.complete(v1);
1694 +
1695 +        checkCompletedWithWrappedCFException(h);
1696 +        checkCompletedNormally(f, v1);
1697 +        checkCompletedNormally(g, v2);
1698 +        }
1699 +    }
1700 +
1701 +    /**
1702 +     * runAfterBoth result completes exceptionally if either source cancelled
1703 +     */
1704 +    public void testRunAfterBoth_sourceCancelled1() {
1705 +        for (ExecutionMode m : ExecutionMode.values())
1706 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1707 +        for (Integer v1 : new Integer[] { 1, null }) {
1708 +
1709 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1710 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1711 +        final Noop r = new Noop();
1712 +        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1713 +
1714 +        assertTrue(f.cancel(mayInterruptIfRunning));
1715 +        checkIncomplete(h);
1716 +        g.complete(v1);
1717 +
1718 +        checkCompletedWithWrappedCancellationException(h);
1719 +        checkCancelled(f);
1720 +        assertEquals(0, r.invocationCount);
1721 +        checkCompletedNormally(g, v1);
1722 +        }
1723 +    }
1724 +
1725 +    public void testRunAfterBoth_sourceCancelled2() {
1726 +        for (ExecutionMode m : ExecutionMode.values())
1727 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1728 +        for (Integer v1 : new Integer[] { 1, null }) {
1729 +
1730 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1731 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1732 +        final Noop r = new Noop();
1733 +        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1734 +
1735 +        assertTrue(g.cancel(mayInterruptIfRunning));
1736 +        checkIncomplete(h);
1737 +        f.complete(v1);
1738 +
1739 +        checkCompletedWithWrappedCancellationException(h);
1740 +        checkCancelled(g);
1741 +        assertEquals(0, r.invocationCount);
1742 +        checkCompletedNormally(f, v1);
1743 +        }
1744 +    }
1745 +
1746 +    public void testRunAfterBoth_sourceCancelled3() {
1747 +        for (ExecutionMode m : ExecutionMode.values())
1748 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1749 +        for (Integer v1 : new Integer[] { 1, null }) {
1750 +
1751 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1752 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1753 +        final Noop r = new Noop();
1754 +
1755 +        assertTrue(g.cancel(mayInterruptIfRunning));
1756 +        f.complete(v1);
1757 +        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1758 +
1759 +        checkCompletedWithWrappedCancellationException(h);
1760 +        checkCancelled(g);
1761 +        assertEquals(0, r.invocationCount);
1762 +        checkCompletedNormally(f, v1);
1763 +        }
1764 +    }
1765 +
1766 +    public void testRunAfterBoth_sourceCancelled4() {
1767 +        for (ExecutionMode m : ExecutionMode.values())
1768 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1769 +        for (Integer v1 : new Integer[] { 1, null }) {
1770 +
1771 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1772 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1773 +        final Noop r = new Noop();
1774 +
1775 +        assertTrue(f.cancel(mayInterruptIfRunning));
1776 +        g.complete(v1);
1777 +        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1778 +
1779 +        checkCompletedWithWrappedCancellationException(h);
1780 +        checkCancelled(f);
1781 +        assertEquals(0, r.invocationCount);
1782 +        checkCompletedNormally(g, v1);
1783 +        }
1784 +    }
1785 +
1786 +    /**
1787 +     * applyToEither result completes normally after normal completion
1788 +     * of either source
1789 +     */
1790 +    public void testApplyToEither_normalCompletion1() {
1791 +        for (ExecutionMode m : ExecutionMode.values())
1792 +        for (Integer v1 : new Integer[] { 1, null })
1793 +        for (Integer v2 : new Integer[] { 2, null }) {
1794 +
1795 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1796 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1797 +        final IncFunction r = new IncFunction();
1798 +        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
1799 +
1800 +        f.complete(v1);
1801 +        checkCompletedNormally(h, inc(v1));
1802 +        g.complete(v2);
1803 +
1804 +        checkCompletedNormally(f, v1);
1805 +        checkCompletedNormally(g, v2);
1806 +        checkCompletedNormally(h, inc(v1));
1807 +        }
1808 +    }
1809 +
1810 +    public void testApplyToEither_normalCompletion2() {
1811 +        for (ExecutionMode m : ExecutionMode.values())
1812 +        for (Integer v1 : new Integer[] { 1, null })
1813 +        for (Integer v2 : new Integer[] { 2, null }) {
1814 +
1815 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1816 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1817 +        final IncFunction r = new IncFunction();
1818 +        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
1819 +
1820 +        g.complete(v2);
1821 +        checkCompletedNormally(h, inc(v2));
1822 +        f.complete(v1);
1823 +
1824 +        checkCompletedNormally(f, v1);
1825 +        checkCompletedNormally(g, v2);
1826 +        checkCompletedNormally(h, inc(v2));
1827 +        }
1828 +    }
1829 +    public void testApplyToEither_normalCompletion3() {
1830 +        for (ExecutionMode m : ExecutionMode.values())
1831 +        for (Integer v1 : new Integer[] { 1, null })
1832 +        for (Integer v2 : new Integer[] { 2, null }) {
1833 +
1834 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1835 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1836 +        final IncFunction r = new IncFunction();
1837 +
1838 +        f.complete(v1);
1839 +        g.complete(v2);
1840 +        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
1841 +
1842 +        checkCompletedNormally(f, v1);
1843 +        checkCompletedNormally(g, v2);
1844 +
1845 +        // unspecified behavior
1846 +        assertTrue(Objects.equals(h.join(), inc(v1)) ||
1847 +                   Objects.equals(h.join(), inc(v2)));
1848 +        assertEquals(1, r.invocationCount);
1849 +        }
1850 +    }
1851 +
1852 +    /**
1853 +     * applyToEither result completes exceptionally after exceptional
1854 +     * completion of either source
1855 +     */
1856 +    public void testApplyToEither_exceptionalCompletion1() {
1857 +        for (ExecutionMode m : ExecutionMode.values())
1858 +        for (Integer v1 : new Integer[] { 1, null }) {
1859 +
1860 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1861 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1862 +        final IncFunction r = new IncFunction();
1863 +        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
1864 +        final CFException ex = new CFException();
1865 +
1866 +        f.completeExceptionally(ex);
1867 +        checkCompletedWithWrappedCFException(h, ex);
1868 +        g.complete(v1);
1869 +
1870 +        assertEquals(0, r.invocationCount);
1871 +        checkCompletedNormally(g, v1);
1872 +        checkCompletedWithWrappedCFException(f, ex);
1873 +        checkCompletedWithWrappedCFException(h, ex);
1874 +        }
1875 +    }
1876 +
1877 +    public void testApplyToEither_exceptionalCompletion2() {
1878 +        for (ExecutionMode m : ExecutionMode.values())
1879 +        for (Integer v1 : new Integer[] { 1, null }) {
1880 +
1881 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1882 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1883 +        final IncFunction r = new IncFunction();
1884 +        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
1885 +        final CFException ex = new CFException();
1886 +
1887 +        g.completeExceptionally(ex);
1888 +        checkCompletedWithWrappedCFException(h, ex);
1889 +        f.complete(v1);
1890 +
1891 +        assertEquals(0, r.invocationCount);
1892 +        checkCompletedNormally(f, v1);
1893 +        checkCompletedWithWrappedCFException(g, ex);
1894 +        checkCompletedWithWrappedCFException(h, ex);
1895 +        }
1896 +    }
1897 +
1898 +    public void testApplyToEither_exceptionalCompletion3() {
1899 +        for (ExecutionMode m : ExecutionMode.values())
1900 +        for (Integer v1 : new Integer[] { 1, null }) {
1901 +
1902 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1903 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1904 +        final IncFunction r = new IncFunction();
1905 +        final CFException ex = new CFException();
1906 +
1907 +        g.completeExceptionally(ex);
1908 +        f.complete(v1);
1909 +        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
1910 +
1911 +        // unspecified behavior
1912 +        Integer v;
1913 +        try {
1914 +            assertEquals(h.join(), inc(v1));
1915 +            assertEquals(1, r.invocationCount);
1916 +        } catch (CompletionException ok) {
1917 +            checkCompletedWithWrappedCFException(h, ex);
1918 +            assertEquals(0, r.invocationCount);
1919 +        }
1920 +
1921 +        checkCompletedWithWrappedCFException(g, ex);
1922 +        checkCompletedNormally(f, v1);
1923 +        }
1924 +    }
1925 +
1926 +    public void testApplyToEither_exceptionalCompletion4() {
1927 +        for (ExecutionMode m : ExecutionMode.values())
1928 +        for (Integer v1 : new Integer[] { 1, null }) {
1929 +
1930 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1931 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1932 +        final IncFunction r = new IncFunction();
1933 +        final CFException ex = new CFException();
1934 +
1935 +        f.completeExceptionally(ex);
1936 +        g.complete(v1);
1937 +        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
1938 +
1939 +        // unspecified behavior
1940 +        Integer v;
1941 +        try {
1942 +            assertEquals(h.join(), inc(v1));
1943 +            assertEquals(1, r.invocationCount);
1944 +        } catch (CompletionException ok) {
1945 +            checkCompletedWithWrappedCFException(h, ex);
1946 +            assertEquals(0, r.invocationCount);
1947 +        }
1948 +
1949 +        checkCompletedWithWrappedCFException(f, ex);
1950 +        checkCompletedNormally(g, v1);
1951 +        }
1952 +    }
1953 +
1954 +    /**
1955 +     * applyToEither result completes exceptionally if action does
1956 +     */
1957 +    public void testApplyToEither_actionFailed1() {
1958 +        for (ExecutionMode m : ExecutionMode.values())
1959 +        for (Integer v1 : new Integer[] { 1, null })
1960 +        for (Integer v2 : new Integer[] { 2, null }) {
1961 +
1962 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1963 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1964 +        final FailingFunction r = new FailingFunction();
1965 +        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
1966 +
1967 +        f.complete(v1);
1968 +        checkCompletedWithWrappedCFException(h);
1969 +        g.complete(v2);
1970 +        checkCompletedNormally(f, v1);
1971 +        checkCompletedNormally(g, v2);
1972 +        }
1973 +    }
1974 +
1975 +    public void testApplyToEither_actionFailed2() {
1976 +        for (ExecutionMode m : ExecutionMode.values())
1977 +        for (Integer v1 : new Integer[] { 1, null })
1978 +        for (Integer v2 : new Integer[] { 2, null }) {
1979 +
1980 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1981 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1982 +        final FailingFunction r = new FailingFunction();
1983 +        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
1984 +
1985 +        g.complete(v2);
1986 +        checkCompletedWithWrappedCFException(h);
1987 +        f.complete(v1);
1988 +        checkCompletedNormally(f, v1);
1989 +        checkCompletedNormally(g, v2);
1990 +        }
1991 +    }
1992 +
1993 +    /**
1994 +     * applyToEither result completes exceptionally if either source cancelled
1995 +     */
1996 +    public void testApplyToEither_sourceCancelled1() {
1997 +        for (ExecutionMode m : ExecutionMode.values())
1998 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1999 +        for (Integer v1 : new Integer[] { 1, null }) {
2000 +
2001 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2002 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2003 +        final IncFunction r = new IncFunction();
2004 +        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
2005 +
2006 +        assertTrue(f.cancel(mayInterruptIfRunning));
2007 +        checkCompletedWithWrappedCancellationException(h);
2008 +        g.complete(v1);
2009 +
2010 +        checkCancelled(f);
2011 +        assertEquals(0, r.invocationCount);
2012 +        checkCompletedNormally(g, v1);
2013 +        checkCompletedWithWrappedCancellationException(h);
2014 +        }
2015 +    }
2016 +
2017 +    public void testApplyToEither_sourceCancelled2() {
2018 +        for (ExecutionMode m : ExecutionMode.values())
2019 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2020 +        for (Integer v1 : new Integer[] { 1, null }) {
2021 +
2022 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2023 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2024 +        final IncFunction r = new IncFunction();
2025 +        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
2026 +
2027 +        assertTrue(g.cancel(mayInterruptIfRunning));
2028 +        checkCompletedWithWrappedCancellationException(h);
2029 +        f.complete(v1);
2030 +
2031 +        checkCancelled(g);
2032 +        assertEquals(0, r.invocationCount);
2033 +        checkCompletedNormally(f, v1);
2034 +        checkCompletedWithWrappedCancellationException(h);
2035 +        }
2036 +    }
2037 +
2038 +    public void testApplyToEither_sourceCancelled3() {
2039 +        for (ExecutionMode m : ExecutionMode.values())
2040 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2041 +        for (Integer v1 : new Integer[] { 1, null }) {
2042 +
2043 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2044 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2045 +        final IncFunction r = new IncFunction();
2046 +
2047 +        assertTrue(g.cancel(mayInterruptIfRunning));
2048 +        f.complete(v1);
2049 +        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
2050 +
2051 +        // unspecified behavior
2052 +        Integer v;
2053 +        try {
2054 +            assertEquals(h.join(), inc(v1));
2055 +            assertEquals(1, r.invocationCount);
2056 +        } catch (CompletionException ok) {
2057 +            checkCompletedWithWrappedCancellationException(h);
2058 +            assertEquals(0, r.invocationCount);
2059 +        }
2060 +
2061 +        checkCancelled(g);
2062 +        checkCompletedNormally(f, v1);
2063 +        }
2064 +    }
2065 +
2066 +    public void testApplyToEither_sourceCancelled4() {
2067 +        for (ExecutionMode m : ExecutionMode.values())
2068 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2069 +        for (Integer v1 : new Integer[] { 1, null }) {
2070 +
2071 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2072 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2073 +        final IncFunction r = new IncFunction();
2074 +
2075 +        assertTrue(f.cancel(mayInterruptIfRunning));
2076 +        g.complete(v1);
2077 +        final CompletableFuture<Integer> h = m.applyToEither(f, g, r);
2078 +
2079 +        // unspecified behavior
2080 +        Integer v;
2081 +        try {
2082 +            assertEquals(h.join(), inc(v1));
2083 +            assertEquals(1, r.invocationCount);
2084 +        } catch (CompletionException ok) {
2085 +            checkCompletedWithWrappedCancellationException(h);
2086 +            assertEquals(0, r.invocationCount);
2087 +        }
2088 +
2089 +        checkCancelled(f);
2090 +        checkCompletedNormally(g, v1);
2091 +        }
2092 +    }
2093 +
2094 +    /**
2095 +     * acceptEither result completes normally after normal completion
2096 +     * of either source
2097 +     */
2098 +    public void testAcceptEither_normalCompletion1() {
2099 +        for (ExecutionMode m : ExecutionMode.values())
2100 +        for (Integer v1 : new Integer[] { 1, null })
2101 +        for (Integer v2 : new Integer[] { 2, null }) {
2102 +
2103 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2104 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2105 +        final IncAction r = new IncAction();
2106 +        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2107 +
2108 +        f.complete(v1);
2109 +        checkCompletedNormally(h, null);
2110 +        assertEquals(r.value, inc(v1));
2111 +        g.complete(v2);
2112 +
2113 +        checkCompletedNormally(f, v1);
2114 +        checkCompletedNormally(g, v2);
2115 +        checkCompletedNormally(h, null);
2116 +        }
2117 +    }
2118 +
2119 +    public void testAcceptEither_normalCompletion2() {
2120 +        for (ExecutionMode m : ExecutionMode.values())
2121 +        for (Integer v1 : new Integer[] { 1, null })
2122 +        for (Integer v2 : new Integer[] { 2, null }) {
2123 +
2124 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2125 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2126 +        final IncAction r = new IncAction();
2127 +        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2128 +
2129 +        g.complete(v2);
2130 +        checkCompletedNormally(h, null);
2131 +        assertEquals(r.value, inc(v2));
2132 +        f.complete(v1);
2133 +
2134 +        checkCompletedNormally(f, v1);
2135 +        checkCompletedNormally(g, v2);
2136 +        checkCompletedNormally(h, null);
2137 +        }
2138 +    }
2139 +    public void testAcceptEither_normalCompletion3() {
2140 +        for (ExecutionMode m : ExecutionMode.values())
2141 +        for (Integer v1 : new Integer[] { 1, null })
2142 +        for (Integer v2 : new Integer[] { 2, null }) {
2143 +
2144 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2145 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2146 +        final IncAction r = new IncAction();
2147 +
2148 +        f.complete(v1);
2149 +        g.complete(v2);
2150 +        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2151 +
2152 +        checkCompletedNormally(h, null);
2153 +        checkCompletedNormally(f, v1);
2154 +        checkCompletedNormally(g, v2);
2155 +
2156 +        // unspecified behavior
2157 +        assertTrue(Objects.equals(r.value, inc(v1)) ||
2158 +                   Objects.equals(r.value, inc(v2)));
2159 +        }
2160 +    }
2161 +
2162 +    /**
2163 +     * acceptEither result completes exceptionally after exceptional
2164 +     * completion of either source
2165 +     */
2166 +    public void testAcceptEither_exceptionalCompletion1() {
2167 +        for (ExecutionMode m : ExecutionMode.values())
2168 +        for (Integer v1 : new Integer[] { 1, null }) {
2169 +
2170 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2171 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2172 +        final IncAction r = new IncAction();
2173 +        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2174 +        final CFException ex = new CFException();
2175 +
2176 +        f.completeExceptionally(ex);
2177 +        checkCompletedWithWrappedCFException(h, ex);
2178 +        g.complete(v1);
2179 +
2180 +        assertEquals(0, r.invocationCount);
2181 +        checkCompletedNormally(g, v1);
2182 +        checkCompletedWithWrappedCFException(f, ex);
2183 +        checkCompletedWithWrappedCFException(h, ex);
2184 +        }
2185 +    }
2186 +
2187 +    public void testAcceptEither_exceptionalCompletion2() {
2188 +        for (ExecutionMode m : ExecutionMode.values())
2189 +        for (Integer v1 : new Integer[] { 1, null }) {
2190 +
2191 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2192 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2193 +        final IncAction r = new IncAction();
2194 +        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2195 +        final CFException ex = new CFException();
2196 +
2197 +        g.completeExceptionally(ex);
2198 +        checkCompletedWithWrappedCFException(h, ex);
2199 +        f.complete(v1);
2200 +
2201 +        assertEquals(0, r.invocationCount);
2202 +        checkCompletedNormally(f, v1);
2203 +        checkCompletedWithWrappedCFException(g, ex);
2204 +        checkCompletedWithWrappedCFException(h, ex);
2205 +        }
2206 +    }
2207 +
2208 +    public void testAcceptEither_exceptionalCompletion3() {
2209 +        for (ExecutionMode m : ExecutionMode.values())
2210 +        for (Integer v1 : new Integer[] { 1, null }) {
2211 +
2212 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2213 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2214 +        final IncAction r = new IncAction();
2215 +        final CFException ex = new CFException();
2216 +
2217 +        g.completeExceptionally(ex);
2218 +        f.complete(v1);
2219 +        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2220 +
2221 +        // unspecified behavior
2222 +        Integer v;
2223 +        try {
2224 +            assertEquals(h.join(), null);
2225 +            assertEquals(1, r.invocationCount);
2226 +            assertEquals(inc(v1), r.value);
2227 +        } catch (CompletionException ok) {
2228 +            checkCompletedWithWrappedCFException(h, ex);
2229 +            assertEquals(0, r.invocationCount);
2230 +        }
2231 +
2232 +        checkCompletedWithWrappedCFException(g, ex);
2233 +        checkCompletedNormally(f, v1);
2234 +        }
2235 +    }
2236 +
2237 +    public void testAcceptEither_exceptionalCompletion4() {
2238 +        for (ExecutionMode m : ExecutionMode.values())
2239 +        for (Integer v1 : new Integer[] { 1, null }) {
2240 +
2241 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2242 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2243 +        final IncAction r = new IncAction();
2244 +        final CFException ex = new CFException();
2245 +
2246 +        f.completeExceptionally(ex);
2247 +        g.complete(v1);
2248 +        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2249 +
2250 +        // unspecified behavior
2251 +        Integer v;
2252 +        try {
2253 +            assertEquals(h.join(), null);
2254 +            assertEquals(1, r.invocationCount);
2255 +            assertEquals(inc(v1), r.value);
2256 +        } catch (CompletionException ok) {
2257 +            checkCompletedWithWrappedCFException(h, ex);
2258 +            assertEquals(0, r.invocationCount);
2259 +        }
2260 +
2261 +        checkCompletedWithWrappedCFException(f, ex);
2262 +        checkCompletedNormally(g, v1);
2263 +        }
2264 +    }
2265 +
2266 +    /**
2267 +     * acceptEither result completes exceptionally if action does
2268 +     */
2269 +    public void testAcceptEither_actionFailed1() {
2270 +        for (ExecutionMode m : ExecutionMode.values())
2271 +        for (Integer v1 : new Integer[] { 1, null })
2272 +        for (Integer v2 : new Integer[] { 2, null }) {
2273 +
2274 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2275 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2276 +        final FailingConsumer r = new FailingConsumer();
2277 +        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2278 +
2279 +        f.complete(v1);
2280 +        checkCompletedWithWrappedCFException(h);
2281 +        g.complete(v2);
2282 +        checkCompletedNormally(f, v1);
2283 +        checkCompletedNormally(g, v2);
2284 +        }
2285 +    }
2286 +
2287 +    public void testAcceptEither_actionFailed2() {
2288 +        for (ExecutionMode m : ExecutionMode.values())
2289 +        for (Integer v1 : new Integer[] { 1, null })
2290 +        for (Integer v2 : new Integer[] { 2, null }) {
2291 +
2292 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2293 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2294 +        final FailingConsumer r = new FailingConsumer();
2295 +        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2296 +
2297 +        g.complete(v2);
2298 +        checkCompletedWithWrappedCFException(h);
2299 +        f.complete(v1);
2300 +        checkCompletedNormally(f, v1);
2301 +        checkCompletedNormally(g, v2);
2302 +        }
2303 +    }
2304 +
2305 +    /**
2306 +     * acceptEither result completes exceptionally if either source cancelled
2307 +     */
2308 +    public void testAcceptEither_sourceCancelled1() {
2309 +        for (ExecutionMode m : ExecutionMode.values())
2310 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2311 +        for (Integer v1 : new Integer[] { 1, null }) {
2312 +
2313 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2314 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2315 +        final IncAction r = new IncAction();
2316 +        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2317 +
2318 +        assertTrue(f.cancel(mayInterruptIfRunning));
2319 +        checkCompletedWithWrappedCancellationException(h);
2320 +        g.complete(v1);
2321 +
2322 +        checkCancelled(f);
2323 +        assertEquals(0, r.invocationCount);
2324 +        checkCompletedNormally(g, v1);
2325 +        checkCompletedWithWrappedCancellationException(h);
2326 +        }
2327 +    }
2328 +
2329 +    public void testAcceptEither_sourceCancelled2() {
2330 +        for (ExecutionMode m : ExecutionMode.values())
2331 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2332 +        for (Integer v1 : new Integer[] { 1, null }) {
2333 +
2334 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2335 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2336 +        final IncAction r = new IncAction();
2337 +        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2338 +
2339 +        assertTrue(g.cancel(mayInterruptIfRunning));
2340 +        checkCompletedWithWrappedCancellationException(h);
2341 +        f.complete(v1);
2342 +
2343 +        checkCancelled(g);
2344 +        assertEquals(0, r.invocationCount);
2345 +        checkCompletedNormally(f, v1);
2346 +        checkCompletedWithWrappedCancellationException(h);
2347 +        }
2348 +    }
2349 +
2350 +    public void testAcceptEither_sourceCancelled3() {
2351 +        for (ExecutionMode m : ExecutionMode.values())
2352 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2353 +        for (Integer v1 : new Integer[] { 1, null }) {
2354 +
2355 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2356 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2357 +        final IncAction r = new IncAction();
2358 +
2359 +        assertTrue(g.cancel(mayInterruptIfRunning));
2360 +        f.complete(v1);
2361 +        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2362 +
2363 +        // unspecified behavior
2364 +        Integer v;
2365 +        try {
2366 +            assertEquals(h.join(), null);
2367 +            assertEquals(1, r.invocationCount);
2368 +            assertEquals(inc(v1), r.value);
2369 +        } catch (CompletionException ok) {
2370 +            checkCompletedWithWrappedCancellationException(h);
2371 +            assertEquals(0, r.invocationCount);
2372 +        }
2373 +
2374 +        checkCancelled(g);
2375 +        checkCompletedNormally(f, v1);
2376 +        }
2377 +    }
2378 +
2379 +    public void testAcceptEither_sourceCancelled4() {
2380 +        for (ExecutionMode m : ExecutionMode.values())
2381 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2382 +        for (Integer v1 : new Integer[] { 1, null }) {
2383 +
2384 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2385 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2386 +        final IncAction r = new IncAction();
2387 +
2388 +        assertTrue(f.cancel(mayInterruptIfRunning));
2389 +        g.complete(v1);
2390 +        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2391 +
2392 +        // unspecified behavior
2393 +        Integer v;
2394 +        try {
2395 +            assertEquals(h.join(), null);
2396 +            assertEquals(1, r.invocationCount);
2397 +            assertEquals(inc(v1), r.value);
2398 +        } catch (CompletionException ok) {
2399 +            checkCompletedWithWrappedCancellationException(h);
2400 +            assertEquals(0, r.invocationCount);
2401 +        }
2402 +
2403 +        checkCancelled(f);
2404 +        checkCompletedNormally(g, v1);
2405 +        }
2406 +    }
2407 +
2408 +    /**
2409 +     * runAfterEither result completes normally after normal completion
2410 +     * of either source
2411 +     */
2412 +    public void testRunAfterEither_normalCompletion1() {
2413 +        for (ExecutionMode m : ExecutionMode.values())
2414 +        for (Integer v1 : new Integer[] { 1, null })
2415 +        for (Integer v2 : new Integer[] { 2, null }) {
2416 +
2417 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2418 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2419 +        final Noop r = new Noop();
2420 +        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2421 +
2422 +        f.complete(v1);
2423 +        checkCompletedNormally(h, null);
2424 +        assertEquals(1, r.invocationCount);
2425 +        g.complete(v2);
2426 +
2427 +        checkCompletedNormally(f, v1);
2428 +        checkCompletedNormally(g, v2);
2429 +        checkCompletedNormally(h, null);
2430 +        assertEquals(1, r.invocationCount);
2431 +        }
2432 +    }
2433 +
2434 +    public void testRunAfterEither_normalCompletion2() {
2435 +        for (ExecutionMode m : ExecutionMode.values())
2436 +        for (Integer v1 : new Integer[] { 1, null })
2437 +        for (Integer v2 : new Integer[] { 2, null }) {
2438 +
2439 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2440 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2441 +        final Noop r = new Noop();
2442 +        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2443 +
2444 +        g.complete(v2);
2445 +        checkCompletedNormally(h, null);
2446 +        assertEquals(1, r.invocationCount);
2447 +        f.complete(v1);
2448 +
2449 +        checkCompletedNormally(f, v1);
2450 +        checkCompletedNormally(g, v2);
2451 +        checkCompletedNormally(h, null);
2452 +        assertEquals(1, r.invocationCount);
2453 +        }
2454 +    }
2455 +    public void testRunAfterEither_normalCompletion3() {
2456 +        for (ExecutionMode m : ExecutionMode.values())
2457 +        for (Integer v1 : new Integer[] { 1, null })
2458 +        for (Integer v2 : new Integer[] { 2, null }) {
2459 +
2460 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2461 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2462 +        final Noop r = new Noop();
2463 +
2464 +        f.complete(v1);
2465 +        g.complete(v2);
2466 +        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2467 +
2468 +        checkCompletedNormally(h, null);
2469 +        checkCompletedNormally(f, v1);
2470 +        checkCompletedNormally(g, v2);
2471 +        assertEquals(1, r.invocationCount);
2472 +        }
2473 +    }
2474 +
2475 +    /**
2476 +     * runAfterEither result completes exceptionally after exceptional
2477 +     * completion of either source
2478 +     */
2479 +    public void testRunAfterEither_exceptionalCompletion1() {
2480 +        for (ExecutionMode m : ExecutionMode.values())
2481 +        for (Integer v1 : new Integer[] { 1, null }) {
2482 +
2483 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2484 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2485 +        final Noop r = new Noop();
2486 +        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2487 +        final CFException ex = new CFException();
2488 +
2489 +        f.completeExceptionally(ex);
2490 +        checkCompletedWithWrappedCFException(h, ex);
2491 +        g.complete(v1);
2492 +
2493 +        assertEquals(0, r.invocationCount);
2494 +        checkCompletedNormally(g, v1);
2495 +        checkCompletedWithWrappedCFException(f, ex);
2496 +        checkCompletedWithWrappedCFException(h, ex);
2497 +        }
2498 +    }
2499 +
2500 +    public void testRunAfterEither_exceptionalCompletion2() {
2501 +        for (ExecutionMode m : ExecutionMode.values())
2502 +        for (Integer v1 : new Integer[] { 1, null }) {
2503 +
2504 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2505 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2506 +        final Noop r = new Noop();
2507 +        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2508 +        final CFException ex = new CFException();
2509 +
2510 +        g.completeExceptionally(ex);
2511 +        checkCompletedWithWrappedCFException(h, ex);
2512 +        f.complete(v1);
2513 +
2514 +        assertEquals(0, r.invocationCount);
2515 +        checkCompletedNormally(f, v1);
2516 +        checkCompletedWithWrappedCFException(g, ex);
2517 +        checkCompletedWithWrappedCFException(h, ex);
2518 +        }
2519 +    }
2520 +
2521 +    public void testRunAfterEither_exceptionalCompletion3() {
2522 +        for (ExecutionMode m : ExecutionMode.values())
2523 +        for (Integer v1 : new Integer[] { 1, null }) {
2524 +
2525 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2526 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2527 +        final Noop r = new Noop();
2528 +        final CFException ex = new CFException();
2529 +
2530 +        g.completeExceptionally(ex);
2531 +        f.complete(v1);
2532 +        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2533 +
2534 +        // unspecified behavior
2535 +        Integer v;
2536 +        try {
2537 +            assertEquals(h.join(), null);
2538 +            assertEquals(1, r.invocationCount);
2539 +        } catch (CompletionException ok) {
2540 +            checkCompletedWithWrappedCFException(h, ex);
2541 +            assertEquals(0, r.invocationCount);
2542 +        }
2543 +
2544 +        checkCompletedWithWrappedCFException(g, ex);
2545 +        checkCompletedNormally(f, v1);
2546 +        }
2547 +    }
2548 +
2549 +    public void testRunAfterEither_exceptionalCompletion4() {
2550 +        for (ExecutionMode m : ExecutionMode.values())
2551 +        for (Integer v1 : new Integer[] { 1, null }) {
2552 +
2553 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2554 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2555 +        final Noop r = new Noop();
2556 +        final CFException ex = new CFException();
2557 +
2558 +        f.completeExceptionally(ex);
2559 +        g.complete(v1);
2560 +        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2561 +
2562 +        // unspecified behavior
2563 +        Integer v;
2564 +        try {
2565 +            assertEquals(h.join(), null);
2566 +            assertEquals(1, r.invocationCount);
2567 +        } catch (CompletionException ok) {
2568 +            checkCompletedWithWrappedCFException(h, ex);
2569 +            assertEquals(0, r.invocationCount);
2570 +        }
2571 +
2572 +        checkCompletedWithWrappedCFException(f, ex);
2573 +        checkCompletedNormally(g, v1);
2574 +        }
2575 +    }
2576 +
2577 +    /**
2578 +     * runAfterEither result completes exceptionally if action does
2579 +     */
2580 +    public void testRunAfterEither_actionFailed1() {
2581 +        for (ExecutionMode m : ExecutionMode.values())
2582 +        for (Integer v1 : new Integer[] { 1, null })
2583 +        for (Integer v2 : new Integer[] { 2, null }) {
2584 +
2585 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2586 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2587 +        final FailingNoop r = new FailingNoop();
2588 +        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2589 +
2590 +        f.complete(v1);
2591 +        checkCompletedWithWrappedCFException(h);
2592 +        g.complete(v2);
2593 +        checkCompletedNormally(f, v1);
2594 +        checkCompletedNormally(g, v2);
2595 +        }
2596 +    }
2597 +
2598 +    public void testRunAfterEither_actionFailed2() {
2599 +        for (ExecutionMode m : ExecutionMode.values())
2600 +        for (Integer v1 : new Integer[] { 1, null })
2601 +        for (Integer v2 : new Integer[] { 2, null }) {
2602 +
2603 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2604 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2605 +        final FailingNoop r = new FailingNoop();
2606 +        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2607 +
2608 +        g.complete(v2);
2609 +        checkCompletedWithWrappedCFException(h);
2610 +        f.complete(v1);
2611 +        checkCompletedNormally(f, v1);
2612 +        checkCompletedNormally(g, v2);
2613 +        }
2614 +    }
2615 +
2616 +    /**
2617 +     * runAfterEither result completes exceptionally if either source cancelled
2618 +     */
2619 +    public void testRunAfterEither_sourceCancelled1() {
2620 +        for (ExecutionMode m : ExecutionMode.values())
2621 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2622 +        for (Integer v1 : new Integer[] { 1, null }) {
2623 +
2624 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2625 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2626 +        final Noop r = new Noop();
2627 +        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2628 +
2629 +        assertTrue(f.cancel(mayInterruptIfRunning));
2630 +        checkCompletedWithWrappedCancellationException(h);
2631 +        g.complete(v1);
2632 +
2633 +        checkCancelled(f);
2634 +        assertEquals(0, r.invocationCount);
2635 +        checkCompletedNormally(g, v1);
2636 +        checkCompletedWithWrappedCancellationException(h);
2637 +        }
2638 +    }
2639 +
2640 +    public void testRunAfterEither_sourceCancelled2() {
2641 +        for (ExecutionMode m : ExecutionMode.values())
2642 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2643 +        for (Integer v1 : new Integer[] { 1, null }) {
2644 +
2645 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2646 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2647 +        final Noop r = new Noop();
2648 +        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2649 +
2650 +        assertTrue(g.cancel(mayInterruptIfRunning));
2651 +        checkCompletedWithWrappedCancellationException(h);
2652 +        f.complete(v1);
2653 +
2654 +        checkCancelled(g);
2655 +        assertEquals(0, r.invocationCount);
2656 +        checkCompletedNormally(f, v1);
2657 +        checkCompletedWithWrappedCancellationException(h);
2658 +        }
2659 +    }
2660 +
2661 +    public void testRunAfterEither_sourceCancelled3() {
2662 +        for (ExecutionMode m : ExecutionMode.values())
2663 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2664 +        for (Integer v1 : new Integer[] { 1, null }) {
2665 +
2666 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2667 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2668 +        final Noop r = new Noop();
2669 +
2670 +        assertTrue(g.cancel(mayInterruptIfRunning));
2671 +        f.complete(v1);
2672 +        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2673 +
2674 +        // unspecified behavior
2675 +        Integer v;
2676 +        try {
2677 +            assertEquals(h.join(), null);
2678 +            assertEquals(1, r.invocationCount);
2679 +        } catch (CompletionException ok) {
2680 +            checkCompletedWithWrappedCancellationException(h);
2681 +            assertEquals(0, r.invocationCount);
2682 +        }
2683 +
2684 +        checkCancelled(g);
2685 +        checkCompletedNormally(f, v1);
2686 +        }
2687 +    }
2688 +
2689 +    public void testRunAfterEither_sourceCancelled4() {
2690 +        for (ExecutionMode m : ExecutionMode.values())
2691 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2692 +        for (Integer v1 : new Integer[] { 1, null }) {
2693 +
2694 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2695 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
2696 +        final Noop r = new Noop();
2697 +
2698 +        assertTrue(f.cancel(mayInterruptIfRunning));
2699 +        g.complete(v1);
2700 +        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2701 +
2702 +        // unspecified behavior
2703 +        Integer v;
2704 +        try {
2705 +            assertEquals(h.join(), null);
2706 +            assertEquals(1, r.invocationCount);
2707 +        } catch (CompletionException ok) {
2708 +            checkCompletedWithWrappedCancellationException(h);
2709 +            assertEquals(0, r.invocationCount);
2710 +        }
2711 +
2712 +        checkCancelled(f);
2713 +        checkCompletedNormally(g, v1);
2714 +        }
2715 +    }
2716 +
2717 +    /**
2718 +     * thenCompose result completes normally after normal completion of source
2719 +     */
2720 +    public void testThenCompose_normalCompletion1() {
2721 +        for (ExecutionMode m : ExecutionMode.values())
2722 +        for (Integer v1 : new Integer[] { 1, null }) {
2723 +
2724 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2725 +        final CompletableFutureInc r = new CompletableFutureInc();
2726 +        final CompletableFuture<Integer> g = f.thenCompose(r);
2727 +        f.complete(v1);
2728 +        checkCompletedNormally(g, inc(v1));
2729 +        checkCompletedNormally(f, v1);
2730 +        assertEquals(1, r.invocationCount);
2731 +        }
2732 +    }
2733 +
2734 +    public void testThenCompose_normalCompletion2() {
2735 +        for (ExecutionMode m : ExecutionMode.values())
2736 +        for (Integer v1 : new Integer[] { 1, null }) {
2737 +
2738 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2739 +        final CompletableFutureInc r = new CompletableFutureInc();
2740 +        f.complete(v1);
2741 +        final CompletableFuture<Integer> g = f.thenCompose(r);
2742 +        checkCompletedNormally(g, inc(v1));
2743 +        checkCompletedNormally(f, v1);
2744 +        assertEquals(1, r.invocationCount);
2745 +        }
2746 +    }
2747 +
2748 +    /**
2749 +     * thenCompose result completes exceptionally after exceptional
2750 +     * completion of source
2751 +     */
2752 +    public void testThenCompose_exceptionalCompletion1() {
2753 +        for (ExecutionMode m : ExecutionMode.values()) {
2754 +
2755 +        final CFException ex = new CFException();
2756 +        final CompletableFutureInc r = new CompletableFutureInc();
2757 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2758 +        final CompletableFuture<Integer> g = f.thenCompose(r);
2759 +        f.completeExceptionally(ex);
2760 +        checkCompletedWithWrappedCFException(g, ex);
2761 +        checkCompletedWithWrappedCFException(f, ex);
2762 +        }
2763 +    }
2764 +
2765 +    public void testThenCompose_exceptionalCompletion2() {
2766 +        for (ExecutionMode m : ExecutionMode.values()) {
2767 +
2768 +        final CFException ex = new CFException();
2769 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2770 +        f.completeExceptionally(ex);
2771 +        final CompletableFutureInc r = new CompletableFutureInc();
2772 +        final CompletableFuture<Integer> g = f.thenCompose(r);
2773 +        checkCompletedWithWrappedCFException(g, ex);
2774 +        checkCompletedWithWrappedCFException(f, ex);
2775 +        }
2776 +    }
2777 +
2778 +    /**
2779 +     * thenCompose result completes exceptionally if action does
2780 +     */
2781 +    public void testThenCompose_actionFailed1() {
2782 +        for (ExecutionMode m : ExecutionMode.values())
2783 +        for (Integer v1 : new Integer[] { 1, null }) {
2784 +
2785 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2786 +        final FailingCompletableFutureFunction r
2787 +            = new FailingCompletableFutureFunction();
2788 +        final CompletableFuture<Integer> g = f.thenCompose(r);
2789 +        f.complete(v1);
2790 +        checkCompletedWithWrappedCFException(g);
2791 +        checkCompletedNormally(f, v1);
2792 +        }
2793 +    }
2794 +
2795 +    public void testThenCompose_actionFailed2() {
2796 +        for (ExecutionMode m : ExecutionMode.values())
2797 +        for (Integer v1 : new Integer[] { 1, null }) {
2798 +
2799 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2800 +        f.complete(v1);
2801 +        final FailingCompletableFutureFunction r
2802 +            = new FailingCompletableFutureFunction();
2803 +        final CompletableFuture<Integer> g = f.thenCompose(r);
2804 +        checkCompletedWithWrappedCFException(g);
2805 +        checkCompletedNormally(f, v1);
2806 +        }
2807 +    }
2808 +
2809 +    /**
2810 +     * thenCompose result completes exceptionally if source cancelled
2811 +     */
2812 +    public void testThenCompose_sourceCancelled1() {
2813 +        for (ExecutionMode m : ExecutionMode.values())
2814 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
2815 +
2816 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2817 +        final CompletableFutureInc r = new CompletableFutureInc();
2818 +        final CompletableFuture<Integer> g = f.thenCompose(r);
2819 +        assertTrue(f.cancel(mayInterruptIfRunning));
2820 +        checkCompletedWithWrappedCancellationException(g);
2821 +        checkCancelled(f);
2822 +        }
2823 +    }
2824 +
2825 +    public void testThenCompose_sourceCancelled2() {
2826 +        for (ExecutionMode m : ExecutionMode.values())
2827 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
2828 +
2829 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2830 +        assertTrue(f.cancel(mayInterruptIfRunning));
2831 +        final CompletableFutureInc r = new CompletableFutureInc();
2832 +        final CompletableFuture<Integer> g = f.thenCompose(r);
2833 +        checkCompletedWithWrappedCancellationException(g);
2834 +        checkCancelled(f);
2835 +        }
2836 +    }
2837 +
2838 +    // asyncs
2839 +
2840 +    /**
2841 +     * thenRunAsync result completes normally after normal completion of source
2842 +     */
2843 +    public void testThenRunAsync() {
2844 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2845 +        Noop r = new Noop();
2846 +        CompletableFuture<Void> g = f.thenRunAsync(r);
2847 +        f.complete(null);
2848 +        checkCompletedNormally(g, null);
2849 +
2850 +        // reordered version
2851 +        f = new CompletableFuture<>();
2852 +        f.complete(null);
2853 +        r = new Noop();
2854 +        g = f.thenRunAsync(r);
2855 +        checkCompletedNormally(g, null);
2856 +    }
2857 +
2858 +    /**
2859 +     * thenRunAsync result completes exceptionally after exceptional
2860 +     * completion of source
2861 +     */
2862 +    public void testThenRunAsync2() {
2863 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2864 +        Noop r = new Noop();
2865 +        CompletableFuture<Void> g = f.thenRunAsync(r);
2866 +        f.completeExceptionally(new CFException());
2867 +        try {
2868 +            g.join();
2869 +            shouldThrow();
2870 +        } catch (CompletionException success) {}
2871 +        checkCompletedWithWrappedCFException(g);
2872 +    }
2873 +
2874 +    /**
2875 +     * thenRunAsync result completes exceptionally if action does
2876 +     */
2877 +    public void testThenRunAsync3() {
2878 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2879 +        FailingNoop r = new FailingNoop();
2880 +        CompletableFuture<Void> g = f.thenRunAsync(r);
2881 +        f.complete(null);
2882 +        checkCompletedWithWrappedCFException(g);
2883 +    }
2884 +
2885 +    /**
2886 +     * thenRunAsync result completes exceptionally if source cancelled
2887 +     */
2888 +    public void testThenRunAsync4() {
2889 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2890 +        Noop r = new Noop();
2891 +        CompletableFuture<Void> g = f.thenRunAsync(r);
2892 +        assertTrue(f.cancel(true));
2893 +        checkCompletedWithWrappedCancellationException(g);
2894 +    }
2895 +
2896 +    /**
2897 +     * thenApplyAsync result completes normally after normal completion of source
2898 +     */
2899 +    public void testThenApplyAsync() {
2900 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2901 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc);
2902 +        f.complete(one);
2903 +        checkCompletedNormally(g, two);
2904 +    }
2905 +
2906 +    /**
2907 +     * thenApplyAsync result completes exceptionally after exceptional
2908 +     * completion of source
2909 +     */
2910 +    public void testThenApplyAsync2() {
2911 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2912 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc);
2913 +        f.completeExceptionally(new CFException());
2914 +        checkCompletedWithWrappedCFException(g);
2915 +    }
2916 +
2917 +    /**
2918 +     * thenApplyAsync result completes exceptionally if action does
2919 +     */
2920 +    public void testThenApplyAsync3() {
2921 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2922 +        FailingFunction r = new FailingFunction();
2923 +        CompletableFuture<Integer> g = f.thenApplyAsync(r);
2924 +        f.complete(null);
2925 +        checkCompletedWithWrappedCFException(g);
2926 +    }
2927 +
2928 +    /**
2929 +     * thenApplyAsync result completes exceptionally if source cancelled
2930 +     */
2931 +    public void testThenApplyAsync4() {
2932 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2933 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc);
2934 +        assertTrue(f.cancel(true));
2935 +        checkCompletedWithWrappedCancellationException(g);
2936 +    }
2937 +
2938 +    /**
2939 +     * thenAcceptAsync result completes normally after normal
2940 +     * completion of source
2941 +     */
2942 +    public void testThenAcceptAsync() {
2943 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2944 +        IncAction r = new IncAction();
2945 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
2946 +        f.complete(one);
2947 +        checkCompletedNormally(g, null);
2948 +        assertEquals(r.value, (Integer) 2);
2949 +    }
2950 +
2951 +    /**
2952 +     * thenAcceptAsync result completes exceptionally after exceptional
2953 +     * completion of source
2954 +     */
2955 +    public void testThenAcceptAsync2() {
2956 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2957 +        IncAction r = new IncAction();
2958 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
2959 +        f.completeExceptionally(new CFException());
2960 +        checkCompletedWithWrappedCFException(g);
2961 +    }
2962 +
2963 +    /**
2964 +     * thenAcceptAsync result completes exceptionally if action does
2965 +     */
2966 +    public void testThenAcceptAsync3() {
2967 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2968 +        FailingConsumer r = new FailingConsumer();
2969 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
2970 +        f.complete(null);
2971 +        checkCompletedWithWrappedCFException(g);
2972 +    }
2973 +
2974 +    /**
2975 +     * thenAcceptAsync result completes exceptionally if source cancelled
2976 +     */
2977 +    public void testThenAcceptAsync4() {
2978 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2979 +        IncAction r = new IncAction();
2980 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
2981 +        assertTrue(f.cancel(true));
2982 +        checkCompletedWithWrappedCancellationException(g);
2983 +    }
2984 +
2985 +    // async with explicit executors
2986 +
2987 +    /**
2988 +     * thenRunAsync result completes normally after normal completion of source
2989 +     */
2990 +    public void testThenRunAsyncE() {
2991 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2992 +        Noop r = new Noop();
2993 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
2994 +        f.complete(null);
2995 +        checkCompletedNormally(g, null);
2996 +
2997 +        // reordered version
2998 +        f = new CompletableFuture<>();
2999 +        f.complete(null);
3000 +        r = new Noop();
3001 +        g = f.thenRunAsync(r, new ThreadExecutor());
3002 +        checkCompletedNormally(g, null);
3003 +    }
3004 +
3005 +    /**
3006 +     * thenRunAsync result completes exceptionally after exceptional
3007 +     * completion of source
3008 +     */
3009 +    public void testThenRunAsync2E() {
3010 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3011 +        Noop r = new Noop();
3012 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
3013 +        f.completeExceptionally(new CFException());
3014 +        try {
3015 +            g.join();
3016 +            shouldThrow();
3017 +        } catch (CompletionException success) {}
3018 +        checkCompletedWithWrappedCFException(g);
3019 +    }
3020 +
3021 +    /**
3022 +     * thenRunAsync result completes exceptionally if action does
3023 +     */
3024 +    public void testThenRunAsync3E() {
3025 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3026 +        FailingNoop r = new FailingNoop();
3027 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
3028 +        f.complete(null);
3029 +        checkCompletedWithWrappedCFException(g);
3030 +    }
3031 +
3032 +    /**
3033 +     * thenRunAsync result completes exceptionally if source cancelled
3034 +     */
3035 +    public void testThenRunAsync4E() {
3036 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3037 +        Noop r = new Noop();
3038 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
3039 +        assertTrue(f.cancel(true));
3040 +        checkCompletedWithWrappedCancellationException(g);
3041 +    }
3042 +
3043 +    /**
3044 +     * thenApplyAsync result completes normally after normal completion of source
3045 +     */
3046 +    public void testThenApplyAsyncE() {
3047 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3048 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc, new ThreadExecutor());
3049 +        f.complete(one);
3050 +        checkCompletedNormally(g, two);
3051 +    }
3052 +
3053 +    /**
3054 +     * thenApplyAsync result completes exceptionally after exceptional
3055 +     * completion of source
3056 +     */
3057 +    public void testThenApplyAsync2E() {
3058 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3059 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc, new ThreadExecutor());
3060 +        f.completeExceptionally(new CFException());
3061 +        checkCompletedWithWrappedCFException(g);
3062 +    }
3063 +
3064 +    /**
3065 +     * thenApplyAsync result completes exceptionally if action does
3066 +     */
3067 +    public void testThenApplyAsync3E() {
3068 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3069 +        FailingFunction r = new FailingFunction();
3070 +        CompletableFuture<Integer> g = f.thenApplyAsync(r, new ThreadExecutor());
3071 +        f.complete(null);
3072 +        checkCompletedWithWrappedCFException(g);
3073 +    }
3074 +
3075 +    /**
3076 +     * thenApplyAsync result completes exceptionally if source cancelled
3077 +     */
3078 +    public void testThenApplyAsync4E() {
3079 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3080 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc, new ThreadExecutor());
3081 +        assertTrue(f.cancel(true));
3082 +        checkCompletedWithWrappedCancellationException(g);
3083 +    }
3084 +
3085 +    /**
3086 +     * thenAcceptAsync result completes normally after normal
3087 +     * completion of source
3088 +     */
3089 +    public void testThenAcceptAsyncE() {
3090 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3091 +        IncAction r = new IncAction();
3092 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
3093 +        f.complete(one);
3094 +        checkCompletedNormally(g, null);
3095 +        assertEquals(r.value, (Integer) 2);
3096 +    }
3097 +
3098 +    /**
3099 +     * thenAcceptAsync result completes exceptionally after exceptional
3100 +     * completion of source
3101 +     */
3102 +    public void testThenAcceptAsync2E() {
3103 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3104 +        IncAction r = new IncAction();
3105 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
3106 +        f.completeExceptionally(new CFException());
3107 +        checkCompletedWithWrappedCFException(g);
3108 +    }
3109 +
3110 +    /**
3111 +     * thenAcceptAsync result completes exceptionally if action does
3112 +     */
3113 +    public void testThenAcceptAsync3E() {
3114 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3115 +        FailingConsumer r = new FailingConsumer();
3116 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
3117 +        f.complete(null);
3118 +        checkCompletedWithWrappedCFException(g);
3119 +    }
3120 +
3121 +    /**
3122 +     * thenAcceptAsync result completes exceptionally if source cancelled
3123 +     */
3124 +    public void testThenAcceptAsync4E() {
3125 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3126 +        IncAction r = new IncAction();
3127 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
3128 +        assertTrue(f.cancel(true));
3129 +        checkCompletedWithWrappedCancellationException(g);
3130 +    }
3131 +
3132 +    // other static methods
3133 +
3134 +    /**
3135       * allOf(no component futures) returns a future completed normally
3136       * with the value null
3137       */
3138      public void testAllOf_empty() throws Exception {
3139 <        CompletableFuture<?> f = CompletableFuture.allOf();
3139 >        CompletableFuture<Void> f = CompletableFuture.allOf();
3140          checkCompletedNormally(f, null);
3141      }
3142  
3143      /**
3144 +     * allOf returns a future completed normally with the value null
3145 +     * when all components complete normally
3146 +     */
3147 +    public void testAllOf_normal() throws Exception {
3148 +        for (int k = 1; k < 20; ++k) {
3149 +            CompletableFuture<Integer>[] fs = (CompletableFuture<Integer>[]) new CompletableFuture[k];
3150 +            for (int i = 0; i < k; ++i)
3151 +                fs[i] = new CompletableFuture<>();
3152 +            CompletableFuture<Void> f = CompletableFuture.allOf(fs);
3153 +            for (int i = 0; i < k; ++i) {
3154 +                checkIncomplete(f);
3155 +                checkIncomplete(CompletableFuture.allOf(fs));
3156 +                fs[i].complete(one);
3157 +            }
3158 +            checkCompletedNormally(f, null);
3159 +            checkCompletedNormally(CompletableFuture.allOf(fs), null);
3160 +        }
3161 +    }
3162 +
3163 +    /**
3164       * anyOf(no component futures) returns an incomplete future
3165       */
3166      public void testAnyOf_empty() throws Exception {
3167 <        CompletableFuture<?> f = CompletableFuture.anyOf();
3167 >        CompletableFuture<Object> f = CompletableFuture.anyOf();
3168          checkIncomplete(f);
3169      }
3170 +
3171 +    /**
3172 +     * anyOf returns a future completed normally with a value when
3173 +     * a component future does
3174 +     */
3175 +    public void testAnyOf_normal() throws Exception {
3176 +        for (int k = 0; k < 10; ++k) {
3177 +            CompletableFuture[] fs = new CompletableFuture[k];
3178 +            for (int i = 0; i < k; ++i)
3179 +                fs[i] = new CompletableFuture<>();
3180 +            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3181 +            checkIncomplete(f);
3182 +            for (int i = 0; i < k; ++i) {
3183 +                fs[i].complete(one);
3184 +                checkCompletedNormally(f, one);
3185 +                checkCompletedNormally(CompletableFuture.anyOf(fs), one);
3186 +            }
3187 +        }
3188 +    }
3189 +
3190 +    /**
3191 +     * anyOf result completes exceptionally when any component does.
3192 +     */
3193 +    public void testAnyOf_exceptional() throws Exception {
3194 +        for (int k = 0; k < 10; ++k) {
3195 +            CompletableFuture[] fs = new CompletableFuture[k];
3196 +            for (int i = 0; i < k; ++i)
3197 +                fs[i] = new CompletableFuture<>();
3198 +            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3199 +            checkIncomplete(f);
3200 +            for (int i = 0; i < k; ++i) {
3201 +                fs[i].completeExceptionally(new CFException());
3202 +                checkCompletedWithWrappedCFException(f);
3203 +                checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs));
3204 +            }
3205 +        }
3206 +    }
3207 +
3208 +    /**
3209 +     * Completion methods throw NullPointerException with null arguments
3210 +     */
3211 +    public void testNPE() {
3212 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3213 +        CompletableFuture<Integer> g = new CompletableFuture<>();
3214 +        CompletableFuture<Integer> nullFuture = (CompletableFuture<Integer>)null;
3215 +        CompletableFuture<?> h;
3216 +        ThreadExecutor exec = new ThreadExecutor();
3217 +
3218 +        Runnable[] throwingActions = {
3219 +            () -> CompletableFuture.supplyAsync(null),
3220 +            () -> CompletableFuture.supplyAsync(null, exec),
3221 +            () -> CompletableFuture.supplyAsync(supplyOne, null),
3222 +
3223 +            () -> CompletableFuture.runAsync(null),
3224 +            () -> CompletableFuture.runAsync(null, exec),
3225 +            () -> CompletableFuture.runAsync(() -> {}, null),
3226 +
3227 +            () -> f.completeExceptionally(null),
3228 +
3229 +            () -> f.thenApply(null),
3230 +            () -> f.thenApplyAsync(null),
3231 +            () -> f.thenApplyAsync((x) -> x, null),
3232 +            () -> f.thenApplyAsync(null, exec),
3233 +
3234 +            () -> f.thenAccept(null),
3235 +            () -> f.thenAcceptAsync(null),
3236 +            () -> f.thenAcceptAsync((x) -> {} , null),
3237 +            () -> f.thenAcceptAsync(null, exec),
3238 +
3239 +            () -> f.thenRun(null),
3240 +            () -> f.thenRunAsync(null),
3241 +            () -> f.thenRunAsync(() -> {} , null),
3242 +            () -> f.thenRunAsync(null, exec),
3243 +
3244 +            () -> f.thenCombine(g, null),
3245 +            () -> f.thenCombineAsync(g, null),
3246 +            () -> f.thenCombineAsync(g, null, exec),
3247 +            () -> f.thenCombine(nullFuture, (x, y) -> x),
3248 +            () -> f.thenCombineAsync(nullFuture, (x, y) -> x),
3249 +            () -> f.thenCombineAsync(nullFuture, (x, y) -> x, exec),
3250 +            () -> f.thenCombineAsync(g, (x, y) -> x, null),
3251 +
3252 +            () -> f.thenAcceptBoth(g, null),
3253 +            () -> f.thenAcceptBothAsync(g, null),
3254 +            () -> f.thenAcceptBothAsync(g, null, exec),
3255 +            () -> f.thenAcceptBoth(nullFuture, (x, y) -> {}),
3256 +            () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}),
3257 +            () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec),
3258 +            () -> f.thenAcceptBothAsync(g, (x, y) -> {}, null),
3259 +
3260 +            () -> f.runAfterBoth(g, null),
3261 +            () -> f.runAfterBothAsync(g, null),
3262 +            () -> f.runAfterBothAsync(g, null, exec),
3263 +            () -> f.runAfterBoth(nullFuture, () -> {}),
3264 +            () -> f.runAfterBothAsync(nullFuture, () -> {}),
3265 +            () -> f.runAfterBothAsync(nullFuture, () -> {}, exec),
3266 +            () -> f.runAfterBothAsync(g, () -> {}, null),
3267 +
3268 +            () -> f.applyToEither(g, null),
3269 +            () -> f.applyToEitherAsync(g, null),
3270 +            () -> f.applyToEitherAsync(g, null, exec),
3271 +            () -> f.applyToEither(nullFuture, (x) -> x),
3272 +            () -> f.applyToEitherAsync(nullFuture, (x) -> x),
3273 +            () -> f.applyToEitherAsync(nullFuture, (x) -> x, exec),
3274 +            () -> f.applyToEitherAsync(g, (x) -> x, null),
3275 +
3276 +            () -> f.acceptEither(g, null),
3277 +            () -> f.acceptEitherAsync(g, null),
3278 +            () -> f.acceptEitherAsync(g, null, exec),
3279 +            () -> f.acceptEither(nullFuture, (x) -> {}),
3280 +            () -> f.acceptEitherAsync(nullFuture, (x) -> {}),
3281 +            () -> f.acceptEitherAsync(nullFuture, (x) -> {}, exec),
3282 +            () -> f.acceptEitherAsync(g, (x) -> {}, null),
3283 +
3284 +            () -> f.runAfterEither(g, null),
3285 +            () -> f.runAfterEitherAsync(g, null),
3286 +            () -> f.runAfterEitherAsync(g, null, exec),
3287 +            () -> f.runAfterEither(nullFuture, () -> {}),
3288 +            () -> f.runAfterEitherAsync(nullFuture, () -> {}),
3289 +            () -> f.runAfterEitherAsync(nullFuture, () -> {}, exec),
3290 +            () -> f.runAfterEitherAsync(g, () -> {}, null),
3291 +
3292 +            () -> f.thenCompose(null),
3293 +            () -> f.thenComposeAsync(null),
3294 +            () -> f.thenComposeAsync(new CompletableFutureInc(), null),
3295 +            () -> f.thenComposeAsync(null, exec),
3296 +
3297 +            () -> f.exceptionally(null),
3298 +
3299 +            () -> f.handle(null),
3300 +
3301 +            () -> CompletableFuture.allOf((CompletableFuture<?>)null),
3302 +            () -> CompletableFuture.allOf((CompletableFuture<?>[])null),
3303 +            () -> CompletableFuture.allOf(f, null),
3304 +            () -> CompletableFuture.allOf(null, f),
3305 +
3306 +            () -> CompletableFuture.anyOf((CompletableFuture<?>)null),
3307 +            () -> CompletableFuture.anyOf((CompletableFuture<?>[])null),
3308 +            () -> CompletableFuture.anyOf(f, null),
3309 +            () -> CompletableFuture.anyOf(null, f),
3310 +
3311 +            () -> f.obtrudeException(null),
3312 +        };
3313 +
3314 +        assertThrows(NullPointerException.class, throwingActions);
3315 +        assertEquals(0, exec.count.get());
3316 +    }
3317 +
3318 +    /**
3319 +     * toCompletableFuture returns this CompletableFuture.
3320 +     */
3321 +    public void testToCompletableFuture() {
3322 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3323 +        assertSame(f, f.toCompletableFuture());
3324 +    }
3325 +
3326 +    /**
3327 +     * whenComplete action executes on normal completion, propagating
3328 +     * source result.
3329 +     */
3330 +    public void testWhenComplete_normalCompletion1() {
3331 +        for (boolean createIncomplete : new boolean[] { true, false })
3332 +        for (ExecutionMode m : ExecutionMode.values())
3333 +        for (Integer v1 : new Integer[] { 1, null }) {
3334 +
3335 +        final AtomicInteger a = new AtomicInteger();
3336 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
3337 +        if (!createIncomplete) f.complete(v1);
3338 +        final CompletableFuture<Integer> g =
3339 +            m.whenComplete(f,
3340 +                           (Integer x, Throwable t) -> {
3341 +                               threadAssertSame(x, v1);
3342 +                               threadAssertNull(t);
3343 +                               a.getAndIncrement();
3344 +                           });
3345 +        if (createIncomplete) f.complete(v1);
3346 +        checkCompletedNormally(f, v1);
3347 +        checkCompletedNormally(g, v1);
3348 +        assertEquals(a.get(), 1);
3349 +        }
3350 +    }
3351 +
3352 +    /**
3353 +     * whenComplete action executes on exceptional completion, propagating
3354 +     * source result.
3355 +     */
3356 +    public void testWhenComplete_exceptionalCompletion() {
3357 +        for (boolean createIncomplete : new boolean[] { true, false })
3358 +        for (ExecutionMode m : ExecutionMode.values())
3359 +        for (Integer v1 : new Integer[] { 1, null }) {
3360 +
3361 +        final AtomicInteger a = new AtomicInteger();
3362 +        final CFException ex = new CFException();
3363 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
3364 +        if (!createIncomplete) f.completeExceptionally(ex);
3365 +        final CompletableFuture<Integer> g = m.whenComplete
3366 +            (f,
3367 +             (Integer x, Throwable t) -> {
3368 +                threadAssertNull(x);
3369 +                threadAssertSame(t, ex);
3370 +                a.getAndIncrement();
3371 +            });
3372 +        if (createIncomplete) f.completeExceptionally(ex);
3373 +        checkCompletedWithWrappedCFException(f, ex);
3374 +        checkCompletedWithWrappedCFException(g, ex);
3375 +        assertEquals(a.get(), 1);
3376 +        }
3377 +    }
3378 +
3379 +    /**
3380 +     * If a whenComplete action throws an exception when triggered by
3381 +     * a normal completion, it completes exceptionally
3382 +     */
3383 +    public void testWhenComplete_actionFailed() {
3384 +        for (boolean createIncomplete : new boolean[] { true, false })
3385 +        for (ExecutionMode m : ExecutionMode.values())
3386 +        for (Integer v1 : new Integer[] { 1, null }) {
3387 +
3388 +        final CFException ex = new CFException();
3389 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
3390 +        if (!createIncomplete) f.complete(v1);
3391 +        final CompletableFuture<Integer> g = m.whenComplete
3392 +            (f,
3393 +             (Integer x, Throwable t) -> {
3394 +                threadAssertSame(x, v1);
3395 +                threadAssertNull(t);
3396 +                throw ex;
3397 +            });
3398 +        if (createIncomplete) f.complete(v1);
3399 +        checkCompletedNormally(f, v1);
3400 +        checkCompletedWithWrappedCFException(g, ex);
3401 +        }
3402 +    }
3403 +
3404 +    /**
3405 +     * If a whenComplete action throws an exception when triggered by
3406 +     * a source completion that also throws an exception, the source
3407 +     * exception takes precedence.
3408 +     */
3409 +    public void testWhenComplete_actionFailedSourceFailed() {
3410 +        for (boolean createIncomplete : new boolean[] { true, false })
3411 +        for (ExecutionMode m : ExecutionMode.values())
3412 +        for (Integer v1 : new Integer[] { 1, null }) {
3413 +
3414 +        final CFException ex1 = new CFException();
3415 +        final CFException ex2 = new CFException();
3416 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
3417 +
3418 +        if (!createIncomplete) f.completeExceptionally(ex1);
3419 +        final CompletableFuture<Integer> g = m.whenComplete
3420 +            (f,
3421 +             (Integer x, Throwable t) -> {
3422 +                threadAssertSame(t, ex1);
3423 +                threadAssertNull(x);
3424 +                throw ex2;
3425 +            });
3426 +        if (createIncomplete) f.completeExceptionally(ex1);
3427 +
3428 +        checkCompletedWithWrappedCFException(f, ex1);
3429 +        checkCompletedWithWrappedCFException(g, ex1);
3430 +        }
3431 +    }
3432 +
3433 +    /**
3434 +     * handleAsync action completes normally with function value on
3435 +     * either normal or exceptional completion of source
3436 +     */
3437 +    public void testHandleAsync() {
3438 +        CompletableFuture<Integer> f, g;
3439 +        IntegerHandler r;
3440 +
3441 +        f = new CompletableFuture<>();
3442 +        g = f.handleAsync(r = new IntegerHandler());
3443 +        assertEquals(0, r.invocationCount);
3444 +        f.completeExceptionally(new CFException());
3445 +        checkCompletedWithWrappedCFException(f);
3446 +        checkCompletedNormally(g, three);
3447 +        assertEquals(1, r.invocationCount);
3448 +
3449 +        f = new CompletableFuture<>();
3450 +        g = f.handleAsync(r = new IntegerHandler());
3451 +        assertEquals(0, r.invocationCount);
3452 +        f.completeExceptionally(new CFException());
3453 +        checkCompletedWithWrappedCFException(f);
3454 +        checkCompletedNormally(g, three);
3455 +        assertEquals(1, r.invocationCount);
3456 +
3457 +        f = new CompletableFuture<>();
3458 +        g = f.handleAsync(r = new IntegerHandler());
3459 +        assertEquals(0, r.invocationCount);
3460 +        f.complete(one);
3461 +        checkCompletedNormally(f, one);
3462 +        checkCompletedNormally(g, two);
3463 +        assertEquals(1, r.invocationCount);
3464 +
3465 +        f = new CompletableFuture<>();
3466 +        g = f.handleAsync(r = new IntegerHandler());
3467 +        assertEquals(0, r.invocationCount);
3468 +        f.complete(one);
3469 +        checkCompletedNormally(f, one);
3470 +        checkCompletedNormally(g, two);
3471 +        assertEquals(1, r.invocationCount);
3472 +    }
3473 +
3474 +    /**
3475 +     * handleAsync action with Executor completes normally with
3476 +     * function value on either normal or exceptional completion of
3477 +     * source
3478 +     */
3479 +    public void testHandleAsync2() {
3480 +        CompletableFuture<Integer> f, g;
3481 +        ThreadExecutor exec = new ThreadExecutor();
3482 +        IntegerHandler r;
3483 +
3484 +        f = new CompletableFuture<>();
3485 +        g = f.handleAsync(r = new IntegerHandler(), exec);
3486 +        assertEquals(0, r.invocationCount);
3487 +        f.completeExceptionally(new CFException());
3488 +        checkCompletedWithWrappedCFException(f);
3489 +        checkCompletedNormally(g, three);
3490 +        assertEquals(1, r.invocationCount);
3491 +
3492 +        f = new CompletableFuture<>();
3493 +        g = f.handleAsync(r = new IntegerHandler(), exec);
3494 +        assertEquals(0, r.invocationCount);
3495 +        f.completeExceptionally(new CFException());
3496 +        checkCompletedWithWrappedCFException(f);
3497 +        checkCompletedNormally(g, three);
3498 +        assertEquals(1, r.invocationCount);
3499 +
3500 +        f = new CompletableFuture<>();
3501 +        g = f.handleAsync(r = new IntegerHandler(), exec);
3502 +        assertEquals(0, r.invocationCount);
3503 +        f.complete(one);
3504 +        checkCompletedNormally(f, one);
3505 +        checkCompletedNormally(g, two);
3506 +        assertEquals(1, r.invocationCount);
3507 +
3508 +        f = new CompletableFuture<>();
3509 +        g = f.handleAsync(r = new IntegerHandler(), exec);
3510 +        assertEquals(0, r.invocationCount);
3511 +        f.complete(one);
3512 +        checkCompletedNormally(f, one);
3513 +        checkCompletedNormally(g, two);
3514 +        assertEquals(1, r.invocationCount);
3515 +    }
3516 +
3517   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines