File Coverage

blib/lib/Promises6.pm
Criterion Covered Total %
statement 65 65 100.0
branch 11 12 91.6
condition n/a
subroutine 23 23 100.0
pod 10 10 100.0
total 109 110 99.0


line stmt bran cond sub pod time code
1             package Promises6;
2 31     31   661439 use Evo::Base -strict;
  31         65  
  31         283  
3 31     31   4834 use Exporter 'import';
  31         54  
  31         975  
4 31     31   10992 use Promises6::Util ':all';
  31         87  
  31         4487  
5 31     31   11414 use Promises6::Evo::Builder;
  31         74  
  31         299  
6 31     31   1468 use Evo::Manager;
  31         48  
  31         102  
7              
8             our $VERSION = '0.006'; # VERSION
9             my @DSL = qw(when_ok when_rejected when_progress promise then);
10             our @EXPORT_OK = (@DSL, qw(deferred resolved rejected all race));
11             our %EXPORT_TAGS = (all => \@EXPORT_OK, dsl => \@DSL);
12 91     91 1 3873 sub deferred { Promises6::Evo::Builder->singleton->deferred() }
13              
14             # dsl
15             sub then {
16 7     7 1 55 _evo()->current->{'promise'} = _evo()->current('promise')->then(@_);
17             }
18 2     2 1 43 sub when_ok : prototype(&) { then(shift, undef, undef) }
19 1     1 1 35 sub when_rejected : prototype(&) { then(undef, shift, undef) }
20 1     1 1 13 sub when_progress : prototype(&) { then(undef, undef, shift) }
21              
22             # es6 mozilla all
23             # resolve all in the same order or reject immidiately with reason
24             # if one of promises is rejected
25 5     5 1 993 sub all(@promises) {
  5         5  
26 5         6 my $total = @promises;
27 5         8 my $d = deferred;
28              
29 5         54 my ($counter, $i, @results) = (0, 0);
30 5         9 foreach my $cur (@promises) {
31 13         61 my $cur_i = $i;
32 13 100       28 my $p = is_promise($cur) ? $cur : resolved($cur);
33             $p->then(
34             sub {
35 11     11   17 $results[$cur_i] = shift;
36 11 100       35 $d->resolve(\@results) unless ++$counter < $total;
37             },
38 2     2   7 sub { $d->reject(shift) }
39 13         181 );
40 13         175 $i++;
41              
42             # already can be rejected
43 13 100       28 last unless $d->state == PENDING;
44             }
45              
46 5         40 $d->promise;
47             }
48              
49             # es6 mozilla race
50             # first who rejects or resolves a promise gets a prize
51 5     5 1 302 sub race(@promises) {
  5         4  
52 5         8 my $total = @promises;
53 5         7 my $d = deferred;
54              
55 5         54 foreach my $cur (@promises) {
56 9 100       39 my $p = is_promise($cur) ? $cur : resolved($cur);
57 9     5   119 $p->then(sub { $d->resolve(shift) }, sub { $d->reject(shift) });
  5         12  
  2         8  
58              
59             # already can be resolved
60 9 100       114 last unless $d->state == PENDING;
61             }
62              
63 5         45 $d->promise;
64             }
65              
66             sub promise : prototype(&) {
67 14     14 1 1595 my $cb = shift;
68 14         35 my $d = deferred;
69 14     3   184 my $resolve = sub { $d->resolve($_[0]) };
  3         32  
70 14     1   38 my $reject = sub { $d->reject($_[0]) };
  1         8  
71 14     2   31 my $notify = sub { $d->notify($_[0]) };
  2         30  
72              
73 14         46 my $promise = $d->promise;
74             _evo()->dsl_call(
75             {promise => $d->promise},
76             $resolve, $reject, $notify,
77             sub {
78 14     14   655 $cb->($resolve, $reject, $notify);
79 14         207 $promise = _evo()->current('promise');
80             }
81 14         168 );
82              
83 14         516 return $promise;
84             }
85              
86             sub resolved : prototype($) {
87 23     23 1 2936 my $val = shift;
88 23         50 deferred->resolve($val)->promise;
89             }
90              
91             sub rejected : prototype($) {
92 5     5 1 531 my $reason = shift;
93 5 50       20 Carp::croak("Provide a reason, not a promise") if is_promise($reason);
94 5         17 deferred->reject($reason)->promise;
95             }
96              
97 42     42   177 sub _evo { Evo::Manager->singleton }
98              
99             1;
100              
101             # ABSTRACT: Promises6 - Promises/A+ with DSL, ES6 syntax and progress notifications
102              
103             __END__