### ----------------------------------------------------
### -- ParaSeq
### -- Licenses: Artistic-2.0
### -- Authors: Elizabeth Mattijsen
### -- File: t/08-grep.rakutest
### ----------------------------------------------------
use Test;
use ParaSeq;

plan 84;

my constant $elems = 200000;
my constant $batch = 16;
my constant @list  = (^$elems).reverse.List;

my constant $grepper = * %% 2;
my constant $grep2    = @list.grep($grepper).List;
#my constant $grep2e   = @list.grep($grepper, :end).List;
my constant $grep2k   = @list.grep($grepper, :k).List;
#my constant $grep2ke  = @list.grep($grepper, :k, :end).List;
my constant $grep2p   = @list.grep($grepper, :p).List;
#my constant $grep2pe  = @list.grep($grepper, :p, :end).List;
my constant $grep2kv  = @list.grep($grepper, :kv).List;
#my constant $grep2kve = @list.grep($grepper, :kv, :end).List;

my constant $grepc2 = @list.grep(-> $a, $b         { True      }).List;
my constant $grepc4 = @list.grep(-> $a, $b, $c, $d { True      }).List;

my constant $last   = 23456;
my constant $grep2l =  @list.grep({ last if $_ == $last; $_ %% 2}).List;

# Block with phasers in them
my atomicint $ENTERseen;
my atomicint $LEAVEseen;
my $phasers = {
    ENTER $ENTERseen⚛++;
    LEAVE $LEAVEseen⚛++;
    $_ %% 2
}

my $lastphasers = {
    ENTER $ENTERseen⚛++;
    LEAVE $LEAVEseen⚛++;
    last if $_ == $last;
    $_ %% 2
}

my subset Even of Int where * %% 2;
my constant $grepm   = @list.grep(Even).List;
my constant $grepmk  = @list.grep(Even, :k).List;
my constant $grepmp  = @list.grep(Even, :p).List;
my constant $grepmkv = @list.grep(Even, :kv).List;

for 1, ParaSeq.default-degree {
    my $seq := @list.&hyperize($batch, $_).grep($grepper);
    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
    is-deeply $seq.List, $grep2, "grep(* %% 2) with degree = $_";

#    $seq := @list.&hyperize($batch, $_).grep($grepper, :end);
#    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
#    is-deeply $seq.List, $grep2e, "grep(* %% 2, :end) with degree = $_";

    $seq := @list.&hyperize($batch, $_).grep($grepper, :v);
    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
    is-deeply $seq.List, $grep2, "grep(* %% 2, :v) with degree = $_";

#    $seq := @list.&hyperize($batch, $_).grep($grepper, :v, :end);
#    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
#    is-deeply $seq.List, $grep2e, "grep(* %% 2, :v, :end) with degree = $_";

    $seq := @list.&hyperize($batch, $_).grep($grepper, :k);
    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
    is-deeply $seq.List, $grep2k, "grep(* %% 2, :k) with degree = $_";

#    $seq := @list.&hyperize($batch, $_).grep($grepper, :k, :end);
#    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
#    is-deeply $seq.List, $grep2ke, "grep(* %% 2, :k, :end) with degree = $_";

    $seq := @list.&hyperize($batch, $_).grep($grepper, :p);
    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
    is-deeply $seq.List, $grep2p, "grep(* %% 2, :p) with degree = $_";

#    $seq := @list.&hyperize($batch, $_).grep($grepper, :p, :end);
#    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
#    is-deeply $seq.List, $grep2pe, "grep(* %% 2, :p, :end) with degree = $_";

    $seq := @list.&hyperize($batch, $_).grep($grepper, :kv);
    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
    is-deeply $seq.List, $grep2kv, "grep(* %% 2, :kv) with degree = $_";

#    $seq := @list.&hyperize($batch, $_).grep($grepper, :kv, :end);
#    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
#    is-deeply $seq.List, $grep2kve, "grep(* %% 2, :kv, :end) with degree = $_";

    $ENTERseen = $LEAVEseen = 0;
    $seq := @list.&hyperize($batch, $_).grep($phasers);
    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
    is-deeply $seq.List, $grep2, "grep(PHASERS) with degree = $_";
    is $ENTERseen, $elems,
      "ENTER phaser fired for each iteration with degree $_";
    is $LEAVEseen, $elems,
      "LEAVE phaser fired for each iteration with degree $_";

    for 'k', $grep2k, 'kv', $grep2kv, 'p', $grep2p -> $named, $result {
        $ENTERseen = $LEAVEseen = 0;
        $seq := @list.&hyperize($batch, $_).grep($phasers, |{ $named => True });
        isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
        is-deeply $seq.List, $result, "grep(PHASERS, :$named) with degree = $_";
        is $ENTERseen, $elems,
          "ENTER phaser :$named fired for each iteration with degree $_";
        is $LEAVEseen, $elems,
          "LEAVE phaser :$named fired for each iteration with degree $_";
    }

    $ENTERseen = $LEAVEseen = 0;
    $seq := @list.&hyperize($batch, $_).grep($lastphasers);
    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
    is-deeply $seq.List, $grep2l,
      "grep(\{ last if \$_ == $last; PHASERS) with degree = $_";
    ok $ENTERseen >= $last,
      "ENTER phaser fired for each iteration with degree $_";
    ok $LEAVEseen >= $last,
      "LEAVE phaser fired for each iteration with degree $_";

    $seq := @list.&hyperize($batch, $_).grep(-> $a, $b { True });
    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
    is-deeply $seq.List, $grepc2,
      "grep(-> \$a, \$b \{ True }) with degree = $_";

    $seq := @list.&hyperize($batch, $_).grep(-> $a, $b, $c, $d { True });
    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
    is-deeply $seq.List, $grepc4,
      "grep(-> \$a, \$b, \$c, \$d \{ True }) with degree = $_";

    $seq := @list.&hyperize($batch, $_).grep(Even);
    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
    is-deeply $seq.List, $grepm, "grep(Even) with degree = $_";

    $seq := @list.&hyperize($batch, $_).grep(Even, :k);
    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
    is-deeply $seq.List, $grepmk, "grep(Even, :k) with degree = $_";

    $seq := @list.&hyperize($batch, $_).grep(Even, :p);
    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
    is-deeply $seq.List, $grepmp, "grep(Even, :p) with degree = $_";

    $seq := @list.&hyperize($batch, $_).grep(Even, :kv);
    isa-ok $seq, $_ == 1 ?? Seq !! ParaSeq;
    is-deeply $seq.List, $grepmkv, "grep(Even, :kv) with degree = $_";
}

# vim: expandtab shiftwidth=4


