### ----------------------------------------------------
### -- Gauge
### -- Licenses: Artistic-2.0
### -- Authors: Ben Davies
### -- File: t/02-basic.rakutest
### ----------------------------------------------------
use v6.d;
use Test;
use Gauge;

plan 21;

my constant SECOND = 1_000_000_000;

{
    my $calls = 0;
    my $it = Gauge(-> { $calls++ }).iterator;
    ok $it ~~ Gauge::Iterator, 'Gauge::It is a type of Gauge::Iterator...';
    isa-ok $it.pull-one, Int, '...which produces an integer duration...';
    ok $calls, '...given a call to the block';
};

{
    my $it = Gauge(-> { sleep 0.5 }).poll(1).iterator;
    ok $it ~~ Gauge::Iterator, 'Gauge::Poller is a type of Gauge::Iterator...';
    isa-ok (my $count = $it.pull-one), Int, '...which produces an integer count...';
    cmp-ok $count, &[~~], (1..2), '...which is reasonable...';
    cmp-ok Gauge(-> { $it.pull-one }).head, &[>=], SECOND, '...taking at least its duration to complete...';
    cmp-ok Gauge(-> { $it.skip-one }).head, &[>=], SECOND, '...even when skipped';
}

{
    my $it = Gauge(-> { (**...**) }).throttle(1).iterator;
    ok $it ~~ Gauge::Iterator, 'Gauge::Throttler is a type of Gauge::Iterator...';
    isa-ok $it.pull-one, Int, '...which transparently wraps its iterator...';
    cmp-ok Gauge(-> { $it.pull-one }).head, &[>=], SECOND, '...performing a cooldown between iterations...';
    cmp-ok Gauge(-> { $it.skip-one }).head, &[>=], SECOND, '...even when skipped';
}

{
    my $it = Gauge(-> { (｢｣...｢｣) }).throttle(1).poll(0.5).iterator;
    cmp-ok $it.pull-one, &[==], 1, 'Gauge::Poller polls before the cooldown of a Gauge::Throttler...';
    cmp-ok Gauge(-> { $it.pull-one }).head, &[>=], SECOND, '...while preserving it between iterations...';
    cmp-ok Gauge(-> { $it.skip-one }).head, &[>=], SECOND, '...even when skipped';
}

{
    my $it = Gauge(-> { ($++,++$) }).poll(0.5).throttle(0.5).iterator;
    cmp-ok $it.pull-one, &[>], 1, 'Gauge::Throttler does not throttle the poll of a Gauge::Poller...';
    cmp-ok Gauge(-> { $it.pull-one }).head, &[>=], SECOND, '...but the iteration performing a poll...';
    cmp-ok Gauge(-> { $it.skip-one }).head, &[>=], SECOND, '...even when skipped';
}

{
    my $calls = $*THREAD.id;
    my $it = Gauge(-> { $calls ⚛= $*THREAD.id }).pledge(0).iterator;
    $it.skip-one;
    cmp-ok ⚛$calls, &[==], $*THREAD.id, 'a void pledge does not a thread make';
}

if $*KERNEL.cpu-cores < 1 {
    skip 'Gauge::Covenant needs threads!';
} else {
    my $calls = $*THREAD.id;
    my $it = Gauge(-> { $calls ⚛= $*THREAD.id }).pledge(1).iterator;
    $it.skip-one;
    cmp-ok ⚛$calls, &[!=], $*THREAD.id, 'Gauge::Covenant iterates from another thread';
}

if $*KERNEL.cpu-cores < 2 {
    skip 'Gauge::Contract needs threads!';
} else {
    my $it = Gauge(-> { (0+*∘*+0) }).throttle(1).poll(1).pledge(2).iterator;
    cmp-ok $it.pull-one, &[>], $it.pull-one, 'Gauge::Contract can time in parallel following its cycle';
}


