summaryrefslogtreecommitdiff
path: root/t/31utils-call-with-escape.t
diff options
context:
space:
mode:
Diffstat (limited to 't/31utils-call-with-escape.t')
-rw-r--r--t/31utils-call-with-escape.t70
1 files changed, 70 insertions, 0 deletions
diff --git a/t/31utils-call-with-escape.t b/t/31utils-call-with-escape.t
new file mode 100644
index 0000000..973900c
--- /dev/null
+++ b/t/31utils-call-with-escape.t
@@ -0,0 +1,70 @@
+#!/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;