File Coverage

blib/lib/Pod/Coverage/TrustMe/Parser.pm
Criterion Covered Total %
statement 97 100 97.0
branch 25 26 96.1
condition 25 30 83.3
subroutine 13 13 100.0
pod 6 6 100.0
total 166 175 94.8


line stmt bran cond sub pod time code
1             package Pod::Coverage::TrustMe::Parser;
2 11     11   63 use strict;
  11         18  
  11         284  
3 11     11   47 use warnings;
  11         20  
  11         476  
4              
5             our $VERSION = '0.001_001';
6             $VERSION =~ tr/_//d;
7              
8 11     11   6179 use Pod::Simple ();
  11         291424  
  11         470  
9             our @ISA = qw(Pod::Simple);
10 11     11   122 use Carp qw(croak);
  11         24  
  11         11836  
11              
12             sub new {
13 50     50 1 104 my $class = shift;
14 50         306 my $self = $class->SUPER::new(@_);
15 50         1540 $self->accept_targets_as_text('Pod::Coverage');
16 50         974 $self->{+__PACKAGE__} = {};
17 50         142 return $self;
18             }
19              
20             sub parse_lines {
21 376     376 1 60140 my $self = shift;
22 376         1245 $self->SUPER::parse_lines(@_);
23 376         54751 my $me = $self->{+__PACKAGE__};
24             {
25             # these are regexes
26 376   100     943 my $trusted = $me->{trusted} ||= [];
27 376         517 my %seen;
28 376         946 @$trusted = sort grep !$seen{$_}++, @$trusted;
29             }
30             {
31 376   100     638 my $links = $me->{links} ||= [];
  376         736  
32 376         454 my %seen;
33 376         1257 @$links = sort grep !$seen{$_}++, @$links;
34             }
35             {
36 376   100     476 my $covered = $me->{covered} ||= [];
  376         483  
  376         838  
37 376         482 my %seen;
38 376         2946 @$covered = sort grep !$seen{$_}++, @$covered;
39             }
40 376         802 return;
41             }
42              
43             sub ignore_empty {
44 241     241 1 339 my $self = shift;
45 241         343 my $me = $self->{+__PACKAGE__};
46 241 100       490 if (@_) {
47 1         9 $me->{ignore_empty} = shift;
48             }
49 241         524 return $me->{ignore_empty};
50             }
51              
52             sub _handle_element_start {
53 1591     1591   243197 my $self = shift;
54 1591         2310 my $me = $self->{+__PACKAGE__};
55 1591         2362 my ($name, $attr) = @_;
56 1591 100 100     8758 if ($name eq 'for') {
    100 100        
    100 100        
    100 100        
57 6         11 push @{ $me->{in} }, $attr;
  6         19  
58             }
59             elsif ($name eq 'L' && $attr->{type} eq 'pod' && defined $attr->{to}) {
60 86         110 push @{ $me->{links} }, "$attr->{to}";
  86         227  
61             }
62             elsif ($name eq 'item-text' || $name eq 'item-bullet' || $name =~ /\Ahead[2-9]\z/) {
63 240         378 delete $me->{maybe_covered};
64 240         406 $me->{consider} = $name;
65 240         395 $me->{consider_text} = '';
66             }
67             elsif ($name =~ /\Ahead1\z/) {
68 96         173 delete $me->{maybe_covered};
69             }
70 1591         4179 $self->SUPER::_handle_element_start(@_);
71             }
72             sub _handle_element_end {
73 1591     1591   14731 my $self = shift;
74 1591         2057 my $me = $self->{+__PACKAGE__};
75 1591         2515 my ($name) = @_;
76 1591 100 100     4540 if ($name eq 'for') {
    100          
77 6         9 pop @{ $self->{+__PACKAGE__}{in} };
  6         16  
78             }
79             elsif ($name eq ($me->{consider}||'')) {
80 240         420 delete $me->{consider};
81 240         367 my $text = delete $me->{consider_text};
82 240         1265 my @covered = $text =~ /([^\s\|,\/]+)/g;
83 240         476 for my $covered ( @covered ) {
84             # looks like a method
85 592         936 $covered =~ s/.*->//;
86             # looks fully qualified
87 592         778 $covered =~ s/\A\w+(?:::\w+)*::(\w+)/$1/;
88             # looks like it includes parameters
89 592         1488 $covered =~ s/(\w+)[;\(].*/$1/;
90             }
91 240         1160 @covered = grep /\A\w+\z/, @covered;
92 240 100       545 if ($self->ignore_empty) {
93 2         2 push @{ $me->{maybe_covered} }, @covered;
  2         5  
94             }
95             else {
96 238         291 push @{ $me->{covered} }, @covered;
  238         573  
97             }
98             }
99 1591         3001 $self->SUPER::_handle_element_end(@_);
100             }
101              
102             sub _handle_text {
103 1885     1885   17079 my $self = shift;
104 1885         2538 my $me = $self->{+__PACKAGE__};
105 1885         2836 my ($text) = @_;
106 1885         2375 my $in = $me->{in};
107 1885 100 100     5313 if ($in && @$in && $in->[-1]{target} eq 'Pod::Coverage') {
    100 66        
    100          
108 7         14 my @trusted;
109 7         45 for my $token ($text =~ /(\S+)/g) {
110 8 100       26 if ($token eq '*EVERYTHING*') {
111 1         5 push @trusted, qr{.?};
112             }
113             else {
114 7         15 my $re = eval { qr/\A(?:$token)\z/ };
  7         142  
115 7 50       27 if (!$re) {
116 0   0     0 my $file = $self->{source_filename} || '';
117 0   0     0 my $line = $in->[-1]{start_line} || '';
118 0         0 croak "Error compiling Pod::Coverage regex /$token/ at $file line $line: $@";
119             }
120 7         19 push @trusted, $re;
121             }
122             }
123              
124 7         14 push @{ $me->{trusted} }, @trusted;
  7         20  
125             }
126             elsif ($me->{consider}) {
127 308         611 $me->{consider_text} .= $text;
128             }
129             elsif ($me->{maybe_covered}) {
130 1         3 push @{ $me->{covered} }, @{ delete $me->{maybe_covered} };
  1         2  
  1         2  
131             }
132 1885         3392 $self->SUPER::_handle_text(@_);
133             }
134              
135             sub links {
136 6     6 1 9 my $self = shift;
137 6         29 return $self->{+__PACKAGE__}{links};
138             }
139              
140             sub trusted {
141 22     22 1 35 my $self = shift;
142 22         225 return $self->{+__PACKAGE__}{trusted};
143             }
144              
145             sub covered {
146 50     50 1 85 my $self = shift;
147 50         400 return $self->{+__PACKAGE__}{covered};
148             }
149              
150             1;
151             __END__