2 # t/test.pl - most of Test::More functionality without the fuss
7 # Do not rely on features found only in more modern Perls here, as some CPAN
8 # distributions copy this file and must operate on older Perls. Similarly, keep
9 # things, simple as this may be run under fairly broken circumstances. For
10 # example, increment ($x++) has a certain amount of cleverness for things like
13 # $x++; # $x eq 'aaa';
15 # This stands more chance of breaking than just a simple
19 # In this file, we use the latter "Baby Perl" approach, and increment
20 # will be worked over by t/op/inc.t
28 # Fatalize warnings, so that we don't introduce new warnings. But on early
29 # perls the burden of avoiding warnings becomes too large, and someone still
30 # trying to use such outmoded versions should be willing to accept warnings in
32 $SIG{__WARN__} = sub { die "Fatalized: $_[0]" } if $] ge "5.6.0";
34 # This defines ASCII/UTF-8 vs EBCDIC/UTF-EBCDIC
35 $::IS_ASCII = ord 'A' == 65;
39 $Tests_Are_Passing = 1;
41 # Use this instead of print to avoid interference while testing globals.
43 local($\, $", $,) = (undef, ' ', '') if "$]" >= 5.004;
48 local($\, $", $,) = (undef, ' ', '') if "$]" >= 5.004;
56 if ($n eq 'no_plan') {
62 $plan{skip_all} and skip_all($plan{skip_all});
65 _print "1..$n\n" unless $noplan;
70 # Set the plan at the end. See Test::More::done_testing.
83 if (defined $planned && $planned != $ran) {
85 "# Looks like you planned $planned tests but ran $ran.\n";
94 my @mess = _comment(@_);
95 $TODO ? _print(@mess) : _print_stderr(@mess);
98 # Use this instead of "print STDERR" when outputting failure diagnostic
104 # Use this instead of "print" when outputting informational messages
107 _print( _comment(@_) );
111 return map { /^#/ ? "$_\n" : "# $_\n" }
112 map { split /\n/ } @_;
115 sub _have_dynamic_extension {
116 my $extension = shift;
117 unless (eval {require Config; 1}) {
118 warn "test.pl had problems loading Config: $@";
121 $extension =~ s!::!/!g;
122 return 1 if ($Config::Config{extensions} =~ /\b$extension\b/);
127 _print "1..0 # Skip @_\n";
136 _print("Bail out! $reason\n");
141 my ($pass, $where, $name, @mess) = @_;
142 # Do not try to microoptimize by factoring out the "not ".
146 # escape out '#' or it will interfere with '# skip' and such
148 $out = $pass ? "ok $test - $name" : "not ok $test - $name";
150 $out = $pass ? "ok $test" : "not ok $test";
154 $out = $out . " # TODO $TODO";
156 $Tests_Are_Passing = 0 unless $pass;
162 note @mess; # Ensure that the message is properly escaped.
165 my $msg = "# Failed test $test - ";
166 $msg.= "$name " if $name;
172 $test = $test + 1; # don't use ++
178 my @caller = caller($Level);
179 return "at $caller[1] line $caller[2]";
183 my ($pass, $name, @mess) = @_;
184 _ok($pass, _where(), $name, @mess);
189 return 'undef' unless defined $x;
198 return defined $x ? '"' . display ($x) . '"' : 'undef';
201 # Support pre-5.10 Perls, for the benefit of CPAN dists that copy this file.
202 # Note that chr(90) exists in both ASCII ("Z") and EBCDIC ("!").
203 my $chars_template = defined(eval { pack "W*", 90 }) ? "W*" : defined(eval { pack "U*", 90 }) ? "U*" : "C*";
204 eval 'sub re::is_regexp { ref($_[0]) eq "Regexp" }'
205 if !defined &re::is_regexp;
207 # keys are the codes \n etc map to, values are 2 char strings such as \n
208 my %backslash_escape;
210 foreach $x (split //, 'nrtfa\\\'"') {
211 $backslash_escape{ord eval "\"\\$x\""} = "\\$x";
213 # A way to display scalars containing control characters and Unicode.
214 # Trying to avoid setting $_, or relying on local $_ to work.
219 if (defined $x and not ref $x) {
222 foreach $c (unpack($chars_template, $x)) {
224 $y = $y . sprintf "\\x{%x}", $c;
225 } elsif ($backslash_escape{$c}) {
226 $y = $y . $backslash_escape{$c};
227 } elsif ($c < ord " ") {
228 # Use octal for characters with small ordinals that are
229 # traditionally expressed as octal: the controls below
230 # space, which on EBCDIC are almost all the controls, but
231 # on ASCII don't include DEL nor the C1 controls.
232 $y = $y . sprintf "\\%03o", $c;
233 } elsif ($::IS_ASCII && $c <= ord('~')) {
235 } elsif ( ! $::IS_ASCII
236 && eval 'chr $c =~ /[^[:^print:][:^ascii:]]/')
237 # The pattern above is equivalent (by de Morgan's
239 # $z =~ /(?[ [:print:] & [:ascii:] ])/
240 # or, $z is an ascii printable character
241 # The /a modifier doesn't go back so far.
245 elsif ($@) { # Should only be an error on platforms too
246 # early to have the [:posix:] syntax, which
247 # also should be ASCII ones
248 die __FILE__ . __LINE__
249 . ": Unexpected non-ASCII platform; $@";
252 $y = $y . sprintf "\\x%02X", $c;
257 return $x unless wantarray;
264 my ($got, $expected, $name, @mess) = @_;
267 if( !defined $got || !defined $expected ) {
268 # undef only matches undef
269 $pass = !defined $got && !defined $expected;
272 $pass = $got eq $expected;
276 unshift(@mess, "# got "._qq($got)."\n",
277 "# expected "._qq($expected)."\n");
279 _ok($pass, _where(), $name, @mess);
283 my ($got, $isnt, $name, @mess) = @_;
286 if( !defined $got || !defined $isnt ) {
287 # undef only matches undef
288 $pass = defined $got || defined $isnt;
291 $pass = $got ne $isnt;
295 unshift(@mess, "# it should not be "._qq($got)."\n",
298 _ok($pass, _where(), $name, @mess);
302 my($got, $type, $expected, $name, @mess) = @_;
307 local($@,$!); # don't interfere with $@
308 # eval() sometimes resets $!
309 $pass = eval "\$got $type \$expected";
312 # It seems Irix long doubles can have 2147483648 and 2147483648
313 # that stringify to the same thing but are actually numerically
314 # different. Display the numbers if $type isn't a string operator,
315 # and the numbers are stringwise the same.
316 # (all string operators have alphabetic names, so tr/a-z// is true)
317 # This will also show numbers for some unneeded cases, but will
318 # definitely be helpful for things such as == and <= that fail
319 if ($got eq $expected and $type !~ tr/a-z//) {
320 unshift @mess, "# $got - $expected = " . ($got - $expected) . "\n";
322 unshift(@mess, "# got "._qq($got)."\n",
323 "# expected $type "._qq($expected)."\n");
325 _ok($pass, _where(), $name, @mess);
328 # Check that $got is within $range of $expected
329 # if $range is 0, then check it's exact
330 # else if $expected is 0, then $range is an absolute value
331 # otherwise $range is a fractional error.
332 # Here $range must be numeric, >= 0
333 # Non numeric ranges might be a useful future extension. (eg %)
335 my ($got, $expected, $range, $name, @mess) = @_;
337 if (!defined $got or !defined $expected or !defined $range) {
338 # This is a fail, but doesn't need extra diagnostics
339 } elsif ($got !~ tr/0-9// or $expected !~ tr/0-9// or $range !~ tr/0-9//) {
341 unshift @mess, "# got, expected and range must be numeric\n";
342 } elsif ($range < 0) {
343 # This is also a fail
344 unshift @mess, "# range must not be negative\n";
345 } elsif ($range == 0) {
347 $pass = $got == $expected;
348 } elsif ($expected == 0) {
349 # If expected is 0, treat range as absolute
350 $pass = ($got <= $range) && ($got >= - $range);
352 my $diff = $got - $expected;
353 $pass = abs ($diff / $expected) < $range;
356 if ($got eq $expected) {
357 unshift @mess, "# $got - $expected = " . ($got - $expected) . "\n";
359 unshift@mess, "# got "._qq($got)."\n",
360 "# expected "._qq($expected)." (within "._qq($range).")\n";
362 _ok($pass, _where(), $name, @mess);
370 _ok(0, _where(), @_);
380 $test = $test + 1; # don't use ++
384 # Note: can't pass multipart messages since we try to
385 # be compatible with Test::More::skip().
388 my $n = @_ ? shift : 1;
393 $bad_swap = $why > 0 && $n == 0;
394 $both_zero = $why == 0 && $n == 0;
396 if ($bad_swap || $both_zero || @_) {
397 my $arg = "'$why', '$n'";
399 $arg .= join(", ", '', map { qq['$_'] } @_);
401 die qq[$0: expected skip(why, count), got skip($arg)\n];
404 _print "ok $test # skip $why\n";
413 return 0 unless $#$ra == $#$rb;
416 next if !defined $ra->[$i] && !defined $rb->[$i];
417 return 0 if !defined $ra->[$i];
418 return 0 if !defined $rb->[$i];
419 return 0 unless $ra->[$i] eq $rb->[$i];
425 my ($orig, $suspect) = @_;
427 while (my ($key, $value) = each %$suspect) {
428 # Force a hash recompute if this perl's internals can cache the hash key.
430 if (exists $orig->{$key}) {
432 defined $orig->{$key} != defined $value
433 || (defined $value && $orig->{$key} ne $value)
435 _print "# key ", _qq($key), " was ", _qq($orig->{$key}),
436 " now ", _qq($value), "\n";
440 _print "# key ", _qq($key), " is ", _qq($value),
441 ", not in original.\n";
445 foreach (keys %$orig) {
446 # Force a hash recompute if this perl's internals can cache the hash key.
448 next if (exists $suspect->{$_});
449 _print "# key ", _qq($_), " was ", _qq($orig->{$_}), " now missing.\n";