### Question:
FutureUtils { public static void propagateCancellation( final CompletableFuture<?> from, final CompletableFuture<?> to) { from.exceptionally( error -> { if (error instanceof CancellationException) { to.cancel(true); } return null; }); }  static CompletableFuture<T> exceptionallyCompose(
      final CompletableFuture<T> future,
      final Function<Throwable, CompletionStage<T>> errorHandler); static void propagateResult(
      final CompletionStage<T> from, final CompletableFuture<T> to); static void propagateResult(
      final Supplier<CompletableFuture<T>> from, final CompletableFuture<T> to); static void propagateCancellation(
      final CompletableFuture<?> from, final CompletableFuture<?> to);  }### Answer:
@Test @SuppressWarnings("unchecked") public void shouldPropagateCancellation() { final CompletableFuture<String> input = new CompletableFuture<>(); final CompletableFuture<String> output = mock(CompletableFuture.class); propagateCancellation(input, output); input.cancel(true); verify(output).cancel(true); }
@Test public void shouldNotPropagateExceptionsOtherThanCancellationWhenPropagatingCancellation() { final CompletableFuture<String> input = new CompletableFuture<>(); final CompletableFuture<String> output = new CompletableFuture<>(); propagateCancellation(input, output); assertThat(output).isNotDone(); input.completeExceptionally(ERROR); assertThat(output).isNotDone(); }
@Test public void shouldNotPropagateResultsWhenPropagatingCancellation() { final CompletableFuture<String> input = new CompletableFuture<>(); final CompletableFuture<String> output = new CompletableFuture<>(); propagateCancellation(input, output); assertThat(output).isNotDone(); input.complete("foo"); assertThat(output).isNotDone(); }