// Path: src/main/java/io/dazraf/vertx/futures/Futures.java
// static <T> Futures<T> when(Future<T> future) {
//   return FuturesImpl.when(future);
// }
// 
// Path: src/main/java/io/dazraf/vertx/futures/processors/CallProcessor.java
// static <T, R> CallProcessor<T, R> call(Supplier<Future<R>> supplier) {
//   return call(result -> supplier.get());
// }
// 
// Path: src/main/java/io/dazraf/vertx/futures/processors/MapProcessor.java
// static <T, R> MapProcessor<T, R> map(Function<T, R> function) {
//   return mapOnResponse(future -> {
//     if (future.succeeded()) {
//       return function.apply(future.result());
//     } else {
//       throw new WrappedException(future.cause());
//     }
//   });
// }
// 
// Path: src/main/java/io/dazraf/vertx/futures/processors/RunProcessor.java
// static <T> RunProcessor<T> runOnFail(Consumer<Throwable> consumer) {
//   return runOnResponse(failure(consumer));
// }
// 
// Path: src/main/java/io/dazraf/vertx/futures/processors/RunProcessor.java
// static <T> RunProcessor<T> run(Runnable runnable) {
//   return runOnResponse(success(runnable));
// }


import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import io.vertx.core.Future;
import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.RunTestOnContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import static io.dazraf.vertx.futures.Futures.when;
import static io.dazraf.vertx.futures.processors.CallProcessor.call;
import static io.dazraf.vertx.futures.processors.MapProcessor.map;
import static io.dazraf.vertx.futures.processors.RunProcessor.runOnFail;
import static io.dazraf.vertx.futures.processors.RunProcessor.run;
import static io.vertx.core.Future.failedFuture;
import static io.vertx.core.Future.future;
import static io.vertx.core.Future.succeededFuture;
        .then(run(val -> context.assertEquals(MSG + NUMBER, val)))
        .then(run(async::complete))
        .then(runOnFail(context::fail));
  }

  @Test
  public void test2Then1SuccessfulFlow(TestContext context) {
    Async async = context.async();
    when(futureMessage(), futureNumber())
        .then(call((msg, number) -> succeededFuture(msg + number)))
        .then(run(val -> context.assertEquals(MSG + NUMBER, val)))
        .then(run(async::complete))
        .then(runOnFail(context::fail));
  }

  @Test
  public void test3Then2Then1SuccessfulFlow(TestContext context) {
    Async async = context.async();
    when(futureMessage(), futureNumber(), futureMessage())
        .then(call((msg1, number, msg2) -> when(succeededFuture(msg1 + msg2), succeededFuture(number))))
        .then(call((msg, number) -> succeededFuture(msg + number)))
        .then(run(val -> context.assertEquals(MSG + MSG + NUMBER, val)))
        .then(run(async::complete))
        .then(runOnFail(context::fail));
  }

  @Test
  public void test4Then2Then1SuccessfulFlow(TestContext context) {
    Async async = context.async();
    when(futureMessage(), futureNumber(), futureMessage(), futureMessage())
// Path: src/main/java/io/dazraf/vertx/futures/Futures.java
// static <T> Futures<T> when(Future<T> future) {
//   return FuturesImpl.when(future);
// }
// 
// Path: src/main/java/io/dazraf/vertx/futures/processors/CallProcessor.java
// static <T, R> CallProcessor<T, R> call(Supplier<Future<R>> supplier) {
//   return call(result -> supplier.get());
// }
// 
// Path: src/main/java/io/dazraf/vertx/futures/processors/MapProcessor.java
// static <T, R> MapProcessor<T, R> map(Function<T, R> function) {
//   return mapOnResponse(future -> {
//     if (future.succeeded()) {
//       return function.apply(future.result());
//     } else {
//       throw new WrappedException(future.cause());
//     }
//   });
// }
// 
// Path: src/main/java/io/dazraf/vertx/futures/processors/RunProcessor.java
// static <T> RunProcessor<T> runOnFail(Consumer<Throwable> consumer) {
//   return runOnResponse(failure(consumer));
// }
// 
// Path: src/main/java/io/dazraf/vertx/futures/processors/RunProcessor.java
// static <T> RunProcessor<T> run(Runnable runnable) {
//   return runOnResponse(success(runnable));
// }


// Path: src/test/java/io/dazraf/vertx/futures/processors/RunProcessorTest.java
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import io.vertx.core.Future;
import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.RunTestOnContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import static io.dazraf.vertx.futures.Futures.when;
import static io.dazraf.vertx.futures.processors.CallProcessor.call;
import static io.dazraf.vertx.futures.processors.MapProcessor.map;
import static io.dazraf.vertx.futures.processors.RunProcessor.runOnFail;
import static io.dazraf.vertx.futures.processors.RunProcessor.run;
import static io.vertx.core.Future.failedFuture;
import static io.vertx.core.Future.future;
import static io.vertx.core.Future.succeededFuture;

        .then(run(val -> context.assertEquals(MSG + NUMBER, val)))
        .then(run(async::complete))
        .then(runOnFail(context::fail));
  }

  @Test
  public void test2Then1SuccessfulFlow(TestContext context) {
    Async async = context.async();
    when(futureMessage(), futureNumber())
        .then(call((msg, number) -> succeededFuture(msg + number)))
        .then(run(val -> context.assertEquals(MSG + NUMBER, val)))
        .then(run(async::complete))
        .then(runOnFail(context::fail));
  }

  @Test
  public void test3Then2Then1SuccessfulFlow(TestContext context) {
    Async async = context.async();
    when(futureMessage(), futureNumber(), futureMessage())
        .then(call((msg1, number, msg2) -> when(succeededFuture(msg1 + msg2), succeededFuture(number))))
        .then(call((msg, number) -> succeededFuture(msg + number)))
        .then(run(val -> context.assertEquals(MSG + MSG + NUMBER, val)))
        .then(run(async::complete))
        .then(runOnFail(context::fail));
  }

  @Test
  public void test4Then2Then1SuccessfulFlow(TestContext context) {
    Async async = context.async();
    when(futureMessage(), futureNumber(), futureMessage(), futureMessage())
      .then(call((msg1, number, msg2, msg3) -> when(