1 package Test::Pod::Coverage;
5 Test::Pod::Coverage - Check for pod coverage in your distribution.
13 our $VERSION = "1.08";
17 Checks for POD coverage in files for your distribution.
19 use Test::Pod::Coverage tests=>1;
20 pod_coverage_ok( "Foo::Bar", "Foo::Bar is covered" );
22 Can also be called with L<Pod::Coverage> parms.
24 use Test::Pod::Coverage tests=>1;
27 { also_private => [ qr/^[A-Z_]+$/ ], },
28 "Foo::Bar, with all-caps functions as privates",
31 The L<Pod::Coverage> parms are also useful for subclasses that don't
32 re-document the parent class's methods. Here's an example from
35 pod_coverage_ok( "Mail::SRS" ); # No exceptions
37 # Define the three overridden methods.
38 my $trustme = { trustme => [qr/^(new|parse|compile)$/] };
39 pod_coverage_ok( "Mail::SRS::DB", $trustme );
40 pod_coverage_ok( "Mail::SRS::Guarded", $trustme );
41 pod_coverage_ok( "Mail::SRS::Reversable", $trustme );
42 pod_coverage_ok( "Mail::SRS::Shortcut", $trustme );
44 Alternately, you could use L<Pod::Coverage::CountParents>, which always allows
45 a subclass to reimplement its parents' methods without redocumenting them. For
48 my $trustparents = { coverage_class => 'Pod::Coverage::CountParents' };
49 pod_coverage_ok( "IO::Handle::Frayed", $trustparents );
51 (The C<coverage_class> parameter is not passed to the coverage class with other
54 If you want POD coverage for your module, but don't want to make
55 Test::Pod::Coverage a prerequisite for installing, create the following
56 as your F<t/pod-coverage.t> file:
59 eval "use Test::Pod::Coverage";
60 plan skip_all => "Test::Pod::Coverage required for testing pod coverage" if $@;
63 pod_coverage_ok( "Pod::Master::Html");
65 Finally, Module authors can include the following in a F<t/pod-coverage.t>
66 file and have C<Test::Pod::Coverage> automatically find and check all
67 modules in the module distribution:
70 eval "use Test::Pod::Coverage 1.00";
71 plan skip_all => "Test::Pod::Coverage 1.00 required for testing POD coverage" if $@;
72 all_pod_coverage_ok();
82 my $Test = Test::Builder->new;
88 *{$caller.'::pod_coverage_ok'} = \&pod_coverage_ok;
89 *{$caller.'::all_pod_coverage_ok'} = \&all_pod_coverage_ok;
90 *{$caller.'::all_modules'} = \&all_modules;
92 $Test->exported_to($caller);
98 All functions listed below are exported to the calling namespace.
100 =head2 all_pod_coverage_ok( [$parms, ] $msg )
102 Checks that the POD code in all modules in the distro have proper POD
105 If the I<$parms> hashref if passed in, they're passed into the
106 C<Pod::Coverage> object that the function uses. Check the
107 L<Pod::Coverage> manual for what those can be.
109 The exception is the C<coverage_class> parameter, which specifies a class to
110 use for coverage testing. It defaults to C<Pod::Coverage>.
114 sub all_pod_coverage_ok {
115 my $parms = (@_ && (ref $_[0] eq "HASH")) ? shift : {};
119 my @modules = all_modules();
121 $Test->plan( tests => scalar @modules );
123 for my $module ( @modules ) {
124 my $thismsg = defined $msg ? $msg : "Pod coverage on $module";
126 my $thisok = pod_coverage_ok( $module, $parms, $thismsg );
127 $ok = 0 unless $thisok;
131 $Test->plan( tests => 1 );
132 $Test->ok( 1, "No modules found." );
139 =head2 pod_coverage_ok( $module, [$parms, ] $msg )
141 Checks that the POD code in I<$module> has proper POD coverage.
143 If the I<$parms> hashref if passed in, they're passed into the
144 C<Pod::Coverage> object that the function uses. Check the
145 L<Pod::Coverage> manual for what those can be.
147 The exception is the C<coverage_class> parameter, which specifies a class to
148 use for coverage testing. It defaults to C<Pod::Coverage>.
152 sub pod_coverage_ok {
154 my %parms = (@_ && (ref $_[0] eq "HASH")) ? %{(shift)} : ();
155 my $msg = @_ ? shift : "Pod coverage on $module";
157 my $pc_class = (delete $parms{coverage_class}) || 'Pod::Coverage';
158 eval "require $pc_class" or die $@;
160 my $pc = $pc_class->new( package => $module, %parms );
162 my $rating = $pc->coverage;
164 if ( defined $rating ) {
165 $ok = ($rating == 1);
166 $Test->ok( $ok, $msg );
168 my @nakies = sort $pc->naked;
169 my $s = @nakies == 1 ? "" : "s";
171 sprintf( "Coverage for %s is %3.1f%%, with %d naked subroutine$s:",
172 $module, $rating*100, scalar @nakies ) );
173 $Test->diag( "\t$_" ) for @nakies;
177 my $why = $pc->why_unrated;
178 my $nopublics = ( $why =~ "no public symbols defined" );
179 my $verbose = $ENV{HARNESS_VERBOSE} || 0;
181 $Test->ok( $ok, $msg );
182 $Test->diag( "$module: $why" ) unless ( $nopublics && !$verbose );
188 =head2 all_modules( [@dirs] )
190 Returns a list of all modules in I<$dir> and in directories below. If
191 no directories are passed, it defaults to F<blib> if F<blib> exists,
194 Note that the modules are as "Foo::Bar", not "Foo/Bar.pm".
196 The order of the files returned is machine-dependent. If you want them
197 sorted, you'll have to sort them yourself.
202 my @starters = @_ ? @_ : _starting_points();
203 my %starters = map {$_,1} @starters;
205 my @queue = @starters;
209 my $file = shift @queue;
212 opendir DH, $file or next;
213 my @newfiles = readdir DH;
216 @newfiles = File::Spec->no_upwards( @newfiles );
217 @newfiles = grep { $_ ne "CVS" && $_ ne ".svn" } @newfiles;
219 push @queue, map "$file/$_", @newfiles;
222 next unless $file =~ /\.pm$/;
224 my @parts = File::Spec->splitdir( $file );
225 shift @parts if @parts && exists $starters{$parts[0]};
226 shift @parts if @parts && $parts[0] eq "lib";
227 $parts[-1] =~ s/\.pm$// if @parts;
231 if ( /^([a-zA-Z0-9_\.\-]+)$/ && ($_ eq $1) ) {
232 $_ = $1; # Untaint the original
235 die qq{Invalid and untaintable filename "$file"!};
238 my $module = join( "::", @parts );
239 push( @modules, $module );
246 sub _starting_points {
247 return 'blib' if -e 'blib';
253 Please report any bugs or feature requests to
254 C<bug-test-pod-coverage at rt.cpan.org>, or through the web interface at
255 L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-Pod-Coverage>.
256 I will be notified, and then you'll automatically be notified of progress on
257 your bug as I make changes.
261 You can find documentation for this module with the perldoc command.
263 perldoc Test::Pod::Coverage
265 You can also look for information at:
269 =item * AnnoCPAN: Annotated CPAN documentation
271 L<http://annocpan.org/dist/Test-Pod-Coverage>
275 L<http://cpanratings.perl.org/d/Test-Pod-Coverage>
277 =item * RT: CPAN's request tracker
279 L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Test-Pod-Coverage>
283 L<http://search.cpan.org/dist/Test-Pod-Coverage>
289 Written by Andy Lester, C<< <andy at petdance.com> >>.
291 =head1 ACKNOWLEDGEMENTS
293 Thanks to Ricardo Signes for patches, and Richard Clamp for
294 writing Pod::Coverage.
296 =head1 COPYRIGHT & LICENSE
298 Copyright 2006, Andy Lester, All Rights Reserved.
300 You may use, modify, and distribute this package under the
301 same terms as Perl itself.