Misapplied regex optimizations when \C is present.
[p5sagit/p5-mst-13.2.git] / lib / Test.pm
CommitLineData
7b13a3f5 1use strict;
2package Test;
3use Test::Harness 1.1601 ();
4use Carp;
17f410f9 5our($VERSION, @ISA, @EXPORT, @EXPORT_OK, $ntest, $TestLevel); #public-ish
6our($TESTOUT, $ONFAIL, %todo, %history, $planned, @FAILDETAIL); #private-ish
99e89e1e 7$VERSION = '1.14';
7b13a3f5 8require Exporter;
9@ISA=('Exporter');
f2ac83ee 10@EXPORT=qw(&plan &ok &skip);
11@EXPORT_OK=qw($ntest $TESTOUT);
7b13a3f5 12
3238f5fe 13$TestLevel = 0; # how many extra stack frames to skip
7b13a3f5 14$|=1;
15#$^W=1; ?
16$ntest=1;
f2ac83ee 17$TESTOUT = *STDOUT{IO};
7b13a3f5 18
3238f5fe 19# Use of this variable is strongly discouraged. It is set mainly to
20# help test coverage analyzers know which test is running.
7b13a3f5 21$ENV{REGRESSION_TEST} = $0;
22
23sub plan {
24 croak "Test::plan(%args): odd number of arguments" if @_ & 1;
8b3be1d1 25 croak "Test::plan(): should not be called more than once" if $planned;
7b13a3f5 26 my $max=0;
27 for (my $x=0; $x < @_; $x+=2) {
28 my ($k,$v) = @_[$x,$x+1];
29 if ($k =~ /^test(s)?$/) { $max = $v; }
30 elsif ($k eq 'todo' or
31 $k eq 'failok') { for (@$v) { $todo{$_}=1; }; }
8b3be1d1 32 elsif ($k eq 'onfail') {
33 ref $v eq 'CODE' or croak "Test::plan(onfail => $v): must be CODE";
34 $ONFAIL = $v;
35 }
7b13a3f5 36 else { carp "Test::plan(): skipping unrecognized directive '$k'" }
37 }
38 my @todo = sort { $a <=> $b } keys %todo;
39 if (@todo) {
f2ac83ee 40 print $TESTOUT "1..$max todo ".join(' ', @todo).";\n";
7b13a3f5 41 } else {
f2ac83ee 42 print $TESTOUT "1..$max\n";
7b13a3f5 43 }
8b3be1d1 44 ++$planned;
7b13a3f5 45}
46
3238f5fe 47sub to_value {
48 my ($v) = @_;
49 (ref $v or '') eq 'CODE' ? $v->() : $v;
50}
51
8b3be1d1 52sub ok ($;$$) {
53 croak "ok: plan before you test!" if !$planned;
3238f5fe 54 my ($pkg,$file,$line) = caller($TestLevel);
55 my $repetition = ++$history{"$file:$line"};
56 my $context = ("$file at line $line".
8b3be1d1 57 ($repetition > 1 ? " fail \#$repetition" : ''));
3238f5fe 58 my $ok=0;
8b3be1d1 59 my $result = to_value(shift);
60 my ($expected,$diag);
3238f5fe 61 if (@_ == 0) {
8b3be1d1 62 $ok = $result;
3238f5fe 63 } else {
8b3be1d1 64 $expected = to_value(shift);
8b3be1d1 65 my ($regex,$ignore);
59e80644 66 if (!defined $expected) {
67 $ok = !defined $result;
68 } elsif (!defined $result) {
69 $ok = 0;
70 } elsif ((ref($expected)||'') eq 'Regexp') {
f2ac83ee 71 $ok = $result =~ /$expected/;
72 } elsif (($regex) = ($expected =~ m,^ / (.+) / $,sx) or
8b3be1d1 73 ($ignore, $regex) = ($expected =~ m,^ m([^\w\s]) (.+) \1 $,sx)) {
74 $ok = $result =~ /$regex/;
3238f5fe 75 } else {
3238f5fe 76 $ok = $result eq $expected;
77 }
8b3be1d1 78 }
f2ac83ee 79 my $todo = $todo{$ntest};
80 if ($todo and $ok) {
81 $context .= ' TODO?!' if $todo;
82 print $TESTOUT "ok $ntest # ($context)\n";
8b3be1d1 83 } else {
f2ac83ee 84 print $TESTOUT "not " if !$ok;
85 print $TESTOUT "ok $ntest\n";
8b3be1d1 86
87 if (!$ok) {
88 my $detail = { 'repetition' => $repetition, 'package' => $pkg,
f2ac83ee 89 'result' => $result, 'todo' => $todo };
8b3be1d1 90 $$detail{expected} = $expected if defined $expected;
91 $diag = $$detail{diagnostic} = to_value(shift) if @_;
f2ac83ee 92 $context .= ' *TODO*' if $todo;
8b3be1d1 93 if (!defined $expected) {
3238f5fe 94 if (!$diag) {
f2ac83ee 95 print $TESTOUT "# Failed test $ntest in $context\n";
3238f5fe 96 } else {
f2ac83ee 97 print $TESTOUT "# Failed test $ntest in $context: $diag\n";
3238f5fe 98 }
8b3be1d1 99 } else {
100 my $prefix = "Test $ntest";
59e80644 101 print $TESTOUT "# $prefix got: ".
102 (defined $result? "'$result'":'<UNDEF>')." ($context)\n";
8b3be1d1 103 $prefix = ' ' x (length($prefix) - 5);
f63ceb1c 104 if ((ref($expected)||'') eq 'Regexp') {
f2ac83ee 105 $expected = 'qr/'.$expected.'/'
106 } else {
107 $expected = "'$expected'";
108 }
8b3be1d1 109 if (!$diag) {
f2ac83ee 110 print $TESTOUT "# $prefix Expected: $expected\n";
3238f5fe 111 } else {
f2ac83ee 112 print $TESTOUT "# $prefix Expected: $expected ($diag)\n";
3238f5fe 113 }
114 }
8b3be1d1 115 push @FAILDETAIL, $detail;
7b13a3f5 116 }
7b13a3f5 117 }
118 ++ $ntest;
119 $ok;
120}
121
8b3be1d1 122sub skip ($$;$$) {
f2ac83ee 123 my $whyskip = to_value(shift);
124 if ($whyskip) {
125 $whyskip = 'skip' if $whyskip =~ m/^\d+$/;
126 print $TESTOUT "ok $ntest # $whyskip\n";
7b13a3f5 127 ++ $ntest;
128 1;
129 } else {
8b3be1d1 130 local($TestLevel) = $TestLevel+1; #ignore this stack frame
131 &ok;
7b13a3f5 132 }
133}
134
8b3be1d1 135END {
136 $ONFAIL->(\@FAILDETAIL) if @FAILDETAIL && $ONFAIL;
137}
138
7b13a3f5 1391;
140__END__
141
142=head1 NAME
143
144 Test - provides a simple framework for writing test scripts
145
146=head1 SYNOPSIS
147
148 use strict;
149 use Test;
f2ac83ee 150
151 # use a BEGIN block so we print our plan before MyModule is loaded
152 BEGIN { plan tests => 14, todo => [3,4] }
153
154 # load your module...
155 use MyModule;
3238f5fe 156
157 ok(0); # failure
158 ok(1); # success
159
160 ok(0); # ok, expected failure (see todo list, above)
161 ok(1); # surprise success!
162
163 ok(0,1); # failure: '0' ne '1'
164 ok('broke','fixed'); # failure: 'broke' ne 'fixed'
165 ok('fixed','fixed'); # success: 'fixed' eq 'fixed'
f2ac83ee 166 ok('fixed',qr/x/); # success: 'fixed' =~ qr/x/
7b13a3f5 167
3238f5fe 168 ok(sub { 1+1 }, 2); # success: '2' eq '2'
169 ok(sub { 1+1 }, 3); # failure: '2' ne '3'
59e80644 170 ok(0, int(rand(2)); # (just kidding :-)
7b13a3f5 171
3238f5fe 172 my @list = (0,0);
8b3be1d1 173 ok @list, 3, "\@list=".join(',',@list); #extra diagnostics
174 ok 'segmentation fault', '/(?i)success/'; #regex match
7b13a3f5 175
3238f5fe 176 skip($feature_is_missing, ...); #do platform specific test
7b13a3f5 177
178=head1 DESCRIPTION
179
d032053e 180L<Test::Harness|Test::Harness> expects to see particular output when it
181executes tests. This module aims to make writing proper test scripts just
182a little bit easier (and less error prone :-).
7b13a3f5 183
3238f5fe 184=head1 TEST TYPES
7b13a3f5 185
186=over 4
187
188=item * NORMAL TESTS
189
f2ac83ee 190These tests are expected to succeed. If they don't something's
3238f5fe 191screwed up!
7b13a3f5 192
193=item * SKIPPED TESTS
194
f2ac83ee 195Skip is for tests that might or might not be possible to run depending
196on the availability of platform specific features. The first argument
197should evaluate to true (think "yes, please skip") if the required
198feature is not available. After the first argument, skip works
3238f5fe 199exactly the same way as do normal tests.
7b13a3f5 200
201=item * TODO TESTS
202
f2ac83ee 203TODO tests are designed for maintaining an B<executable TODO list>.
204These tests are expected NOT to succeed. If a TODO test does succeed,
205the feature in question should not be on the TODO list, now should it?
7b13a3f5 206
f2ac83ee 207Packages should NOT be released with succeeding TODO tests. As soon
7b13a3f5 208as a TODO test starts working, it should be promoted to a normal test
f2ac83ee 209and the newly working feature should be documented in the release
210notes or change log.
7b13a3f5 211
212=back
213
f2ac83ee 214=head1 RETURN VALUE
215
216Both C<ok> and C<skip> return true if their test succeeds and false
217otherwise in a scalar context.
218
8b3be1d1 219=head1 ONFAIL
220
221 BEGIN { plan test => 4, onfail => sub { warn "CALL 911!" } }
222
f2ac83ee 223While test failures should be enough, extra diagnostics can be
224triggered at the end of a test run. C<onfail> is passed an array ref
225of hash refs that describe each test failure. Each hash will contain
226at least the following fields: C<package>, C<repetition>, and
227C<result>. (The file, line, and test number are not included because
f610777f 228their correspondence to a particular test is tenuous.) If the test
f2ac83ee 229had an expected value or a diagnostic string, these will also be
230included.
231
232The B<optional> C<onfail> hook might be used simply to print out the
233version of your package and/or how to report problems. It might also
234be used to generate extremely sophisticated diagnostics for a
235particularly bizarre test failure. However it's not a panacea. Core
236dumps or other unrecoverable errors prevent the C<onfail> hook from
237running. (It is run inside an C<END> block.) Besides, C<onfail> is
238probably over-kill in most cases. (Your test code should be simpler
8b3be1d1 239than the code it is testing, yes?)
240
7b13a3f5 241=head1 SEE ALSO
242
f2ac83ee 243L<Test::Harness> and, perhaps, test coverage analysis tools.
7b13a3f5 244
245=head1 AUTHOR
246
59e80644 247Copyright (c) 1998-1999 Joshua Nathaniel Pritikin. All rights reserved.
7b13a3f5 248
249This package is free software and is provided "as is" without express
250or implied warranty. It may be used, redistributed and/or modified
251under the terms of the Perl Artistic License (see
252http://www.perl.com/perl/misc/Artistic.html)
253
254=cut