diff options
Diffstat (limited to 't/35utils-map-void.t')
-rw-r--r-- | t/35utils-map-void.t | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/t/35utils-map-void.t b/t/35utils-map-void.t new file mode 100644 index 0000000..3f62e5f --- /dev/null +++ b/t/35utils-map-void.t @@ -0,0 +1,200 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Test::More; +use Test::Identity; + +use Future; +use Future::Utils qw( fmap_void ); + +# fmap_void from ARRAY, no concurrency +{ + my @subf; + my $future = fmap_void { + return $subf[$_[0]] = Future->new + } foreach => [ 0 .. 2 ]; + + ok( defined $future, '$future defined for fmap non-concurrent' ); + + ok( defined $subf[0], '$subf[0] defined' ); + ok( !defined $subf[1], '$subf[1] not yet defined' ); + + $subf[0]->done; + + ok( defined $subf[1], '$subf[1] defined after $subf[0] done' ); + + $subf[1]->done; + + $subf[2]->done; + + ok( $future->is_ready, '$future now ready after subs done' ); + is_deeply( [ $future->get ], [], '$future->get empty for fmap_void' ); +} + +# fmap_void from CODE +{ + my @subf; + my $future = fmap_void { + return $subf[$_[0]] = Future->new + } generate => do { my $count = 0; + sub { return unless $count < 3; $count++ } }; + + ok( defined $future, '$future defined for fmap non-concurrent from CODE' ); + + ok( defined $subf[0], '$subf[0] defined' ); + + $subf[0]->done; + $subf[1]->done; + $subf[2]->done; + + ok( $future->is_ready, '$future now ready after subs done from CODE' ); +} + +# fmap_void concurrent +{ + my @subf; + my $future = fmap_void { + return $subf[$_[0]] = Future->new + } foreach => [ 0 .. 4 ], + concurrent => 2; + + ok( defined $future, '$future defined for fmap concurrent=2' ); + + ok( defined $subf[0], '$subf[0] defined' ); + ok( defined $subf[1], '$subf[1] defined' ); + + $subf[0]->done; $subf[1]->done; + + ok( defined $subf[2], '$subf[2] defined' ); + ok( defined $subf[3], '$subf[3] defined' ); + + $subf[2]->done; $subf[3]->done; + + ok( defined $subf[4], '$subf[4] deifned' ); + ok( !$future->is_ready, '$future not yet ready while one sub remains' ); + + $subf[4]->done; + + ok( $future->is_ready, '$future now ready after concurrent subs done' ); +} + +# fmap_void late-addition concurrently +{ + my @items = ( 1, 2, 3 ); + my @subf; + my $future = fmap_void { + my $val = shift; + my $f = $subf[$val] = Future->new; + $f->on_done( sub { push @items, 4, 5, 6 } ) if $val == 3; + $f + } foreach => \@items, + concurrent => 4; + + ok( defined $future, '$future defined for fmap concurrent=3 late-add' ); + + ok( $subf[1] && $subf[2] && $subf[3], '3 subfutures initally ready' ); + + $subf[1]->done; + $subf[2]->done; + + ok( !$subf[4], 'No $subf[4] before $subf[3] done' ); + + $subf[3]->done; + + ok( $subf[4] && $subf[5] && $subf[6], '3 new subfutures now ready' ); + + $subf[4]->done; + $subf[5]->done; + $subf[6]->done; + + ok( $future->is_ready, '$future now ready after all 6 subfutures done' ); +} + +# fmap_void on immediates +{ + my $future = fmap_void { + return Future->done + } foreach => [ 0 .. 2 ]; + + ok( $future->is_ready, '$future already ready for fmap on immediates' ); +} + +# fmap_void on non/immediate mix +{ + my @item_f = ( my $item = Future->new, Future->done, Future->done ); + my $future = fmap_void { + return $_[0]; + } foreach => \@item_f, + concurrent => 2; + + ok( !$future->is_ready, '$future not yet ready before non-immediate done' ); + + $item->done; + ok( $future->is_ready, '$future now ready after non-immediate done' ); +} + +# fmap_void fail +{ + my @subf; + my $future = fmap_void { + return $subf[$_[0]] = Future->new; + } foreach => [ 0, 1, 2 ], + concurrent => 2; + + ok( !$subf[0]->is_cancelled, '$subf[0] not cancelled before failure' ); + + $subf[1]->fail( "failure" ); + + ok( $subf[0]->is_cancelled, '$subf[0] now cancelled after $subf[1] failure' ); + ok( $future->is_ready, '$future now ready after $sub[1] failure' ); + is( scalar $future->failure, "failure", '$future->failure after $sub[1] failure' ); + ok( !defined $subf[2], '$subf[2] was never started after $subf[1] failure' ); +} + +# fmap_void immediate fail +{ + my @subf; + my $future = fmap_void { + if( $_[0] eq "fail" ) { + return Future->fail( "failure" ); + } + else { + $subf[$_[0]] = Future->new; + } + } foreach => [ 0, "fail", 2 ], + concurrent => 3; + + ok( $future->is_ready, '$future is already ready' ); + is( scalar $future->failure, "failure", '$future->failure after immediate failure' ); + + ok( $subf[0]->is_cancelled, '$subf[0] is cancelled after immediate failure' ); + ok( !defined $subf[2], '$subf[2] was never started after immediate failure' ); +} + +# fmap_void cancel +{ + my @subf; + my $future = fmap_void { + return $subf[$_[0]] = Future->new; + } foreach => [ 0, 1, 2 ], + concurrent => 2; + + $future->cancel; + + ok( $subf[0]->is_cancelled, '$subf[0] now cancelled after ->cancel' ); + ok( $subf[1]->is_cancelled, '$subf[1] now cancelled after ->cancel' ); + ok( !defined $subf[2], '$subf[2] was never started after ->cancel' ); +} + +# fmap_void return +{ + my $future = fmap_void { + return Future->done; + } foreach => [ 0 ], return => my $ret = Future->new; + + identical( $future, $ret, 'repeat with return yields correct instance' ); +} + +done_testing; |