/*
 * Copyright (C) 2010 TranceCode Software
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 */
package org.trancecode.parallel;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.testng.Assert;
import org.testng.annotations.Test;
import org.trancecode.AbstractTest;
import org.trancecode.math.NumberFunctions;

/**
 * Tests for {@link ParallelIterables}.
 * 
 * @author Herve Quiroz
 */
public final class ParallelIterablesTest extends AbstractTest
{
    private static final int MANY_ELEMENTS = 1000;

    private static void assertEquals(final Iterable<?> actual, final Iterable<?> expected)
    {
        Assert.assertEquals(ImmutableList.copyOf(actual), ImmutableList.copyOf(expected));
    }

    @Test
    public void transform()
    {
        final List<String> strings = buildInputList(5);
        final List<Integer> integers = ImmutableList.of(0, 1, 2, 3, 4);

        final ExecutorService executor = Executors.newFixedThreadPool(3);
        final Iterable<Integer> result = ParallelIterables.transform(strings, NumberFunctions.parseInt(), executor);

        assertEquals(result, integers);
    }

    @Test
    public void transformMany()
    {
        transformMany(Executors.newFixedThreadPool(3));
    }

    @Test
    public void transformManyWithSingleThread()
    {
        transformMany(Executors.newSingleThreadExecutor());
    }

    private static void transformMany(final ExecutorService executor)
    {
        final List<String> strings = buildInputList(MANY_ELEMENTS);
        final Iterable<Integer> result = ParallelIterables.transform(strings, NumberFunctions.parseInt(), executor);
        Assert.assertEquals(Iterables.size(result), MANY_ELEMENTS);
    }

    private static List<String> buildInputList(final int numberOfElements)
    {
        final List<String> strings = Lists.newArrayList();
        for (int i = 0; i < numberOfElements; i++)
        {
            strings.add(Integer.toString(i));
        }
        return strings;
    }
}

@@ -815,16 +815,56 @@
 allel;%0A%0A
+import com.google.common.base.Function;%0A
 import c
@@ -1094,16 +1094,66 @@
 ecutors;
+%0Aimport java.util.concurrent.atomic.AtomicInteger;
 %0A%0Aimport
@@ -2952,11 +2952,1129 @@
 s;%0A    %7D
+%0A%0A    @Test%0A    public void transformCancel()%0A    %7B%0A        final int limit = MANY_ELEMENTS / 10;%0A        final List%3CString%3E strings = buildInputList(MANY_ELEMENTS);%0A        final AtomicInteger count = new AtomicInteger();%0A        final RuntimeException expectedError = new IllegalStateException();%0A        final Function%3CString, String%3E function = new Function%3CString, String%3E()%0A        %7B%0A            @Override%0A            public String apply(final String string)%0A            %7B%0A                if (count.get() == limit)%0A                %7B%0A                    throw expectedError;%0A                %7D%0A%0A                count.incrementAndGet();%0A                return string;%0A            %7D%0A        %7D;%0A%0A        final ExecutorService executor = Executors.newSingleThreadExecutor();%0A        try%0A        %7B%0A            Iterables.size(ParallelIterables.transform(strings, function, executor));%0A        %7D%0A        catch (final Exception e)%0A        %7B%0A            if (e != expectedError)%0A            %7B%0A                throw new IllegalStateException(e);%0A            %7D%0A        %7D%0A%0A        Assert.assertEquals(count.get(), limit);%0A    %7D
 %0A%7D%0A

Add a test for ParallelIterables.transform() when an error occurs and tasks should be canceled