package algebras;

import org.junit.Before;
import org.junit.Test;
import streams.algebras.ExecTakeStreamAlg;
import streams.factories.ExecPullFactory;
import streams.factories.ExecPullWithTakeFactory;
import streams.factories.ExecPushFactory;
import streams.factories.ExecPushWithTakeFactory;
import streams.higher.Id;
import streams.higher.Pull;
import streams.higher.Push;

import java.util.stream.IntStream;
import java.util.stream.Stream;

import static org.junit.Assert.assertEquals;

public class TestAlgebrasTake {

    public int limit;
    public Long[] v, v_small;

    @Before
    public void setUp() {
        v = IntStream.range(0, 5).mapToObj(Long::new).toArray(Long[]::new);
        v_small = IntStream.range(0, 2).mapToObj(Long::new).toArray(Long[]::new);
        limit = 10;
    }

    @Test
    public void testTakePull() {
        ExecTakeStreamAlg<Id.t, Pull.t> alg = new ExecPullWithTakeFactory<>(new ExecPullFactory());

        Long actual = Id.prj(alg.count(alg.take(limit, alg.source(v)))).value;

        Long expected = Stream.of(v)
                .limit(limit)
                .count();

        assertEquals(expected, actual);
    }

    @Test
    public void testTakePush() {
        ExecTakeStreamAlg<Id.t, Push.t> alg = new ExecPushWithTakeFactory<>(new ExecPushFactory());

        Long actual = Id.prj(alg.count(alg.take(limit, alg.source(v)))).value;

        Long expected = java.util.stream.Stream.of(v)
                .limit(limit)
                .count();

        assertEquals(expected, actual);
    }

    @Test
    public void testTakeCartPull() {
        ExecTakeStreamAlg<Id.t, Pull.t> alg = new ExecPullWithTakeFactory<>(new ExecPullFactory());

        Long actual = Id.prj(
                alg.reduce(0L, Long::sum,
                        alg.take(limit,
                                alg.flatMap(x -> alg.map(y -> {
                                    System.out.println("y: " + y);
                                    return y * x;
                                }, alg.source(v)), alg.source(v_small))))).value;

        System.out.println("---");

        Long expected = Stream
                .of(v_small) // 15
                .flatMap(x -> Stream
                        .of(v) // 5
                        .map(y -> {
                            System.out.println("y: " + y);
                            return y * x;
                        }))
                .limit(limit)
                .reduce(0L, Long::sum);

        assertEquals(expected, actual);
    }

    @Test
    public void testTakeCartPush() {
        ExecTakeStreamAlg<Id.t, Push.t> alg = new ExecPushWithTakeFactory<>(new ExecPushFactory());

        Long actual = Id.prj(
                alg.reduce(0L, Long::sum,
                        alg.take(limit, alg.flatMap(x -> alg.map(y -> {
                            System.out.println("y: " + y);
                            return y * x;
                        }, alg.source(v)), alg.source(v_small))))).value;

        System.out.println("---");

        Long expected = Stream
                .of(v_small) // 5
                .flatMap(x -> Stream
                        .of(v) // 10
                        .map(y -> {
                            System.out.println("y: " + y);
                            return y * x;
                        }))
                .limit(limit)
                .reduce(0L, Long::sum);

        assertEquals(expected, actual);
    }
}
@@ -1892,32 +1892,34 @@
                 
+//
 System.out.print
@@ -1925,32 +1925,32 @@
 tln(%22y: %22 + y);%0A
-
                 
@@ -2066,32 +2066,34 @@
 value;%0A%0A        
+//
 System.out.print
@@ -2299,32 +2299,34 @@
                 
+//
 System.out.print
@@ -2840,32 +2840,34 @@
                 
+//
 System.out.print
@@ -2998,32 +2998,34 @@
 value;%0A%0A        
+//
 System.out.print
@@ -3203,32 +3203,32 @@
     .map(y -%3E %7B%0A
-
                 
@@ -3239,16 +3239,18 @@
         
+//
 System.o

Remove println from Take test.