public void testThenCombine_sourceCancelled() throws Throwable {
  for (  ExecutionMode m : ExecutionMode.values())   for (  boolean mayInterruptIfRunning : new boolean[]{true,false})   for (  boolean fFirst : new boolean[]{true,false})   for (  boolean failFirst : new boolean[]{true,false})   for (  Integer v1 : new Integer[]{1,null}) {
    final CompletableFuture<Integer> f=new CompletableFuture<>();
    final CompletableFuture<Integer> g=new CompletableFuture<>();
    final SubtractFunction r1=new SubtractFunction(m);
    final SubtractFunction r2=new SubtractFunction(m);
    final SubtractFunction r3=new SubtractFunction(m);
    final CompletableFuture<Integer> fst=fFirst ? f : g;
    final CompletableFuture<Integer> snd=!fFirst ? f : g;
    final Callable<Boolean> complete1=failFirst ? null : null;
    final Callable<Boolean> complete2=failFirst ? null : null;
    final CompletableFuture<Integer> h1=m.thenCombine(f,g,r1);
    assertTrue(complete1.call());
    final CompletableFuture<Integer> h2=m.thenCombine(f,g,r2);
    checkIncomplete(h1);
    checkIncomplete(h2);
    assertTrue(complete2.call());
    final CompletableFuture<Integer> h3=m.thenCombine(f,g,r3);
    checkCompletedWithWrappedCancellationException(h1);
    checkCompletedWithWrappedCancellationException(h2);
    checkCompletedWithWrappedCancellationException(h3);
    r1.assertNotInvoked();
    r2.assertNotInvoked();
    r3.assertNotInvoked();
    checkCompletedNormally(failFirst ? snd : fst,v1);
    checkCancelled(failFirst ? fst : snd);
  }
}

public void testThenCombine_sourceCancelled ( ) throws Throwable { for ( ExecutionMode m : ExecutionMode . values ( ) ) for ( boolean mayInterruptIfRunning : new boolean [ ] { true , false } ) for ( boolean fFirst : new boolean [ ] { true , false } ) for ( boolean failFirst : new boolean [ ] { true , false } ) for ( Integer v1 : new Integer [ ] { 1 , null } ) { final CompletableFuture < Integer > f = new CompletableFuture < > ( ) ; final CompletableFuture < Integer > g = new CompletableFuture < > ( ) ; final SubtractFunction r1 = new SubtractFunction ( m ) ; final SubtractFunction r2 = new SubtractFunction ( m ) ; final SubtractFunction r3 = new SubtractFunction ( m ) ; final CompletableFuture < Integer > fst = fFirst ? f : g ; final CompletableFuture < Integer > snd = ! fFirst ? f : g ; final Callable < Boolean > complete1 = failFirst ? null : null ; final Callable < Boolean > complete2 = failFirst ? null : null ; final CompletableFuture < Integer > h1 = m . thenCombine ( f , g , r1 ) ; assertTrue ( complete1 . call ( ) ) ; final CompletableFuture < Integer > h2 = m . thenCombine ( f , g , r2 ) ; checkIncomplete ( h1 ) ; checkIncomplete ( h2 ) ; assertTrue ( complete2 . call ( ) ) ; final CompletableFuture < Integer > h3 = m . thenCombine ( f , g , r3 ) ; checkCompletedWithWrappedCancellationException ( h1 ) ; checkCompletedWithWrappedCancellationException ( h2 ) ; checkCompletedWithWrappedCancellationException ( h3 ) ; r1 . assertNotInvoked ( ) ; r2 . assertNotInvoked ( ) ; r3 . assertNotInvoked ( ) ; checkCompletedNormally ( failFirst ? snd : fst , v1 ) ; checkCancelled ( failFirst ? fst : snd ) ; } }
thencombine result completes exceptionally if either source cancelled
