File Coverage

blib/lib/Test/Future/Deferred.pm
Criterion Covered Total %
statement 20 20 100.0
branch 2 4 50.0
condition n/a
subroutine 7 7 100.0
pod 3 3 100.0
total 32 34 94.1


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2018 -- leonerd@leonerd.org.uk
5              
6             package Test::Future::Deferred;
7              
8 1     1   224707 use v5.10;
  1         9  
9 1     1   10 use strict;
  1         2  
  1         19  
10 1     1   4 use warnings;
  1         2  
  1         29  
11 1     1   4 use base qw( Future );
  1         2  
  1         581  
12              
13             our $VERSION = '0.50';
14              
15             =head1 NAME
16              
17             C - a future which completes later
18              
19             my $future = Test::Future::Deferred->done_later( 1, 2, 3 );
20              
21             # Future is not ready yet
22              
23             my @result = $future->get;
24              
25             =head1 DESCRIPTION
26              
27             This subclass of L provides two new methods and an implementation of
28             the C interface, which allows the futures to appear pending at first,
29             but then to complete when C is called at the toplevel on one of them.
30              
31             This behaviour is useful in unit tests to check that behaviour of a module
32             under test is correct even with non-immediate futures, as it allows a future
33             to easily be constructed that will complete "soon", but not yet, without
34             needing an event loop.
35              
36             Because these futures provide their own C method, they shouldn't be
37             mixed in the same program with other kinds of futures from real event systems
38             or similar.
39              
40             =cut
41              
42             my @deferrals;
43              
44             sub await
45             {
46 3     3 1 11 while( my $d = shift @deferrals ) {
47 3         8 my ( $f, $method, @args ) = @$d;
48 3         20 $f->$method( @args );
49             }
50             # TODO: detect if still not done with no more deferrals
51             }
52              
53             =head1 METHODS
54              
55             =cut
56              
57             =head2 done_later
58              
59             $f->done_later( @args )
60              
61             Equivalent to invoking the regular C method as part of the C
62             operation called on the toplevel future. This makes the future complete with
63             the given result, but only when C is called.
64              
65             =cut
66              
67             sub done_later
68             {
69 1 50   1 1 108 my $self = ref $_[0] ? shift : shift->new;
70 1         4 push @deferrals, [ $self, done => @_ ];
71 1         3 return $self;
72             }
73              
74             =head2 fail_later
75              
76             $f->fail_later( $message, $category, @details )
77              
78             Equivalent to invoking the regular C method as part of the C
79             operation called on the toplevel future. This makes the future complete with
80             the given failure, but only when C is called. As the C method
81             also waits for completion of the future, then it will return the failure
82             message given here also.
83              
84             =cut
85              
86             sub fail_later
87             {
88 2 50   2 1 997 my $self = ref $_[0] ? shift : shift->new;
89 2         7 push @deferrals, [ $self, fail => @_ ];
90 2         5 return $self;
91             }
92              
93             =head1 AUTHOR
94              
95             Paul Evans
96              
97             =cut
98              
99             0x55AA;