File Coverage

blib/lib/Test/Pod/Coverage.pm
Criterion Covered Total %
statement 92 96 95.8
branch 31 44 70.4
condition 14 22 63.6
subroutine 11 11 100.0
pod 3 3 100.0
total 151 176 85.8


line stmt bran cond sub pod time code
1             package Test::Pod::Coverage;
2              
3             =head1 NAME
4              
5             Test::Pod::Coverage - Check for pod coverage in your distribution.
6              
7             =head1 VERSION
8              
9             Version 1.10
10              
11             =cut
12              
13             our $VERSION = "1.10";
14              
15             =head1 SYNOPSIS
16              
17             In one of your dist's test files (eg C):
18              
19             use Test::Pod::Coverage tests=>1;
20             pod_coverage_ok( "Foo::Bar", "Foo::Bar is covered" );
21              
22             =head1 DESCRIPTION
23              
24             Test::Pod::Coverage is used to create a test for your distribution,
25             to ensure that all relevant files in your distribution are appropriately
26             documented in pod.
27              
28             Can also be called with L parms.
29              
30             use Test::Pod::Coverage tests=>1;
31             pod_coverage_ok(
32             "Foo::Bar",
33             { also_private => [ qr/^[A-Z_]+$/ ], },
34             "Foo::Bar, with all-caps functions as privates",
35             );
36              
37             The L parms are also useful for subclasses that don't
38             re-document the parent class's methods. Here's an example from
39             L.
40              
41             pod_coverage_ok( "Mail::SRS" ); # No exceptions
42              
43             # Define the three overridden methods.
44             my $trustme = { trustme => [qr/^(new|parse|compile)$/] };
45             pod_coverage_ok( "Mail::SRS::DB", $trustme );
46             pod_coverage_ok( "Mail::SRS::Guarded", $trustme );
47             pod_coverage_ok( "Mail::SRS::Reversable", $trustme );
48             pod_coverage_ok( "Mail::SRS::Shortcut", $trustme );
49              
50             Alternately, you could use L, which always allows
51             a subclass to reimplement its parents' methods without redocumenting them. For
52             example:
53              
54             my $trustparents = { coverage_class => 'Pod::Coverage::CountParents' };
55             pod_coverage_ok( "IO::Handle::Frayed", $trustparents );
56              
57             (The C parameter is not passed to the coverage class with other
58             parameters.)
59              
60             If you want POD coverage for your module, but don't want to make
61             Test::Pod::Coverage a prerequisite for installing, create the following
62             as your F file:
63              
64             use Test::More;
65             eval "use Test::Pod::Coverage";
66             plan skip_all => "Test::Pod::Coverage required for testing pod coverage" if $@;
67              
68             plan tests => 1;
69             pod_coverage_ok( "Pod::Master::Html");
70              
71             Finally, Module authors can include the following in a F
72             file and have C automatically find and check all
73             modules in the module distribution:
74              
75             use Test::More;
76             eval "use Test::Pod::Coverage 1.00";
77             plan skip_all => "Test::Pod::Coverage 1.00 required for testing POD coverage" if $@;
78             all_pod_coverage_ok();
79              
80             =cut
81              
82 10     10   250693 use 5.006;
  10         76  
  10         481  
83 10     10   65 use strict;
  10         24  
  10         326  
84 10     10   63 use warnings;
  10         20  
  10         339  
85              
86 10     10   141 use Pod::Coverage;
  10         25  
  10         267  
87 10     10   2377 use Test::Builder;
  10         25283  
  10         685  
88              
89             my $Test = Test::Builder->new;
90              
91             sub import {
92 10     10   99 my $self = shift;
93 10         33 my $caller = caller;
94 10     10   62 no strict 'refs';
  10         19  
  10         13227  
95 10         27 *{$caller.'::pod_coverage_ok'} = \&pod_coverage_ok;
  10         65  
96 10         27 *{$caller.'::all_pod_coverage_ok'} = \&all_pod_coverage_ok;
  10         54  
97 10         117 *{$caller.'::all_modules'} = \&all_modules;
  10         55  
98              
99 10         55 $Test->exported_to($caller);
100 10         125 $Test->plan(@_);
101             }
102              
103             =head1 FUNCTIONS
104              
105             All functions listed below are exported to the calling namespace.
106              
107             =head2 all_pod_coverage_ok( [$parms, ] $msg )
108              
109             Checks that the POD code in all modules in the distro have proper POD
110             coverage.
111              
112             If the I<$parms> hashref if passed in, they're passed into the
113             C object that the function uses. Check the
114             L manual for what those can be.
115              
116             The exception is the C parameter, which specifies a class to
117             use for coverage testing. It defaults to C.
118              
119             =cut
120              
121             sub all_pod_coverage_ok {
122 1 50 33 1 1 16 my $parms = (@_ && (ref $_[0] eq "HASH")) ? shift : {};
123 1         3 my $msg = shift;
124              
125 1         2 my $ok = 1;
126 1         6 my @modules = all_modules();
127 1 50       5 if ( @modules ) {
128 1         12 $Test->plan( tests => scalar @modules );
129              
130 1         617 for my $module ( @modules ) {
131 1 50       8 my $thismsg = defined $msg ? $msg : "Pod coverage on $module";
132              
133 1         5 my $thisok = pod_coverage_ok( $module, $parms, $thismsg );
134 1 50       13 $ok = 0 unless $thisok;
135             }
136             }
137             else {
138 0         0 $Test->plan( tests => 1 );
139 0         0 $Test->ok( 1, "No modules found." );
140             }
141              
142 1         107 return $ok;
143             }
144              
145              
146             =head2 pod_coverage_ok( $module, [$parms, ] $msg )
147              
148             Checks that the POD code in I<$module> has proper POD coverage.
149              
150             If the I<$parms> hashref if passed in, they're passed into the
151             C object that the function uses. Check the
152             L manual for what those can be.
153              
154             The exception is the C parameter, which specifies a class to
155             use for coverage testing. It defaults to C.
156              
157             =cut
158              
159             sub pod_coverage_ok {
160 13     13 1 5325 my $module = shift;
161 13 100 100     129 my %parms = (@_ && (ref $_[0] eq "HASH")) ? %{(shift)} : ();
  4         19  
162 13 100       59 my $msg = @_ ? shift : "Pod coverage on $module";
163              
164 13   100     89 my $pc_class = (delete $parms{coverage_class}) || 'Pod::Coverage';
165 13 50       1153 eval "require $pc_class" or die $@;
166              
167 13         534 my $pc = $pc_class->new( package => $module, %parms );
168              
169 13         35894 my $rating = $pc->coverage;
170 13         9290 my $ok;
171 13 100       58 if ( defined $rating ) {
172 10         30 $ok = ($rating == 1);
173 10         66 $Test->ok( $ok, $msg );
174 10 100       5325 if ( !$ok ) {
175 1         23 my @nakies = sort $pc->naked;
176 1 50       6 my $s = @nakies == 1 ? "" : "s";
177 1         29 $Test->diag(
178             sprintf( "Coverage for %s is %3.1f%%, with %d naked subroutine$s:",
179             $module, $rating*100, scalar @nakies ) );
180 1         89 $Test->diag( "\t$_" ) for @nakies;
181             }
182             }
183             else { # No symbols
184 3         18 my $why = $pc->why_unrated;
185 3         10 my $nopublics = ( $why =~ "no public symbols defined" );
186 3   100     21 my $verbose = $ENV{HARNESS_VERBOSE} || 0;
187 3         7 $ok = $nopublics;
188 3         19 $Test->ok( $ok, $msg );
189 3 100 100     1210 $Test->diag( "$module: $why" ) unless ( $nopublics && !$verbose );
190             }
191              
192 13         708 return $ok;
193             }
194              
195             =head2 all_modules( [@dirs] )
196              
197             Returns a list of all modules in I<$dir> and in directories below. If
198             no directories are passed, it defaults to F if F exists,
199             or F if not.
200              
201             Note that the modules are as "Foo::Bar", not "Foo/Bar.pm".
202              
203             The order of the files returned is machine-dependent. If you want them
204             sorted, you'll have to sort them yourself.
205              
206             =cut
207              
208             sub all_modules {
209 2 100   2 1 19 my @starters = @_ ? @_ : _starting_points();
210 2         6 my %starters = map {$_,1} @starters;
  2         14  
211              
212 2         7 my @queue = @starters;
213              
214 2         6 my @modules;
215 2         13 while ( @queue ) {
216 52         120 my $file = shift @queue;
217 52 100       797 if ( -d $file ) {
218 34         83 local *DH;
219 34 50       695 opendir DH, $file or next;
220 34         445 my @newfiles = readdir DH;
221 34         347 closedir DH;
222              
223 34         442 @newfiles = File::Spec->no_upwards( @newfiles );
224 34 50       72 @newfiles = grep { $_ ne "CVS" && $_ ne ".svn" } @newfiles;
  50         344  
225              
226 34         234 push @queue, map "$file/$_", @newfiles;
227             }
228 52 100       946 if ( -f $file ) {
229 18 100       93 next unless $file =~ /\.pm$/;
230              
231 2         48 my @parts = File::Spec->splitdir( $file );
232 2 50 33     25 shift @parts if @parts && exists $starters{$parts[0]};
233 2 50 33     22 shift @parts if @parts && $parts[0] eq "lib";
234 2 50       17 $parts[-1] =~ s/\.pm$// if @parts;
235              
236             # Untaint the parts
237 2         26 for ( @parts ) {
238 6 50 33     74 if ( /^([a-zA-Z0-9_\.\-]+)$/ && ($_ eq $1) ) {
239 6         22 $_ = $1; # Untaint the original
240             }
241             else {
242 0         0 die qq{Invalid and untaintable filename "$file"!};
243             }
244             }
245 2         10 my $module = join( "::", @parts );
246 2         12 push( @modules, $module );
247             }
248             } # while
249              
250 2         31 return @modules;
251             }
252              
253             sub _starting_points {
254 1 50   1   40 return 'blib' if -e 'blib';
255 0           return 'lib';
256             }
257              
258             =head1 BUGS
259              
260             Please report any bugs or feature requests to
261             C, or through the web interface at
262             L.
263             I will be notified, and then you'll automatically be notified of progress on
264             your bug as I make changes.
265              
266             =head1 SUPPORT
267              
268             You can find documentation for this module with the perldoc command.
269              
270             perldoc Test::Pod::Coverage
271              
272             You can also look for information at:
273              
274             =over 4
275              
276             =item * AnnoCPAN: Annotated CPAN documentation
277              
278             L
279              
280             =item * CPAN Ratings
281              
282             L
283              
284             =item * RT: CPAN's request tracker
285              
286             L
287              
288             =item * Search CPAN
289              
290             L
291              
292             =back
293              
294             =head1 REPOSITORY
295              
296             L
297              
298             =head1 AUTHOR
299              
300             Written by Andy Lester, C<< >>.
301              
302             =head1 ACKNOWLEDGEMENTS
303              
304             Thanks to Ricardo Signes for patches, and Richard Clamp for
305             writing Pod::Coverage.
306              
307             =head1 COPYRIGHT & LICENSE
308              
309             Copyright 2006, Andy Lester, All Rights Reserved.
310              
311             This program is free software; you can redistribute it and/or modify it
312             under the terms of the Artistic License version 2.0.
313              
314             See http://dev.perl.org/licenses/ for more information
315              
316             =cut
317              
318             1;