File Coverage

blib/lib/WWW/Chain.pm
Criterion Covered Total %
statement 69 70 98.5
branch 20 34 58.8
condition 1 3 33.3
subroutine 13 13 100.0
pod 0 7 0.0
total 103 127 81.1


line stmt bran cond sub pod time code
1             package WWW::Chain;
2             our $VERSION = '0.101';
3             our $AUTHORITY = 'cpan:GETTY';
4             # ABSTRACT: A web request chain
5              
6 5     5   640500 use Moo;
  5         40538  
  5         28  
7 5     5   10029 use MooX::Types::MooseLike::Base qw(:all);
  5         46489  
  5         2028  
8 5     5   2619 use Safe::Isa;
  5         3233  
  5         623  
9 5     5   2579 use WWW::Chain::UA::LWP;
  5         21  
  5         253  
10 5     5   40 use Exporter 'import';
  5         9  
  5         5590  
11              
12             our @EXPORT = qw( www_chain );
13              
14             has stash => (
15             isa => HashRef,
16             is => 'lazy',
17             );
18 4     4   3792 sub _build_stash {{}}
19              
20             has next_requests => (
21             isa => ArrayRef,
22             is => 'rwp',
23             clearer => 1,
24             );
25              
26             has next_step => (
27             isa => AnyOf[Str, CodeRef],
28             is => 'rwp',
29             clearer => 1,
30             );
31              
32             has done => (
33             isa => Bool,
34             is => 'rwp',
35             lazy => 1,
36             default => sub { 0 },
37             );
38              
39             has request_count => (
40             isa => Num,
41             is => 'rwp',
42             lazy => 1,
43             default => sub { 0 },
44             );
45              
46             has result_count => (
47             isa => Num,
48             is => 'rwp',
49             lazy => 1,
50             default => sub { 0 },
51             );
52              
53             sub www_chain {
54 3     3 0 1140767 my ( @args ) = @_;
55 3         84 my ( $next_requests, $next_step, @others ) = __PACKAGE__->parse_chain(@args);
56 3 50 33     51 die __PACKAGE__." can only use coderef as next step" unless !$next_step or ref $next_step eq 'CODE';
57             return WWW::Chain->new(
58             next_requests => $next_requests,
59             next_step => $next_step,
60 3         9 request_count => scalar @{$next_requests},
  3         55  
61             @others,
62             );
63             }
64              
65             sub request_with_lwp {
66 1     1 0 7 my ( $self ) = @_;
67 1         40 return WWW::Chain::UA::LWP->new->request_chain($self);
68             }
69              
70 8     8 0 64 sub is_response { $_[1]->$_isa('HTTP::Response') }
71 24     24 0 232 sub is_request { $_[1]->$_isa('HTTP::Request') }
72              
73             sub parse_chain {
74 8     8 0 13405 my ( $self, @args ) = @_;
75 8         157 my $step;
76             my @requests;
77 8         32 while (@args) {
78 16         60 my $arg = shift @args;
79 16 100       68 if ( $self->is_request($arg) ) {
    100          
    50          
80 8         350 push @requests, $arg;
81             } elsif (ref $arg eq '') {
82 2 50       34 die "".(ref $self)."->parse_chain '".$arg."' is not a known function" unless $self->can($arg);
83 2         5 $step = $arg;
84 2         8 last;
85             } elsif (ref $arg eq 'CODE') {
86 6         120 $step = $arg;
87 6         17 last;
88             } else {
89 0 0       0 die __PACKAGE__."->parse_chain got unparseable element".(defined $arg ? " ".$arg : "" );
90             }
91             }
92 8 50       30 die __PACKAGE__."->parse_chain found no HTTP::Request objects" unless @requests;
93 8         60 return \@requests, $step, @args;
94             }
95              
96             sub next_responses {
97 8     8 0 3141 my ( $self, @responses ) = @_;
98 8 50       345 die "".(ref $self)."->next_responses can't be called on chain which is done." if $self->done;
99 8         177 my $amount = scalar @{$self->next_requests};
  8         72  
100 8 50       519 die "".(ref $self)."->next_responses would need ".$amount." HTTP::Response objects to proceed"
101             unless scalar @responses == $amount;
102             die "".(ref $self)."->next_responses only takes HTTP::Response objects"
103 8 50       44 if grep { !$self->is_response($_) } @responses;
  8         36  
104 8         360 $self->clear_next_requests;
105 8         99 my @result = $self->${\$self->next_step}(@responses);
  8         61  
106 8         22595 $self->clear_next_step;
107 8         306 $self->_set_result_count($self->result_count + 1);
108             # If the first result is a request again, then we need to parse_chain again.
109 8 100       911 if ( $self->is_request($result[0]) ) {
110 4         84 my ( $next_requests, $next_step, @others ) = $self->parse_chain(@result);
111 4 50       26 die "".(ref $self)."->next_responses can't parse the result, more arguments after next step" if @others;
112 4         152 $self->_set_next_requests($next_requests);
113 4         311 $self->_set_next_step($next_step);
114 4         1937 $self->_set_request_count($self->request_count + scalar @{$next_requests});
  4         185  
115 4         372 return 0;
116             }
117 4         216 $self->_set_done(1);
118 4         332 return $self->stash;
119             }
120              
121             sub BUILD {
122 4     4 0 428704 my ( $self ) = @_;
123 4 100       84 unless ($self->next_requests) {
124 1 50       6 die "".(ref $self)." has no start_chain function and no requests supplied on build" unless $self->can('start_chain');
125 1         10 my ( $next_requests, $next_step, @others ) = $self->parse_chain($self->start_chain);
126 1 50       7 die "".(ref $self)." parse_chain can't parse the start_chain return, more arguments after next step" if scalar @others > 0;
127 1 50       3 die "".(ref $self)." has no requests from start_chain" unless scalar @{$next_requests} > 0;
  1         5  
128 1 50       99 $self->_set_next_step($next_step) if $next_step;
129 1         154 $self->_set_next_requests($next_requests);
130             }
131             }
132              
133             1;
134              
135             __END__