package com.millross.blog.async;

import org.junit.Test;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.function.Supplier;

import static java.util.concurrent.CompletableFuture.*;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

/**
 *
 */
public class SimpleCompletableFutureTest {

    // We'll allow a 3-sized thread pool for async execution, rather than using the fork/join pool for asynchronous
    // value generation
    final Executor executor = Executors.newFixedThreadPool(3);

    @Test
    public void testSimpleFutureCompletion() throws Exception {
        final CompletableFuture<Integer> future = supplyAsync(delayedValueSupplier(1), executor);
        assertThat(future.get(), is(1));
    }

    @Test
    public void demoThenApply() throws Exception {
        final CompletableFuture<Integer> future = supplyAsync(delayedValueSupplier(1), executor)
                .thenApply(i -> i + 3);
        assertThat(future.get(), is(4));
    }

    @Test
    public void demoThenCompose() throws Exception {
        // We'll use one future to specify how long a subsequent future will take
        final CompletableFuture<Integer> future = supplyAsync(delayedValueSupplier(3), executor)
                .thenApply(i -> {
                    System.out.println("First future completed, " + i);
                    return i;
                })
                .thenCompose(i -> supplyAsync(delayedValueSupplier(2, i * 100), executor));
        assertThat(future.get(), is(2));
    }

    public Supplier<Integer> delayedValueSupplier(final int value) {
        return delayedValueSupplier(value, 1000);
    }

    public Supplier<Integer> delayedValueSupplier(final int value, final int delayMs) {
        return () -> {
            try {
                Thread.sleep(delayMs);
            } catch (InterruptedException e) {
                throw new RuntimeException("Problem while waiting to return value");
            }
            return value;
        };
    }

}

@@ -1325,32 +1325,421 @@
 r(3), executor)%0A
+                .thenCompose(i -%3E supplyAsync(delayedValueSupplier(2, i * 100), executor));%0A        assertThat(future.get(), is(2));%0A    %7D%0A%0A    @Test%0A    public void demoMultiStagePipeline() throws Exception %7B%0A        // We'll use one future to specify how long a subsequent future will take%0A        final CompletableFuture%3CInteger%3E future = supplyAsync(delayedValueSupplier(3), executor)%0A
                 
@@ -1856,16 +1856,20 @@
 return i
+ + 1
 ;%0A      
@@ -1940,32 +1940,36 @@
 edValueSupplier(
+i + 
 2, i * 100), exe
@@ -2005,33 +2005,33 @@
 uture.get(), is(
-2
+6
 ));%0A    %7D%0A%0A    p

Add demoMultiStagePipeline test