1*0Sstevel@tonic-gate 2*0Sstevel@tonic-gaterequire 5.004; 3*0Sstevel@tonic-gatepackage Test; 4*0Sstevel@tonic-gate# Time-stamp: "2003-04-18 21:48:01 AHDT" 5*0Sstevel@tonic-gate 6*0Sstevel@tonic-gateuse strict; 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gateuse Carp; 9*0Sstevel@tonic-gateuse vars (qw($VERSION @ISA @EXPORT @EXPORT_OK $ntest $TestLevel), #public-ish 10*0Sstevel@tonic-gate qw($TESTOUT $TESTERR %Program_Lines 11*0Sstevel@tonic-gate $ONFAIL %todo %history $planned @FAILDETAIL) #private-ish 12*0Sstevel@tonic-gate ); 13*0Sstevel@tonic-gate 14*0Sstevel@tonic-gate# In case a test is run in a persistent environment. 15*0Sstevel@tonic-gatesub _reset_globals { 16*0Sstevel@tonic-gate %todo = (); 17*0Sstevel@tonic-gate %history = (); 18*0Sstevel@tonic-gate @FAILDETAIL = (); 19*0Sstevel@tonic-gate $ntest = 1; 20*0Sstevel@tonic-gate $TestLevel = 0; # how many extra stack frames to skip 21*0Sstevel@tonic-gate $planned = 0; 22*0Sstevel@tonic-gate} 23*0Sstevel@tonic-gate 24*0Sstevel@tonic-gate$VERSION = '1.24'; 25*0Sstevel@tonic-gaterequire Exporter; 26*0Sstevel@tonic-gate@ISA=('Exporter'); 27*0Sstevel@tonic-gate 28*0Sstevel@tonic-gate@EXPORT = qw(&plan &ok &skip); 29*0Sstevel@tonic-gate@EXPORT_OK = qw($ntest $TESTOUT $TESTERR); 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate$|=1; 32*0Sstevel@tonic-gate$TESTOUT = *STDOUT{IO}; 33*0Sstevel@tonic-gate$TESTERR = *STDERR{IO}; 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gate# Use of this variable is strongly discouraged. It is set mainly to 36*0Sstevel@tonic-gate# help test coverage analyzers know which test is running. 37*0Sstevel@tonic-gate$ENV{REGRESSION_TEST} = $0; 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gate=head1 NAME 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gateTest - provides a simple framework for writing test scripts 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate=head1 SYNOPSIS 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate use strict; 47*0Sstevel@tonic-gate use Test; 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gate # use a BEGIN block so we print our plan before MyModule is loaded 50*0Sstevel@tonic-gate BEGIN { plan tests => 14, todo => [3,4] } 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate # load your module... 53*0Sstevel@tonic-gate use MyModule; 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gate # Helpful notes. All note-lines must start with a "#". 56*0Sstevel@tonic-gate print "# I'm testing MyModule version $MyModule::VERSION\n"; 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate ok(0); # failure 59*0Sstevel@tonic-gate ok(1); # success 60*0Sstevel@tonic-gate 61*0Sstevel@tonic-gate ok(0); # ok, expected failure (see todo list, above) 62*0Sstevel@tonic-gate ok(1); # surprise success! 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate ok(0,1); # failure: '0' ne '1' 65*0Sstevel@tonic-gate ok('broke','fixed'); # failure: 'broke' ne 'fixed' 66*0Sstevel@tonic-gate ok('fixed','fixed'); # success: 'fixed' eq 'fixed' 67*0Sstevel@tonic-gate ok('fixed',qr/x/); # success: 'fixed' =~ qr/x/ 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate ok(sub { 1+1 }, 2); # success: '2' eq '2' 70*0Sstevel@tonic-gate ok(sub { 1+1 }, 3); # failure: '2' ne '3' 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate my @list = (0,0); 73*0Sstevel@tonic-gate ok @list, 3, "\@list=".join(',',@list); #extra notes 74*0Sstevel@tonic-gate ok 'segmentation fault', '/(?i)success/'; #regex match 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gate skip( 77*0Sstevel@tonic-gate $^O eq 'MSWin' ? "Skip unless MSWin" : 0, # whether to skip 78*0Sstevel@tonic-gate $foo, $bar # arguments just like for ok(...) 79*0Sstevel@tonic-gate ); 80*0Sstevel@tonic-gate skip( 81*0Sstevel@tonic-gate $^O eq 'MSWin' ? 0 : "Skip if MSWin", # whether to skip 82*0Sstevel@tonic-gate $foo, $bar # arguments just like for ok(...) 83*0Sstevel@tonic-gate ); 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate=head1 DESCRIPTION 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gateThis module simplifies the task of writing test files for Perl modules, 88*0Sstevel@tonic-gatesuch that their output is in the format that 89*0Sstevel@tonic-gateL<Test::Harness|Test::Harness> expects to see. 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate=head1 QUICK START GUIDE 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gateTo write a test for your new (and probably not even done) module, create 94*0Sstevel@tonic-gatea new file called F<t/test.t> (in a new F<t> directory). If you have 95*0Sstevel@tonic-gatemultiple test files, to test the "foo", "bar", and "baz" feature sets, 96*0Sstevel@tonic-gatethen feel free to call your files F<t/foo.t>, F<t/bar.t>, and 97*0Sstevel@tonic-gateF<t/baz.t> 98*0Sstevel@tonic-gate 99*0Sstevel@tonic-gate=head2 Functions 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gateThis module defines three public functions, C<plan(...)>, C<ok(...)>, 102*0Sstevel@tonic-gateand C<skip(...)>. By default, all three are exported by 103*0Sstevel@tonic-gatethe C<use Test;> statement. 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gate=over 4 106*0Sstevel@tonic-gate 107*0Sstevel@tonic-gate=item C<plan(...)> 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gate BEGIN { plan %theplan; } 110*0Sstevel@tonic-gate 111*0Sstevel@tonic-gateThis should be the first thing you call in your test script. It 112*0Sstevel@tonic-gatedeclares your testing plan, how many there will be, if any of them 113*0Sstevel@tonic-gateshould be allowed to fail, and so on. 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gateTypical usage is just: 116*0Sstevel@tonic-gate 117*0Sstevel@tonic-gate use Test; 118*0Sstevel@tonic-gate BEGIN { plan tests => 23 } 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gateThese are the things that you can put in the parameters to plan: 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate=over 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate=item C<tests =E<gt> I<number>> 125*0Sstevel@tonic-gate 126*0Sstevel@tonic-gateThe number of tests in your script. 127*0Sstevel@tonic-gateThis means all ok() and skip() calls. 128*0Sstevel@tonic-gate 129*0Sstevel@tonic-gate=item C<todo =E<gt> [I<1,5,14>]> 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gateA reference to a list of tests which are allowed to fail. 132*0Sstevel@tonic-gateSee L</TODO TESTS>. 133*0Sstevel@tonic-gate 134*0Sstevel@tonic-gate=item C<onfail =E<gt> sub { ... }> 135*0Sstevel@tonic-gate 136*0Sstevel@tonic-gate=item C<onfail =E<gt> \&some_sub> 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gateA subroutine reference to be run at the end of the test script, if 139*0Sstevel@tonic-gateany of the tests fail. See L</ONFAIL>. 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gate=back 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gateYou must call C<plan(...)> once and only once. You should call it 144*0Sstevel@tonic-gatein a C<BEGIN {...}> block, like so: 145*0Sstevel@tonic-gate 146*0Sstevel@tonic-gate BEGIN { plan tests => 23 } 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate=cut 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gatesub plan { 151*0Sstevel@tonic-gate croak "Test::plan(%args): odd number of arguments" if @_ & 1; 152*0Sstevel@tonic-gate croak "Test::plan(): should not be called more than once" if $planned; 153*0Sstevel@tonic-gate 154*0Sstevel@tonic-gate local($\, $,); # guard against -l and other things that screw with 155*0Sstevel@tonic-gate # print 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate _reset_globals(); 158*0Sstevel@tonic-gate 159*0Sstevel@tonic-gate _read_program( (caller)[1] ); 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate my $max=0; 162*0Sstevel@tonic-gate for (my $x=0; $x < @_; $x+=2) { 163*0Sstevel@tonic-gate my ($k,$v) = @_[$x,$x+1]; 164*0Sstevel@tonic-gate if ($k =~ /^test(s)?$/) { $max = $v; } 165*0Sstevel@tonic-gate elsif ($k eq 'todo' or 166*0Sstevel@tonic-gate $k eq 'failok') { for (@$v) { $todo{$_}=1; }; } 167*0Sstevel@tonic-gate elsif ($k eq 'onfail') { 168*0Sstevel@tonic-gate ref $v eq 'CODE' or croak "Test::plan(onfail => $v): must be CODE"; 169*0Sstevel@tonic-gate $ONFAIL = $v; 170*0Sstevel@tonic-gate } 171*0Sstevel@tonic-gate else { carp "Test::plan(): skipping unrecognized directive '$k'" } 172*0Sstevel@tonic-gate } 173*0Sstevel@tonic-gate my @todo = sort { $a <=> $b } keys %todo; 174*0Sstevel@tonic-gate if (@todo) { 175*0Sstevel@tonic-gate print $TESTOUT "1..$max todo ".join(' ', @todo).";\n"; 176*0Sstevel@tonic-gate } else { 177*0Sstevel@tonic-gate print $TESTOUT "1..$max\n"; 178*0Sstevel@tonic-gate } 179*0Sstevel@tonic-gate ++$planned; 180*0Sstevel@tonic-gate print $TESTOUT "# Running under perl version $] for $^O", 181*0Sstevel@tonic-gate (chr(65) eq 'A') ? "\n" : " in a non-ASCII world\n"; 182*0Sstevel@tonic-gate 183*0Sstevel@tonic-gate print $TESTOUT "# Win32::BuildNumber ", &Win32::BuildNumber(), "\n" 184*0Sstevel@tonic-gate if defined(&Win32::BuildNumber) and defined &Win32::BuildNumber(); 185*0Sstevel@tonic-gate 186*0Sstevel@tonic-gate print $TESTOUT "# MacPerl version $MacPerl::Version\n" 187*0Sstevel@tonic-gate if defined $MacPerl::Version; 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate printf $TESTOUT 190*0Sstevel@tonic-gate "# Current time local: %s\n# Current time GMT: %s\n", 191*0Sstevel@tonic-gate scalar(localtime($^T)), scalar(gmtime($^T)); 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gate print $TESTOUT "# Using Test.pm version $VERSION\n"; 194*0Sstevel@tonic-gate 195*0Sstevel@tonic-gate # Retval never used: 196*0Sstevel@tonic-gate return undef; 197*0Sstevel@tonic-gate} 198*0Sstevel@tonic-gate 199*0Sstevel@tonic-gatesub _read_program { 200*0Sstevel@tonic-gate my($file) = shift; 201*0Sstevel@tonic-gate return unless defined $file and length $file 202*0Sstevel@tonic-gate and -e $file and -f _ and -r _; 203*0Sstevel@tonic-gate open(SOURCEFILE, "<$file") || return; 204*0Sstevel@tonic-gate $Program_Lines{$file} = [<SOURCEFILE>]; 205*0Sstevel@tonic-gate close(SOURCEFILE); 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gate foreach my $x (@{$Program_Lines{$file}}) 208*0Sstevel@tonic-gate { $x =~ tr/\cm\cj\n\r//d } 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gate unshift @{$Program_Lines{$file}}, ''; 211*0Sstevel@tonic-gate return 1; 212*0Sstevel@tonic-gate} 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gate=begin _private 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate=item B<_to_value> 217*0Sstevel@tonic-gate 218*0Sstevel@tonic-gate my $value = _to_value($input); 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gateConverts an C<ok> parameter to its value. Typically this just means 221*0Sstevel@tonic-gaterunning it, if it's a code reference. You should run all inputted 222*0Sstevel@tonic-gatevalues through this. 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate=cut 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gatesub _to_value { 227*0Sstevel@tonic-gate my ($v) = @_; 228*0Sstevel@tonic-gate return (ref $v or '') eq 'CODE' ? $v->() : $v; 229*0Sstevel@tonic-gate} 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate=end _private 232*0Sstevel@tonic-gate 233*0Sstevel@tonic-gate=item C<ok(...)> 234*0Sstevel@tonic-gate 235*0Sstevel@tonic-gate ok(1 + 1 == 2); 236*0Sstevel@tonic-gate ok($have, $expect); 237*0Sstevel@tonic-gate ok($have, $expect, $diagnostics); 238*0Sstevel@tonic-gate 239*0Sstevel@tonic-gateThis function is the reason for C<Test>'s existence. It's 240*0Sstevel@tonic-gatethe basic function that 241*0Sstevel@tonic-gatehandles printing "C<ok>" or "C<not ok>", along with the 242*0Sstevel@tonic-gatecurrent test number. (That's what C<Test::Harness> wants to see.) 243*0Sstevel@tonic-gate 244*0Sstevel@tonic-gateIn its most basic usage, C<ok(...)> simply takes a single scalar 245*0Sstevel@tonic-gateexpression. If its value is true, the test passes; if false, 246*0Sstevel@tonic-gatethe test fails. Examples: 247*0Sstevel@tonic-gate 248*0Sstevel@tonic-gate # Examples of ok(scalar) 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate ok( 1 + 1 == 2 ); # ok if 1 + 1 == 2 251*0Sstevel@tonic-gate ok( $foo =~ /bar/ ); # ok if $foo contains 'bar' 252*0Sstevel@tonic-gate ok( baz($x + $y) eq 'Armondo' ); # ok if baz($x + $y) returns 253*0Sstevel@tonic-gate # 'Armondo' 254*0Sstevel@tonic-gate ok( @a == @b ); # ok if @a and @b are the same length 255*0Sstevel@tonic-gate 256*0Sstevel@tonic-gateThe expression is evaluated in scalar context. So the following will 257*0Sstevel@tonic-gatework: 258*0Sstevel@tonic-gate 259*0Sstevel@tonic-gate ok( @stuff ); # ok if @stuff has any elements 260*0Sstevel@tonic-gate ok( !grep !defined $_, @stuff ); # ok if everything in @stuff is 261*0Sstevel@tonic-gate # defined. 262*0Sstevel@tonic-gate 263*0Sstevel@tonic-gateA special case is if the expression is a subroutine reference (in either 264*0Sstevel@tonic-gateC<sub {...}> syntax or C<\&foo> syntax). In 265*0Sstevel@tonic-gatethat case, it is executed and its value (true or false) determines if 266*0Sstevel@tonic-gatethe test passes or fails. For example, 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate ok( sub { # See whether sleep works at least passably 269*0Sstevel@tonic-gate my $start_time = time; 270*0Sstevel@tonic-gate sleep 5; 271*0Sstevel@tonic-gate time() - $start_time >= 4 272*0Sstevel@tonic-gate }); 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gateIn its two-argument form, C<ok(I<arg1>,I<arg2>)> compares the two scalar 275*0Sstevel@tonic-gatevalues to see if they equal. (The equality is checked with C<eq>). 276*0Sstevel@tonic-gate 277*0Sstevel@tonic-gate # Example of ok(scalar, scalar) 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gate ok( "this", "that" ); # not ok, 'this' ne 'that' 280*0Sstevel@tonic-gate 281*0Sstevel@tonic-gateIf either (or both!) is a subroutine reference, it is run and used 282*0Sstevel@tonic-gateas the value for comparing. For example: 283*0Sstevel@tonic-gate 284*0Sstevel@tonic-gate ok 4, sub { 285*0Sstevel@tonic-gate open(OUT, ">x.dat") || die $!; 286*0Sstevel@tonic-gate print OUT "\x{e000}"; 287*0Sstevel@tonic-gate close OUT; 288*0Sstevel@tonic-gate my $bytecount = -s 'x.dat'; 289*0Sstevel@tonic-gate unlink 'x.dat' or warn "Can't unlink : $!"; 290*0Sstevel@tonic-gate return $bytecount; 291*0Sstevel@tonic-gate }, 292*0Sstevel@tonic-gate ; 293*0Sstevel@tonic-gate 294*0Sstevel@tonic-gateThe above test passes two values to C<ok(arg1, arg2)> -- the first is 295*0Sstevel@tonic-gatethe number 4, and the second is a coderef. Before C<ok> compares them, 296*0Sstevel@tonic-gateit calls the coderef, and uses its return value as the real value of 297*0Sstevel@tonic-gatethis parameter. Assuming that C<$bytecount> returns 4, C<ok> ends up 298*0Sstevel@tonic-gatetesting C<4 eq 4>. Since that's true, this test passes. 299*0Sstevel@tonic-gate 300*0Sstevel@tonic-gateIf C<arg2> is either a regex object (i.e., C<qr/.../>) or a string 301*0Sstevel@tonic-gatethat I<looks like> a regex (e.g., C<'/foo/'>), then 302*0Sstevel@tonic-gateC<ok(I<arg1>,I<arg2>)> will perform a pattern 303*0Sstevel@tonic-gatematch against it, instead of using C<eq>. 304*0Sstevel@tonic-gate 305*0Sstevel@tonic-gate ok( 'JaffO', '/Jaff/' ); # ok, 'JaffO' =~ /Jaff/ 306*0Sstevel@tonic-gate ok( 'JaffO', qr/Jaff/ ); # ok, 'JaffO' =~ qr/Jaff/; 307*0Sstevel@tonic-gate ok( 'JaffO', '/(?i)jaff/ ); # ok, 'JaffO' =~ /jaff/i; 308*0Sstevel@tonic-gate 309*0Sstevel@tonic-gateFinally, you can append an optional third argument, in 310*0Sstevel@tonic-gateC<ok(I<arg1>,I<arg2>, I<note>)>, where I<note> is a string value that 311*0Sstevel@tonic-gatewill be printed if the test fails. This should be some useful 312*0Sstevel@tonic-gateinformation about the test, pertaining to why it failed, and/or 313*0Sstevel@tonic-gatea description of the test. For example: 314*0Sstevel@tonic-gate 315*0Sstevel@tonic-gate ok( grep($_ eq 'something unique', @stuff), 1, 316*0Sstevel@tonic-gate "Something that should be unique isn't!\n". 317*0Sstevel@tonic-gate '@stuff = '.join ', ', @stuff 318*0Sstevel@tonic-gate ); 319*0Sstevel@tonic-gate 320*0Sstevel@tonic-gateUnfortunately, a note cannot be used with the single argument 321*0Sstevel@tonic-gatestyle of C<ok()>. That is, if you try C<ok(I<arg1>, I<note>)>, then 322*0Sstevel@tonic-gateC<Test> will interpret this as C<ok(I<arg1>, I<arg2>)>, and probably 323*0Sstevel@tonic-gateend up testing C<I<arg1> eq I<arg2>> -- and that's not what you want! 324*0Sstevel@tonic-gate 325*0Sstevel@tonic-gateAll of the above special cases can occasionally cause some 326*0Sstevel@tonic-gateproblems. See L</BUGS and CAVEATS>. 327*0Sstevel@tonic-gate 328*0Sstevel@tonic-gate=cut 329*0Sstevel@tonic-gate 330*0Sstevel@tonic-gate# A past maintainer of this module said: 331*0Sstevel@tonic-gate# <<ok(...)'s special handling of subroutine references is an unfortunate 332*0Sstevel@tonic-gate# "feature" that can't be removed due to compatibility.>> 333*0Sstevel@tonic-gate# 334*0Sstevel@tonic-gate 335*0Sstevel@tonic-gatesub ok ($;$$) { 336*0Sstevel@tonic-gate croak "ok: plan before you test!" if !$planned; 337*0Sstevel@tonic-gate 338*0Sstevel@tonic-gate local($\,$,); # guard against -l and other things that screw with 339*0Sstevel@tonic-gate # print 340*0Sstevel@tonic-gate 341*0Sstevel@tonic-gate my ($pkg,$file,$line) = caller($TestLevel); 342*0Sstevel@tonic-gate my $repetition = ++$history{"$file:$line"}; 343*0Sstevel@tonic-gate my $context = ("$file at line $line". 344*0Sstevel@tonic-gate ($repetition > 1 ? " fail \#$repetition" : '')); 345*0Sstevel@tonic-gate 346*0Sstevel@tonic-gate # Are we comparing two values? 347*0Sstevel@tonic-gate my $compare = 0; 348*0Sstevel@tonic-gate 349*0Sstevel@tonic-gate my $ok=0; 350*0Sstevel@tonic-gate my $result = _to_value(shift); 351*0Sstevel@tonic-gate my ($expected,$diag,$isregex,$regex); 352*0Sstevel@tonic-gate if (@_ == 0) { 353*0Sstevel@tonic-gate $ok = $result; 354*0Sstevel@tonic-gate } else { 355*0Sstevel@tonic-gate $compare = 1; 356*0Sstevel@tonic-gate $expected = _to_value(shift); 357*0Sstevel@tonic-gate if (!defined $expected) { 358*0Sstevel@tonic-gate $ok = !defined $result; 359*0Sstevel@tonic-gate } elsif (!defined $result) { 360*0Sstevel@tonic-gate $ok = 0; 361*0Sstevel@tonic-gate } elsif ((ref($expected)||'') eq 'Regexp') { 362*0Sstevel@tonic-gate $ok = $result =~ /$expected/; 363*0Sstevel@tonic-gate $regex = $expected; 364*0Sstevel@tonic-gate } elsif (($regex) = ($expected =~ m,^ / (.+) / $,sx) or 365*0Sstevel@tonic-gate (undef, $regex) = ($expected =~ m,^ m([^\w\s]) (.+) \1 $,sx)) { 366*0Sstevel@tonic-gate $ok = $result =~ /$regex/; 367*0Sstevel@tonic-gate } else { 368*0Sstevel@tonic-gate $ok = $result eq $expected; 369*0Sstevel@tonic-gate } 370*0Sstevel@tonic-gate } 371*0Sstevel@tonic-gate my $todo = $todo{$ntest}; 372*0Sstevel@tonic-gate if ($todo and $ok) { 373*0Sstevel@tonic-gate $context .= ' TODO?!' if $todo; 374*0Sstevel@tonic-gate print $TESTOUT "ok $ntest # ($context)\n"; 375*0Sstevel@tonic-gate } else { 376*0Sstevel@tonic-gate # Issuing two seperate prints() causes problems on VMS. 377*0Sstevel@tonic-gate if (!$ok) { 378*0Sstevel@tonic-gate print $TESTOUT "not ok $ntest\n"; 379*0Sstevel@tonic-gate } 380*0Sstevel@tonic-gate else { 381*0Sstevel@tonic-gate print $TESTOUT "ok $ntest\n"; 382*0Sstevel@tonic-gate } 383*0Sstevel@tonic-gate 384*0Sstevel@tonic-gate if (!$ok) { 385*0Sstevel@tonic-gate my $detail = { 'repetition' => $repetition, 'package' => $pkg, 386*0Sstevel@tonic-gate 'result' => $result, 'todo' => $todo }; 387*0Sstevel@tonic-gate $$detail{expected} = $expected if defined $expected; 388*0Sstevel@tonic-gate 389*0Sstevel@tonic-gate # Get the user's diagnostic, protecting against multi-line 390*0Sstevel@tonic-gate # diagnostics. 391*0Sstevel@tonic-gate $diag = $$detail{diagnostic} = _to_value(shift) if @_; 392*0Sstevel@tonic-gate $diag =~ s/\n/\n#/g if defined $diag; 393*0Sstevel@tonic-gate 394*0Sstevel@tonic-gate $context .= ' *TODO*' if $todo; 395*0Sstevel@tonic-gate if (!$compare) { 396*0Sstevel@tonic-gate if (!$diag) { 397*0Sstevel@tonic-gate print $TESTERR "# Failed test $ntest in $context\n"; 398*0Sstevel@tonic-gate } else { 399*0Sstevel@tonic-gate print $TESTERR "# Failed test $ntest in $context: $diag\n"; 400*0Sstevel@tonic-gate } 401*0Sstevel@tonic-gate } else { 402*0Sstevel@tonic-gate my $prefix = "Test $ntest"; 403*0Sstevel@tonic-gate print $TESTERR "# $prefix got: ". 404*0Sstevel@tonic-gate (defined $result? "'$result'":'<UNDEF>')." ($context)\n"; 405*0Sstevel@tonic-gate $prefix = ' ' x (length($prefix) - 5); 406*0Sstevel@tonic-gate if (defined $regex) { 407*0Sstevel@tonic-gate $expected = 'qr{'.$regex.'}'; 408*0Sstevel@tonic-gate } 409*0Sstevel@tonic-gate elsif (defined $expected) { 410*0Sstevel@tonic-gate $expected = "'$expected'"; 411*0Sstevel@tonic-gate } 412*0Sstevel@tonic-gate else { 413*0Sstevel@tonic-gate $expected = '<UNDEF>'; 414*0Sstevel@tonic-gate } 415*0Sstevel@tonic-gate if (!$diag) { 416*0Sstevel@tonic-gate print $TESTERR "# $prefix Expected: $expected\n"; 417*0Sstevel@tonic-gate } else { 418*0Sstevel@tonic-gate print $TESTERR "# $prefix Expected: $expected ($diag)\n"; 419*0Sstevel@tonic-gate } 420*0Sstevel@tonic-gate } 421*0Sstevel@tonic-gate 422*0Sstevel@tonic-gate if(defined $Program_Lines{$file}[$line]) { 423*0Sstevel@tonic-gate print $TESTERR 424*0Sstevel@tonic-gate "# $file line $line is: $Program_Lines{$file}[$line]\n" 425*0Sstevel@tonic-gate if 426*0Sstevel@tonic-gate $Program_Lines{$file}[$line] =~ m/[^\s\#\(\)\{\}\[\]\;]/ 427*0Sstevel@tonic-gate # Otherwise it's a pretty uninteresting line! 428*0Sstevel@tonic-gate ; 429*0Sstevel@tonic-gate 430*0Sstevel@tonic-gate undef $Program_Lines{$file}[$line]; 431*0Sstevel@tonic-gate # So we won't repeat it. 432*0Sstevel@tonic-gate } 433*0Sstevel@tonic-gate 434*0Sstevel@tonic-gate push @FAILDETAIL, $detail; 435*0Sstevel@tonic-gate } 436*0Sstevel@tonic-gate } 437*0Sstevel@tonic-gate ++ $ntest; 438*0Sstevel@tonic-gate $ok; 439*0Sstevel@tonic-gate} 440*0Sstevel@tonic-gate 441*0Sstevel@tonic-gate=item C<skip(I<skip_if_true>, I<args...>)> 442*0Sstevel@tonic-gate 443*0Sstevel@tonic-gateThis is used for tests that under some conditions can be skipped. It's 444*0Sstevel@tonic-gatebasically equivalent to: 445*0Sstevel@tonic-gate 446*0Sstevel@tonic-gate if( $skip_if_true ) { 447*0Sstevel@tonic-gate ok(1); 448*0Sstevel@tonic-gate } else { 449*0Sstevel@tonic-gate ok( args... ); 450*0Sstevel@tonic-gate } 451*0Sstevel@tonic-gate 452*0Sstevel@tonic-gate...except that the C<ok(1)> emits not just "C<ok I<testnum>>" but 453*0Sstevel@tonic-gateactually "C<ok I<testnum> # I<skip_if_true_value>>". 454*0Sstevel@tonic-gate 455*0Sstevel@tonic-gateThe arguments after the I<skip_if_true> are what is fed to C<ok(...)> if 456*0Sstevel@tonic-gatethis test isn't skipped. 457*0Sstevel@tonic-gate 458*0Sstevel@tonic-gateExample usage: 459*0Sstevel@tonic-gate 460*0Sstevel@tonic-gate my $if_MSWin = 461*0Sstevel@tonic-gate $^O eq 'MSWin' ? 'Skip if under MSWin' : ''; 462*0Sstevel@tonic-gate 463*0Sstevel@tonic-gate # A test to be run EXCEPT under MSWin: 464*0Sstevel@tonic-gate skip($if_MSWin, thing($foo), thing($bar) ); 465*0Sstevel@tonic-gate 466*0Sstevel@tonic-gateOr, going the other way: 467*0Sstevel@tonic-gate 468*0Sstevel@tonic-gate my $unless_MSWin = 469*0Sstevel@tonic-gate $^O eq 'MSWin' ? 'Skip unless under MSWin' : ''; 470*0Sstevel@tonic-gate 471*0Sstevel@tonic-gate # A test to be run EXCEPT under MSWin: 472*0Sstevel@tonic-gate skip($unless_MSWin, thing($foo), thing($bar) ); 473*0Sstevel@tonic-gate 474*0Sstevel@tonic-gateThe tricky thing to remember is that the first parameter is true if 475*0Sstevel@tonic-gateyou want to I<skip> the test, not I<run> it; and it also doubles as a 476*0Sstevel@tonic-gatenote about why it's being skipped. So in the first codeblock above, read 477*0Sstevel@tonic-gatethe code as "skip if MSWin -- (otherwise) test whether C<thing($foo)> is 478*0Sstevel@tonic-gateC<thing($bar)>" or for the second case, "skip unless MSWin...". 479*0Sstevel@tonic-gate 480*0Sstevel@tonic-gateAlso, when your I<skip_if_reason> string is true, it really should (for 481*0Sstevel@tonic-gatebackwards compatibility with older Test.pm versions) start with the 482*0Sstevel@tonic-gatestring "Skip", as shown in the above examples. 483*0Sstevel@tonic-gate 484*0Sstevel@tonic-gateNote that in the above cases, C<thing($foo)> and C<thing($bar)> 485*0Sstevel@tonic-gateI<are> evaluated -- but as long as the C<skip_if_true> is true, 486*0Sstevel@tonic-gatethen we C<skip(...)> just tosses out their value (i.e., not 487*0Sstevel@tonic-gatebothering to treat them like values to C<ok(...)>. But if 488*0Sstevel@tonic-gateyou need to I<not> eval the arguments when skipping the 489*0Sstevel@tonic-gatetest, use 490*0Sstevel@tonic-gatethis format: 491*0Sstevel@tonic-gate 492*0Sstevel@tonic-gate skip( $unless_MSWin, 493*0Sstevel@tonic-gate sub { 494*0Sstevel@tonic-gate # This code returns true if the test passes. 495*0Sstevel@tonic-gate # (But it doesn't even get called if the test is skipped.) 496*0Sstevel@tonic-gate thing($foo) eq thing($bar) 497*0Sstevel@tonic-gate } 498*0Sstevel@tonic-gate ); 499*0Sstevel@tonic-gate 500*0Sstevel@tonic-gateor even this, which is basically equivalent: 501*0Sstevel@tonic-gate 502*0Sstevel@tonic-gate skip( $unless_MSWin, 503*0Sstevel@tonic-gate sub { thing($foo) }, sub { thing($bar) } 504*0Sstevel@tonic-gate ); 505*0Sstevel@tonic-gate 506*0Sstevel@tonic-gateThat is, both are like this: 507*0Sstevel@tonic-gate 508*0Sstevel@tonic-gate if( $unless_MSWin ) { 509*0Sstevel@tonic-gate ok(1); # but it actually appends "# $unless_MSWin" 510*0Sstevel@tonic-gate # so that Test::Harness can tell it's a skip 511*0Sstevel@tonic-gate } else { 512*0Sstevel@tonic-gate # Not skipping, so actually call and evaluate... 513*0Sstevel@tonic-gate ok( sub { thing($foo) }, sub { thing($bar) } ); 514*0Sstevel@tonic-gate } 515*0Sstevel@tonic-gate 516*0Sstevel@tonic-gate=cut 517*0Sstevel@tonic-gate 518*0Sstevel@tonic-gatesub skip ($;$$$) { 519*0Sstevel@tonic-gate local($\, $,); # guard against -l and other things that screw with 520*0Sstevel@tonic-gate # print 521*0Sstevel@tonic-gate 522*0Sstevel@tonic-gate my $whyskip = _to_value(shift); 523*0Sstevel@tonic-gate if (!@_ or $whyskip) { 524*0Sstevel@tonic-gate $whyskip = '' if $whyskip =~ m/^\d+$/; 525*0Sstevel@tonic-gate $whyskip =~ s/^[Ss]kip(?:\s+|$)//; # backwards compatibility, old 526*0Sstevel@tonic-gate # versions required the reason 527*0Sstevel@tonic-gate # to start with 'skip' 528*0Sstevel@tonic-gate # We print in one shot for VMSy reasons. 529*0Sstevel@tonic-gate my $ok = "ok $ntest # skip"; 530*0Sstevel@tonic-gate $ok .= " $whyskip" if length $whyskip; 531*0Sstevel@tonic-gate $ok .= "\n"; 532*0Sstevel@tonic-gate print $TESTOUT $ok; 533*0Sstevel@tonic-gate ++ $ntest; 534*0Sstevel@tonic-gate return 1; 535*0Sstevel@tonic-gate } else { 536*0Sstevel@tonic-gate # backwards compatiblity (I think). skip() used to be 537*0Sstevel@tonic-gate # called like ok(), which is weird. I haven't decided what to do with 538*0Sstevel@tonic-gate # this yet. 539*0Sstevel@tonic-gate# warn <<WARN if $^W; 540*0Sstevel@tonic-gate#This looks like a skip() using the very old interface. Please upgrade to 541*0Sstevel@tonic-gate#the documented interface as this has been deprecated. 542*0Sstevel@tonic-gate#WARN 543*0Sstevel@tonic-gate 544*0Sstevel@tonic-gate local($TestLevel) = $TestLevel+1; #to ignore this stack frame 545*0Sstevel@tonic-gate return &ok(@_); 546*0Sstevel@tonic-gate } 547*0Sstevel@tonic-gate} 548*0Sstevel@tonic-gate 549*0Sstevel@tonic-gate=back 550*0Sstevel@tonic-gate 551*0Sstevel@tonic-gate=cut 552*0Sstevel@tonic-gate 553*0Sstevel@tonic-gateEND { 554*0Sstevel@tonic-gate $ONFAIL->(\@FAILDETAIL) if @FAILDETAIL && $ONFAIL; 555*0Sstevel@tonic-gate} 556*0Sstevel@tonic-gate 557*0Sstevel@tonic-gate1; 558*0Sstevel@tonic-gate__END__ 559*0Sstevel@tonic-gate 560*0Sstevel@tonic-gate=head1 TEST TYPES 561*0Sstevel@tonic-gate 562*0Sstevel@tonic-gate=over 4 563*0Sstevel@tonic-gate 564*0Sstevel@tonic-gate=item * NORMAL TESTS 565*0Sstevel@tonic-gate 566*0Sstevel@tonic-gateThese tests are expected to succeed. Usually, most or all of your tests 567*0Sstevel@tonic-gateare in this category. If a normal test doesn't succeed, then that 568*0Sstevel@tonic-gatemeans that something is I<wrong>. 569*0Sstevel@tonic-gate 570*0Sstevel@tonic-gate=item * SKIPPED TESTS 571*0Sstevel@tonic-gate 572*0Sstevel@tonic-gateThe C<skip(...)> function is for tests that might or might not be 573*0Sstevel@tonic-gatepossible to run, depending 574*0Sstevel@tonic-gateon the availability of platform-specific features. The first argument 575*0Sstevel@tonic-gateshould evaluate to true (think "yes, please skip") if the required 576*0Sstevel@tonic-gatefeature is I<not> available. After the first argument, C<skip(...)> works 577*0Sstevel@tonic-gateexactly the same way as C<ok(...)> does. 578*0Sstevel@tonic-gate 579*0Sstevel@tonic-gate=item * TODO TESTS 580*0Sstevel@tonic-gate 581*0Sstevel@tonic-gateTODO tests are designed for maintaining an B<executable TODO list>. 582*0Sstevel@tonic-gateThese tests are I<expected to fail.> If a TODO test does succeed, 583*0Sstevel@tonic-gatethen the feature in question shouldn't be on the TODO list, now 584*0Sstevel@tonic-gateshould it? 585*0Sstevel@tonic-gate 586*0Sstevel@tonic-gatePackages should NOT be released with succeeding TODO tests. As soon 587*0Sstevel@tonic-gateas a TODO test starts working, it should be promoted to a normal test, 588*0Sstevel@tonic-gateand the newly working feature should be documented in the release 589*0Sstevel@tonic-gatenotes or in the change log. 590*0Sstevel@tonic-gate 591*0Sstevel@tonic-gate=back 592*0Sstevel@tonic-gate 593*0Sstevel@tonic-gate=head1 ONFAIL 594*0Sstevel@tonic-gate 595*0Sstevel@tonic-gate BEGIN { plan test => 4, onfail => sub { warn "CALL 911!" } } 596*0Sstevel@tonic-gate 597*0Sstevel@tonic-gateAlthough test failures should be enough, extra diagnostics can be 598*0Sstevel@tonic-gatetriggered at the end of a test run. C<onfail> is passed an array ref 599*0Sstevel@tonic-gateof hash refs that describe each test failure. Each hash will contain 600*0Sstevel@tonic-gateat least the following fields: C<package>, C<repetition>, and 601*0Sstevel@tonic-gateC<result>. (The file, line, and test number are not included because 602*0Sstevel@tonic-gatetheir correspondence to a particular test is tenuous.) If the test 603*0Sstevel@tonic-gatehad an expected value or a diagnostic (or "note") string, these will also be 604*0Sstevel@tonic-gateincluded. 605*0Sstevel@tonic-gate 606*0Sstevel@tonic-gateThe I<optional> C<onfail> hook might be used simply to print out the 607*0Sstevel@tonic-gateversion of your package and/or how to report problems. It might also 608*0Sstevel@tonic-gatebe used to generate extremely sophisticated diagnostics for a 609*0Sstevel@tonic-gateparticularly bizarre test failure. However it's not a panacea. Core 610*0Sstevel@tonic-gatedumps or other unrecoverable errors prevent the C<onfail> hook from 611*0Sstevel@tonic-gaterunning. (It is run inside an C<END> block.) Besides, C<onfail> is 612*0Sstevel@tonic-gateprobably over-kill in most cases. (Your test code should be simpler 613*0Sstevel@tonic-gatethan the code it is testing, yes?) 614*0Sstevel@tonic-gate 615*0Sstevel@tonic-gate 616*0Sstevel@tonic-gate=head1 BUGS and CAVEATS 617*0Sstevel@tonic-gate 618*0Sstevel@tonic-gate=over 619*0Sstevel@tonic-gate 620*0Sstevel@tonic-gate=item * 621*0Sstevel@tonic-gate 622*0Sstevel@tonic-gateC<ok(...)>'s special handing of strings which look like they might be 623*0Sstevel@tonic-gateregexes can also cause unexpected behavior. An innocent: 624*0Sstevel@tonic-gate 625*0Sstevel@tonic-gate ok( $fileglob, '/path/to/some/*stuff/' ); 626*0Sstevel@tonic-gate 627*0Sstevel@tonic-gatewill fail, since Test.pm considers the second argument to be a regex! 628*0Sstevel@tonic-gateThe best bet is to use the one-argument form: 629*0Sstevel@tonic-gate 630*0Sstevel@tonic-gate ok( $fileglob eq '/path/to/some/*stuff/' ); 631*0Sstevel@tonic-gate 632*0Sstevel@tonic-gate=item * 633*0Sstevel@tonic-gate 634*0Sstevel@tonic-gateC<ok(...)>'s use of string C<eq> can sometimes cause odd problems 635*0Sstevel@tonic-gatewhen comparing 636*0Sstevel@tonic-gatenumbers, especially if you're casting a string to a number: 637*0Sstevel@tonic-gate 638*0Sstevel@tonic-gate $foo = "1.0"; 639*0Sstevel@tonic-gate ok( $foo, 1 ); # not ok, "1.0" ne 1 640*0Sstevel@tonic-gate 641*0Sstevel@tonic-gateYour best bet is to use the single argument form: 642*0Sstevel@tonic-gate 643*0Sstevel@tonic-gate ok( $foo == 1 ); # ok "1.0" == 1 644*0Sstevel@tonic-gate 645*0Sstevel@tonic-gate=item * 646*0Sstevel@tonic-gate 647*0Sstevel@tonic-gateAs you may have inferred from the above documentation and examples, 648*0Sstevel@tonic-gateC<ok>'s prototype is C<($;$$)> (and, incidentally, C<skip>'s is 649*0Sstevel@tonic-gateC<($;$$$)>). This means, for example, that you can do C<ok @foo, @bar> 650*0Sstevel@tonic-gateto compare the I<size> of the two arrays. But don't be fooled into 651*0Sstevel@tonic-gatethinking that C<ok @foo, @bar> means a comparison of the contents of two 652*0Sstevel@tonic-gatearrays -- you're comparing I<just> the number of elements of each. It's 653*0Sstevel@tonic-gateso easy to make that mistake in reading C<ok @foo, @bar> that you might 654*0Sstevel@tonic-gatewant to be very explicit about it, and instead write C<ok scalar(@foo), 655*0Sstevel@tonic-gatescalar(@bar)>. 656*0Sstevel@tonic-gate 657*0Sstevel@tonic-gate=item * 658*0Sstevel@tonic-gate 659*0Sstevel@tonic-gateThis almost definitely doesn't do what you expect: 660*0Sstevel@tonic-gate 661*0Sstevel@tonic-gate ok $thingy->can('some_method'); 662*0Sstevel@tonic-gate 663*0Sstevel@tonic-gateWhy? Because C<can> returns a coderef to mean "yes it can (and the 664*0Sstevel@tonic-gatemethod is this...)", and then C<ok> sees a coderef and thinks you're 665*0Sstevel@tonic-gatepassing a function that you want it to call and consider the truth of 666*0Sstevel@tonic-gatethe result of! I.e., just like: 667*0Sstevel@tonic-gate 668*0Sstevel@tonic-gate ok $thingy->can('some_method')->(); 669*0Sstevel@tonic-gate 670*0Sstevel@tonic-gateWhat you probably want instead is this: 671*0Sstevel@tonic-gate 672*0Sstevel@tonic-gate ok $thingy->can('some_method') && 1; 673*0Sstevel@tonic-gate 674*0Sstevel@tonic-gateIf the C<can> returns false, then that is passed to C<ok>. If it 675*0Sstevel@tonic-gatereturns true, then the larger expression S<< C<< 676*0Sstevel@tonic-gate$thingy->can('some_method') && 1 >> >> returns 1, which C<ok> sees as 677*0Sstevel@tonic-gatea simple signal of success, as you would expect. 678*0Sstevel@tonic-gate 679*0Sstevel@tonic-gate 680*0Sstevel@tonic-gate=item * 681*0Sstevel@tonic-gate 682*0Sstevel@tonic-gateThe syntax for C<skip> is about the only way it can be, but it's still 683*0Sstevel@tonic-gatequite confusing. Just start with the above examples and you'll 684*0Sstevel@tonic-gatebe okay. 685*0Sstevel@tonic-gate 686*0Sstevel@tonic-gateMoreover, users may expect this: 687*0Sstevel@tonic-gate 688*0Sstevel@tonic-gate skip $unless_mswin, foo($bar), baz($quux); 689*0Sstevel@tonic-gate 690*0Sstevel@tonic-gateto not evaluate C<foo($bar)> and C<baz($quux)> when the test is being 691*0Sstevel@tonic-gateskipped. But in reality, they I<are> evaluated, but C<skip> just won't 692*0Sstevel@tonic-gatebother comparing them if C<$unless_mswin> is true. 693*0Sstevel@tonic-gate 694*0Sstevel@tonic-gateYou could do this: 695*0Sstevel@tonic-gate 696*0Sstevel@tonic-gate skip $unless_mswin, sub{foo($bar)}, sub{baz($quux)}; 697*0Sstevel@tonic-gate 698*0Sstevel@tonic-gateBut that's not terribly pretty. You may find it simpler or clearer in 699*0Sstevel@tonic-gatethe long run to just do things like this: 700*0Sstevel@tonic-gate 701*0Sstevel@tonic-gate if( $^O =~ m/MSWin/ ) { 702*0Sstevel@tonic-gate print "# Yay, we're under $^O\n"; 703*0Sstevel@tonic-gate ok foo($bar), baz($quux); 704*0Sstevel@tonic-gate ok thing($whatever), baz($stuff); 705*0Sstevel@tonic-gate ok blorp($quux, $whatever); 706*0Sstevel@tonic-gate ok foo($barzbarz), thang($quux); 707*0Sstevel@tonic-gate } else { 708*0Sstevel@tonic-gate print "# Feh, we're under $^O. Watch me skip some tests...\n"; 709*0Sstevel@tonic-gate for(1 .. 4) { skip "Skip unless under MSWin" } 710*0Sstevel@tonic-gate } 711*0Sstevel@tonic-gate 712*0Sstevel@tonic-gateBut be quite sure that C<ok> is called exactly as many times in the 713*0Sstevel@tonic-gatefirst block as C<skip> is called in the second block. 714*0Sstevel@tonic-gate 715*0Sstevel@tonic-gate=back 716*0Sstevel@tonic-gate 717*0Sstevel@tonic-gate=head1 NOTE 718*0Sstevel@tonic-gate 719*0Sstevel@tonic-gateA past developer of this module once said that it was no longer being 720*0Sstevel@tonic-gateactively developed. However, rumors of its demise were greatly 721*0Sstevel@tonic-gateexaggerated. Feedback and suggestions are quite welcome. 722*0Sstevel@tonic-gate 723*0Sstevel@tonic-gateBe aware that the main value of this module is its simplicity. Note 724*0Sstevel@tonic-gatethat there are already more ambitious modules out there, such as 725*0Sstevel@tonic-gateL<Test::More> and L<Test::Unit>. 726*0Sstevel@tonic-gate 727*0Sstevel@tonic-gate 728*0Sstevel@tonic-gate=head1 SEE ALSO 729*0Sstevel@tonic-gate 730*0Sstevel@tonic-gateL<Test::Harness> 731*0Sstevel@tonic-gate 732*0Sstevel@tonic-gateL<Test::Simple>, L<Test::More>, L<Devel::Cover> 733*0Sstevel@tonic-gate 734*0Sstevel@tonic-gateL<Test::Builder> for building your own testing library. 735*0Sstevel@tonic-gate 736*0Sstevel@tonic-gateL<Test::Unit> is an interesting XUnit-style testing library. 737*0Sstevel@tonic-gate 738*0Sstevel@tonic-gateL<Test::Inline> and L<SelfTest> let you embed tests in code. 739*0Sstevel@tonic-gate 740*0Sstevel@tonic-gate 741*0Sstevel@tonic-gate=head1 AUTHOR 742*0Sstevel@tonic-gate 743*0Sstevel@tonic-gateCopyright (c) 1998-2000 Joshua Nathaniel Pritikin. All rights reserved. 744*0Sstevel@tonic-gate 745*0Sstevel@tonic-gateCopyright (c) 2001-2002 Michael G. Schwern. 746*0Sstevel@tonic-gate 747*0Sstevel@tonic-gateCopyright (c) 2002-2003 Sean M. Burke. 748*0Sstevel@tonic-gate 749*0Sstevel@tonic-gateCurrent maintainer: Sean M. Burke. E<lt>sburke@cpan.orgE<gt> 750*0Sstevel@tonic-gate 751*0Sstevel@tonic-gateThis package is free software and is provided "as is" without express 752*0Sstevel@tonic-gateor implied warranty. It may be used, redistributed and/or modified 753*0Sstevel@tonic-gateunder the same terms as Perl itself. 754*0Sstevel@tonic-gate 755*0Sstevel@tonic-gate=cut 756*0Sstevel@tonic-gate 757*0Sstevel@tonic-gate# "Your mistake was a hidden intention." 758*0Sstevel@tonic-gate# -- /Oblique Strategies/, Brian Eno and Peter Schmidt 759