#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
use Test::Refcount;
use Future;
use Future::Utils qw( call_with_escape );
# call_with_escape normal return
{
my $ret_f;
my $f = call_with_escape {
return $ret_f = Future->new;
};
$ret_f->done( "result" );
ok( $f->is_ready, 'call_with_escape ready after returned future ready' );
is( scalar $f->get, "result", 'result of call_with_escape' );
$f = call_with_escape {
return $ret_f = Future->new;
};
$ret_f->fail( "failure" );
ok( $f->is_ready, 'call_with_escape ready after returned future ready' );
is( scalar $f->failure, "failure", 'result of call_with_escape' );
undef $ret_f;
is_oneref( $f, 'call_with_escape has refcount 1 before EOF' );
}
# call_with_escape synchronous escape
{
my $f = call_with_escape {
my $escape = shift;
$escape->done( "escaped" );
};
ok( $f->is_ready, 'call_with_escape ready after synchronous escape' );
is( scalar $f->get, "escaped", 'result of call_with_escape' );
}
# call_with_escape delayed escape
{
my $ret_f = Future->new;
my $inner_f;
my $f = call_with_escape {
my $escape = shift;
return $inner_f = $ret_f->then( sub {
return $escape->done( "later escape" );
});
};
ok( !$f->is_ready, 'call_with_escape not yet ready before deferral' );
$ret_f->done;
ok( $f->is_ready, 'call_with_escape ready after deferral' );
is( scalar $f->get, "later escape", 'result of call_with_escape' );
ok( $inner_f->is_cancelled, 'code-returned future cancelled after escape' );
}
done_testing;