File Coverage

blib/lib/Test/LocalFunctions/PPI.pm
Criterion Covered Total %
statement 53 53 100.0
branch 4 4 100.0
condition 1 2 50.0
subroutine 14 14 100.0
pod 2 3 66.6
total 74 76 97.3


line stmt bran cond sub pod time code
1             package Test::LocalFunctions::PPI;
2              
3 19     19   62206 use strict;
  19         40  
  19         796  
4 19     19   108 use warnings;
  19         47  
  19         659  
5 19     19   8441 use Test::LocalFunctions::Util;
  19         45  
  19         755  
6 19     19   8718 use Test::LocalFunctions::Receptor;
  19         52  
  19         616  
7 19     19   20094 use PPI::Document;
  19         2910100  
  19         669  
8 19     19   15266 use PPI::Dumper;
  19         19608  
  19         593  
9 19     19   14339 use parent qw/Test::Builder::Module/;
  19         4833  
  19         174  
10              
11             our @EXPORT = qw/all_local_functions_ok local_functions_ok/;
12              
13 19   50 19   231695 use constant _VERBOSE => ( $ENV{TEST_VERBOSE} || 0 );
  19         51  
  19         10981  
14              
15             sub all_local_functions_ok {
16 6     6 1 108 my ($args) = @_;
17 6         42 return Test::LocalFunctions::Receptor::all_local_functions_ok( __PACKAGE__, $args );
18             }
19              
20             sub local_functions_ok {
21 13     13 1 29955 my ( $lib, $args ) = @_;
22 13         103 return Test::LocalFunctions::Receptor::local_functions_ok( __PACKAGE__, $lib, $args );
23             }
24              
25             sub is_in_use {
26 10     10 0 626 my ( undef, $builder, $file, $args ) = @_; # append $args later?
27              
28 10         258 my $ignore_functions = $args->{ignore_functions};
29 10         720 my $module = Test::LocalFunctions::Util::extract_module_name($file);
30 10         216 my @local_functions = Test::LocalFunctions::Util::list_local_functions($module);
31 10         162 my $ppi_document = _generate_PPI_document($file);
32              
33 10         19218 my $fail = 0;
34 10         60 foreach my $local_function (@local_functions) {
35 19 100       704 unless ( $ppi_document =~ /$local_function\'/ ) {
36 6 100       19 unless ( grep { $local_function =~ $_ } @$ignore_functions ) {
  9         97  
37 3         92 $builder->diag("Test::LocalFunctions failed: '$local_function' is not used.");
38 3         1362 $fail++;
39             }
40             }
41             }
42              
43 10         2396 return $fail;
44             }
45              
46             sub _generate_PPI_document {
47 10     10   45 my $file = shift;
48              
49 10         846 my $document = PPI::Document->new($file);
50 10         419003 my $dumper = PPI::Dumper->new(_prune_PPI_tokens($document));
51 10         1346 return _remove_declarations_sub( $dumper->string() );
52             }
53              
54             sub _remove_declarations_sub {
55 10     10   108321 my $document = shift;
56              
57 10         646 $document =~ s/
58             PPI::Statement::Sub \n
59             \s*? PPI::Token::Word \s* \'sub\' \n
60             \s*? PPI::Token::Whitespace .*? \n
61             \s*? PPI::Token::Word .*? \n
62             //gxm;
63              
64 10         461 return $document;
65             }
66              
67             sub _prune_PPI_tokens {
68 10     10   48 my $document = shift;
69              
70 10         198 my @surplus_tokens = (
71             'Operator', 'Number', 'Comment', 'Pod',
72             'BOM', 'Data', 'End', 'Prototype',
73             'Separator', 'Quote',
74             );
75              
76 10         88 foreach my $surplus_token (@surplus_tokens) {
77 100         822222 $document->prune( 'PPI::Token::' . $surplus_token );
78             }
79              
80 10         81560 return $document;
81             }
82             1;
83             __END__