// 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/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/MapProcessor.java
// static <T, R> MapProcessor<T, R> mapOnResponse(Function<AsyncResult<T>, R> function) {
//   return future -> {
//     try {
//       return succeededFuture(function.apply(future));
//     }
//     catch (WrappedException err) {
//       return failedFuture(err.getCause());
//     }
//     catch (Throwable err) {
//       return failedFuture(err);
//     }
//   };
// }
// 
// Path: src/main/java/io/dazraf/vertx/futures/processors/RunProcessor.java
// public interface RunProcessor<T> extends FutureProcessor<T, T> {
// 
//   Logger LOG = getLogger(RunProcessor.class);
// 
//   /**
//    * Observe the state of the chain. Any exceptions from the consumer will cause the chain to fail.
//    * @param consumer
//    * @param <T>
//    * @return
//    */
//   static <T> RunProcessor<T> runOnResponse(Handler<AsyncResult<T>> consumer) {
//     return future -> {
//       Future<T> result = Future.future();
//       try {
//         consumer.handle(future);
//         result.completer().handle(future);
//       } catch (Throwable error) {
//         LOG.error("consumer function failed", error);
//         result.fail(error);
//       }
//       return result;
//     };
//   }
// 
//   static <T> RunProcessor<T> run(Runnable runnable) {
//     return runOnResponse(success(runnable));
//   }
// 
//   static <T> RunProcessor<T> run(Consumer<T> consumer) {
//     return runOnResponse(success(consumer));
//   }
// 
//   static <T1, T2> RunProcessor<Tuple2<T1, T2>> run(Consumer2<T1, T2> consumer) {
//     return runOnResponse(success(consumer));
//   }
// 
//   static <T1, T2, T3> RunProcessor<Tuple3<T1, T2, T3>> run(Consumer3<T1, T2, T3> consumer) {
//     return runOnResponse(success(consumer));
//   }
// 
//   static <T1, T2, T3, T4> RunProcessor<Tuple4<T1, T2, T3, T4>> run(Consumer4<T1, T2, T3, T4> consumer) {
//     return runOnResponse(success(consumer));
//   }
// 
//   static <T1, T2, T3, T4, T5> RunProcessor<Tuple5<T1, T2, T3, T4, T5>> run(Consumer5<T1, T2, T3, T4, T5> consumer) {
//     return runOnResponse(success(consumer));
//   }
// 
//   static <T> RunProcessor<T> runOnFail(Consumer<Throwable> consumer) {
//     return runOnResponse(failure(consumer));
//   }
// 
// }


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.MapProcessor.map;
import static io.dazraf.vertx.futures.processors.MapProcessor.mapOnResponse;
import static io.dazraf.vertx.futures.processors.RunProcessor.*;
import static io.vertx.core.Future.*;
                      context
                          .assertEquals(MSG, val1).assertEquals(MSG, val2)
                          .assertEquals(MSG, val3)
                          .assertEquals(MSG, val4)))
        .then(map((val1, val2, val3, val4) -> val1 + val2 + val3 + val4))
        .then(run(val -> context.assertEquals(MSG + MSG + MSG + MSG, val)))
        .then(run(async::complete))
        .then(runOnFail(context::fail));
  }

  @Test
  public void map5ValuesTest(TestContext context) {
    Async async = context.async();
    when(futureMessage(), futureMessage(), futureMessage(), futureMessage(), futureMessage())
      .then(run((val1, val2, val3, val4, val5) ->
        context
          .assertEquals(MSG, val1).assertEquals(MSG, val2)
          .assertEquals(MSG, val3)
          .assertEquals(MSG, val4)
          .assertEquals(MSG, val5)))
      .then(map((val1, val2, val3, val4, val5) -> val1 + val2 + val3 + val4 + val5))
      .then(run(val -> context.assertEquals(MSG + MSG + MSG + MSG + MSG, val)))
      .then(run(async::complete))
      .then(runOnFail(context::fail));
  }

  @Test
  public void mapResponseTest(TestContext context) {
    Async async = context.async();
    when(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/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/MapProcessor.java
// static <T, R> MapProcessor<T, R> mapOnResponse(Function<AsyncResult<T>, R> function) {
//   return future -> {
//     try {
//       return succeededFuture(function.apply(future));
//     }
//     catch (WrappedException err) {
//       return failedFuture(err.getCause());
//     }
//     catch (Throwable err) {
//       return failedFuture(err);
//     }
//   };
// }
// 
// Path: src/main/java/io/dazraf/vertx/futures/processors/RunProcessor.java
// public interface RunProcessor<T> extends FutureProcessor<T, T> {
// 
//   Logger LOG = getLogger(RunProcessor.class);
// 
//   /**
//    * Observe the state of the chain. Any exceptions from the consumer will cause the chain to fail.
//    * @param consumer
//    * @param <T>
//    * @return
//    */
//   static <T> RunProcessor<T> runOnResponse(Handler<AsyncResult<T>> consumer) {
//     return future -> {
//       Future<T> result = Future.future();
//       try {
//         consumer.handle(future);
//         result.completer().handle(future);
//       } catch (Throwable error) {
//         LOG.error("consumer function failed", error);
//         result.fail(error);
//       }
//       return result;
//     };
//   }
// 
//   static <T> RunProcessor<T> run(Runnable runnable) {
//     return runOnResponse(success(runnable));
//   }
// 
//   static <T> RunProcessor<T> run(Consumer<T> consumer) {
//     return runOnResponse(success(consumer));
//   }
// 
//   static <T1, T2> RunProcessor<Tuple2<T1, T2>> run(Consumer2<T1, T2> consumer) {
//     return runOnResponse(success(consumer));
//   }
// 
//   static <T1, T2, T3> RunProcessor<Tuple3<T1, T2, T3>> run(Consumer3<T1, T2, T3> consumer) {
//     return runOnResponse(success(consumer));
//   }
// 
//   static <T1, T2, T3, T4> RunProcessor<Tuple4<T1, T2, T3, T4>> run(Consumer4<T1, T2, T3, T4> consumer) {
//     return runOnResponse(success(consumer));
//   }
// 
//   static <T1, T2, T3, T4, T5> RunProcessor<Tuple5<T1, T2, T3, T4, T5>> run(Consumer5<T1, T2, T3, T4, T5> consumer) {
//     return runOnResponse(success(consumer));
//   }
// 
//   static <T> RunProcessor<T> runOnFail(Consumer<Throwable> consumer) {
//     return runOnResponse(failure(consumer));
//   }
// 
// }


// Path: src/test/java/io/dazraf/vertx/futures/processors/MapProcessorTest.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.MapProcessor.map;
import static io.dazraf.vertx.futures.processors.MapProcessor.mapOnResponse;
import static io.dazraf.vertx.futures.processors.RunProcessor.*;
import static io.vertx.core.Future.*;

                      context
                          .assertEquals(MSG, val1).assertEquals(MSG, val2)
                          .assertEquals(MSG, val3)
                          .assertEquals(MSG, val4)))
        .then(map((val1, val2, val3, val4) -> val1 + val2 + val3 + val4))
        .then(run(val -> context.assertEquals(MSG + MSG + MSG + MSG, val)))
        .then(run(async::complete))
        .then(runOnFail(context::fail));
  }

  @Test
  public void map5ValuesTest(TestContext context) {
    Async async = context.async();
    when(futureMessage(), futureMessage(), futureMessage(), futureMessage(), futureMessage())
      .then(run((val1, val2, val3, val4, val5) ->
        context
          .assertEquals(MSG, val1).assertEquals(MSG, val2)
          .assertEquals(MSG, val3)
          .assertEquals(MSG, val4)
          .assertEquals(MSG, val5)))
      .then(map((val1, val2, val3, val4, val5) -> val1 + val2 + val3 + val4 + val5))
      .then(run(val -> context.assertEquals(MSG + MSG + MSG + MSG + MSG, val)))
      .then(run(async::complete))
      .then(runOnFail(context::fail));
  }

  @Test
  public void mapResponseTest(TestContext context) {
    Async async = context.async();
    when(futureMessage(), futureMessage())
        .then(mapOnResponse(asyncResult -> {