my $planned;
$TODO = 0;
+$NO_ENDING = 0;
sub plan {
my $n;
END {
my $ran = $test - 1;
- if (defined $planned && $planned != $ran) {
- print STDOUT "# Looks like you planned $planned tests but ran $ran.\n";
+ if (!$NO_ENDING && defined $planned && $planned != $ran) {
+ print STDERR "# Looks like you planned $planned tests but ran $ran.\n";
}
}
+# Use this instead of "print STDERR" when outputing failure diagnostic
+# messages
+sub _diag {
+ my $fh = $TODO ? *STDOUT : *STDERR;
+ print $fh @_;
+}
+
sub skip_all {
if (@_) {
print STDOUT "1..0 - @_\n";
# VMS will avenge.
my $out;
if ($name) {
+ # escape out '#' or it will interfere with '# skip' and such
+ $name =~ s/#/\\#/g;
$out = $pass ? "ok $test - $name" : "not ok $test - $name";
} else {
$out = $pass ? "ok $test" : "not ok $test";
print STDOUT "$out\n";
unless ($pass) {
- print STDOUT "# Failed $where\n";
+ _diag "# Failed $where\n";
}
# Ensure that the message is properly escaped.
- print STDOUT map { /^#/ ? "$_\n" : "# $_\n" }
- map { split /\n/ } @mess if @mess;
+ _diag map { /^#/ ? "$_\n" : "# $_\n" }
+ map { split /\n/ } @mess if @mess;
$test++;
my $x = shift;
return 'undef' unless defined $x;
my $q = $x;
+ $q =~ s/\\/\\\\/;
$q =~ s/'/\\'/;
return "'$q'";
}
+sub _qq {
+ my $x = shift;
+ return defined $x ? '"' . display ($x) . '"' : 'undef';
+};
+
+# keys are the codes \n etc map to, values are 2 char strings such as \n
+my %backslash_escape;
+foreach my $x (split //, 'nrtfa\\\'"') {
+ $backslash_escape{ord eval "\"\\$x\""} = "\\$x";
+}
+# A way to display scalars containing control characters and Unicode.
+# Trying to avoid setting $_, or relying on local $_ to work.
+sub display {
+ my @result;
+ foreach my $x (@_) {
+ if (defined $x and not ref $x) {
+ my $y = '';
+ foreach my $c (unpack("U*", $x)) {
+ if ($c > 255) {
+ $y .= sprintf "\\x{%x}", $c;
+ } elsif ($backslash_escape{$c}) {
+ $y .= $backslash_escape{$c};
+ } else {
+ my $z = chr $c; # Maybe we can get away with a literal...
+ $z = sprintf "\\%03o", $c if $z =~ /[[:^print:]]/;
+ $y .= $z;
+ }
+ }
+ $x = $y;
+ }
+ return $x unless wantarray;
+ push @result, $x;
+ }
+ return @result;
+}
+
sub is {
my ($got, $expected, $name, @mess) = @_;
my $pass = $got eq $expected;
if (ref $expected eq 'Regexp') {
$pass = $got =~ $expected;
unless ($pass) {
- unshift(@mess, "# got '$got'\n");
+ unshift(@mess, "# got '$got'\n",
+ "# expected /$expected/\n");
}
} else {
$pass = $got =~ /$expected/;
return 1;
}
+sub eq_hash {
+ my ($orig, $suspect) = @_;
+ my $fail;
+ while (my ($key, $value) = each %$suspect) {
+ # Force a hash recompute if this perl's internals can cache the hash key.
+ $key = "" . $key;
+ if (exists $orig->{$key}) {
+ if ($orig->{$key} ne $value) {
+ print STDOUT "# key ", _qq($key), " was ", _qq($orig->{$key}),
+ " now ", _qq($value), "\n";
+ $fail = 1;
+ }
+ } else {
+ print STDOUT "# key ", _qq($key), " is ", _qq($value),
+ ", not in original.\n";
+ $fail = 1;
+ }
+ }
+ foreach (keys %$orig) {
+ # Force a hash recompute if this perl's internals can cache the hash key.
+ $_ = "" . $_;
+ next if (exists $suspect->{$_});
+ print STDOUT "# key ", _qq($_), " was ", _qq($orig->{$_}), " now missing.\n";
+ $fail = 1;
+ }
+ !$fail;
+}
+
sub require_ok {
my ($require) = @_;
eval <<REQUIRE_OK;
if ($args{verbose}) {
my $runperldisplay = $runperl;
$runperldisplay =~ s/\n/\n\#/g;
- print STDOUT "# $runperldisplay\n";
+ print STDERR "# $runperldisplay\n";
}
my $result = `$runperl`;
$result =~ s/\n\n/\n/ if $is_vms; # XXX pipes sometimes double these
}
-sub BAILOUT {
- print STDOUT "Bail out! @_\n";
- exit;
+sub DIE {
+ print STDERR "# @_\n";
+ exit 1;
}
-
-# A way to display scalars containing control characters and Unicode.
-sub display {
- map { join("", map { $_ > 255 ? sprintf("\\x{%x}", $_) : chr($_) =~ /[[:cntrl:]]/ ? sprintf("\\%03o", $_) : chr($_) } unpack("U*", $_)) } @_;
-}
-
-
# A somewhat safer version of the sometimes wrong $^X.
-BEGIN: {
- eval {
- require File::Spec;
- require Config;
- Config->import;
- };
- warn "test.pl had problems loading other modules: $@" if $@;
-}
-
-# We do this at compile time before the test might have chdir'd around
-# and make sure its absolute in case they do later.
-my $Perl = $^X;
-$Perl = File::Spec->rel2abs(File::Spec->catfile(File::Spec->curdir(), $Perl))
- if $^X eq "perl$Config{_exe}";
-warn "Can't generate which_perl from $^X" unless -f $Perl;
-
-# For subcommands to use.
-$ENV{PERLEXE} = $Perl;
-
+my $Perl;
sub which_perl {
+ unless (defined $Perl) {
+ $Perl = $^X;
+
+ my $exe;
+ eval "require Config; Config->import";
+ if ($@) {
+ warn "test.pl had problems loading Config: $@";
+ $exe = '';
+ } else {
+ $exe = $Config{_exe};
+ }
+ $exe = '' unless defined $exe;
+
+ # This doesn't absolutize the path: beware of future chdirs().
+ # We could do File::Spec->abs2rel() but that does getcwd()s,
+ # which is a bit heavyweight to do here.
+
+ if ($Perl =~ /^perl\Q$exe\E$/i) {
+ my $perl = "perl$exe";
+ eval "require File::Spec";
+ if ($@) {
+ warn "test.pl had problems loading File::Spec: $@";
+ $Perl = "./$perl";
+ } else {
+ $Perl = File::Spec->catfile(File::Spec->curdir(), $perl);
+ }
+ }
+
+ # Its like this. stat on Cygwin treats 'perl' to mean 'perl.exe'
+ # but open does not. This can get confusing, so to be safe we
+ # always put the .exe on the end on Cygwin.
+ $Perl .= $exe if $^O eq 'cygwin' && $Perl !~ /\Q$exe\E$/;
+
+ warn "which_perl: cannot find $Perl from $^X" unless -f $Perl;
+
+ # For subcommands to use.
+ $ENV{PERLEXE} = $Perl;
+ }
return $Perl;
}
+sub unlink_all {
+ foreach my $file (@_) {
+ 1 while unlink $file;
+ print STDERR "# Couldn't unlink '$file': $!\n" if -f $file;
+ }
+}
1;