File Coverage

blib/lib/Plack/App/Cascade.pm
Criterion Covered Total %
statement 45 45 100.0
branch 16 16 100.0
condition n/a
subroutine 8 8 100.0
pod 3 3 100.0
total 72 72 100.0


line stmt bran cond sub pod time code
1             package Plack::App::Cascade;
2 2     2   287495 use strict;
  2         6  
  2         102  
3 2     2   17 use base qw(Plack::Component);
  2         5  
  2         1128  
4              
5 2     2   16 use Plack::Util;
  2         5  
  2         2167  
6 2     2   1077 use Plack::Util::Accessor qw(apps catch codes);
  2         6  
  2         42  
7              
8             sub add {
9 6     6 1 37 my $self = shift;
10 6 100       18 $self->apps([]) unless $self->apps;
11 6         10 push @{$self->apps}, @_;
  6         14  
12             }
13              
14             sub prepare_app {
15 6     6 1 8 my $self = shift;
16 6 100       7 my %codes = map { $_ => 1 } @{ $self->catch || [ 404 ] };
  8         32  
  6         31  
17 6         19 $self->codes(\%codes);
18             }
19              
20             sub call {
21 6     6 1 12 my($self, $env) = @_;
22              
23             return sub {
24 6     6   10 my $respond = shift;
25              
26 6         16 my $done;
27             my $respond_wrapper = sub {
28 9         21 my $res = shift;
29 9 100       49 if ($self->codes->{$res->[0]}) {
30             # suppress output by giving the app an
31             # output spool which drops everything on the floor
32             return Plack::Util::inline_object
33 7         49 write => sub { }, close => sub { };
34             } else {
35 2         3 $done = 1;
36 2         5 return $respond->($res);
37             }
38 6         20 };
39              
40 6 100       11 my @try = @{$self->apps || []};
  6         17  
41 6         15 my $tries_left = 0 + @try;
42              
43 6 100       12 if (not $tries_left) {
44 1         5 return $respond->([ 404, [ 'Content-Type' => 'text/html' ], [ '404 Not Found' ] ])
45             }
46              
47 5         12 for my $app (@try) {
48 12         33 my $res = $app->($env);
49 12 100       125 if ($tries_left-- == 1) {
50 3         22 $respond_wrapper = sub { $respond->(shift) };
  3         25  
51             }
52              
53 12 100       36 if (ref $res eq 'CODE') {
54 4         12 $res->($respond_wrapper);
55             } else {
56 8         14 $respond_wrapper->($res);
57             }
58 12 100       89 return if $done;
59             }
60 6         60 };
61             }
62              
63             1;
64              
65             __END__