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