--- jsr166/src/test/tck/CompletableFutureTest.java 2013/07/15 03:50:08 1.29 +++ jsr166/src/test/tck/CompletableFutureTest.java 2014/06/01 21:17:05 1.34 @@ -102,6 +102,37 @@ public class CompletableFutureTest exten assertTrue(f.toString().contains("[Completed exceptionally]")); } + void checkCompletedWithWrappedCFException(CompletableFuture f, + CFException ex) { + try { + f.get(LONG_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (ExecutionException success) { + assertSame(ex, success.getCause()); + } catch (Throwable fail) { threadUnexpectedException(fail); } + try { + f.join(); + shouldThrow(); + } catch (CompletionException success) { + assertSame(ex, success.getCause()); + } + try { + f.getNow(null); + shouldThrow(); + } catch (CompletionException success) { + assertSame(ex, success.getCause()); + } + try { + f.get(); + shouldThrow(); + } catch (ExecutionException success) { + assertSame(ex, success.getCause()); + } catch (Throwable fail) { threadUnexpectedException(fail); } + assertTrue(f.isDone()); + assertFalse(f.isCancelled()); + assertTrue(f.toString().contains("[Completed exceptionally]")); + } + void checkCancelled(CompletableFuture f) { try { f.get(LONG_DELAY_MS, MILLISECONDS); @@ -375,7 +406,7 @@ public class CompletableFutureTest exten /** * exceptionally action completes with function value on source - * exception; otherwise with source value + * exception; otherwise with source value */ public void testExceptionally() { CompletableFuture f = new CompletableFuture<>(); @@ -916,117 +947,335 @@ public class CompletableFutureTest exten } /** + * Permits the testing of parallel code for the 3 different + * execution modes without repeating all the testing code. + */ + enum ExecutionMode { + DEFAULT { + public CompletableFuture runAfterBoth + (CompletableFuture f, CompletableFuture g, Runnable r) { + return f.runAfterBoth(g, r); + } + }, + + DEFAULT_ASYNC { + public CompletableFuture runAfterBoth + (CompletableFuture f, CompletableFuture g, Runnable r) { + return f.runAfterBothAsync(g, r); + } + }, + + EXECUTOR { + public CompletableFuture runAfterBoth + (CompletableFuture f, CompletableFuture g, Runnable r) { + return f.runAfterBothAsync(g, r, new ThreadExecutor()); + } + }; + + public abstract CompletableFuture runAfterBoth + (CompletableFuture f, CompletableFuture g, Runnable r); + } + + /** * runAfterBoth result completes normally after normal * completion of sources */ - public void testRunAfterBoth() { - CompletableFuture f, g; - CompletableFuture h; - Noop r; + public void testRunAfterBoth_normalCompletion1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + final CompletableFuture h = m.runAfterBoth(f, g, r); - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.runAfterBoth(g, r = new Noop()); - f.complete(3); + f.complete(v1); checkIncomplete(h); - g.complete(1); + assertFalse(r.ran); + g.complete(v2); + checkCompletedNormally(h, null); assertTrue(r.ran); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } + } - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.runAfterBoth(g, r = new Noop()); - g.complete(1); + public void testRunAfterBoth_normalCompletion2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + final CompletableFuture h = m.runAfterBoth(f, g, r); + + g.complete(v2); checkIncomplete(h); - f.complete(3); + assertFalse(r.ran); + f.complete(v1); + checkCompletedNormally(h, null); assertTrue(r.ran); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } + } + + public void testRunAfterBoth_normalCompletion3() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + + g.complete(v2); + f.complete(v1); + final CompletableFuture h = m.runAfterBoth(f, g, r); + + checkCompletedNormally(h, null); + assertTrue(r.ran); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } + } + + public void testRunAfterBoth_normalCompletion4() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + + f.complete(v1); + g.complete(v2); + final CompletableFuture h = m.runAfterBoth(f, g, r); - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - g.complete(1); - f.complete(3); - h = f.runAfterBoth(g, r = new Noop()); checkCompletedNormally(h, null); assertTrue(r.ran); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } } /** * runAfterBoth result completes exceptionally after exceptional * completion of either source */ - public void testRunAfterBoth2() { - CompletableFuture f, g; - CompletableFuture h; - Noop r; + public void testRunAfterBoth_exceptionalCompletion1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + final CompletableFuture h = m.runAfterBoth(f, g, r); + final CFException ex = new CFException(); - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.runAfterBoth(g, r = new Noop()); - f.completeExceptionally(new CFException()); + f.completeExceptionally(ex); checkIncomplete(h); - g.complete(1); - checkCompletedWithWrappedCFException(h); + g.complete(v1); + + checkCompletedWithWrappedCFException(h, ex); + checkCompletedWithWrappedCFException(f, ex); assertFalse(r.ran); + checkCompletedNormally(g, v1); + } + } - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - h = f.runAfterBoth(g, r = new Noop()); - g.completeExceptionally(new CFException()); + public void testRunAfterBoth_exceptionalCompletion2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + final CompletableFuture h = m.runAfterBoth(f, g, r); + final CFException ex = new CFException(); + + g.completeExceptionally(ex); checkIncomplete(h); - f.complete(3); - checkCompletedWithWrappedCFException(h); + f.complete(v1); + + checkCompletedWithWrappedCFException(h, ex); + checkCompletedWithWrappedCFException(g, ex); assertFalse(r.ran); + checkCompletedNormally(f, v1); + } + } - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - g.completeExceptionally(new CFException()); - f.complete(3); - h = f.runAfterBoth(g, r = new Noop()); - checkCompletedWithWrappedCFException(h); + public void testRunAfterBoth_exceptionalCompletion3() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + final CFException ex = new CFException(); + + g.completeExceptionally(ex); + f.complete(v1); + final CompletableFuture h = m.runAfterBoth(f, g, r); + + checkCompletedWithWrappedCFException(h, ex); + checkCompletedWithWrappedCFException(g, ex); assertFalse(r.ran); + checkCompletedNormally(f, v1); + } + } - f = new CompletableFuture<>(); - g = new CompletableFuture<>(); - f.completeExceptionally(new CFException()); - g.complete(1); - h = f.runAfterBoth(g, r = new Noop()); - checkCompletedWithWrappedCFException(h); + public void testRunAfterBoth_exceptionalCompletion4() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + final CFException ex = new CFException(); + + f.completeExceptionally(ex); + g.complete(v1); + final CompletableFuture h = m.runAfterBoth(f, g, r); + + checkCompletedWithWrappedCFException(h, ex); + checkCompletedWithWrappedCFException(f, ex); assertFalse(r.ran); + checkCompletedNormally(g, v1); + } } /** * runAfterBoth result completes exceptionally if action does */ - public void testRunAfterBoth3() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - FailingNoop r = new FailingNoop(); - CompletableFuture g = f.runAfterBoth(f2, r); - f.complete(one); - checkIncomplete(g); - f2.complete(two); - checkCompletedWithWrappedCFException(g); + public void testRunAfterBoth_actionFailed1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final FailingNoop r = new FailingNoop(); + final CompletableFuture h = m.runAfterBoth(f, g, r); + + f.complete(v1); + checkIncomplete(h); + g.complete(v2); + + checkCompletedWithWrappedCFException(h); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } + } + + public void testRunAfterBoth_actionFailed2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final FailingNoop r = new FailingNoop(); + final CompletableFuture h = m.runAfterBoth(f, g, r); + + g.complete(v2); + checkIncomplete(h); + f.complete(v1); + + checkCompletedWithWrappedCFException(h); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } } /** * runAfterBoth result completes exceptionally if either source cancelled */ - public void testRunAfterBoth4() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterBoth(f2, r); - assertTrue(f.cancel(true)); - f2.complete(two); - checkCompletedWithWrappedCancellationException(g); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - r = new Noop(); - g = f.runAfterBoth(f2, r); - f.complete(one); - assertTrue(f2.cancel(true)); - checkCompletedWithWrappedCancellationException(g); + public void testRunAfterBoth_sourceCancelled1() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + final CompletableFuture h = m.runAfterBoth(f, g, r); + + assertTrue(f.cancel(mayInterruptIfRunning)); + checkIncomplete(h); + g.complete(v1); + + checkCompletedWithWrappedCancellationException(h); + checkCancelled(f); + assertFalse(r.ran); + checkCompletedNormally(g, v1); + } + } + + public void testRunAfterBoth_sourceCancelled2() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + final CompletableFuture h = m.runAfterBoth(f, g, r); + + assertTrue(g.cancel(mayInterruptIfRunning)); + checkIncomplete(h); + f.complete(v1); + + checkCompletedWithWrappedCancellationException(h); + checkCancelled(g); + assertFalse(r.ran); + checkCompletedNormally(f, v1); + } + } + + public void testRunAfterBoth_sourceCancelled3() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + + assertTrue(g.cancel(mayInterruptIfRunning)); + f.complete(v1); + final CompletableFuture h = m.runAfterBoth(f, g, r); + + checkCompletedWithWrappedCancellationException(h); + checkCancelled(g); + assertFalse(r.ran); + checkCompletedNormally(f, v1); + } + } + + public void testRunAfterBoth_sourceCancelled4() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + + assertTrue(f.cancel(mayInterruptIfRunning)); + g.complete(v1); + final CompletableFuture h = m.runAfterBoth(f, g, r); + + checkCompletedWithWrappedCancellationException(h); + checkCancelled(f); + assertFalse(r.ran); + checkCompletedNormally(g, v1); + } } /** @@ -1718,79 +1967,6 @@ public class CompletableFutureTest exten } /** - * runAfterBothAsync result completes normally after normal - * completion of sources - */ - public void testRunAfterBothAsync() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterBothAsync(f2, r); - f.complete(one); - checkIncomplete(g); - f2.complete(two); - checkCompletedNormally(g, null); - assertTrue(r.ran); - } - - /** - * runAfterBothAsync result completes exceptionally after exceptional - * completion of source - */ - public void testRunAfterBothAsync2() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterBothAsync(f2, r); - f.completeExceptionally(new CFException()); - f2.complete(two); - checkCompletedWithWrappedCFException(g); - - r = new Noop(); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - g = f.runAfterBothAsync(f2, r); - f.complete(one); - f2.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); - } - - /** - * runAfterBothAsync result completes exceptionally if action does - */ - public void testRunAfterBothAsync3() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - FailingNoop r = new FailingNoop(); - CompletableFuture g = f.runAfterBothAsync(f2, r); - f.complete(one); - checkIncomplete(g); - f2.complete(two); - checkCompletedWithWrappedCFException(g); - } - - /** - * runAfterBothAsync result completes exceptionally if either source cancelled - */ - public void testRunAfterBothAsync4() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterBothAsync(f2, r); - assertTrue(f.cancel(true)); - f2.complete(two); - checkCompletedWithWrappedCancellationException(g); - - r = new Noop(); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - g = f.runAfterBothAsync(f2, r); - f.complete(one); - assertTrue(f2.cancel(true)); - checkCompletedWithWrappedCancellationException(g); - } - - /** * applyToEitherAsync result completes normally after normal * completion of sources */ @@ -2510,79 +2686,6 @@ public class CompletableFutureTest exten } /** - * runAfterBothAsync result completes normally after normal - * completion of sources - */ - public void testRunAfterBothAsyncE() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterBothAsync(f2, r, new ThreadExecutor()); - f.complete(one); - checkIncomplete(g); - f2.complete(two); - checkCompletedNormally(g, null); - assertTrue(r.ran); - } - - /** - * runAfterBothAsync result completes exceptionally after exceptional - * completion of source - */ - public void testRunAfterBothAsync2E() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterBothAsync(f2, r, new ThreadExecutor()); - f.completeExceptionally(new CFException()); - f2.complete(two); - checkCompletedWithWrappedCFException(g); - - r = new Noop(); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - g = f.runAfterBothAsync(f2, r, new ThreadExecutor()); - f.complete(one); - f2.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); - } - - /** - * runAfterBothAsync result completes exceptionally if action does - */ - public void testRunAfterBothAsync3E() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - FailingNoop r = new FailingNoop(); - CompletableFuture g = f.runAfterBothAsync(f2, r, new ThreadExecutor()); - f.complete(one); - checkIncomplete(g); - f2.complete(two); - checkCompletedWithWrappedCFException(g); - } - - /** - * runAfterBothAsync result completes exceptionally if either source cancelled - */ - public void testRunAfterBothAsync4E() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterBothAsync(f2, r, new ThreadExecutor()); - assertTrue(f.cancel(true)); - f2.complete(two); - checkCompletedWithWrappedCancellationException(g); - - r = new Noop(); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - g = f.runAfterBothAsync(f2, r, new ThreadExecutor()); - f.complete(one); - assertTrue(f2.cancel(true)); - checkCompletedWithWrappedCancellationException(g); - } - - /** * applyToEitherAsync result completes normally after normal * completion of sources */ @@ -2931,97 +3034,99 @@ public class CompletableFutureTest exten ThreadExecutor exec = new ThreadExecutor(); Runnable[] throwingActions = { - () -> { CompletableFuture.supplyAsync(null); }, - () -> { CompletableFuture.supplyAsync(null, exec); }, - () -> { CompletableFuture.supplyAsync(supplyOne, null); }, - - () -> { CompletableFuture.runAsync(null); }, - () -> { CompletableFuture.runAsync(null, exec); }, - () -> { CompletableFuture.runAsync(() -> {}, null); }, - - () -> { f.completeExceptionally(null); }, - - () -> { f.thenApply(null); }, - () -> { f.thenApplyAsync(null); }, - () -> { f.thenApplyAsync((x) -> x, null); }, - () -> { f.thenApplyAsync(null, exec); }, - - () -> { f.thenAccept(null); }, - () -> { f.thenAcceptAsync(null); }, - () -> { f.thenAcceptAsync((x) -> { ; }, null); }, - () -> { f.thenAcceptAsync(null, exec); }, - - () -> { f.thenRun(null); }, - () -> { f.thenRunAsync(null); }, - () -> { f.thenRunAsync(() -> { ; }, null); }, - () -> { f.thenRunAsync(null, exec); }, - - () -> { f.thenCombine(g, null); }, - () -> { f.thenCombineAsync(g, null); }, - () -> { f.thenCombineAsync(g, null, exec); }, - () -> { f.thenCombine(nullFuture, (x, y) -> x); }, - () -> { f.thenCombineAsync(nullFuture, (x, y) -> x); }, - () -> { f.thenCombineAsync(nullFuture, (x, y) -> x, exec); }, - () -> { f.thenCombineAsync(g, (x, y) -> x, null); }, - - () -> { f.thenAcceptBoth(g, null); }, - () -> { f.thenAcceptBothAsync(g, null); }, - () -> { f.thenAcceptBothAsync(g, null, exec); }, - () -> { f.thenAcceptBoth(nullFuture, (x, y) -> {}); }, - () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}); }, - () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec); }, - () -> { f.thenAcceptBothAsync(g, (x, y) -> {}, null); }, - - () -> { f.runAfterBoth(g, null); }, - () -> { f.runAfterBothAsync(g, null); }, - () -> { f.runAfterBothAsync(g, null, exec); }, - () -> { f.runAfterBoth(nullFuture, () -> {}); }, - () -> { f.runAfterBothAsync(nullFuture, () -> {}); }, - () -> { f.runAfterBothAsync(nullFuture, () -> {}, exec); }, - () -> { f.runAfterBothAsync(g, () -> {}, null); }, - - () -> { f.applyToEither(g, null); }, - () -> { f.applyToEitherAsync(g, null); }, - () -> { f.applyToEitherAsync(g, null, exec); }, - () -> { f.applyToEither(nullFuture, (x) -> x); }, - () -> { f.applyToEitherAsync(nullFuture, (x) -> x); }, - () -> { f.applyToEitherAsync(nullFuture, (x) -> x, exec); }, - () -> { f.applyToEitherAsync(g, (x) -> x, null); }, - - () -> { f.acceptEither(g, null); }, - () -> { f.acceptEitherAsync(g, null); }, - () -> { f.acceptEitherAsync(g, null, exec); }, - () -> { f.acceptEither(nullFuture, (x) -> {}); }, - () -> { f.acceptEitherAsync(nullFuture, (x) -> {}); }, - () -> { f.acceptEitherAsync(nullFuture, (x) -> {}, exec); }, - () -> { f.acceptEitherAsync(g, (x) -> {}, null); }, - - () -> { f.runAfterEither(g, null); }, - () -> { f.runAfterEitherAsync(g, null); }, - () -> { f.runAfterEitherAsync(g, null, exec); }, - () -> { f.runAfterEither(nullFuture, () -> {}); }, - () -> { f.runAfterEitherAsync(nullFuture, () -> {}); }, - () -> { f.runAfterEitherAsync(nullFuture, () -> {}, exec); }, - () -> { f.runAfterEitherAsync(g, () -> {}, null); }, - - () -> { f.thenCompose(null); }, - () -> { f.thenComposeAsync(null); }, - () -> { f.thenComposeAsync(new CompletableFutureInc(), null); }, - () -> { f.thenComposeAsync(null, exec); }, - - () -> { f.exceptionally(null); }, - - () -> { f.handle(null); }, - - () -> { CompletableFuture.allOf((CompletableFuture)null); }, - () -> { CompletableFuture.allOf((CompletableFuture[])null); }, - () -> { CompletableFuture.allOf(f, null); }, - () -> { CompletableFuture.allOf(null, f); }, - - () -> { CompletableFuture.anyOf((CompletableFuture)null); }, - () -> { CompletableFuture.anyOf((CompletableFuture[])null); }, - () -> { CompletableFuture.anyOf(f, null); }, - () -> { CompletableFuture.anyOf(null, f); }, + () -> CompletableFuture.supplyAsync(null), + () -> CompletableFuture.supplyAsync(null, exec), + () -> CompletableFuture.supplyAsync(supplyOne, null), + + () -> CompletableFuture.runAsync(null), + () -> CompletableFuture.runAsync(null, exec), + () -> CompletableFuture.runAsync(() -> {}, null), + + () -> f.completeExceptionally(null), + + () -> f.thenApply(null), + () -> f.thenApplyAsync(null), + () -> f.thenApplyAsync((x) -> x, null), + () -> f.thenApplyAsync(null, exec), + + () -> f.thenAccept(null), + () -> f.thenAcceptAsync(null), + () -> f.thenAcceptAsync((x) -> {} , null), + () -> f.thenAcceptAsync(null, exec), + + () -> f.thenRun(null), + () -> f.thenRunAsync(null), + () -> f.thenRunAsync(() -> {} , null), + () -> f.thenRunAsync(null, exec), + + () -> f.thenCombine(g, null), + () -> f.thenCombineAsync(g, null), + () -> f.thenCombineAsync(g, null, exec), + () -> f.thenCombine(nullFuture, (x, y) -> x), + () -> f.thenCombineAsync(nullFuture, (x, y) -> x), + () -> f.thenCombineAsync(nullFuture, (x, y) -> x, exec), + () -> f.thenCombineAsync(g, (x, y) -> x, null), + + () -> f.thenAcceptBoth(g, null), + () -> f.thenAcceptBothAsync(g, null), + () -> f.thenAcceptBothAsync(g, null, exec), + () -> f.thenAcceptBoth(nullFuture, (x, y) -> {}), + () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}), + () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec), + () -> f.thenAcceptBothAsync(g, (x, y) -> {}, null), + + () -> f.runAfterBoth(g, null), + () -> f.runAfterBothAsync(g, null), + () -> f.runAfterBothAsync(g, null, exec), + () -> f.runAfterBoth(nullFuture, () -> {}), + () -> f.runAfterBothAsync(nullFuture, () -> {}), + () -> f.runAfterBothAsync(nullFuture, () -> {}, exec), + () -> f.runAfterBothAsync(g, () -> {}, null), + + () -> f.applyToEither(g, null), + () -> f.applyToEitherAsync(g, null), + () -> f.applyToEitherAsync(g, null, exec), + () -> f.applyToEither(nullFuture, (x) -> x), + () -> f.applyToEitherAsync(nullFuture, (x) -> x), + () -> f.applyToEitherAsync(nullFuture, (x) -> x, exec), + () -> f.applyToEitherAsync(g, (x) -> x, null), + + () -> f.acceptEither(g, null), + () -> f.acceptEitherAsync(g, null), + () -> f.acceptEitherAsync(g, null, exec), + () -> f.acceptEither(nullFuture, (x) -> {}), + () -> f.acceptEitherAsync(nullFuture, (x) -> {}), + () -> f.acceptEitherAsync(nullFuture, (x) -> {}, exec), + () -> f.acceptEitherAsync(g, (x) -> {}, null), + + () -> f.runAfterEither(g, null), + () -> f.runAfterEitherAsync(g, null), + () -> f.runAfterEitherAsync(g, null, exec), + () -> f.runAfterEither(nullFuture, () -> {}), + () -> f.runAfterEitherAsync(nullFuture, () -> {}), + () -> f.runAfterEitherAsync(nullFuture, () -> {}, exec), + () -> f.runAfterEitherAsync(g, () -> {}, null), + + () -> f.thenCompose(null), + () -> f.thenComposeAsync(null), + () -> f.thenComposeAsync(new CompletableFutureInc(), null), + () -> f.thenComposeAsync(null, exec), + + () -> f.exceptionally(null), + + () -> f.handle(null), + + () -> CompletableFuture.allOf((CompletableFuture)null), + () -> CompletableFuture.allOf((CompletableFuture[])null), + () -> CompletableFuture.allOf(f, null), + () -> CompletableFuture.allOf(null, f), + + () -> CompletableFuture.anyOf((CompletableFuture)null), + () -> CompletableFuture.anyOf((CompletableFuture[])null), + () -> CompletableFuture.anyOf(f, null), + () -> CompletableFuture.anyOf(null, f), + + () -> f.obtrudeException(null), }; assertThrows(NullPointerException.class, throwingActions);