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