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