package com.dazito.java.dakkabase;

import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import org.junit.Test;
import scala.concurrent.Future;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import static akka.pattern.Patterns.ask;
import static scala.compat.java8.FutureConverters.toJava;

/**
 * Created by daz on 21/02/2016.
 */
public class PongActorTest {

    private ActorSystem actorSystem = ActorSystem.create();
    private ActorRef actorRef = actorSystem.actorOf(Props.create(JavaPongActor.class));

    @Test
    public void shouldReplyToPingWithPong() throws Exception {
        Future scalaFuture = ask(actorRef, "Ping", 1000);

        // Convert from Scala to Java future
        final CompletionStage<String> completationStage = toJava(scalaFuture);
        final CompletableFuture<String> javaFuture = (CompletableFuture) completationStage;

        assert(javaFuture.get(1000, TimeUnit.MILLISECONDS).equals("Pong"));
    }

    @Test(expected = ExecutionException.class)
    public void shouldReplyToUnknownMessageWithFailure() throws Exception {
        Future scalaFuture = ask(actorRef, "unknown", 1000);
        final CompletionStage<String> completionStage = toJava(scalaFuture);
        final CompletableFuture<String> javaFuture = (CompletableFuture) completionStage;

        javaFuture.get(1000, TimeUnit.MILLISECONDS);
    }
}

@@ -1510,11 +1510,1665 @@
 );%0A    %7D
+%0A%0A    @Test%0A    public void printToConsole() throws Exception %7B%0A        askPong(%22Ping%22).thenAccept(s -%3E System.out.println(%22printToConsole - Replied with: %22 + s));%0A        Thread.sleep(100);%0A    %7D%0A%0A    @Test%0A    public void shouldCauseFailure() %7B%0A        askPong(%22causeError%22).handle((x, throwable) -%3E %7B%0A            if(throwable != null) %7B%0A                System.out.println(%22shouldCauseFailure - Error: %22 + throwable);%0A            %7D%0A            return null;%0A        %7D);%0A    %7D%0A%0A    @Test%0A    public void shouldCauseFailureAndRecover() %7B%0A        System.out.println(%22shouldCauseFailureAndRecover%22);%0A        CompletionStage%3CString%3E completionStage = askPong(%22causeError%22).exceptionally(throwable -%3E %7B%0A            return %22default%22; // In case of error, return %22default%22%0A        %7D);%0A    %7D%0A%0A    @Test%0A    public void recoverFromFailureAsync() %7B%0A        askPong(%22causeError%22)%0A                .handle((result, exception) -%3E %7B%0A                    if (exception == null) return CompletableFuture.completedFuture(result);%0A                    else return askPong(%22Ping%22);%0A                %7D).thenCompose(x -%3E x);%0A    %7D%0A%0A    @Test%0A    public void composingFutures() %7B%0A        // Compose futures and check for errors at the end of the pipeline%0A        askPong(%22ping%22).thenCompose(x -%3E askPong(%22ping%22 + x)).handle((message, throwable) -%3E %7B%0A           if(throwable != null) return %22default%22;%0A           else return message;%0A        %7D);%0A    %7D%0A%0A    public CompletionStage%3CString%3E askPong(String message) %7B%0A        Future scalaFuture = ask(actorRef, message, 1000);%0A        CompletionStage%3CString%3E completionStage = toJava(scalaFuture);%0A        return completionStage;%0A    %7D
 %0A%7D%0A

Handle failure and compose futures