package algebras;

import base.BaseTest;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import streams.factories.PullFactory;
import streams.higher.App;
import streams.higher.Pull;

import java.util.Iterator;
import java.util.stream.*;
import java.util.stream.Stream;

/**
 * Authors:
 * Aggelos Biboudis (@biboudis)
 * Nick Palladinos (@NickPalladinos)
 */
public class TestAlgebrasFlatMapAlgebras extends BaseTest {

    public Long[] v_outer, v_inner;

    @Before
    public void setUp() {
        v_outer = IntStream.range(0, 5).mapToObj(i -> (long) (i % 5)).toArray(Long[]::new);
        v_inner = IntStream.range(0, 5).mapToObj(i -> (long) (i % 5)).toArray(Long[]::new);
    }

    @Test
    public void testPull(){
        PullFactory algebra = new PullFactory();

        App<Pull.t, Long> map = algebra.map(y -> {
            System.out.println("inner: " + y);
            return (long) 10 * y;
        }, algebra.source(v_inner));

        App<Pull.t, Long> flatMap = algebra.flatMap(y -> map, algebra.source(v_outer));

        Pull<Long> prj = Pull.prj(flatMap);

        prj.hasNext();

        System.out.println(prj.next());

        Assert.assertEquals(
                "inner: 0\n" +
                        "0\n",
                outContent.toString());
    }

    @Test
    public void testJava8StreamsPushWithPull(){
        Iterator<Long> iterator = Stream.of(v_outer)
                .flatMap(x -> {
                    return Stream.of(v_inner).map(y -> {
                        System.out.println("inner: " + y);
                        return x * y;
                    });
                }).iterator();

        iterator.hasNext();

        System.out.println(iterator.next());

        Assert.assertEquals(
                "inner: 0\n" +
                        "inner: 1\n" +
                        "inner: 2\n" +
                        "inner: 3\n" +
                        "inner: 4\n" +
                        "0\n",
                outContent.toString());
    }
}

@@ -30,24 +30,75 @@
 e.BaseTest;%0A
+import jdk.nashorn.internal.runtime.ECMAException;%0A
 import org.j
@@ -152,20 +152,85 @@
 g.junit.
-Test
+Rule;%0Aimport org.junit.Test;%0Aimport org.junit.rules.ExpectedException
 ;%0Aimport
@@ -344,16 +344,47 @@
 erator;%0A
+import java.util.concurrent.*;%0A
 import j
@@ -435,16 +435,117 @@
 tream;%0A%0A
+import static junit.framework.Assert.assertEquals;%0Aimport static junit.framework.Assert.assertTrue;%0A%0A
 /**%0A * A
@@ -2267,11 +2267,896 @@
 );%0A    %7D
+%0A%0A    @Test(expected = TimeoutException.class)%0A    public void testJava8StreamsPushWithInfinite() throws ExecutionException, InterruptedException, TimeoutException %7B%0A        ExecutorService service = Executors.newSingleThreadExecutor();%0A        Future%3CLong%3E result = service.submit(() -%3E %7B%0A            Stream%3CLong%3E longStream = Stream.iterate(0L, i -%3E i + 2);%0A%0A            Iterator%3CLong%3E iterator = Stream.of(v_outer)%0A                    .flatMap(x -%3E %7B%0A                        return longStream.map(y -%3E %7B%0A                            System.out.println(%22inner: %22 + y);%0A                            return x * y;%0A                        %7D);%0A                    %7D).iterator();%0A%0A            iterator.hasNext();%0A%0A            Long value = iterator.next();%0A%0A            System.out.println(value);%0A%0A            return value;%0A        %7D);%0A%0A        result.get(1000, TimeUnit.MILLISECONDS);%0A    %7D
 %0A%7D%0A

Add time out exception in java 8 streams test.