// Path: src/main/java/org/dataloader/DataLoaderFactory.java
// public static <K, V> DataLoader<K, V> newDataLoader(BatchLoader<K, V> batchLoadFunction) {
//     return newDataLoader(batchLoadFunction, null);
// }
// 
// Path: src/main/java/org/dataloader/DataLoaderOptions.java
// public static DataLoaderOptions newOptions() {
//     return new DataLoaderOptions();
// }
// 
// Path: src/test/java/org/dataloader/fixtures/TestKit.java
// public static <V> CompletableFuture<V> futureError() {
//     return failedFuture(new IllegalStateException("Error"));
// }
// 
// Path: src/test/java/org/dataloader/fixtures/TestKit.java
// public static Collection<Integer> listFrom(int i, int max) {
//     List<Integer> ints = new ArrayList<>();
//     for (int j = i; j < max; j++) {
//         ints.add(j);
//     }
//     return ints;
// }
// 
// Path: src/main/java/org/dataloader/impl/CompletableFutureKit.java
// public static <V> Throwable cause(CompletableFuture<V> completableFuture) {
//     if (!completableFuture.isCompletedExceptionally()) {
//         return null;
//     }
//     try {
//         completableFuture.get();
//         return null;
//     } catch (InterruptedException e) {
//         Thread.currentThread().interrupt();
//         return e;
//     } catch (ExecutionException e) {
//         Throwable cause = e.getCause();
//         if (cause != null) {
//             return cause;
//         }
//         return e;
//     }
// }


import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.awaitility.Awaitility.await;
import static org.dataloader.DataLoaderFactory.newDataLoader;
import static org.dataloader.DataLoaderOptions.newOptions;
import static org.dataloader.fixtures.TestKit.futureError;
import static org.dataloader.fixtures.TestKit.listFrom;
import static org.dataloader.impl.CompletableFutureKit.cause;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
package org.dataloader;




/**
 * Much of the tests that related to {@link MappedBatchLoader} also related to
 * {@link org.dataloader.BatchLoader}.  This is white box testing somewhat because we could have repeated
 * ALL the tests in {@link org.dataloader.DataLoaderTest} here as well but chose not to because we KNOW that
 * DataLoader differs only a little in how it handles the 2 types of loader functions. We choose to grab some
 * common functionality for repeat testing and otherwise rely on the very complete other tests.
 */
public class DataLoaderMapBatchLoaderTest {

    MappedBatchLoader<String, String> evensOnlyMappedBatchLoader = (keys) -> {
        Map<String, String> mapOfResults = new HashMap<>();

        AtomicInteger index = new AtomicInteger();
        keys.forEach(k -> {
            int i = index.getAndIncrement();
            if (i % 2 == 0) {
                mapOfResults.put(k, k);
            }
        });
        return CompletableFuture.completedFuture(mapOfResults);
    };

    private static <K, V> DataLoader<K, V> idMapLoader(DataLoaderOptions options, List<Collection<K>> loadCalls) {
        MappedBatchLoader<K, V> kvBatchLoader = (keys) -> {
            loadCalls.add(new ArrayList<>(keys));
            Map<K, V> map = new HashMap<>();
            //noinspection unchecked
            keys.forEach(k -> map.put(k, (V) k));
            return CompletableFuture.completedFuture(map);
        };
        return DataLoaderFactory.newMappedDataLoader(kvBatchLoader, options);
    }

    private static <K, V> DataLoader<K, V> idMapLoaderBlowsUps(
            DataLoaderOptions options, List<Collection<K>> loadCalls) {
// Path: src/main/java/org/dataloader/DataLoaderFactory.java
// public static <K, V> DataLoader<K, V> newDataLoader(BatchLoader<K, V> batchLoadFunction) {
//     return newDataLoader(batchLoadFunction, null);
// }
// 
// Path: src/main/java/org/dataloader/DataLoaderOptions.java
// public static DataLoaderOptions newOptions() {
//     return new DataLoaderOptions();
// }
// 
// Path: src/test/java/org/dataloader/fixtures/TestKit.java
// public static <V> CompletableFuture<V> futureError() {
//     return failedFuture(new IllegalStateException("Error"));
// }
// 
// Path: src/test/java/org/dataloader/fixtures/TestKit.java
// public static Collection<Integer> listFrom(int i, int max) {
//     List<Integer> ints = new ArrayList<>();
//     for (int j = i; j < max; j++) {
//         ints.add(j);
//     }
//     return ints;
// }
// 
// Path: src/main/java/org/dataloader/impl/CompletableFutureKit.java
// public static <V> Throwable cause(CompletableFuture<V> completableFuture) {
//     if (!completableFuture.isCompletedExceptionally()) {
//         return null;
//     }
//     try {
//         completableFuture.get();
//         return null;
//     } catch (InterruptedException e) {
//         Thread.currentThread().interrupt();
//         return e;
//     } catch (ExecutionException e) {
//         Throwable cause = e.getCause();
//         if (cause != null) {
//             return cause;
//         }
//         return e;
//     }
// }


// Path: src/test/java/org/dataloader/DataLoaderMapBatchLoaderTest.java
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.awaitility.Awaitility.await;
import static org.dataloader.DataLoaderFactory.newDataLoader;
import static org.dataloader.DataLoaderOptions.newOptions;
import static org.dataloader.fixtures.TestKit.futureError;
import static org.dataloader.fixtures.TestKit.listFrom;
import static org.dataloader.impl.CompletableFutureKit.cause;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

package org.dataloader;




/**
 * Much of the tests that related to {@link MappedBatchLoader} also related to
 * {@link org.dataloader.BatchLoader}.  This is white box testing somewhat because we could have repeated
 * ALL the tests in {@link org.dataloader.DataLoaderTest} here as well but chose not to because we KNOW that
 * DataLoader differs only a little in how it handles the 2 types of loader functions. We choose to grab some
 * common functionality for repeat testing and otherwise rely on the very complete other tests.
 */
public class DataLoaderMapBatchLoaderTest {

    MappedBatchLoader<String, String> evensOnlyMappedBatchLoader = (keys) -> {
        Map<String, String> mapOfResults = new HashMap<>();

        AtomicInteger index = new AtomicInteger();
        keys.forEach(k -> {
            int i = index.getAndIncrement();
            if (i % 2 == 0) {
                mapOfResults.put(k, k);
            }
        });
        return CompletableFuture.completedFuture(mapOfResults);
    };

    private static <K, V> DataLoader<K, V> idMapLoader(DataLoaderOptions options, List<Collection<K>> loadCalls) {
        MappedBatchLoader<K, V> kvBatchLoader = (keys) -> {
            loadCalls.add(new ArrayList<>(keys));
            Map<K, V> map = new HashMap<>();
            //noinspection unchecked
            keys.forEach(k -> map.put(k, (V) k));
            return CompletableFuture.completedFuture(map);
        };
        return DataLoaderFactory.newMappedDataLoader(kvBatchLoader, options);
    }

    private static <K, V> DataLoader<K, V> idMapLoaderBlowsUps(
            DataLoaderOptions options, List<Collection<K>> loadCalls) {
        return newDataLoader((keys) -> {