File Coverage

blib/lib/Test/UsedModules.pm
Criterion Covered Total %
statement 82 84 97.6
branch 15 18 83.3
condition 3 3 100.0
subroutine 17 17 100.0
pod 2 2 100.0
total 119 124 95.9


line stmt bran cond sub pod time code
1             package Test::UsedModules;
2 26     26   104440 use 5.008005;
  26         96  
  26         1101  
3 26     26   151 use strict;
  26         47  
  26         963  
4 26     26   136 use warnings;
  26         59  
  26         701  
5 26     26   2082 use utf8;
  26         80  
  26         152  
6 26     26   29965 use parent qw/Test::Builder::Module/;
  26         9436  
  26         144  
7 26     26   541065 use ExtUtils::Manifest qw/maniread/;
  26         340498  
  26         2315  
8 26     26   15907 use Test::UsedModules::PPIDocument;
  26         80  
  26         18117  
9              
10             our $VERSION = "0.03";
11             our @EXPORT = qw/all_used_modules_ok used_modules_ok/;
12              
13             sub all_used_modules_ok {
14 4     4 1 68 my $builder = __PACKAGE__->builder;
15 4         64 my @lib_files = _list_up_modules_from_manifest($builder);
16              
17 4         52 $builder->plan( tests => scalar @lib_files );
18              
19 4         1888 my $fail = 0;
20 4         12 for my $file (@lib_files) {
21 9 50       7458 _used_modules_ok( $builder, $file ) or $fail++;
22             }
23              
24 1         1018 return $fail == 0;
25             }
26              
27             sub used_modules_ok {
28 117     117 1 138130 my ($lib_file) = @_;
29 117         1900 return _used_modules_ok( __PACKAGE__->builder, $lib_file );
30             }
31              
32             sub _used_modules_ok {
33 126     126   2259 my ( $builder, $file ) = @_;
34              
35 126         5579 local $Test::Builder::Level = $Test::Builder::Level + 1;
36              
37 126         299770 my $pid = fork;
38 126 50       8589 if ( defined $pid ) {
39 126 100       2295 if ( $pid != 0 ) {
40             # Parent process
41 105         57056597 wait;
42 105         7688 return $builder->ok( $? == 0, $file );
43             }
44             # Child processes
45 21         3249 exit _check_used_modules( $builder, $file );
46             }
47              
48 0         0 die "fail forking: $!";
49             }
50              
51             sub _check_used_modules {
52 21     21   1244 my ( $builder, $file ) = @_;
53              
54 21         2026 my ($ppi_document, $load_removed) = Test::UsedModules::PPIDocument::generate($file);
55 21         185 my ($ppi_document_without_symbol) = Test::UsedModules::PPIDocument::generate($file, 'Symbol');
56              
57 21         144 my @used_modules = Test::UsedModules::PPIDocument::fetch_modules_in_module($file);
58              
59 21         81 my $fail = 0;
60 21         236 CHECK: for my $used_module (@used_modules) {
61 25 100       160 next if $used_module->{name} eq 'Exporter';
62 24 100 100     215 next if $used_module->{name} eq 'Module::Load' && $load_removed;
63 22 100       1107 next if $ppi_document =~ /$used_module->{name}/;
64              
65 13         122 my @imported_subs = _fetch_imported_subs($used_module);
66 13         53 for my $sub (@imported_subs) {
67 16 100       259 next CHECK if $ppi_document_without_symbol =~ /$sub/;
68             }
69              
70 6         198 $builder->diag( "Test::UsedModules failed: '$used_module->{name}' is not used.");
71 6         2227 $fail++;
72             }
73              
74 21         6266 return $fail;
75             }
76              
77             sub _fetch_imported_subs {
78 13     13   39 my ($used_module) = @_;
79 13         95 my $importer = "$used_module->{type} $used_module->{name}";
80              
81 13 100       66 if ( my $extend = $used_module->{extend} ) {
82 6         36 $extend =~ s/\( \.\.\. \)/()/;
83 6         19 $importer .= " $extend";
84             }
85              
86 13         55 my %imported_refs;
87 26     26   191 no strict 'refs';
  26         43  
  26         1079  
88 13         34 %{'Test::UsedModules::Sandbox::'} = ();
  13         586  
89 26     26   140 use strict;
  26         60  
  26         4999  
90              
91 13     13   2505 eval <
  13     11   11823  
  13         9669  
  13         1830  
  11         354  
  11         28  
  11         616  
92             package Test::UsedModules::Sandbox;
93             $importer;
94             no strict 'refs';
95             %imported_refs = %{'Test::UsedModules::Sandbox::'};
96             EOC
97              
98 13         44 delete $imported_refs{BEGIN};
99 13         124 return keys %imported_refs;
100             }
101              
102             sub _list_up_modules_from_manifest {
103 4     4   8 my ($builder) = @_;
104              
105 4         8 my $manifest = $ExtUtils::Manifest::MANIFEST;
106 4 50       72 if ( not -f $manifest ) {
107 0         0 $builder->plan( skip_all => "$manifest doesn't exist" );
108             }
109 4         8 return grep { m!\Alib/.*\.pm\Z! } keys %{ maniread() };
  164         2136  
  4         20  
110             }
111             1;
112             __END__