1#!/usr/bin/perl 2 3use strict; 4use warnings; 5 6use Test::More; 7use Test::Identity; 8 9use lib "."; 10use t::TimeAbout; 11 12use IO::Async::Loop; 13 14use Future; 15use IO::Async::Future; 16 17use constant AUT => $ENV{TEST_QUICK_TIMERS} ? 0.1 : 1; 18 19my $loop = IO::Async::Loop->new_builtin; 20 21{ 22 my $future = Future->new; 23 24 $loop->later( sub { $future->done( "result" ) } ); 25 26 my $ret = $loop->await( $future ); 27 identical( $ret, $future, '$loop->await( $future ) returns $future' ); 28 29 is_deeply( [ $future->get ], [ "result" ], '$future->get' ); 30} 31 32{ 33 my $future = $loop->later; 34 my $cancellable_future = $loop->later; 35 36 ok( !$future->is_ready, '$loop->later returns a pending Future' ); 37 ok( !$cancellable_future->is_ready, 'another $loop->later also returns a pending Future' ); 38 39 $cancellable_future->cancel; 40 $loop->loop_once; 41 42 ok( $future->is_done, '$loop->later Future is resolved after one loop iteration' ); 43 ok( $cancellable_future->is_cancelled, '$loop->later Future cancels cleanly' ); 44} 45 46{ 47 my @futures = map { Future->new } 0 .. 2; 48 49 do { my $id = $_; $loop->later( sub { $futures[$id]->done } ) } for 0 .. 2; 50 51 $loop->await_all( @futures ); 52 53 ok( 1, '$loop->await_all' ); 54 ok( $futures[$_]->is_ready, "future $_ ready" ) for 0 .. 2; 55} 56 57{ 58 my $future = IO::Async::Future->new( $loop ); 59 60 identical( $future->loop, $loop, '$future->loop yields $loop' ); 61 62 $loop->later( sub { $future->done( "result" ) } ); 63 64 is_deeply( [ $future->get ], [ "result" ], '$future->get on IO::Async::Future' ); 65} 66 67{ 68 my $future = $loop->new_future; 69 70 $loop->later( sub { $future->done( "result" ) } ); 71 72 is_deeply( [ $future->get ], [ "result" ], '$future->get on IO::Async::Future from $loop->new_future' ); 73} 74 75# done_later 76{ 77 my $future = $loop->new_future; 78 79 identical( $future->done_later( "deferred result" ), $future, '->done_later returns $future' ); 80 ok( !$future->is_ready, '$future not yet ready after ->done_later' ); 81 82 is_deeply( [ $future->get ], [ "deferred result" ], '$future now ready after ->get' ); 83} 84 85# fail_later 86{ 87 my $future = $loop->new_future; 88 89 identical( $future->fail_later( "deferred exception\n" ), $future, '->fail_later returns $future' ); 90 ok( !$future->is_ready, '$future not yet ready after ->fail_later' ); 91 92 $loop->await( $future ); 93 94 is_deeply( [ $future->failure ], [ "deferred exception\n" ], '$future now ready after $loop->await' ); 95} 96 97# delay_future 98{ 99 my $future = $loop->delay_future( after => 1 * AUT ); 100 101 time_about( sub { $loop->await( $future ) }, 1, '->delay_future is ready' ); 102 103 ok( $future->is_ready, '$future is ready from delay_future' ); 104 is_deeply( [ $future->get ], [], '$future->get returns empty list on delay_future' ); 105 106 # Check that ->cancel does not crash 107 $loop->delay_future( after => 1 * AUT )->cancel; 108} 109 110# timeout_future 111{ 112 my $future = $loop->timeout_future( after => 1 * AUT ); 113 114 time_about( sub { $loop->await( $future ) }, 1, '->timeout_future is ready' ); 115 116 ok( $future->is_ready, '$future is ready from timeout_future' ); 117 is( scalar $future->failure, "Timeout", '$future failed with "Timeout" for timeout_future' ); 118 119 # Check that ->cancel does not crash 120 $loop->timeout_future( after => 1 * AUT )->cancel; 121} 122 123done_testing; 124