1#!/usr/bin/perl -w 2 3use strict; 4 5use Test::Harness; 6use Getopt::Long; 7use Pod::Usage 1.12; 8use File::Spec; 9 10use vars qw( $VERSION ); 11$VERSION = "1.04"; 12 13my @ext = (); 14my $shuffle = 0; 15my $dry = 0; 16my $blib = 0; 17my $lib = 0; 18my $recurse = 0; 19my @includes = (); 20my @switches = (); 21 22# Allow cuddling the paths with the -I 23@ARGV = map { /^(-I)(.+)/ ? ($1,$2) : $_ } @ARGV; 24 25# Stick any default switches at the beginning, so they can be overridden 26# by the command line switches. 27unshift @ARGV, split( " ", $ENV{PROVE_SWITCHES} ) if defined $ENV{PROVE_SWITCHES}; 28 29Getopt::Long::Configure( "no_ignore_case" ); 30Getopt::Long::Configure( "bundling" ); 31GetOptions( 32 'b|blib' => \$blib, 33 'd|debug' => \$Test::Harness::debug, 34 'D|dry' => \$dry, 35 'h|help|?' => sub {pod2usage({-verbose => 1, -input => \*DATA}); exit}, 36 'H|man' => sub {pod2usage({-verbose => 2, -input => \*DATA}); exit}, 37 'I=s@' => \@includes, 38 'l|lib' => \$lib, 39 'r|recurse' => \$recurse, 40 's|shuffle' => \$shuffle, 41 't' => sub { unshift @switches, "-t" }, # Always want -t up front 42 'T' => sub { unshift @switches, "-T" }, # Always want -T up front 43 'v|verbose' => \$Test::Harness::verbose, 44 'V|version' => sub { print_version(); exit; }, 45 'ext=s@' => \@ext, 46) or exit 1; 47 48# Build up extensions regex 49@ext = map { split /,/ } @ext; 50s/^\.// foreach @ext; 51@ext = ("t") unless @ext; 52my $ext_regex = join( "|", map { quotemeta } @ext ); 53$ext_regex = qr/\.($ext_regex)$/; 54 55# Handle blib includes 56if ( $blib ) { 57 my @blibdirs = blibdirs(); 58 if ( @blibdirs ) { 59 unshift @includes, @blibdirs; 60 } else { 61 warn "No blib directories found.\n"; 62 } 63} 64 65# Handle lib includes 66if ( $lib ) { 67 unshift @includes, "lib"; 68} 69 70# Build up TH switches 71push( @switches, map { /\s/ && !/^".*"$/ ? qq["-I$_"] : "-I$_" } @includes ); 72$Test::Harness::Switches = join( " ", @switches ); 73print "# \$Test::Harness::Switches: $Test::Harness::Switches\n" if $Test::Harness::debug; 74 75my @tests; 76@ARGV = File::Spec->curdir unless @ARGV; 77push( @tests, -d $_ ? all_in( $_ ) : $_ ) for @ARGV; 78 79if ( @tests ) { 80 shuffle(@tests) if $shuffle; 81 if ( $dry ) { 82 print join( "\n", @tests, "" ); 83 } else { 84 print "# ", scalar @tests, " tests to run\n" if $Test::Harness::debug; 85 runtests(@tests); 86 } 87} 88 89sub all_in { 90 my $start = shift; 91 92 my @hits = (); 93 94 local *DH; 95 if ( opendir( DH, $start ) ) { 96 while ( my $file = readdir DH ) { 97 next if $file eq File::Spec->updir || $file eq File::Spec->curdir; 98 next if $file eq ".svn"; 99 next if $file eq "CVS"; 100 101 my $currfile = File::Spec->catfile( $start, $file ); 102 if ( -d $currfile ) { 103 push( @hits, all_in( $currfile ) ) if $recurse; 104 } else { 105 push( @hits, $currfile ) if $currfile =~ $ext_regex; 106 } 107 } 108 } else { 109 warn "$start: $!\n"; 110 } 111 112 return @hits; 113} 114 115sub shuffle { 116 # Fisher-Yates shuffle 117 my $i = @_; 118 while ($i) { 119 my $j = rand $i--; 120 @_[$i, $j] = @_[$j, $i]; 121 } 122} 123 124sub print_version { 125 printf( "prove v%s, using Test::Harness v%s and Perl v%vd\n", 126 $VERSION, $Test::Harness::VERSION, $^V ); 127} 128 129# Stolen directly from blib.pm 130sub blibdirs { 131 my $dir = File::Spec->curdir; 132 if ($^O eq 'VMS') { 133 ($dir = VMS::Filespec::unixify($dir)) =~ s-/\z--; 134 } 135 my $archdir = "arch"; 136 if ( $^O eq "MacOS" ) { 137 # Double up the MP::A so that it's not used only once. 138 $archdir = $MacPerl::Architecture = $MacPerl::Architecture; 139 } 140 141 my $i = 5; 142 while ($i--) { 143 my $blib = File::Spec->catdir( $dir, "blib" ); 144 my $blib_lib = File::Spec->catdir( $blib, "lib" ); 145 my $blib_arch = File::Spec->catdir( $blib, $archdir ); 146 147 if ( -d $blib && -d $blib_arch && -d $blib_lib ) { 148 return ($blib_arch,$blib_lib); 149 } 150 $dir = File::Spec->catdir($dir, File::Spec->updir); 151 } 152 warn "$0: Cannot find blib\n"; 153 return; 154} 155 156__END__ 157 158=head1 NAME 159 160prove -- A command-line tool for running tests against Test::Harness 161 162=head1 SYNOPSIS 163 164prove [options] [files/directories] 165 166Options: 167 168 -b, --blib Adds blib/lib to the path for your tests, a la "use blib". 169 -d, --debug Includes extra debugging information. 170 -D, --dry Dry run: Show the tests to run, but don't run them. 171 --ext=x Extensions (defaults to .t) 172 -h, --help Display this help 173 -H, --man Longer manpage for prove 174 -I Add libraries to @INC, as Perl's -I 175 -l, --lib Add lib to the path for your tests. 176 -r, --recurse Recursively descend into directories. 177 -s, --shuffle Run the tests in a random order. 178 -T Enable tainting checks 179 -t Enable tainting warnings 180 -v, --verbose Display standard output of test scripts while running them. 181 -V, --version Display version info 182 183Single-character options may be stacked. Default options may be set by 184specifying the PROVE_SWITCHES environment variable. 185 186=head1 OVERVIEW 187 188F<prove> is a command-line interface to the test-running functionality 189of C<Test::Harness>. With no arguments, it will run all tests in the 190current directory. 191 192Shell metacharacters may be used with command lines options and will be exanded 193via C<glob>. 194 195=head1 PROVE VS. "MAKE TEST" 196 197F<prove> has a number of advantages over C<make test> when doing development. 198 199=over 4 200 201=item * F<prove> is designed as a development tool 202 203Perl users typically run the test harness through a makefile via 204C<make test>. That's fine for module distributions, but it's 205suboptimal for a test/code/debug development cycle. 206 207=item * F<prove> is granular 208 209F<prove> lets your run against only the files you want to check. 210Running C<prove t/live/ t/master.t> checks every F<*.t> in F<t/live>, 211plus F<t/master.t>. 212 213=item * F<prove> has an easy verbose mode 214 215F<prove> has a C<-v> option to see the raw output from the tests. 216To do this with C<make test>, you must set C<HARNESS_VERBOSE=1> in 217the environment. 218 219=item * F<prove> can run under taint mode 220 221F<prove>'s C<-T> runs your tests under C<perl -T>, and C<-t> runs them 222under C<perl -t>. 223 224=item * F<prove> can shuffle tests 225 226You can use F<prove>'s C<--shuffle> option to try to excite problems 227that don't show up when tests are run in the same order every time. 228 229=item * F<prove> doesn't rely on a make tool 230 231Not everyone wants to write a makefile, or use L<ExtUtils::MakeMaker> 232to do so. F<prove> has no external dependencies. 233 234=item * Not everything is a module 235 236More and more users are using Perl's testing tools outside the 237context of a module distribution, and may not even use a makefile 238at all. 239 240=back 241 242=head1 COMMAND LINE OPTIONS 243 244=head2 -b, --blib 245 246Adds blib/lib to the path for your tests, a la "use blib". 247 248=head2 -d, --debug 249 250Include debug information about how F<prove> is being run. This 251option doesn't show the output from the test scripts. That's handled 252by -v,--verbose. 253 254=head2 -D, --dry 255 256Dry run: Show the tests to run, but don't run them. 257 258=head2 --ext=extension 259 260Specify extensions of the test files to run. By default, these are .t, 261but you may have other non-.t test files, most likely .sh shell scripts. 262The --ext is repeatable. 263 264=head2 -I 265 266Add libraries to @INC, as Perl's -I. 267 268=head2 -l, --lib 269 270Add C<lib> to @INC. Equivalent to C<-Ilib>. 271 272=head2 -r, --recurse 273 274Descends into subdirectories of any directories specified, looking for tests. 275 276=head2 -s, --shuffle 277 278Sometimes tests are accidentally dependent on tests that have been 279run before. This switch will shuffle the tests to be run prior to 280running them, thus ensuring that hidden dependencies in the test 281order are likely to be revealed. The author hopes the run the 282algorithm on the preceding sentence to see if he can produce something 283slightly less awkward. 284 285=head2 -t 286 287Runs test programs under perl's -t taint warning mode. 288 289=head2 -T 290 291Runs test programs under perl's -T taint mode. 292 293=head2 -v, --verbose 294 295Display standard output of test scripts while running them. 296 297=head2 -V, --version 298 299Display version info. 300 301=head1 BUGS 302 303Please use the CPAN bug ticketing system at L<http://rt.cpan.org/>. 304You can also mail bugs, fixes and enhancements to 305C<< <bug-test-harness@rt.cpan.org> >>. 306 307=head1 TODO 308 309=over 4 310 311=item * 312 313Shuffled tests must be recreatable 314 315=back 316 317=head1 AUTHORS 318 319Andy Lester C<< <andy@petdance.com> >> 320 321=head1 COPYRIGHT 322 323Copyright 2003 by Andy Lester C<< <andy@petdance.com> >>. 324 325This program is free software; you can redistribute it and/or 326modify it under the same terms as Perl itself. 327 328See L<http://www.perl.com/perl/misc/Artistic.html>. 329 330=cut 331