File Coverage

lib/Unexpected/TraitFor/TracingStacks.pm
Criterion Covered Total %
statement 45 45 100.0
branch 16 20 100.0
condition 9 12 83.3
subroutine 10 10 100.0
pod 3 3 100.0
total 83 90 97.7


line stmt bran cond sub pod time code
1             package Unexpected::TraitFor::TracingStacks;
2              
3 4     4   1489 use namespace::autoclean;
  4         5  
  4         19  
4              
5 4     4   191 use Scalar::Util qw( weaken );
  4         5  
  4         152  
6 4     4   13 use Unexpected::Types qw( HashRef LoadableClass Tracer );
  4         6  
  4         17  
7 4     4   1788 use Moo::Role;
  4         5  
  4         19  
8              
9             requires qw( BUILD );
10              
11             # Object attributes (public)
12             has 'trace' => is => 'lazy', isa => Tracer, builder => sub {
13 31     31   2275 $_[ 0 ]->trace_class->new( %{ $_[ 0 ]->trace_args } ) },
  31         69  
14             handles => [ qw( frames ) ], init_arg => undef;
15              
16             has 'trace_args' => is => 'lazy', isa => HashRef, builder => sub { {
17 30     30   2363 filter_frames_early => 1,
18             no_refs => 1,
19             respect_overload => 0,
20             max_arg_length => 0,
21             frame_filter => $_[ 0 ]->trace_frame_filter, } };
22              
23             has 'trace_class' => is => 'ro', isa => LoadableClass,
24             default => 'Devel::StackTrace';
25              
26             # Construction
27             before 'BUILD' => sub {
28             my $self = shift; $self->trace; return;
29             };
30              
31             # Public methods
32             sub message { # Stringify self and a full stack trace
33 1     1 1 272 my $self = shift; return "${self}\n".$self->trace->as_string."\n";
  1         3  
34             }
35              
36             sub stacktrace {
37 3     3 1 1237 my ($self, $skip) = @_; my (@lines, %seen, $subr);
  3         4  
38              
39 3         7 for my $frame (reverse $self->frames) {
40 12         181 my $package = $frame->package; my $l_no;
  12         25  
41              
42 12 100 100     28 unless ($l_no = $seen{ $package } and $l_no == $frame->line) {
43 9   66     34 my $lead = $subr || $package; # uncoverable condition false
44              
45             # uncoverable branch false
46 9 50       31 $lead !~ m{ (?: \A \(eval\) ) | (?: ::try) | (?: :: __ANON__ \z) }mx
47             and push @lines, join q( ), $lead, 'line', $frame->line;
48 9         34 $seen{ $package } = $frame->line;
49             }
50              
51 12 50       38 $frame->subroutine !~ m{ :: __ANON__ \z }mx # uncoverable branch false
52             and $subr = $frame->subroutine;
53             }
54              
55 3 100       20 defined $skip or $skip = 0; pop @lines while ($skip--);
  3         9  
56              
57 3 100       14 return wantarray ? reverse @lines : (join "\n", reverse @lines)."\n";
58             }
59              
60             sub trace_frame_filter { # Lifted from StackTrace::Auto
61 30     30 1 30 my $self = shift; my $found_mark = 0; weaken( $self );
  30         30  
  30         56  
62              
63             return sub {
64 268     268   6344 my ($raw) = @_;
65 268         252 my $subr = $raw->{caller}->[ 3 ];
66 268         753 (my $package = $subr) =~ s{ :: \w+ \z }{}mx;
67              
68             # uncoverable branch true
69             # uncoverable condition right
70 268 50       415 $ENV{UNEXPECTED_SHOW_RAW_TRACE} and warn "${subr}\n";
71              
72 268 100       428 if ($found_mark == 2) { return 1 }
  59 100       92  
73             elsif ($found_mark == 1) {
74             # uncoverable branch true
75             # uncoverable condition right
76 29 50 33     88 $subr =~ m{ :: new \z }mx and $self->isa( $package ) and return 0;
77 29         24 $found_mark++; return 1;
  29         55  
78             }
79              
80             # uncoverable condition right
81 180 100 100     571 $subr =~ m{ :: new \z }mx and $self->isa( $package ) and $found_mark++;
82 180         295 return 0;
83             }
84 30         540 }
85              
86             1;
87              
88             __END__