This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
SYN SYN
[perl5.git] / lib / Test.pm
CommitLineData
7b13a3f5
JP
1use strict;
2package Test;
3use Test::Harness 1.1601 ();
4use Carp;
cb50131a
CB
5our($VERSION, @ISA, @EXPORT, @EXPORT_OK, $ntest, $TestLevel); #public-ish
6our($TESTOUT, $ONFAIL, %todo, %history, $planned, @FAILDETAIL); #private-ish
22d4bb9c 7$VERSION = '1.14';
7b13a3f5
JP
8require Exporter;
9@ISA=('Exporter');
f2ac83ee
GS
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
JP
14$|=1;
15#$^W=1; ?
16$ntest=1;
f2ac83ee 17$TESTOUT = *STDOUT{IO};
7b13a3f5 18
3238f5fe
JP
19# Use of this variable is strongly discouraged. It is set mainly to
20# help test coverage analyzers know which test is running.
7b13a3f5
JP
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
JP
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
JP
32 elsif ($k eq 'onfail') {
33 ref $v eq 'CODE' or croak "Test::plan(onfail => $v): must be CODE";
34 $ONFAIL = $v;
35 }
7b13a3f5
JP
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
JP
45}
46
3238f5fe
JP
47sub to_value {
48 my ($v) = @_;
49 (ref $v or '') eq 'CODE' ? $v->() : $v;
50}
51
8b3be1d1
JP
52sub ok ($;$$) {
53 croak "ok: plan before you test!" if !$planned;
3238f5fe
JP
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
JP
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
JP
66 if (!defined $expected) {
67 $ok = !defined $result;
68 } elsif (!defined $result) {
69 $ok = 0;
70 } elsif ((ref($expected)||'') eq 'Regexp') {
f2ac83ee
GS
71 $ok = $result =~ /$expected/;
72 } elsif (($regex) = ($expected =~ m,^ / (.+) / $,sx) or
8b3be1d1
JP
73 ($ignore, $regex) = ($expected =~ m,^ m([^\w\s]) (.+) \1 $,sx)) {
74 $ok = $result =~ /$regex/;
3238f5fe 75 } else {
3238f5fe
JP
76 $ok = $result eq $expected;
77 }
8b3be1d1 78 }
f2ac83ee
GS
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
GS
84 print $TESTOUT "not " if !$ok;
85 print $TESTOUT "ok $ntest\n";
8b3be1d1
JP
86
87 if (!$ok) {
88 my $detail = { 'repetition' => $repetition, 'package' => $pkg,
f2ac83ee 89 'result' => $result, 'todo' => $todo };
8b3be1d1
JP
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
JP
99 } else {
100 my $prefix = "Test $ntest";
59e80644
JP
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
GS
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
JP
113 }
114 }
8b3be1d1 115 push @FAILDETAIL, $detail;
7b13a3f5 116 }
7b13a3f5
JP
117 }
118 ++ $ntest;
119 $ok;
120}
121
8b3be1d1 122sub skip ($$;$$) {
f2ac83ee
GS
123 my $whyskip = to_value(shift);
124 if ($whyskip) {
125 $whyskip = 'skip' if $whyskip =~ m/^\d+$/;
126 print $TESTOUT "ok $ntest # $whyskip\n";
7b13a3f5
JP
127 ++ $ntest;
128 1;
129 } else {
8b3be1d1
JP
130 local($TestLevel) = $TestLevel+1; #ignore this stack frame
131 &ok;
7b13a3f5
JP
132 }
133}
134
8b3be1d1
JP
135END {
136 $ONFAIL->(\@FAILDETAIL) if @FAILDETAIL && $ONFAIL;
137}
138
7b13a3f5
JP
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
GS
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
JP
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
JP
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
JP
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
JP
177
178=head1 DESCRIPTION
179
f2ac83ee
GS
180L<Test::Harness> expects to see particular output when it executes
181tests. This module aims to make writing proper test scripts just a
182little bit easier (and less error prone :-).
7b13a3f5 183
3238f5fe 184=head1 TEST TYPES
7b13a3f5
JP
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
JP
192
193=item * SKIPPED TESTS
194
f2ac83ee
GS
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
JP
200
201=item * TODO TESTS
202
f2ac83ee
GS
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
GS
209and the newly working feature should be documented in the release
210notes or change log.
7b13a3f5
JP
211
212=back
213
f2ac83ee
GS
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
JP
219=head1 ONFAIL
220
221 BEGIN { plan test => 4, onfail => sub { warn "CALL 911!" } }
222
f2ac83ee
GS
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
GS
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
JP
239than the code it is testing, yes?)
240
7b13a3f5
JP
241=head1 SEE ALSO
242
f2ac83ee 243L<Test::Harness> and, perhaps, test coverage analysis tools.
7b13a3f5
JP
244
245=head1 AUTHOR
246
59e80644 247Copyright (c) 1998-1999 Joshua Nathaniel Pritikin. All rights reserved.
7b13a3f5
JP
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