|
|
78f1eb |
From 01aed385e6bdbdcfd13bb66e9d8b7c55d2cfc34a Mon Sep 17 00:00:00 2001
|
|
|
78f1eb |
From: James E Keenan <jkeenan@cpan.org>
|
|
|
78f1eb |
Date: Thu, 19 Sep 2019 23:02:54 -0400
|
|
|
78f1eb |
Subject: [PATCH] Handle undefined values correctly
|
|
|
78f1eb |
MIME-Version: 1.0
|
|
|
78f1eb |
Content-Type: text/plain; charset=UTF-8
|
|
|
78f1eb |
Content-Transfer-Encoding: 8bit
|
|
|
78f1eb |
|
|
|
78f1eb |
As reported by Henrik Pauli in RT 134441, the documentation's claim that
|
|
|
78f1eb |
|
|
|
78f1eb |
$dv->dumpValue([$x, $y]);
|
|
|
78f1eb |
|
|
|
78f1eb |
and
|
|
|
78f1eb |
|
|
|
78f1eb |
$dv->dumpValues($x, $y);
|
|
|
78f1eb |
|
|
|
78f1eb |
was not being sustained in the case where one of the elements in the
|
|
|
78f1eb |
array (or array ref) was undefined. This was due to an insufficiently
|
|
|
78f1eb |
precise specification within the dumpValues() method for determining
|
|
|
78f1eb |
when the value "undef\n" should be printed.
|
|
|
78f1eb |
|
|
|
78f1eb |
Tests for previously untested cases have been provided in
|
|
|
78f1eb |
t/rt-134441-dumpvalue.t. They were not appended to t/Dumpvalue.t (as
|
|
|
78f1eb |
would normally have been the case) because the tests in that file have
|
|
|
78f1eb |
accreted over the years in a sub-optimal manner: changes in attributes
|
|
|
78f1eb |
of the Dumpvalue object are tested but those changes are not zeroed-out
|
|
|
78f1eb |
(by, e.g., use of 'local $self->{attribute} = undef')
|
|
|
78f1eb |
before additional attributes are modified and tested. As a consequence,
|
|
|
78f1eb |
it's difficult to determine the state of the Dumpvalue object at any
|
|
|
78f1eb |
particular point and interactions between attributes cannot be ruled
|
|
|
78f1eb |
out.
|
|
|
78f1eb |
|
|
|
78f1eb |
Package TieOut, used to capture STDOUT during testing, has been
|
|
|
78f1eb |
extracted to its own file so that it can be used by all test files.
|
|
|
78f1eb |
|
|
|
78f1eb |
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
|
|
78f1eb |
---
|
|
|
78f1eb |
MANIFEST | 2 +
|
|
|
78f1eb |
dist/Dumpvalue/lib/Dumpvalue.pm | 4 +-
|
|
|
78f1eb |
dist/Dumpvalue/t/Dumpvalue.t | 20 +-----
|
|
|
78f1eb |
dist/Dumpvalue/t/lib/TieOut.pm | 20 ++++++
|
|
|
78f1eb |
dist/Dumpvalue/t/rt-134441-dumpvalue.t | 86 ++++++++++++++++++++++++++
|
|
|
78f1eb |
5 files changed, 112 insertions(+), 20 deletions(-)
|
|
|
78f1eb |
create mode 100644 dist/Dumpvalue/t/lib/TieOut.pm
|
|
|
78f1eb |
create mode 100644 dist/Dumpvalue/t/rt-134441-dumpvalue.t
|
|
|
78f1eb |
|
|
|
78f1eb |
diff --git a/MANIFEST b/MANIFEST
|
|
|
78f1eb |
index 7bf62d8479..8159ac8cc1 100644
|
|
|
78f1eb |
--- a/MANIFEST
|
|
|
78f1eb |
+++ b/MANIFEST
|
|
|
78f1eb |
@@ -3455,6 +3455,8 @@ dist/Devel-SelfStubber/lib/Devel/SelfStubber.pm Generate stubs for SelfLoader.pm
|
|
|
78f1eb |
dist/Devel-SelfStubber/t/Devel-SelfStubber.t See if Devel::SelfStubber works
|
|
|
78f1eb |
dist/Dumpvalue/lib/Dumpvalue.pm Screen dump of perl values
|
|
|
78f1eb |
dist/Dumpvalue/t/Dumpvalue.t See if Dumpvalue works
|
|
|
78f1eb |
+dist/Dumpvalue/t/lib/TieOut.pm Helper module for Dumpvalue tests
|
|
|
78f1eb |
+dist/Dumpvalue/t/rt-134441-dumpvalue.t See if Dumpvalue works
|
|
|
78f1eb |
dist/encoding-warnings/lib/encoding/warnings.pm warn on implicit encoding conversions
|
|
|
78f1eb |
dist/encoding-warnings/t/1-warning.t tests for encoding::warnings
|
|
|
78f1eb |
dist/encoding-warnings/t/2-fatal.t tests for encoding::warnings
|
|
|
78f1eb |
diff --git a/dist/Dumpvalue/lib/Dumpvalue.pm b/dist/Dumpvalue/lib/Dumpvalue.pm
|
|
|
78f1eb |
index eef9b27157..3faf829538 100644
|
|
|
78f1eb |
--- a/dist/Dumpvalue/lib/Dumpvalue.pm
|
|
|
78f1eb |
+++ b/dist/Dumpvalue/lib/Dumpvalue.pm
|
|
|
78f1eb |
@@ -1,7 +1,7 @@
|
|
|
78f1eb |
use 5.006_001; # for (defined ref) and $#$v and our
|
|
|
78f1eb |
package Dumpvalue;
|
|
|
78f1eb |
use strict;
|
|
|
78f1eb |
-our $VERSION = '1.18';
|
|
|
78f1eb |
+our $VERSION = '1.19';
|
|
|
78f1eb |
our(%address, $stab, @stab, %stab, %subs);
|
|
|
78f1eb |
|
|
|
78f1eb |
sub ASCII { return ord('A') == 65; }
|
|
|
78f1eb |
@@ -79,7 +79,7 @@ sub dumpValues {
|
|
|
78f1eb |
my $self = shift;
|
|
|
78f1eb |
local %address;
|
|
|
78f1eb |
local $^W=0;
|
|
|
78f1eb |
- (print "undef\n"), return unless defined $_[0];
|
|
|
78f1eb |
+ (print "undef\n"), return if (@_ == 1 and not defined $_[0]);
|
|
|
78f1eb |
$self->unwrap(\@_,0);
|
|
|
78f1eb |
}
|
|
|
78f1eb |
|
|
|
78f1eb |
diff --git a/dist/Dumpvalue/t/Dumpvalue.t b/dist/Dumpvalue/t/Dumpvalue.t
|
|
|
78f1eb |
index 7063dd984c..ba8775126e 100644
|
|
|
78f1eb |
--- a/dist/Dumpvalue/t/Dumpvalue.t
|
|
|
78f1eb |
+++ b/dist/Dumpvalue/t/Dumpvalue.t
|
|
|
78f1eb |
@@ -16,6 +16,8 @@ BEGIN {
|
|
|
78f1eb |
|
|
|
78f1eb |
our ( $foo, @bar, %baz );
|
|
|
78f1eb |
|
|
|
78f1eb |
+use lib ("./t/lib");
|
|
|
78f1eb |
+use TieOut;
|
|
|
78f1eb |
use Test::More tests => 88;
|
|
|
78f1eb |
|
|
|
78f1eb |
use_ok( 'Dumpvalue' );
|
|
|
78f1eb |
@@ -278,21 +280,3 @@ is( $out->read, "0 0..0 'two'\n", 'dumpValues worked on array ref' );
|
|
|
78f1eb |
$d->dumpValues('one', 'two');
|
|
|
78f1eb |
is( $out->read, "0..1 'one' 'two'\n", 'dumpValues worked on multiple values' );
|
|
|
78f1eb |
|
|
|
78f1eb |
-
|
|
|
78f1eb |
-package TieOut;
|
|
|
78f1eb |
-use overload '"' => sub { "overloaded!" };
|
|
|
78f1eb |
-
|
|
|
78f1eb |
-sub TIEHANDLE {
|
|
|
78f1eb |
- my $class = shift;
|
|
|
78f1eb |
- bless(\( my $ref), $class);
|
|
|
78f1eb |
-}
|
|
|
78f1eb |
-
|
|
|
78f1eb |
-sub PRINT {
|
|
|
78f1eb |
- my $self = shift;
|
|
|
78f1eb |
- $$self .= join('', @_);
|
|
|
78f1eb |
-}
|
|
|
78f1eb |
-
|
|
|
78f1eb |
-sub read {
|
|
|
78f1eb |
- my $self = shift;
|
|
|
78f1eb |
- return substr($$self, 0, length($$self), '');
|
|
|
78f1eb |
-}
|
|
|
78f1eb |
diff --git a/dist/Dumpvalue/t/lib/TieOut.pm b/dist/Dumpvalue/t/lib/TieOut.pm
|
|
|
78f1eb |
new file mode 100644
|
|
|
78f1eb |
index 0000000000..568caedf9c
|
|
|
78f1eb |
--- /dev/null
|
|
|
78f1eb |
+++ b/dist/Dumpvalue/t/lib/TieOut.pm
|
|
|
78f1eb |
@@ -0,0 +1,20 @@
|
|
|
78f1eb |
+package TieOut;
|
|
|
78f1eb |
+use overload '"' => sub { "overloaded!" };
|
|
|
78f1eb |
+
|
|
|
78f1eb |
+sub TIEHANDLE {
|
|
|
78f1eb |
+ my $class = shift;
|
|
|
78f1eb |
+ bless(\( my $ref), $class);
|
|
|
78f1eb |
+}
|
|
|
78f1eb |
+
|
|
|
78f1eb |
+sub PRINT {
|
|
|
78f1eb |
+ my $self = shift;
|
|
|
78f1eb |
+ $$self .= join('', @_);
|
|
|
78f1eb |
+}
|
|
|
78f1eb |
+
|
|
|
78f1eb |
+sub read {
|
|
|
78f1eb |
+ my $self = shift;
|
|
|
78f1eb |
+ return substr($$self, 0, length($$self), '');
|
|
|
78f1eb |
+}
|
|
|
78f1eb |
+
|
|
|
78f1eb |
+1;
|
|
|
78f1eb |
+
|
|
|
78f1eb |
diff --git a/dist/Dumpvalue/t/rt-134441-dumpvalue.t b/dist/Dumpvalue/t/rt-134441-dumpvalue.t
|
|
|
78f1eb |
new file mode 100644
|
|
|
78f1eb |
index 0000000000..cc9f270f5a
|
|
|
78f1eb |
--- /dev/null
|
|
|
78f1eb |
+++ b/dist/Dumpvalue/t/rt-134441-dumpvalue.t
|
|
|
78f1eb |
@@ -0,0 +1,86 @@
|
|
|
78f1eb |
+BEGIN {
|
|
|
78f1eb |
+ require Config;
|
|
|
78f1eb |
+ if (($Config::Config{'extensions'} !~ m!\bList/Util\b!) ){
|
|
|
78f1eb |
+ print "1..0 # Skip -- Perl configured without List::Util module\n";
|
|
|
78f1eb |
+ exit 0;
|
|
|
78f1eb |
+ }
|
|
|
78f1eb |
+
|
|
|
78f1eb |
+ # `make test` in the CPAN version of this module runs us with -w, but
|
|
|
78f1eb |
+ # Dumpvalue.pm relies on all sorts of things that can cause warnings. I
|
|
|
78f1eb |
+ # don't think that's worth fixing, so we just turn off all warnings
|
|
|
78f1eb |
+ # during testing.
|
|
|
78f1eb |
+ $^W = 0;
|
|
|
78f1eb |
+}
|
|
|
78f1eb |
+
|
|
|
78f1eb |
+use lib ("./t/lib");
|
|
|
78f1eb |
+use TieOut;
|
|
|
78f1eb |
+use Test::More tests => 17;
|
|
|
78f1eb |
+
|
|
|
78f1eb |
+use_ok( 'Dumpvalue' );
|
|
|
78f1eb |
+
|
|
|
78f1eb |
+my $d;
|
|
|
78f1eb |
+ok( $d = Dumpvalue->new(), 'create a new Dumpvalue object' );
|
|
|
78f1eb |
+
|
|
|
78f1eb |
+my $out = tie *OUT, 'TieOut';
|
|
|
78f1eb |
+select(OUT);
|
|
|
78f1eb |
+
|
|
|
78f1eb |
+my (@foobar, $x, $y);
|
|
|
78f1eb |
+
|
|
|
78f1eb |
+@foobar = ('foo', 'bar');
|
|
|
78f1eb |
+$d->dumpValue([@foobar]);
|
|
|
78f1eb |
+$x = $out->read;
|
|
|
78f1eb |
+is( $x, "0 'foo'\n1 'bar'\n", 'dumpValue worked on array ref' );
|
|
|
78f1eb |
+$d->dumpValues(@foobar);
|
|
|
78f1eb |
+$y = $out->read;
|
|
|
78f1eb |
+is( $y, "0 'foo'\n1 'bar'\n", 'dumpValues worked on array' );
|
|
|
78f1eb |
+is( $y, $x,
|
|
|
78f1eb |
+ "dumpValues called on array returns same as dumpValue on array ref");
|
|
|
78f1eb |
+
|
|
|
78f1eb |
+@foobar = (undef, 'bar');
|
|
|
78f1eb |
+$d->dumpValue([@foobar]);
|
|
|
78f1eb |
+$x = $out->read;
|
|
|
78f1eb |
+is( $x, "0 undef\n1 'bar'\n",
|
|
|
78f1eb |
+ 'dumpValue worked on array ref, first element undefined' );
|
|
|
78f1eb |
+$d->dumpValues(@foobar);
|
|
|
78f1eb |
+$y = $out->read;
|
|
|
78f1eb |
+is( $y, "0 undef\n1 'bar'\n",
|
|
|
78f1eb |
+ 'dumpValues worked on array, first element undefined' );
|
|
|
78f1eb |
+is( $y, $x,
|
|
|
78f1eb |
+ "dumpValues called on array returns same as dumpValue on array ref, first element undefined");
|
|
|
78f1eb |
+
|
|
|
78f1eb |
+@foobar = ('bar', undef);
|
|
|
78f1eb |
+$d->dumpValue([@foobar]);
|
|
|
78f1eb |
+$x = $out->read;
|
|
|
78f1eb |
+is( $x, "0 'bar'\n1 undef\n",
|
|
|
78f1eb |
+ 'dumpValue worked on array ref, last element undefined' );
|
|
|
78f1eb |
+$d->dumpValues(@foobar);
|
|
|
78f1eb |
+$y = $out->read;
|
|
|
78f1eb |
+is( $y, "0 'bar'\n1 undef\n",
|
|
|
78f1eb |
+ 'dumpValues worked on array, last element undefined' );
|
|
|
78f1eb |
+is( $y, $x,
|
|
|
78f1eb |
+ "dumpValues called on array returns same as dumpValue on array ref, last element undefined");
|
|
|
78f1eb |
+
|
|
|
78f1eb |
+@foobar = ('', 'bar');
|
|
|
78f1eb |
+$d->dumpValue([@foobar]);
|
|
|
78f1eb |
+$x = $out->read;
|
|
|
78f1eb |
+is( $x, "0 ''\n1 'bar'\n",
|
|
|
78f1eb |
+ 'dumpValue worked on array ref, first element empty string' );
|
|
|
78f1eb |
+$d->dumpValues(@foobar);
|
|
|
78f1eb |
+$y = $out->read;
|
|
|
78f1eb |
+is( $y, "0 ''\n1 'bar'\n",
|
|
|
78f1eb |
+ 'dumpValues worked on array, first element empty string' );
|
|
|
78f1eb |
+is( $y, $x,
|
|
|
78f1eb |
+ "dumpValues called on array returns same as dumpValue on array ref, first element empty string");
|
|
|
78f1eb |
+
|
|
|
78f1eb |
+@foobar = ('bar', '');
|
|
|
78f1eb |
+$d->dumpValue([@foobar]);
|
|
|
78f1eb |
+$x = $out->read;
|
|
|
78f1eb |
+is( $x, "0 'bar'\n1 ''\n",
|
|
|
78f1eb |
+ 'dumpValue worked on array ref, last element empty string' );
|
|
|
78f1eb |
+$d->dumpValues(@foobar);
|
|
|
78f1eb |
+$y = $out->read;
|
|
|
78f1eb |
+is( $y, "0 'bar'\n1 ''\n",
|
|
|
78f1eb |
+ 'dumpValues worked on array, last element empty string' );
|
|
|
78f1eb |
+is( $y, $x,
|
|
|
78f1eb |
+ "dumpValues called on array returns same as dumpValue on array ref, last element empty string");
|
|
|
78f1eb |
+
|
|
|
78f1eb |
--
|
|
|
78f1eb |
2.21.0
|
|
|
78f1eb |
|