File Coverage

blib/lib/Plack/Middleware/Test/StashWarnings.pm
Criterion Covered Total %
statement 46 47 97.8
branch 8 10 80.0
condition 4 8 50.0
subroutine 13 14 92.8
pod 2 4 50.0
total 73 83 87.9


line stmt bran cond sub pod time code
1             package Plack::Middleware::Test::StashWarnings;
2              
3 4     4   127820 use strict;
  4         12  
  4         231  
4 4     4   121 use 5.008_001;
  4         17  
  4         598  
5             our $VERSION = '0.08';
6              
7 4     4   1504 use parent qw(Plack::Middleware);
  4         736  
  4         32  
8 4     4   57411 use Carp ();
  4         14  
  4         110  
9 4     4   3054 use Storable 'nfreeze';
  4         8918  
  4         2893  
10              
11             sub new {
12 3     3 1 173 my $proto = shift;
13 3   33     28 my $class = ref $proto || $proto;
14 3         38 my $self = $class->SUPER::new(@_);
15 3 50       523 $self->{verbose} = $ENV{TEST_VERBOSE} unless defined $self->{verbose};
16 3         14 return $self;
17             }
18              
19             sub call {
20 11     11 1 213130 my ($self, $env) = @_;
21              
22 11 100       65 if ($env->{PATH_INFO} eq '/__test_warnings') {
23 6 50 33     26 Carp::carp("Use a single process server like Standalone to run Test::StashWarnings middleware")
24             if $env->{'psgi.multiprocess'} && $self->{multiprocess_warn}++ == 0;
25              
26 6         32 return [ 200, ["Content-Type", "application/x-storable"], [ $self->dump_warnings ] ];
27             }
28              
29 5         65 my $ret = $self->_stash_warnings_for($self->app, $env);
30              
31             # for the streaming API, we need to re-instate the dynamic sigwarn handler
32             # around the streaming callback
33 5 100       1624 if (ref($ret) eq 'CODE') {
34 2     2   20 return sub { $self->_stash_warnings_for($ret, @_) };
  2         43  
35             }
36              
37 3         23 return $ret;
38             }
39              
40             sub _stash_warnings_for {
41 7     7   55 my $self = shift;
42 7         14 my $code = shift;
43              
44 7   100 0   66 my $old_warn = $SIG{__WARN__} || sub { warn @_ };
  0         0  
45             local $SIG{__WARN__} = sub {
46 3     3   650 $self->add_warning(@_);
47 3 100       32 $old_warn->(@_) if $self->{verbose};
48 7         54 };
49              
50 7         40 return $code->(@_);
51             }
52              
53             sub add_warning {
54 3     3 0 6 my $self = shift;
55 3         7 push @{ $self->{stashed_warnings} }, @_;
  3         14  
56             }
57              
58             sub dump_warnings {
59 6     6 0 12 my $self = shift;
60              
61 6         12 return nfreeze([ splice @{ $self->{stashed_warnings} } ]);
  6         47  
62             }
63              
64             sub DESTROY {
65 3     3   9543 my $self = shift;
66 3         12 for (splice @{ $self->{stashed_warnings} }) {
  3         260  
67 1         8 warn "Unhandled warning: $_";
68             }
69             }
70              
71             1;
72             __END__