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