1b39c5158Smillert#!./perl -w 2b39c5158Smillert# 3b39c5158Smillert# testsuite for Data::Dumper 4b39c5158Smillert# 5b39c5158Smillert 6eac174f2Safresh1use strict; 7eac174f2Safresh1use warnings; 8b39c5158Smillert 9b39c5158Smillertuse Data::Dumper; 10b39c5158Smillertuse Config; 11eac174f2Safresh1use Test::More; 12b39c5158Smillert 13eac174f2Safresh1# Since Perl 5.8.1 because otherwise hash ordering is really random. 14eac174f2Safresh1$Data::Dumper::Sortkeys = 1; 15b39c5158Smillert$Data::Dumper::Pad = "#"; 16eac174f2Safresh1 17b39c5158Smillertmy $XS; 18eac174f2Safresh1 19eac174f2Safresh1# Force Data::Dumper::Dump to use perl. We test Dumpxs explicitly by calling 20eac174f2Safresh1# it direct. Out here it lets us knobble the next if to test that the perl 21eac174f2Safresh1# only tests do work (and count correctly) 22eac174f2Safresh1$Data::Dumper::Useperl = 1; 23eac174f2Safresh1if (defined &Data::Dumper::Dumpxs) { 24eac174f2Safresh1 print "### XS extension loaded, will run XS tests\n"; 25eac174f2Safresh1 $XS = 1; 26eac174f2Safresh1} 27eac174f2Safresh1else { 28eac174f2Safresh1 print "### XS extensions not loaded, will NOT run XS tests\n"; 29eac174f2Safresh1 $XS = 0; 30eac174f2Safresh1} 31eac174f2Safresh1 32eac174f2Safresh1our ( @a, $c, $d, $foo, @foo, %foo, @globs, $v, $ping, %ping ); 33eac174f2Safresh1our ( @dogs, %kennel, $mutts ); 34eac174f2Safresh1 35eac174f2Safresh1our ( @numbers, @strings ); 36eac174f2Safresh1our ( @numbers_s, @numbers_i, @numbers_is, @numbers_n, @numbers_ns, @numbers_ni, @numbers_nis ); 37eac174f2Safresh1our ( @strings_s, @strings_i, @strings_is, @strings_n, @strings_ns, @strings_ni, @strings_nis ); 38b39c5158Smillert 39b46d8ef2Safresh1# Perl 5.16 was the first version that correctly handled Unicode in typeglob 40b46d8ef2Safresh1# names. Tests for how globs are dumped must revise their expectations 41b46d8ef2Safresh1# downwards when run on earlier Perls. 42b46d8ef2Safresh1sub change_glob_expectation { 43b46d8ef2Safresh1 my ($input) = @_; 44b46d8ef2Safresh1 if ($] < 5.016) { 45b46d8ef2Safresh1 $input =~ s<\\x\{([0-9a-f]+)\}>{ 46b46d8ef2Safresh1 my $s = chr hex $1; 47b46d8ef2Safresh1 utf8::encode($s); 48b46d8ef2Safresh1 join '', map sprintf('\\%o', ord), split //, $s; 49b46d8ef2Safresh1 }ge; 50b46d8ef2Safresh1 } 51b46d8ef2Safresh1 return $input; 52b46d8ef2Safresh1} 53b46d8ef2Safresh1 54eac174f2Safresh1sub convert_to_native { 55b8851fccSafresh1 my $input = shift; 56b8851fccSafresh1 57b8851fccSafresh1 my @output; 58b8851fccSafresh1 59b8851fccSafresh1 # The input should always be one of the following constructs 60b8851fccSafresh1 while ($input =~ m/ ( \\ [0-7]+ ) 61b8851fccSafresh1 | ( \\ x \{ [[:xdigit:]]+ } ) 62b8851fccSafresh1 | ( \\ . ) 63b8851fccSafresh1 | ( . ) /gx) 64b8851fccSafresh1 { 65b8851fccSafresh1 #print STDERR __LINE__, ": ", $&, "\n"; 66b8851fccSafresh1 my $index; 67b8851fccSafresh1 my $replacement; 68b8851fccSafresh1 if (defined $4) { # Literal 69b8851fccSafresh1 $index = ord $4; 70b8851fccSafresh1 $replacement = $4; 71b8851fccSafresh1 } 72b8851fccSafresh1 elsif (defined $3) { # backslash escape 73b8851fccSafresh1 $index = ord eval "\"$3\""; 74b8851fccSafresh1 $replacement = $3; 75b8851fccSafresh1 } 76b8851fccSafresh1 elsif (defined $2) { # Hex 77b8851fccSafresh1 $index = utf8::unicode_to_native(ord eval "\"$2\""); 78b8851fccSafresh1 79b8851fccSafresh1 # But low hex numbers are always in octal. These are all 80eac174f2Safresh1 # controls. The outlier \c? control is also in octal. 81eac174f2Safresh1 my $format = ($index < ord(" ") || $index == ord("\c?")) 82b8851fccSafresh1 ? "\\%o" 83b8851fccSafresh1 : "\\x{%x}"; 84b8851fccSafresh1 $replacement = sprintf($format, $index); 85b8851fccSafresh1 } 86b8851fccSafresh1 elsif (defined $1) { # Octal 87b8851fccSafresh1 $index = utf8::unicode_to_native(ord eval "\"$1\""); 88b8851fccSafresh1 $replacement = sprintf("\\%o", $index); 89b8851fccSafresh1 } 90b8851fccSafresh1 else { 91b8851fccSafresh1 die "Unexpected match in convert_to_native()"; 92b8851fccSafresh1 } 93b8851fccSafresh1 94b8851fccSafresh1 if (defined $output[$index]) { 95b8851fccSafresh1 print STDERR "ordinal $index already has '$output[$index]'; skipping '$replacement'\n"; 96b8851fccSafresh1 next; 97b8851fccSafresh1 } 98b8851fccSafresh1 99b8851fccSafresh1 $output[$index] = $replacement; 100b8851fccSafresh1 } 101b8851fccSafresh1 102b8851fccSafresh1 return join "", grep { defined } @output; 103b8851fccSafresh1} 104b8851fccSafresh1 105b39c5158Smillertsub TEST { 106eac174f2Safresh1 my ($string, $desc, $want) = @_; 107eac174f2Safresh1 Carp::confess("Tests must have a description") 108eac174f2Safresh1 unless $desc; 109b39c5158Smillert 110eac174f2Safresh1 local $Test::Builder::Level = $Test::Builder::Level + 1; 111eac174f2Safresh1 SKIP: { 112eac174f2Safresh1 my $have = do { 113eac174f2Safresh1 no strict; 114eac174f2Safresh1 eval $string; 115eac174f2Safresh1 }; 116eac174f2Safresh1 my $error = $@; 117b39c5158Smillert 118eac174f2Safresh1 if (defined $error && length $error) { 119eac174f2Safresh1 is($error, "", "$desc set \$@"); 120eac174f2Safresh1 skip('No point in running eval after an error', 2); 121b39c5158Smillert } 122b39c5158Smillert 123eac174f2Safresh1 $have =~ s/([A-Z]+)\(0x[0-9a-f]+\)/$1(0xdeadbeef)/g 124eac174f2Safresh1 if $want =~ /deadbeef/; 125eac174f2Safresh1 is($have, $want, $desc); 126eac174f2Safresh1 127eac174f2Safresh1 { 128eac174f2Safresh1 no strict; 129eac174f2Safresh1 eval "$have"; 130b39c5158Smillert } 131b39c5158Smillert 132eac174f2Safresh1 is($@, "", "$desc - output did not eval") 133eac174f2Safresh1 or skip('No point in restesting if output failed eval'); 134b8851fccSafresh1 135eac174f2Safresh1 $have = do { 136eac174f2Safresh1 no strict; 137eac174f2Safresh1 eval $string; 138eac174f2Safresh1 }; 139eac174f2Safresh1 $error = $@; 140eac174f2Safresh1 141eac174f2Safresh1 if (defined $error && length $error) { 142eac174f2Safresh1 is($error, "", "$desc after eval set \$@"); 143b39c5158Smillert } 144b39c5158Smillert else { 145eac174f2Safresh1 $have =~ s/([A-Z]+)\(0x[0-9a-f]+\)/$1(0xdeadbeef)/g 146eac174f2Safresh1 if $want =~ /deadbeef/; 147eac174f2Safresh1 is($have, $want, "$desc after eval"); 148eac174f2Safresh1 } 149eac174f2Safresh1 } 150b39c5158Smillert} 151b39c5158Smillert 152eac174f2Safresh1sub SKIP_BOTH { 153eac174f2Safresh1 my $reason = shift; 154eac174f2Safresh1 SKIP: { 155eac174f2Safresh1 skip($reason, $XS ? 6 : 3); 156eac174f2Safresh1 } 157eac174f2Safresh1} 158b39c5158Smillert 159eac174f2Safresh1# It's more reliable to match (and substitute) on 'Dumpxs' than 'Dump' 160eac174f2Safresh1# (the latter is a substring of many things), but as historically we've tested 161eac174f2Safresh1# "pure perl" then "XS" it seems better to have $want_xs as an optional 162eac174f2Safresh1# parameter. 163eac174f2Safresh1sub TEST_BOTH { 164eac174f2Safresh1 my ($testcase, $desc, $want, $want_xs, $skip_xs) = @_; 165eac174f2Safresh1 $want_xs = $want 166eac174f2Safresh1 unless defined $want_xs; 167eac174f2Safresh1 my $desc_pp = $desc; 168eac174f2Safresh1 my $testcase_pp = $testcase; 169eac174f2Safresh1 Carp::confess("Testcase must contain ->Dumpxs or DumperX") 170eac174f2Safresh1 unless $testcase_pp =~ s/->Dumpxs\b/->Dump/g 171eac174f2Safresh1 || $testcase_pp =~ s/\bDumperX\b/Dumper/g; 172eac174f2Safresh1 unless ($desc_pp =~ s/Dumpxs/Dump/ || $desc_pp =~ s/\bDumperX\b/Dumper/) { 173eac174f2Safresh1 $desc .= ', XS'; 174eac174f2Safresh1 } 175eac174f2Safresh1 176eac174f2Safresh1 local $Test::Builder::Level = $Test::Builder::Level + 1; 177eac174f2Safresh1 TEST($testcase_pp, $desc_pp, $want); 178eac174f2Safresh1 return 179eac174f2Safresh1 unless $XS; 180eac174f2Safresh1 if ($skip_xs) { 181eac174f2Safresh1 SKIP: { 182eac174f2Safresh1 skip($skip_xs, 3); 183eac174f2Safresh1 } 184eac174f2Safresh1 } 185eac174f2Safresh1 else { 186eac174f2Safresh1 TEST($testcase, $desc, $want_xs); 187eac174f2Safresh1 } 188eac174f2Safresh1} 189eac174f2Safresh1 190eac174f2Safresh1 191b39c5158Smillert############# 192b39c5158Smillert 193eac174f2Safresh1my @c = ('c'); 194b39c5158Smillert$c = \@c; 195eac174f2Safresh1$b = {}; # FIXME - use another variable name 196eac174f2Safresh1$a = [1, $b, $c]; # FIXME - use another variable name 197b39c5158Smillert$b->{a} = $a; 198b39c5158Smillert$b->{b} = $a->[1]; 199b39c5158Smillert$b->{c} = $a->[2]; 200b39c5158Smillert 201b8851fccSafresh1############# 202b39c5158Smillert## 203eac174f2Safresh1my $want = <<'EOT'; 204b39c5158Smillert#$a = [ 205b39c5158Smillert# 1, 206b39c5158Smillert# { 207b39c5158Smillert# 'a' => $a, 208b39c5158Smillert# 'b' => $a->[1], 209b39c5158Smillert# 'c' => [ 210b39c5158Smillert# 'c' 211b39c5158Smillert# ] 212b39c5158Smillert# }, 213b39c5158Smillert# $a->[1]{'c'} 214b39c5158Smillert# ]; 215b39c5158Smillert#$b = $a->[1]; 216b39c5158Smillert#$6 = $a->[1]{'c'}; 217b39c5158SmillertEOT 218b39c5158Smillert 219eac174f2Safresh1TEST_BOTH(q(Data::Dumper->Dumpxs([$a,$b,$c], [qw(a b), 6])), 220eac174f2Safresh1 'basic test with names: Dumpxs()', 221eac174f2Safresh1 $want); 222b39c5158Smillert 22391f110e0Safresh1SCOPE: { 22491f110e0Safresh1 local $Data::Dumper::Sparseseen = 1; 225eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([$a,$b,$c], [qw(a b), 6])), 226eac174f2Safresh1 'Sparseseen with names: Dumpxs()', 227eac174f2Safresh1 $want); 22891f110e0Safresh1} 229b39c5158Smillert 230b8851fccSafresh1############# 231b39c5158Smillert## 232eac174f2Safresh1$want = <<'EOT'; 233b39c5158Smillert#@a = ( 234b39c5158Smillert# 1, 235b39c5158Smillert# { 236b39c5158Smillert# 'a' => [], 237b39c5158Smillert# 'b' => {}, 238b39c5158Smillert# 'c' => [ 239b39c5158Smillert# 'c' 240b39c5158Smillert# ] 241b39c5158Smillert# }, 242b39c5158Smillert# [] 243b39c5158Smillert# ); 244b39c5158Smillert#$a[1]{'a'} = \@a; 245b39c5158Smillert#$a[1]{'b'} = $a[1]; 246b39c5158Smillert#$a[2] = $a[1]{'c'}; 247b39c5158Smillert#$b = $a[1]; 248b39c5158SmillertEOT 249b39c5158Smillert 250b39c5158Smillert$Data::Dumper::Purity = 1; # fill in the holes for eval 251eac174f2Safresh1TEST_BOTH(q(Data::Dumper->Dumpxs([$a, $b], [qw(*a b)])), 252eac174f2Safresh1 'Purity: basic test with dereferenced array: Dumpxs()', 253eac174f2Safresh1 $want); 254b39c5158Smillert 25591f110e0Safresh1SCOPE: { 25691f110e0Safresh1 local $Data::Dumper::Sparseseen = 1; 257eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([$a, $b], [qw(*a b)])), 258eac174f2Safresh1 'Purity: Sparseseen with dereferenced array: Dumpxs()', 259eac174f2Safresh1 $want); 26091f110e0Safresh1} 26191f110e0Safresh1 262b8851fccSafresh1############# 263b39c5158Smillert## 264eac174f2Safresh1$want = <<'EOT'; 265b39c5158Smillert#%b = ( 266b39c5158Smillert# 'a' => [ 267b39c5158Smillert# 1, 268b39c5158Smillert# {}, 269b39c5158Smillert# [ 270b39c5158Smillert# 'c' 271b39c5158Smillert# ] 272b39c5158Smillert# ], 273b39c5158Smillert# 'b' => {}, 274b39c5158Smillert# 'c' => [] 275b39c5158Smillert# ); 276b39c5158Smillert#$b{'a'}[1] = \%b; 277b39c5158Smillert#$b{'b'} = \%b; 278b39c5158Smillert#$b{'c'} = $b{'a'}[2]; 279b39c5158Smillert#$a = $b{'a'}; 280b39c5158SmillertEOT 281b39c5158Smillert 282eac174f2Safresh1TEST_BOTH(q(Data::Dumper->Dumpxs([$b, $a], [qw(*b a)])), 283eac174f2Safresh1 'basic test with dereferenced hash: Dumpxs()', 284eac174f2Safresh1 $want); 285b39c5158Smillert 286b8851fccSafresh1############# 287b39c5158Smillert## 288eac174f2Safresh1$want = <<'EOT'; 289b39c5158Smillert#$a = [ 290b39c5158Smillert# 1, 291b39c5158Smillert# { 292b39c5158Smillert# 'a' => [], 293b39c5158Smillert# 'b' => {}, 294b39c5158Smillert# 'c' => [] 295b39c5158Smillert# }, 296b39c5158Smillert# [] 297b39c5158Smillert#]; 298b39c5158Smillert#$a->[1]{'a'} = $a; 299b39c5158Smillert#$a->[1]{'b'} = $a->[1]; 300b39c5158Smillert#$a->[1]{'c'} = \@c; 301b39c5158Smillert#$a->[2] = \@c; 302b39c5158Smillert#$b = $a->[1]; 303b39c5158SmillertEOT 304b39c5158Smillert 305b39c5158Smillert$Data::Dumper::Indent = 1; 306eac174f2Safresh1TEST_BOTH(q{ 307b39c5158Smillert $d = Data::Dumper->new([$a,$b], [qw(a b)]); 308b39c5158Smillert $d->Seen({'*c' => $c}); 309b39c5158Smillert $d->Dumpxs; 310eac174f2Safresh1 }, 'Indent: Seen: Dumpxs()', 311eac174f2Safresh1 $want); 312b39c5158Smillert 313b8851fccSafresh1############# 314b39c5158Smillert## 315eac174f2Safresh1$want = <<'EOT'; 316b39c5158Smillert#$a = [ 317b39c5158Smillert# #0 318b39c5158Smillert# 1, 319b39c5158Smillert# #1 320b39c5158Smillert# { 321b39c5158Smillert# a => $a, 322b39c5158Smillert# b => $a->[1], 323b39c5158Smillert# c => [ 324b39c5158Smillert# #0 325b39c5158Smillert# 'c' 326b39c5158Smillert# ] 327b39c5158Smillert# }, 328b39c5158Smillert# #2 329b39c5158Smillert# $a->[1]{c} 330b39c5158Smillert# ]; 331b39c5158Smillert#$b = $a->[1]; 332b39c5158SmillertEOT 333b39c5158Smillert 334b39c5158Smillert$d->Indent(3); 335b39c5158Smillert$d->Purity(0)->Quotekeys(0); 336eac174f2Safresh1TEST_BOTH(q( $d->Reset; $d->Dumpxs ), 337eac174f2Safresh1 'Indent(3): Purity(0)->Quotekeys(0): Dumpxs()', 338eac174f2Safresh1 $want); 339b39c5158Smillert 340b8851fccSafresh1############# 341b39c5158Smillert## 342eac174f2Safresh1$want = <<'EOT'; 343b39c5158Smillert#$VAR1 = [ 344b39c5158Smillert# 1, 345b39c5158Smillert# { 346b39c5158Smillert# 'a' => [], 347b39c5158Smillert# 'b' => {}, 348b39c5158Smillert# 'c' => [ 349b39c5158Smillert# 'c' 350b39c5158Smillert# ] 351b39c5158Smillert# }, 352b39c5158Smillert# [] 353b39c5158Smillert#]; 354b39c5158Smillert#$VAR1->[1]{'a'} = $VAR1; 355b39c5158Smillert#$VAR1->[1]{'b'} = $VAR1->[1]; 356b39c5158Smillert#$VAR1->[2] = $VAR1->[1]{'c'}; 357b39c5158SmillertEOT 358b39c5158Smillert 359eac174f2Safresh1TEST_BOTH(q(Data::Dumper::DumperX($a)), 360eac174f2Safresh1 'DumperX', 361eac174f2Safresh1 $want); 362b39c5158Smillert 363b8851fccSafresh1############# 364b39c5158Smillert## 365eac174f2Safresh1$want = <<'EOT'; 366b39c5158Smillert#[ 367b39c5158Smillert# 1, 368b39c5158Smillert# { 369b39c5158Smillert# a => $VAR1, 370b39c5158Smillert# b => $VAR1->[1], 371b39c5158Smillert# c => [ 372b39c5158Smillert# 'c' 373b39c5158Smillert# ] 374b39c5158Smillert# }, 375b39c5158Smillert# $VAR1->[1]{c} 376b39c5158Smillert#] 377b39c5158SmillertEOT 378b39c5158Smillert 379b39c5158Smillert{ 380b39c5158Smillert local $Data::Dumper::Purity = 0; 381b39c5158Smillert local $Data::Dumper::Quotekeys = 0; 382b39c5158Smillert local $Data::Dumper::Terse = 1; 383eac174f2Safresh1 TEST_BOTH(q(Data::Dumper::DumperX($a)), 384eac174f2Safresh1 'Purity 0: Quotekeys 0: Terse 1: DumperX', 385eac174f2Safresh1 $want); 386b39c5158Smillert} 387b39c5158Smillert 388b8851fccSafresh1############# 389b39c5158Smillert## 390eac174f2Safresh1$want = <<'EOT'; 391b39c5158Smillert#$VAR1 = { 392b39c5158Smillert# "abc\0'\efg" => "mno\0", 393b39c5158Smillert# "reftest" => \\1 394b39c5158Smillert#}; 395b39c5158SmillertEOT 396b39c5158Smillert 397b39c5158Smillert$foo = { "abc\000\'\efg" => "mno\000", 398b39c5158Smillert "reftest" => \\1, 399b39c5158Smillert }; 400b39c5158Smillert{ 401b39c5158Smillert local $Data::Dumper::Useqq = 1; 402eac174f2Safresh1 TEST_BOTH(q(Data::Dumper::DumperX($foo)), 403eac174f2Safresh1 'Useqq: DumperX', 404eac174f2Safresh1 $want); 405b39c5158Smillert} 406b39c5158Smillert 407b39c5158Smillert############# 408b39c5158Smillert############# 409b39c5158Smillert 410b39c5158Smillert{ 411b39c5158Smillert package main; 412b39c5158Smillert use Data::Dumper; 413b39c5158Smillert $foo = 5; 414b39c5158Smillert @foo = (-10,\*foo); 415b39c5158Smillert %foo = (a=>1,b=>\$foo,c=>\@foo); 416b39c5158Smillert $foo{d} = \%foo; 417b39c5158Smillert $foo[2] = \%foo; 418b39c5158Smillert 419b8851fccSafresh1############# 420b39c5158Smillert## 421eac174f2Safresh1 my $want = <<'EOT'; 422b39c5158Smillert#$foo = \*::foo; 423b39c5158Smillert#*::foo = \5; 424b39c5158Smillert#*::foo = [ 425b39c5158Smillert# #0 426b39c5158Smillert# -10, 427b39c5158Smillert# #1 428b39c5158Smillert# do{my $o}, 429b39c5158Smillert# #2 430b39c5158Smillert# { 431b39c5158Smillert# 'a' => 1, 432b39c5158Smillert# 'b' => do{my $o}, 433b39c5158Smillert# 'c' => [], 434b39c5158Smillert# 'd' => {} 435b39c5158Smillert# } 436b39c5158Smillert# ]; 437b39c5158Smillert#*::foo{ARRAY}->[1] = $foo; 438b39c5158Smillert#*::foo{ARRAY}->[2]{'b'} = *::foo{SCALAR}; 439b39c5158Smillert#*::foo{ARRAY}->[2]{'c'} = *::foo{ARRAY}; 440b39c5158Smillert#*::foo{ARRAY}->[2]{'d'} = *::foo{ARRAY}->[2]; 441b39c5158Smillert#*::foo = *::foo{ARRAY}->[2]; 442b39c5158Smillert#@bar = @{*::foo{ARRAY}}; 443b39c5158Smillert#%baz = %{*::foo{ARRAY}->[2]}; 444b39c5158SmillertEOT 445b39c5158Smillert 446b39c5158Smillert $Data::Dumper::Purity = 1; 447b39c5158Smillert $Data::Dumper::Indent = 3; 448eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([\\*foo, \\@foo, \\%foo], ['*foo', '*bar', '*baz'])), 449eac174f2Safresh1 'Purity 1: Indent 3: Dumpxs()', 450eac174f2Safresh1 $want); 451b39c5158Smillert 452b8851fccSafresh1############# 453b39c5158Smillert## 454eac174f2Safresh1 $want = <<'EOT'; 455b39c5158Smillert#$foo = \*::foo; 456b39c5158Smillert#*::foo = \5; 457b39c5158Smillert#*::foo = [ 458b39c5158Smillert# -10, 459b39c5158Smillert# do{my $o}, 460b39c5158Smillert# { 461b39c5158Smillert# 'a' => 1, 462b39c5158Smillert# 'b' => do{my $o}, 463b39c5158Smillert# 'c' => [], 464b39c5158Smillert# 'd' => {} 465b39c5158Smillert# } 466b39c5158Smillert#]; 467b39c5158Smillert#*::foo{ARRAY}->[1] = $foo; 468b39c5158Smillert#*::foo{ARRAY}->[2]{'b'} = *::foo{SCALAR}; 469b39c5158Smillert#*::foo{ARRAY}->[2]{'c'} = *::foo{ARRAY}; 470b39c5158Smillert#*::foo{ARRAY}->[2]{'d'} = *::foo{ARRAY}->[2]; 471b39c5158Smillert#*::foo = *::foo{ARRAY}->[2]; 472b39c5158Smillert#$bar = *::foo{ARRAY}; 473b39c5158Smillert#$baz = *::foo{ARRAY}->[2]; 474b39c5158SmillertEOT 475b39c5158Smillert 476b39c5158Smillert $Data::Dumper::Indent = 1; 477eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([\\*foo, \\@foo, \\%foo], ['foo', 'bar', 'baz'])), 478eac174f2Safresh1 'Purity 1: Indent 1: Dumpxs()', 479eac174f2Safresh1 $want); 480b39c5158Smillert 481b8851fccSafresh1############# 482b39c5158Smillert## 483eac174f2Safresh1 $want = <<'EOT'; 484b39c5158Smillert#@bar = ( 485b39c5158Smillert# -10, 486b39c5158Smillert# \*::foo, 487b39c5158Smillert# {} 488b39c5158Smillert#); 489b39c5158Smillert#*::foo = \5; 490b39c5158Smillert#*::foo = \@bar; 491b39c5158Smillert#*::foo = { 492b39c5158Smillert# 'a' => 1, 493b39c5158Smillert# 'b' => do{my $o}, 494b39c5158Smillert# 'c' => [], 495b39c5158Smillert# 'd' => {} 496b39c5158Smillert#}; 497b39c5158Smillert#*::foo{HASH}->{'b'} = *::foo{SCALAR}; 498b39c5158Smillert#*::foo{HASH}->{'c'} = \@bar; 499b39c5158Smillert#*::foo{HASH}->{'d'} = *::foo{HASH}; 500b39c5158Smillert#$bar[2] = *::foo{HASH}; 501b39c5158Smillert#%baz = %{*::foo{HASH}}; 502b39c5158Smillert#$foo = $bar[1]; 503b39c5158SmillertEOT 504b39c5158Smillert 505eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([\\@foo, \\%foo, \\*foo], ['*bar', '*baz', '*foo'])), 506eac174f2Safresh1 'array|hash|glob dereferenced: Dumpxs()', 507eac174f2Safresh1 $want); 508b39c5158Smillert 509b8851fccSafresh1############# 510b39c5158Smillert## 511eac174f2Safresh1 $want = <<'EOT'; 512b39c5158Smillert#$bar = [ 513b39c5158Smillert# -10, 514b39c5158Smillert# \*::foo, 515b39c5158Smillert# {} 516b39c5158Smillert#]; 517b39c5158Smillert#*::foo = \5; 518b39c5158Smillert#*::foo = $bar; 519b39c5158Smillert#*::foo = { 520b39c5158Smillert# 'a' => 1, 521b39c5158Smillert# 'b' => do{my $o}, 522b39c5158Smillert# 'c' => [], 523b39c5158Smillert# 'd' => {} 524b39c5158Smillert#}; 525b39c5158Smillert#*::foo{HASH}->{'b'} = *::foo{SCALAR}; 526b39c5158Smillert#*::foo{HASH}->{'c'} = $bar; 527b39c5158Smillert#*::foo{HASH}->{'d'} = *::foo{HASH}; 528b39c5158Smillert#$bar->[2] = *::foo{HASH}; 529b39c5158Smillert#$baz = *::foo{HASH}; 530b39c5158Smillert#$foo = $bar->[1]; 531b39c5158SmillertEOT 532b39c5158Smillert 533eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([\\@foo, \\%foo, \\*foo], ['bar', 'baz', 'foo'])), 534eac174f2Safresh1 'array|hash|glob: not dereferenced: Dumpxs()', 535eac174f2Safresh1 $want); 536b39c5158Smillert 537b8851fccSafresh1############# 538b39c5158Smillert## 539eac174f2Safresh1 $want = <<'EOT'; 540b39c5158Smillert#$foo = \*::foo; 541b39c5158Smillert#@bar = ( 542b39c5158Smillert# -10, 543b39c5158Smillert# $foo, 544b39c5158Smillert# { 545b39c5158Smillert# a => 1, 546b39c5158Smillert# b => \5, 547b39c5158Smillert# c => \@bar, 548b39c5158Smillert# d => $bar[2] 549b39c5158Smillert# } 550b39c5158Smillert#); 551b39c5158Smillert#%baz = %{$bar[2]}; 552b39c5158SmillertEOT 553b39c5158Smillert 554b39c5158Smillert $Data::Dumper::Purity = 0; 555b39c5158Smillert $Data::Dumper::Quotekeys = 0; 556eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([\\*foo, \\@foo, \\%foo], ['*foo', '*bar', '*baz'])), 557eac174f2Safresh1 'Purity 0: Quotekeys 0: dereferenced: Dumpxs', 558eac174f2Safresh1 $want); 559b39c5158Smillert 560b8851fccSafresh1############# 561b39c5158Smillert## 562eac174f2Safresh1 $want = <<'EOT'; 563b39c5158Smillert#$foo = \*::foo; 564b39c5158Smillert#$bar = [ 565b39c5158Smillert# -10, 566b39c5158Smillert# $foo, 567b39c5158Smillert# { 568b39c5158Smillert# a => 1, 569b39c5158Smillert# b => \5, 570b39c5158Smillert# c => $bar, 571b39c5158Smillert# d => $bar->[2] 572b39c5158Smillert# } 573b39c5158Smillert#]; 574b39c5158Smillert#$baz = $bar->[2]; 575b39c5158SmillertEOT 576b39c5158Smillert 577eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([\\*foo, \\@foo, \\%foo], ['foo', 'bar', 'baz'])), 578eac174f2Safresh1 'Purity 0: Quotekeys 0: not dereferenced: Dumpxs()', 579eac174f2Safresh1 $want); 580b39c5158Smillert} 581b39c5158Smillert 582b39c5158Smillert############# 583b39c5158Smillert############# 584eac174f2Safresh1 585b39c5158Smillert{ 586b39c5158Smillert package main; 587b39c5158Smillert @dogs = ( 'Fido', 'Wags' ); 588b39c5158Smillert %kennel = ( 589b39c5158Smillert First => \$dogs[0], 590b39c5158Smillert Second => \$dogs[1], 591b39c5158Smillert ); 592b39c5158Smillert $dogs[2] = \%kennel; 593b39c5158Smillert $mutts = \%kennel; 594b39c5158Smillert $mutts = $mutts; # avoid warning 595b39c5158Smillert 596b8851fccSafresh1############# 597b39c5158Smillert## 598eac174f2Safresh1 my $want = <<'EOT'; 599b39c5158Smillert#%kennels = ( 600b39c5158Smillert# First => \'Fido', 601b39c5158Smillert# Second => \'Wags' 602b39c5158Smillert#); 603b39c5158Smillert#@dogs = ( 604b39c5158Smillert# ${$kennels{First}}, 605b39c5158Smillert# ${$kennels{Second}}, 606b39c5158Smillert# \%kennels 607b39c5158Smillert#); 608b39c5158Smillert#%mutts = %kennels; 609b39c5158SmillertEOT 610b39c5158Smillert 611eac174f2Safresh1 TEST_BOTH(q{ 612b39c5158Smillert $d = Data::Dumper->new([\\%kennel, \\@dogs, $mutts], 613b39c5158Smillert [qw(*kennels *dogs *mutts)] ); 614b39c5158Smillert $d->Dumpxs; 615eac174f2Safresh1 }, 'constructor: hash|array|scalar: Dumpxs()', 616eac174f2Safresh1 $want); 617b39c5158Smillert 618b8851fccSafresh1############# 619b39c5158Smillert## 620eac174f2Safresh1 $want = <<'EOT'; 621b39c5158Smillert#%kennels = %kennels; 622b39c5158Smillert#@dogs = @dogs; 623b39c5158Smillert#%mutts = %kennels; 624b39c5158SmillertEOT 625b39c5158Smillert 626eac174f2Safresh1 TEST_BOTH(q($d->Dumpxs), 627eac174f2Safresh1 'object call: Dumpxs', 628eac174f2Safresh1 $want); 629b39c5158Smillert 630b8851fccSafresh1############# 631b39c5158Smillert## 632eac174f2Safresh1 $want = <<'EOT'; 633b39c5158Smillert#%kennels = ( 634b39c5158Smillert# First => \'Fido', 635b39c5158Smillert# Second => \'Wags' 636b39c5158Smillert#); 637b39c5158Smillert#@dogs = ( 638b39c5158Smillert# ${$kennels{First}}, 639b39c5158Smillert# ${$kennels{Second}}, 640b39c5158Smillert# \%kennels 641b39c5158Smillert#); 642b39c5158Smillert#%mutts = %kennels; 643b39c5158SmillertEOT 644b39c5158Smillert 645eac174f2Safresh1 TEST_BOTH(q($d->Reset; $d->Dumpxs), 646eac174f2Safresh1 'Reset and Dumpxs separate calls', 647eac174f2Safresh1 $want); 648b39c5158Smillert 649b8851fccSafresh1############# 650b39c5158Smillert## 651eac174f2Safresh1 $want = <<'EOT'; 652b39c5158Smillert#@dogs = ( 653b39c5158Smillert# 'Fido', 654b39c5158Smillert# 'Wags', 655b39c5158Smillert# { 656b39c5158Smillert# First => \$dogs[0], 657b39c5158Smillert# Second => \$dogs[1] 658b39c5158Smillert# } 659b39c5158Smillert#); 660b39c5158Smillert#%kennels = %{$dogs[2]}; 661b39c5158Smillert#%mutts = %{$dogs[2]}; 662b39c5158SmillertEOT 663b39c5158Smillert 664eac174f2Safresh1 TEST_BOTH(q{ 665b39c5158Smillert $d = Data::Dumper->new([\\@dogs, \\%kennel, $mutts], 666b39c5158Smillert [qw(*dogs *kennels *mutts)] ); 667b39c5158Smillert $d->Dumpxs; 668eac174f2Safresh1 }, 'constructor: array|hash|scalar: Dumpxs()', 669eac174f2Safresh1 $want); 670b39c5158Smillert 671b8851fccSafresh1############# 672b39c5158Smillert## 673eac174f2Safresh1 TEST_BOTH(q($d->Reset->Dumpxs), 674eac174f2Safresh1 'Reset Dumpxs chained', 675eac174f2Safresh1 $want); 676b39c5158Smillert 677b8851fccSafresh1############# 678b39c5158Smillert## 679eac174f2Safresh1 $want = <<'EOT'; 680b39c5158Smillert#@dogs = ( 681b39c5158Smillert# 'Fido', 682b39c5158Smillert# 'Wags', 683b39c5158Smillert# { 684b39c5158Smillert# First => \'Fido', 685b39c5158Smillert# Second => \'Wags' 686b39c5158Smillert# } 687b39c5158Smillert#); 688b39c5158Smillert#%kennels = ( 689b39c5158Smillert# First => \'Fido', 690b39c5158Smillert# Second => \'Wags' 691b39c5158Smillert#); 692b39c5158SmillertEOT 693b39c5158Smillert 694eac174f2Safresh1 TEST_BOTH(q{ 6956fb12b70Safresh1 $d = Data::Dumper->new( [\@dogs, \%kennel], [qw(*dogs *kennels)] ); 6966fb12b70Safresh1 $d->Deepcopy(1)->Dumpxs; 697eac174f2Safresh1 }, 'Deepcopy(1): Dumpxs', 698eac174f2Safresh1 $want); 699b39c5158Smillert} 700b39c5158Smillert 701b39c5158Smillert{ 702b39c5158Smillert 703b39c5158Smillertsub z { print "foo\n" } 704b39c5158Smillert$c = [ \&z ]; 705b39c5158Smillert 706b8851fccSafresh1############# 707b39c5158Smillert## 708eac174f2Safresh1 my $want = <<'EOT'; 709b39c5158Smillert#$a = $b; 710b39c5158Smillert#$c = [ 711b39c5158Smillert# $b 712b39c5158Smillert#]; 713b39c5158SmillertEOT 714b39c5158Smillert 715eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new([\&z,$c],['a','c'])->Seen({'b' => \&z})->Dumpxs;), 716eac174f2Safresh1 'Seen: scalar: Dumpxs', 717eac174f2Safresh1 $want); 718b39c5158Smillert 719b8851fccSafresh1############# 720b39c5158Smillert## 721eac174f2Safresh1 $want = <<'EOT'; 722b39c5158Smillert#$a = \&b; 723b39c5158Smillert#$c = [ 724b39c5158Smillert# \&b 725b39c5158Smillert#]; 726b39c5158SmillertEOT 727b39c5158Smillert 728eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new([\&z,$c],['a','c'])->Seen({'*b' => \&z})->Dumpxs;), 729eac174f2Safresh1 'Seen: glob: Dumpxs', 730eac174f2Safresh1 $want); 731b39c5158Smillert 732b8851fccSafresh1############# 733b39c5158Smillert## 734eac174f2Safresh1 $want = <<'EOT'; 735b39c5158Smillert#*a = \&b; 736b39c5158Smillert#@c = ( 737b39c5158Smillert# \&b 738b39c5158Smillert#); 739b39c5158SmillertEOT 740b39c5158Smillert 741eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new([\&z,$c],['*a','*c'])->Seen({'*b' => \&z})->Dumpxs;), 742eac174f2Safresh1 'Seen: glob: derference: Dumpxs', 743eac174f2Safresh1 $want); 744b39c5158Smillert} 745b39c5158Smillert 746b39c5158Smillert{ 747b39c5158Smillert $a = []; 748b39c5158Smillert $a->[1] = \$a->[0]; 749b39c5158Smillert 750b8851fccSafresh1############# 751b39c5158Smillert## 752eac174f2Safresh1 my $want = <<'EOT'; 753b39c5158Smillert#@a = ( 754b39c5158Smillert# undef, 755b39c5158Smillert# do{my $o} 756b39c5158Smillert#); 757b39c5158Smillert#$a[1] = \$a[0]; 758b39c5158SmillertEOT 759b39c5158Smillert 760eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new([$a],['*a'])->Purity(1)->Dumpxs;), 761eac174f2Safresh1 'Purity(1): dereference: Dumpxs', 762eac174f2Safresh1 $want); 763b39c5158Smillert} 764b39c5158Smillert 765b39c5158Smillert{ 766b39c5158Smillert $a = \\\\\'foo'; 767b39c5158Smillert $b = $$$a; 768b39c5158Smillert 769b8851fccSafresh1############# 770b39c5158Smillert## 771eac174f2Safresh1 my $want = <<'EOT'; 772b39c5158Smillert#$a = \\\\\'foo'; 773b39c5158Smillert#$b = ${${$a}}; 774b39c5158SmillertEOT 775b39c5158Smillert 776eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new([$a,$b],['a','b'])->Purity(1)->Dumpxs;), 777eac174f2Safresh1 'Purity(1): not dereferenced: Dumpxs', 778eac174f2Safresh1 $want); 779b39c5158Smillert} 780b39c5158Smillert 781b39c5158Smillert{ 782b39c5158Smillert $a = [{ a => \$b }, { b => undef }]; 783b39c5158Smillert $b = [{ c => \$b }, { d => \$a }]; 784b39c5158Smillert 785b8851fccSafresh1############# 786b39c5158Smillert## 787eac174f2Safresh1 my $want = <<'EOT'; 788b39c5158Smillert#$a = [ 789b39c5158Smillert# { 790b39c5158Smillert# a => \[ 791b39c5158Smillert# { 792b39c5158Smillert# c => do{my $o} 793b39c5158Smillert# }, 794b39c5158Smillert# { 795b39c5158Smillert# d => \[] 796b39c5158Smillert# } 797b39c5158Smillert# ] 798b39c5158Smillert# }, 799b39c5158Smillert# { 800b39c5158Smillert# b => undef 801b39c5158Smillert# } 802b39c5158Smillert#]; 803b39c5158Smillert#${$a->[0]{a}}->[0]->{c} = $a->[0]{a}; 804b39c5158Smillert#${${$a->[0]{a}}->[1]->{d}} = $a; 805b39c5158Smillert#$b = ${$a->[0]{a}}; 806b39c5158SmillertEOT 807b39c5158Smillert 808eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new([$a,$b],['a','b'])->Purity(1)->Dumpxs;), 809eac174f2Safresh1 'Purity(1); Dumpxs again', 810eac174f2Safresh1 $want); 811b39c5158Smillert} 812b39c5158Smillert 813b39c5158Smillert{ 814b39c5158Smillert $a = [[[[\\\\\'foo']]]]; 815b39c5158Smillert $b = $a->[0][0]; 816b39c5158Smillert $c = $${$b->[0][0]}; 817b39c5158Smillert 818b8851fccSafresh1############# 819b39c5158Smillert## 820eac174f2Safresh1 my $want = <<'EOT'; 821b39c5158Smillert#$a = [ 822b39c5158Smillert# [ 823b39c5158Smillert# [ 824b39c5158Smillert# [ 825b39c5158Smillert# \\\\\'foo' 826b39c5158Smillert# ] 827b39c5158Smillert# ] 828b39c5158Smillert# ] 829b39c5158Smillert#]; 830b39c5158Smillert#$b = $a->[0][0]; 831b39c5158Smillert#$c = ${${$a->[0][0][0][0]}}; 832b39c5158SmillertEOT 833b39c5158Smillert 834eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new([$a,$b,$c],['a','b','c'])->Purity(1)->Dumpxs;), 835eac174f2Safresh1 'Purity(1): Dumpxs: 3 elements', 836eac174f2Safresh1 $want); 837b39c5158Smillert} 838b39c5158Smillert 839b39c5158Smillert{ 840eac174f2Safresh1 my $f = "pearl"; 841eac174f2Safresh1 my $e = [ $f ]; 842b39c5158Smillert $d = { 'e' => $e }; 843b39c5158Smillert $c = [ $d ]; 844eac174f2Safresh1 $b = { 'c' => $c }; # FIXME use different variable name 845eac174f2Safresh1 $a = { 'b' => $b }; # FIXME use different variable name 846b39c5158Smillert 847b8851fccSafresh1############# 848b39c5158Smillert## 849eac174f2Safresh1 my $want = <<'EOT'; 850b39c5158Smillert#$a = { 851b39c5158Smillert# b => { 852b39c5158Smillert# c => [ 853b39c5158Smillert# { 854b39c5158Smillert# e => 'ARRAY(0xdeadbeef)' 855b39c5158Smillert# } 856b39c5158Smillert# ] 857b39c5158Smillert# } 858b39c5158Smillert#}; 859b39c5158Smillert#$b = $a->{b}; 860b39c5158Smillert#$c = $a->{b}{c}; 861b39c5158SmillertEOT 862b39c5158Smillert 863eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new([$a,$b,$c],['a','b','c'])->Maxdepth(4)->Dumpxs;), 864eac174f2Safresh1 'Maxdepth(4): Dumpxs()', 865eac174f2Safresh1 $want); 866b39c5158Smillert 867b8851fccSafresh1############# 868b39c5158Smillert## 869eac174f2Safresh1 $want = <<'EOT'; 870b39c5158Smillert#$a = { 871b39c5158Smillert# b => 'HASH(0xdeadbeef)' 872b39c5158Smillert#}; 873b39c5158Smillert#$b = $a->{b}; 874b39c5158Smillert#$c = [ 875b39c5158Smillert# 'HASH(0xdeadbeef)' 876b39c5158Smillert#]; 877b39c5158SmillertEOT 878b39c5158Smillert 879eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new([$a,$b,$c],['a','b','c'])->Maxdepth(1)->Dumpxs;), 880eac174f2Safresh1 'Maxdepth(1): Dumpxs()', 881eac174f2Safresh1 $want); 882b39c5158Smillert} 883b39c5158Smillert 884b39c5158Smillert{ 885b39c5158Smillert $a = \$a; 886b39c5158Smillert $b = [$a]; 887b39c5158Smillert 888b8851fccSafresh1############# 889b39c5158Smillert## 890eac174f2Safresh1 my $want = <<'EOT'; 891b39c5158Smillert#$b = [ 892b39c5158Smillert# \$b->[0] 893b39c5158Smillert#]; 894b39c5158SmillertEOT 895b39c5158Smillert 896eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new([$b],['b'])->Purity(0)->Dumpxs;), 897eac174f2Safresh1 'Purity(0): Dumpxs()', 898eac174f2Safresh1 $want); 899b39c5158Smillert 900b8851fccSafresh1############# 901b39c5158Smillert## 902eac174f2Safresh1 $want = <<'EOT'; 903b39c5158Smillert#$b = [ 904b39c5158Smillert# \do{my $o} 905b39c5158Smillert#]; 906b39c5158Smillert#${$b->[0]} = $b->[0]; 907b39c5158SmillertEOT 908b39c5158Smillert 909eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new([$b],['b'])->Purity(1)->Dumpxs;), 910eac174f2Safresh1 'Purity(1): Dumpxs', 911eac174f2Safresh1 $want); 912b39c5158Smillert} 913b39c5158Smillert 914b39c5158Smillert{ 915b39c5158Smillert $a = "\x{09c10}"; 916b8851fccSafresh1############# 917b39c5158Smillert## XS code was adding an extra \0 918eac174f2Safresh1 my $want = <<'EOT'; 919b39c5158Smillert#$a = "\x{9c10}"; 920b39c5158SmillertEOT 921b39c5158Smillert 922eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([$a], ['a'])), 923eac174f2Safresh1 "\\x{9c10}", 924eac174f2Safresh1 $want); 925b39c5158Smillert} 926b39c5158Smillert 927b39c5158Smillert{ 928eac174f2Safresh1 my $i = 0; 929eac174f2Safresh1 $a = { map { ("$_$_$_", ++$i) } 'I'..'Q' }; # FIXME use different variable name 930b39c5158Smillert 931b8851fccSafresh1############# 932b39c5158Smillert## 933eac174f2Safresh1 my $want = <<'EOT'; 934b39c5158Smillert#$VAR1 = { 935b39c5158Smillert# III => 1, 936b39c5158Smillert# JJJ => 2, 937b39c5158Smillert# KKK => 3, 938b39c5158Smillert# LLL => 4, 939b39c5158Smillert# MMM => 5, 940b39c5158Smillert# NNN => 6, 941b39c5158Smillert# OOO => 7, 942b39c5158Smillert# PPP => 8, 943b39c5158Smillert# QQQ => 9 944b39c5158Smillert#}; 945b39c5158SmillertEOT 946b39c5158Smillert 947eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new([$a])->Dumpxs;), 948eac174f2Safresh1 'basic test without names: Dumpxs()', 949eac174f2Safresh1 $want); 950b39c5158Smillert} 951b39c5158Smillert 952b39c5158Smillert{ 953eac174f2Safresh1 my $i = 5; 954b39c5158Smillert $c = { map { (++$i, "$_$_$_") } 'I'..'Q' }; 955b39c5158Smillert local $Data::Dumper::Sortkeys = \&sort199; 956b39c5158Smillert sub sort199 { 957b39c5158Smillert my $hash = shift; 958b39c5158Smillert return [ sort { $b <=> $a } keys %$hash ]; 959b39c5158Smillert } 960b39c5158Smillert 961b8851fccSafresh1############# 962b39c5158Smillert## 963eac174f2Safresh1 my $want = <<'EOT'; 964b39c5158Smillert#$VAR1 = { 965b39c5158Smillert# 14 => 'QQQ', 966b39c5158Smillert# 13 => 'PPP', 967b39c5158Smillert# 12 => 'OOO', 968b39c5158Smillert# 11 => 'NNN', 969b39c5158Smillert# 10 => 'MMM', 970b39c5158Smillert# 9 => 'LLL', 971b39c5158Smillert# 8 => 'KKK', 972b39c5158Smillert# 7 => 'JJJ', 973b39c5158Smillert# 6 => 'III' 974b39c5158Smillert#}; 975b39c5158SmillertEOT 976b39c5158Smillert 977eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new([$c])->Dumpxs;), 978eac174f2Safresh1 "sortkeys sub", 979eac174f2Safresh1 $want); 980b39c5158Smillert} 981b39c5158Smillert 982b39c5158Smillert{ 983eac174f2Safresh1 my $i = 5; 984b39c5158Smillert $c = { map { (++$i, "$_$_$_") } 'I'..'Q' }; 985b39c5158Smillert $d = { reverse %$c }; 986b39c5158Smillert local $Data::Dumper::Sortkeys = \&sort205; 987b39c5158Smillert sub sort205 { 988b39c5158Smillert my $hash = shift; 989b39c5158Smillert return [ 990b39c5158Smillert $hash eq $c ? (sort { $a <=> $b } keys %$hash) 991b39c5158Smillert : (reverse sort keys %$hash) 992b39c5158Smillert ]; 993b39c5158Smillert } 994b39c5158Smillert 995b8851fccSafresh1############# 996b39c5158Smillert## 997eac174f2Safresh1 my $want = <<'EOT'; 998b39c5158Smillert#$VAR1 = [ 999b39c5158Smillert# { 1000b39c5158Smillert# 6 => 'III', 1001b39c5158Smillert# 7 => 'JJJ', 1002b39c5158Smillert# 8 => 'KKK', 1003b39c5158Smillert# 9 => 'LLL', 1004b39c5158Smillert# 10 => 'MMM', 1005b39c5158Smillert# 11 => 'NNN', 1006b39c5158Smillert# 12 => 'OOO', 1007b39c5158Smillert# 13 => 'PPP', 1008b39c5158Smillert# 14 => 'QQQ' 1009b39c5158Smillert# }, 1010b39c5158Smillert# { 1011b39c5158Smillert# QQQ => 14, 1012b39c5158Smillert# PPP => 13, 1013b39c5158Smillert# OOO => 12, 1014b39c5158Smillert# NNN => 11, 1015b39c5158Smillert# MMM => 10, 1016b39c5158Smillert# LLL => 9, 1017b39c5158Smillert# KKK => 8, 1018b39c5158Smillert# JJJ => 7, 1019b39c5158Smillert# III => 6 1020b39c5158Smillert# } 1021b39c5158Smillert#]; 1022b39c5158SmillertEOT 1023b39c5158Smillert 10246fb12b70Safresh1 # the XS code does number values as strings 1025eac174f2Safresh1 my $want_xs = $want; 1026eac174f2Safresh1 $want_xs =~ s/ (\d+)(,?)$/ '$1'$2/gm; 1027eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new([[$c, $d]])->Dumpxs;), 1028eac174f2Safresh1 "more sortkeys sub", 1029eac174f2Safresh1 $want, $want_xs); 1030b39c5158Smillert} 1031b39c5158Smillert 1032b39c5158Smillert{ 1033b39c5158Smillert local $Data::Dumper::Deparse = 1; 1034b39c5158Smillert local $Data::Dumper::Indent = 2; 1035b39c5158Smillert 1036b8851fccSafresh1############# 1037b39c5158Smillert## 1038eac174f2Safresh1 my $want = <<'EOT'; 1039b39c5158Smillert#$VAR1 = { 1040b39c5158Smillert# foo => sub { 1041eac174f2Safresh1# use warnings; 1042b39c5158Smillert# print 'foo'; 1043b39c5158Smillert# } 1044b39c5158Smillert# }; 1045b39c5158SmillertEOT 1046b39c5158Smillert 1047b39c5158Smillert if(" $Config{'extensions'} " !~ m[ B ]) { 1048eac174f2Safresh1 SKIP_BOTH("Perl configured without B module"); 1049b39c5158Smillert } else { 1050eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new([{ foo => sub { print "foo"; } }])->Dumpxs), 1051eac174f2Safresh1 'Deparse 1: Indent 2; Dumpxs()', 1052eac174f2Safresh1 $want); 1053b39c5158Smillert } 1054b39c5158Smillert} 1055b39c5158Smillert 1056b8851fccSafresh1############# 1057b39c5158Smillert## 1058b39c5158Smillert 1059b39c5158Smillert# This is messy. 1060b39c5158Smillert# The controls (bare numbers) are stored either as integers or floating point. 1061eac174f2Safresh1# [depending on whether the tokeniser sees things like ".".] 1062b39c5158Smillert# The peephole optimiser only runs for constant folding, not single constants, 1063b39c5158Smillert# so I already have some NVs, some IVs 1064b39c5158Smillert# The string versions are not. They are all PV 1065b39c5158Smillert 1066b39c5158Smillert# This is arguably all far too chummy with the implementation, but I really 1067b39c5158Smillert# want to ensure that we don't go wrong when flags on scalars get as side 1068b39c5158Smillert# effects of reading them. 1069b39c5158Smillert 1070b39c5158Smillert# These tests are actually testing the precise output of the current 1071b39c5158Smillert# implementation, so will most likely fail if the implementation changes, 1072b39c5158Smillert# even if the new implementation produces different but correct results. 1073b39c5158Smillert# It would be nice to test for wrong answers, but I can't see how to do that, 1074b39c5158Smillert# so instead I'm checking for unexpected answers. (ie -2 becoming "-2" is not 1075b39c5158Smillert# wrong, but I can't see an easy, reliable way to code that knowledge) 1076b39c5158Smillert 1077eac174f2Safresh1{ 1078b39c5158Smillert # Numbers (seen by the tokeniser as numbers, stored as numbers. 1079eac174f2Safresh1 @numbers = ( 1080b39c5158Smillert 0, +1, -2, 3.0, +4.0, -5.0, 6.5, +7.5, -8.5, 1081b39c5158Smillert 9, +10, -11, 12.0, +13.0, -14.0, 15.5, +16.25, -17.75, 1082b39c5158Smillert ); 1083b39c5158Smillert # Strings 1084eac174f2Safresh1 @strings = ( 1085b39c5158Smillert "0", "+1", "-2", "3.0", "+4.0", "-5.0", "6.5", "+7.5", "-8.5", " 9", 1086b39c5158Smillert " +10", " -11", " 12.0", " +13.0", " -14.0", " 15.5", " +16.25", " -17.75", 1087b39c5158Smillert ); 1088b39c5158Smillert 1089b39c5158Smillert # The perl code always does things the same way for numbers. 1090eac174f2Safresh1 my $WANT_PL_N = <<'EOT'; 1091b39c5158Smillert#$VAR1 = 0; 1092b39c5158Smillert#$VAR2 = 1; 1093b39c5158Smillert#$VAR3 = -2; 1094b39c5158Smillert#$VAR4 = 3; 1095b39c5158Smillert#$VAR5 = 4; 1096b39c5158Smillert#$VAR6 = -5; 1097b39c5158Smillert#$VAR7 = '6.5'; 1098b39c5158Smillert#$VAR8 = '7.5'; 1099b39c5158Smillert#$VAR9 = '-8.5'; 1100b39c5158Smillert#$VAR10 = 9; 1101b39c5158Smillert#$VAR11 = 10; 1102b39c5158Smillert#$VAR12 = -11; 1103b39c5158Smillert#$VAR13 = 12; 1104b39c5158Smillert#$VAR14 = 13; 1105b39c5158Smillert#$VAR15 = -14; 1106b39c5158Smillert#$VAR16 = '15.5'; 1107b39c5158Smillert#$VAR17 = '16.25'; 1108b39c5158Smillert#$VAR18 = '-17.75'; 1109b39c5158SmillertEOT 1110b39c5158Smillert # The perl code knows that 0 and -2 stringify exactly back to the strings, 1111b39c5158Smillert # so it dumps them as numbers, not strings. 1112eac174f2Safresh1 my $WANT_PL_S = <<'EOT'; 1113b39c5158Smillert#$VAR1 = 0; 1114b39c5158Smillert#$VAR2 = '+1'; 1115b39c5158Smillert#$VAR3 = -2; 1116b39c5158Smillert#$VAR4 = '3.0'; 1117b39c5158Smillert#$VAR5 = '+4.0'; 1118b39c5158Smillert#$VAR6 = '-5.0'; 1119b39c5158Smillert#$VAR7 = '6.5'; 1120b39c5158Smillert#$VAR8 = '+7.5'; 1121b39c5158Smillert#$VAR9 = '-8.5'; 1122b39c5158Smillert#$VAR10 = ' 9'; 1123b39c5158Smillert#$VAR11 = ' +10'; 1124b39c5158Smillert#$VAR12 = ' -11'; 1125b39c5158Smillert#$VAR13 = ' 12.0'; 1126b39c5158Smillert#$VAR14 = ' +13.0'; 1127b39c5158Smillert#$VAR15 = ' -14.0'; 1128b39c5158Smillert#$VAR16 = ' 15.5'; 1129b39c5158Smillert#$VAR17 = ' +16.25'; 1130b39c5158Smillert#$VAR18 = ' -17.75'; 1131b39c5158SmillertEOT 1132b39c5158Smillert 1133b39c5158Smillert # The XS code differs. 1134b39c5158Smillert # These are the numbers as seen by the tokeniser. Constants aren't folded 1135b39c5158Smillert # (which makes IVs where possible) so values the tokeniser thought were 1136b39c5158Smillert # floating point are stored as NVs. The XS code outputs these as strings, 1137b39c5158Smillert # but as it has converted them from NVs, leading + signs will not be there. 1138eac174f2Safresh1 my $WANT_XS_N = <<'EOT'; 1139b39c5158Smillert#$VAR1 = 0; 1140b39c5158Smillert#$VAR2 = 1; 1141b39c5158Smillert#$VAR3 = -2; 1142b39c5158Smillert#$VAR4 = '3'; 1143b39c5158Smillert#$VAR5 = '4'; 1144b39c5158Smillert#$VAR6 = '-5'; 1145b39c5158Smillert#$VAR7 = '6.5'; 1146b39c5158Smillert#$VAR8 = '7.5'; 1147b39c5158Smillert#$VAR9 = '-8.5'; 1148b39c5158Smillert#$VAR10 = 9; 1149b39c5158Smillert#$VAR11 = 10; 1150b39c5158Smillert#$VAR12 = -11; 1151b39c5158Smillert#$VAR13 = '12'; 1152b39c5158Smillert#$VAR14 = '13'; 1153b39c5158Smillert#$VAR15 = '-14'; 1154b39c5158Smillert#$VAR16 = '15.5'; 1155b39c5158Smillert#$VAR17 = '16.25'; 1156b39c5158Smillert#$VAR18 = '-17.75'; 1157b39c5158SmillertEOT 1158b39c5158Smillert 1159b39c5158Smillert # These are the strings as seen by the tokeniser. The XS code will output 1160b39c5158Smillert # these for all cases except where the scalar has been used in integer context 1161eac174f2Safresh1 my $WANT_XS_S = <<'EOT'; 1162b39c5158Smillert#$VAR1 = '0'; 1163b39c5158Smillert#$VAR2 = '+1'; 1164b39c5158Smillert#$VAR3 = '-2'; 1165b39c5158Smillert#$VAR4 = '3.0'; 1166b39c5158Smillert#$VAR5 = '+4.0'; 1167b39c5158Smillert#$VAR6 = '-5.0'; 1168b39c5158Smillert#$VAR7 = '6.5'; 1169b39c5158Smillert#$VAR8 = '+7.5'; 1170b39c5158Smillert#$VAR9 = '-8.5'; 1171b39c5158Smillert#$VAR10 = ' 9'; 1172b39c5158Smillert#$VAR11 = ' +10'; 1173b39c5158Smillert#$VAR12 = ' -11'; 1174b39c5158Smillert#$VAR13 = ' 12.0'; 1175b39c5158Smillert#$VAR14 = ' +13.0'; 1176b39c5158Smillert#$VAR15 = ' -14.0'; 1177b39c5158Smillert#$VAR16 = ' 15.5'; 1178b39c5158Smillert#$VAR17 = ' +16.25'; 1179b39c5158Smillert#$VAR18 = ' -17.75'; 1180b39c5158SmillertEOT 1181b39c5158Smillert 1182b39c5158Smillert # These are the numbers as IV-ized by & 1183b39c5158Smillert # These will differ from WANT_XS_N because now IV flags will be set on all 1184b39c5158Smillert # values that were actually integer, and the XS code will then output these 1185b39c5158Smillert # as numbers not strings. 1186eac174f2Safresh1 my $WANT_XS_I = <<'EOT'; 1187b39c5158Smillert#$VAR1 = 0; 1188b39c5158Smillert#$VAR2 = 1; 1189b39c5158Smillert#$VAR3 = -2; 1190b39c5158Smillert#$VAR4 = 3; 1191b39c5158Smillert#$VAR5 = 4; 1192b39c5158Smillert#$VAR6 = -5; 1193b39c5158Smillert#$VAR7 = '6.5'; 1194b39c5158Smillert#$VAR8 = '7.5'; 1195b39c5158Smillert#$VAR9 = '-8.5'; 1196b39c5158Smillert#$VAR10 = 9; 1197b39c5158Smillert#$VAR11 = 10; 1198b39c5158Smillert#$VAR12 = -11; 1199b39c5158Smillert#$VAR13 = 12; 1200b39c5158Smillert#$VAR14 = 13; 1201b39c5158Smillert#$VAR15 = -14; 1202b39c5158Smillert#$VAR16 = '15.5'; 1203b39c5158Smillert#$VAR17 = '16.25'; 1204b39c5158Smillert#$VAR18 = '-17.75'; 1205b39c5158SmillertEOT 1206b39c5158Smillert 1207b39c5158Smillert # Some of these tests will be redundant. 1208eac174f2Safresh1 @numbers_s = @numbers_i = @numbers_is = @numbers_n = @numbers_ns 1209eac174f2Safresh1 = @numbers_ni = @numbers_nis = @numbers; 1210eac174f2Safresh1 @strings_s = @strings_i = @strings_is = @strings_n = @strings_ns 1211eac174f2Safresh1 = @strings_ni = @strings_nis = @strings; 1212b39c5158Smillert # Use them in an integer context 1213b39c5158Smillert foreach (@numbers_i, @numbers_ni, @numbers_nis, @numbers_is, 1214b39c5158Smillert @strings_i, @strings_ni, @strings_nis, @strings_is) { 1215b39c5158Smillert my $b = sprintf "%d", $_; 1216b39c5158Smillert } 1217b39c5158Smillert # Use them in a floating point context 1218b39c5158Smillert foreach (@numbers_n, @numbers_ni, @numbers_nis, @numbers_ns, 1219b39c5158Smillert @strings_n, @strings_ni, @strings_nis, @strings_ns) { 1220b39c5158Smillert my $b = sprintf "%e", $_; 1221b39c5158Smillert } 1222b39c5158Smillert # Use them in a string context 1223b39c5158Smillert foreach (@numbers_s, @numbers_is, @numbers_nis, @numbers_ns, 1224b39c5158Smillert @strings_s, @strings_is, @strings_nis, @strings_ns) { 1225b39c5158Smillert my $b = sprintf "%s", $_; 1226b39c5158Smillert } 1227b39c5158Smillert 1228b39c5158Smillert # use Devel::Peek; Dump ($_) foreach @vanilla_c; 1229b39c5158Smillert 1230eac174f2Safresh1 my $nv_preserves_uv_4bits = defined $Config{d_nv_preserves_uv} 1231eac174f2Safresh1 || (exists($Config{nv_preserves_uv_bits}) && $Config{nv_preserves_uv_bits} >= 4); 1232b39c5158Smillert 1233eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new(\@numbers)->Dumpxs), 1234eac174f2Safresh1 'Numbers', 1235eac174f2Safresh1 $WANT_PL_N, $WANT_XS_N); 1236eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new(\@numbers_s)->Dumpxs), 1237eac174f2Safresh1 'Numbers PV', 1238eac174f2Safresh1 $WANT_PL_N, $WANT_XS_N); 1239eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new(\@numbers_i)->Dumpxs), 1240eac174f2Safresh1 'Numbers IV', 1241eac174f2Safresh1 $WANT_PL_N, $WANT_XS_I, 1242eac174f2Safresh1 $nv_preserves_uv_4bits ? "" : "NV does not preserve 4bits"); 1243eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new(\@numbers_is)->Dumpxs), 1244eac174f2Safresh1 'Numbers IV,PV', 1245eac174f2Safresh1 $WANT_PL_N, $WANT_XS_I, 1246eac174f2Safresh1 $nv_preserves_uv_4bits ? "" : "NV does not preserve 4bits"); 1247eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new(\@numbers_n)->Dumpxs), 1248eac174f2Safresh1 'XS Numbers NV', 1249eac174f2Safresh1 $WANT_PL_N, $WANT_XS_N); 1250eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new(\@numbers_ns)->Dumpxs), 1251eac174f2Safresh1 'XS Numbers NV,PV', 1252eac174f2Safresh1 $WANT_PL_N, $WANT_XS_N); 1253eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new(\@numbers_ni)->Dumpxs), 1254eac174f2Safresh1 'Numbers NV,IV', 1255eac174f2Safresh1 $WANT_PL_N, $WANT_XS_I, 1256eac174f2Safresh1 $nv_preserves_uv_4bits ? "" : "NV does not preserve 4bits"); 1257eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new(\@numbers_nis)->Dumpxs), 1258eac174f2Safresh1 'Numbers NV,IV,PV', 1259eac174f2Safresh1 $WANT_PL_N, $WANT_XS_I, 1260eac174f2Safresh1 $nv_preserves_uv_4bits ? "" : "NV does not preserve 4bits"); 1261eac174f2Safresh1 1262eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new(\@strings)->Dumpxs), 1263eac174f2Safresh1 'Strings', 1264eac174f2Safresh1 $WANT_PL_S, $WANT_XS_S); 1265eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new(\@strings_s)->Dumpxs), 1266eac174f2Safresh1 'Strings PV', 1267eac174f2Safresh1 $WANT_PL_S, $WANT_XS_S); 1268b39c5158Smillert # This one used to really mess up. New code actually emulates the .pm code 1269eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new(\@strings_i)->Dumpxs), 1270eac174f2Safresh1 'Strings IV', 1271eac174f2Safresh1 $WANT_PL_S); 1272eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new(\@strings_is)->Dumpxs), 1273eac174f2Safresh1 'Strings IV,PV', 1274eac174f2Safresh1 $WANT_PL_S); 1275eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new(\@strings_n)->Dumpxs), 1276eac174f2Safresh1 'Strings NV', 1277eac174f2Safresh1 $WANT_PL_S, $WANT_XS_S, 1278eac174f2Safresh1 $nv_preserves_uv_4bits ? "" : "NV does not preserve 4bits"); 1279eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new(\@strings_ns)->Dumpxs), 1280eac174f2Safresh1 'Strings NV,PV', 1281eac174f2Safresh1 $WANT_PL_S, $WANT_XS_S, 1282eac174f2Safresh1 $nv_preserves_uv_4bits ? "" : "NV does not preserve 4bits"); 1283b39c5158Smillert # This one used to really mess up. New code actually emulates the .pm code 1284eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new(\@strings_ni)->Dumpxs), 1285eac174f2Safresh1 'Strings NV,IV', 1286eac174f2Safresh1 $WANT_PL_S); 1287eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new(\@strings_nis)->Dumpxs), 1288eac174f2Safresh1 'Strings NV,IV,PV', 1289eac174f2Safresh1 $WANT_PL_S); 1290b39c5158Smillert} 1291b39c5158Smillert 1292b39c5158Smillert{ 1293b39c5158Smillert $a = "1\n"; 1294b8851fccSafresh1############# 1295b39c5158Smillert## Perl code was using /...$/ and hence missing the \n. 1296eac174f2Safresh1 my $want = <<'EOT'; 1297b39c5158Smillertmy $VAR1 = '42 1298b39c5158Smillert'; 1299b39c5158SmillertEOT 1300b39c5158Smillert 1301b39c5158Smillert # Can't pad with # as the output has an embedded newline. 1302b39c5158Smillert local $Data::Dumper::Pad = "my "; 1303eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs(["42\n"])), 1304eac174f2Safresh1 "number with trailing newline", 1305eac174f2Safresh1 $want); 1306b39c5158Smillert} 1307b39c5158Smillert 1308b39c5158Smillert{ 1309b39c5158Smillert @a = ( 1310b39c5158Smillert 999999999, 1311b39c5158Smillert 1000000000, 1312b39c5158Smillert 9999999999, 1313b39c5158Smillert 10000000000, 1314b39c5158Smillert -999999999, 1315b39c5158Smillert -1000000000, 1316b39c5158Smillert -9999999999, 1317b39c5158Smillert -10000000000, 1318b39c5158Smillert 4294967295, 1319b39c5158Smillert 4294967296, 1320b39c5158Smillert -2147483648, 1321b39c5158Smillert -2147483649, 1322b39c5158Smillert ); 1323b8851fccSafresh1############# 1324b39c5158Smillert## Perl code flips over at 10 digits. 1325eac174f2Safresh1 my $want = <<'EOT'; 1326b39c5158Smillert#$VAR1 = 999999999; 1327b39c5158Smillert#$VAR2 = '1000000000'; 1328b39c5158Smillert#$VAR3 = '9999999999'; 1329b39c5158Smillert#$VAR4 = '10000000000'; 1330b39c5158Smillert#$VAR5 = -999999999; 1331b39c5158Smillert#$VAR6 = '-1000000000'; 1332b39c5158Smillert#$VAR7 = '-9999999999'; 1333b39c5158Smillert#$VAR8 = '-10000000000'; 1334b39c5158Smillert#$VAR9 = '4294967295'; 1335b39c5158Smillert#$VAR10 = '4294967296'; 1336b39c5158Smillert#$VAR11 = '-2147483648'; 1337b39c5158Smillert#$VAR12 = '-2147483649'; 1338b39c5158SmillertEOT 1339b39c5158Smillert 1340b39c5158Smillert## XS code flips over at 11 characters ("-" is a char) or larger than int. 1341eac174f2Safresh1 my $want_xs = ~0 == 0xFFFFFFFF ? << 'EOT32' : << 'EOT64'; 1342b39c5158Smillert#$VAR1 = 999999999; 1343b39c5158Smillert#$VAR2 = 1000000000; 1344b39c5158Smillert#$VAR3 = '9999999999'; 1345b39c5158Smillert#$VAR4 = '10000000000'; 1346b39c5158Smillert#$VAR5 = -999999999; 1347b39c5158Smillert#$VAR6 = '-1000000000'; 1348b39c5158Smillert#$VAR7 = '-9999999999'; 1349b39c5158Smillert#$VAR8 = '-10000000000'; 1350b39c5158Smillert#$VAR9 = 4294967295; 1351b39c5158Smillert#$VAR10 = '4294967296'; 1352b39c5158Smillert#$VAR11 = '-2147483648'; 1353b39c5158Smillert#$VAR12 = '-2147483649'; 1354eac174f2Safresh1EOT32 1355b39c5158Smillert#$VAR1 = 999999999; 1356b39c5158Smillert#$VAR2 = 1000000000; 1357b39c5158Smillert#$VAR3 = 9999999999; 1358b39c5158Smillert#$VAR4 = '10000000000'; 1359b39c5158Smillert#$VAR5 = -999999999; 1360b39c5158Smillert#$VAR6 = '-1000000000'; 1361b39c5158Smillert#$VAR7 = '-9999999999'; 1362b39c5158Smillert#$VAR8 = '-10000000000'; 1363b39c5158Smillert#$VAR9 = 4294967295; 1364b39c5158Smillert#$VAR10 = 4294967296; 1365b39c5158Smillert#$VAR11 = '-2147483648'; 1366b39c5158Smillert#$VAR12 = '-2147483649'; 1367eac174f2Safresh1EOT64 1368eac174f2Safresh1 1369eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs(\@a)), 1370eac174f2Safresh1 "long integers", 1371eac174f2Safresh1 $want, $want_xs); 1372b39c5158Smillert} 1373b39c5158Smillert 1374b39c5158Smillert{ 1375b39c5158Smillert $b = "Bad. XS didn't escape dollar sign"; 1376b8851fccSafresh1############# 1377b8851fccSafresh1 # B6 is chosen because it is UTF-8 variant on ASCII and all 3 EBCDIC 1378b8851fccSafresh1 # platforms that Perl currently purports to work on. It also is the only 1379b8851fccSafresh1 # such code point that has the same meaning on all 4, the paragraph sign. 1380eac174f2Safresh1 my $want = <<"EOT"; # Careful. This is '' string written inside "" here doc 1381b8851fccSafresh1#\$VAR1 = '\$b\"\@\\\\\xB6'; 1382b39c5158SmillertEOT 1383b39c5158Smillert 1384b8851fccSafresh1 $a = "\$b\"\@\\\xB6\x{100}"; 1385b39c5158Smillert chop $a; 1386eac174f2Safresh1 my $want_xs = <<'EOT'; # While this is "" string written inside "" here doc 1387b8851fccSafresh1#$VAR1 = "\$b\"\@\\\x{b6}"; 1388b39c5158SmillertEOT 1389eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([$a])), 1390eac174f2Safresh1 "XS utf8 flag with \" and \$", 1391eac174f2Safresh1 $want, $want_xs); 1392eac174f2Safresh1 1393b39c5158Smillert # XS used to produce "$b\"' which is 4 chars, not 3. [ie wrongly qq(\$b\\\")] 1394b8851fccSafresh1############# 1395eac174f2Safresh1 $want = <<'EOT'; 1396b39c5158Smillert#$VAR1 = '$b"'; 1397b39c5158SmillertEOT 1398b39c5158Smillert 1399b39c5158Smillert $a = "\$b\"\x{100}"; 1400b39c5158Smillert chop $a; 1401eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([$a])), 1402eac174f2Safresh1 "XS utf8 flag with \" and \$", 1403eac174f2Safresh1 $want); 1404b39c5158Smillert 1405b39c5158Smillert 1406b39c5158Smillert # XS used to produce 'D'oh!' which is well, D'oh! 1407b39c5158Smillert # Andreas found this one, which in turn discovered the previous two. 1408b8851fccSafresh1############# 1409eac174f2Safresh1 $want = <<'EOT'; 1410b39c5158Smillert#$VAR1 = 'D\'oh!'; 1411b39c5158SmillertEOT 1412b39c5158Smillert 1413b39c5158Smillert $a = "D'oh!\x{100}"; 1414b39c5158Smillert chop $a; 1415eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([$a])), 1416eac174f2Safresh1 "XS utf8 flag with '", 1417eac174f2Safresh1 $want); 1418b39c5158Smillert} 1419b39c5158Smillert 1420b39c5158Smillert# Jarkko found that -Mutf8 caused some tests to fail. Turns out that there 1421b39c5158Smillert# was an otherwise untested code path in the XS for utf8 hash keys with purity 1422b39c5158Smillert# 1 1423b39c5158Smillert 1424b39c5158Smillert{ 1425eac174f2Safresh1 my $want = <<'EOT'; 1426b39c5158Smillert#$ping = \*::ping; 1427b39c5158Smillert#*::ping = \5; 1428b39c5158Smillert#*::ping = { 1429b39c5158Smillert# "\x{decaf}\x{decaf}\x{decaf}\x{decaf}" => do{my $o} 1430b39c5158Smillert#}; 1431b39c5158Smillert#*::ping{HASH}->{"\x{decaf}\x{decaf}\x{decaf}\x{decaf}"} = *::ping{SCALAR}; 1432b39c5158Smillert#%pong = %{*::ping{HASH}}; 1433b39c5158SmillertEOT 1434b39c5158Smillert local $Data::Dumper::Purity = 1; 1435b39c5158Smillert local $Data::Dumper::Sortkeys; 1436b39c5158Smillert $ping = 5; 1437b39c5158Smillert %ping = (chr (0xDECAF) x 4 =>\$ping); 1438b39c5158Smillert for $Data::Dumper::Sortkeys (0, 1) { 1439eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([\\*ping, \\%ping], ['*ping', '*pong'])), 1440eac174f2Safresh1 "utf8: Purity 1: Sortkeys: Dumpxs()", 1441eac174f2Safresh1 $want); 1442b39c5158Smillert } 1443b39c5158Smillert} 1444b39c5158Smillert 1445b39c5158Smillert# XS for quotekeys==0 was not being defensive enough against utf8 flagged 1446b39c5158Smillert# scalars 1447b39c5158Smillert 1448b39c5158Smillert{ 1449eac174f2Safresh1 my $want = <<'EOT'; 1450b39c5158Smillert#$VAR1 = { 1451b39c5158Smillert# perl => 'rocks' 1452b39c5158Smillert#}; 1453b39c5158SmillertEOT 1454b39c5158Smillert local $Data::Dumper::Quotekeys = 0; 1455b39c5158Smillert my $k = 'perl' . chr 256; 1456b39c5158Smillert chop $k; 1457b39c5158Smillert %foo = ($k => 'rocks'); 1458b39c5158Smillert 1459eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([\\%foo])), 1460eac174f2Safresh1 "quotekeys == 0 for utf8 flagged ASCII", 1461eac174f2Safresh1 $want); 1462b39c5158Smillert} 1463b8851fccSafresh1############# 1464b39c5158Smillert{ 1465eac174f2Safresh1 my $want = <<'EOT'; 1466b39c5158Smillert#$VAR1 = [ 1467b39c5158Smillert# undef, 1468b39c5158Smillert# undef, 1469b39c5158Smillert# 1 1470b39c5158Smillert#]; 1471b39c5158SmillertEOT 1472b39c5158Smillert @foo = (); 1473b39c5158Smillert $foo[2] = 1; 1474eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([\@foo])), 1475eac174f2Safresh1 'Richard Clamp, Message-Id: <20030104005247.GA27685@mirth.demon.co.uk>: Dumpxs()', 1476eac174f2Safresh1 $want); 1477b39c5158Smillert} 1478b39c5158Smillert 1479b8851fccSafresh1############# 1480898184e3Ssthen# Make sure $obj->Dumpxs returns the right thing in list context. This was 1481898184e3Ssthen# broken by the initial attempt to fix [perl #74170]. 1482eac174f2Safresh1{ 1483eac174f2Safresh1 my $want = <<'EOT'; 1484898184e3Ssthen#$VAR1 = []; 1485898184e3SsthenEOT 1486eac174f2Safresh1 TEST_BOTH(q(join " ", new Data::Dumper [[]],[] =>->Dumpxs), 1487eac174f2Safresh1 '$obj->Dumpxs in list context', 1488eac174f2Safresh1 $want); 1489eac174f2Safresh1} 1490b39c5158Smillert 1491b8851fccSafresh1############# 1492898184e3Ssthen{ 1493eac174f2Safresh1 my $want = '\0\1\2\3\4\5\6\a\b\t\n\13\f\r\16\17\20\21\22\23\24\25\26\27\30\31\32\e\34\35\36\37 !\"#\$%&\'()*+,-./0123456789:;<=>?\@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377'; 1494eac174f2Safresh1 $want = convert_to_native($want); 1495eac174f2Safresh1 $want = <<"EOT"; 1496b8851fccSafresh1#\$VAR1 = [ 1497eac174f2Safresh1# "$want" 1498898184e3Ssthen#]; 1499898184e3SsthenEOT 1500898184e3Ssthen 1501898184e3Ssthen $foo = [ join "", map chr, 0..255 ]; 1502898184e3Ssthen local $Data::Dumper::Useqq = 1; 1503eac174f2Safresh1 TEST_BOTH(q(Data::Dumper::DumperX($foo)), 1504eac174f2Safresh1 'All latin1 characters: DumperX', 1505eac174f2Safresh1 $want); 1506898184e3Ssthen} 1507898184e3Ssthen 1508b8851fccSafresh1############# 1509898184e3Ssthen{ 1510eac174f2Safresh1 my $want = '\0\1\2\3\4\5\6\a\b\t\n\13\f\r\16\17\20\21\22\23\24\25\26\27\30\31\32\e\34\35\36\37 !\"#\$%&\'()*+,-./0123456789:;<=>?\@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177\x{80}\x{81}\x{82}\x{83}\x{84}\x{85}\x{86}\x{87}\x{88}\x{89}\x{8a}\x{8b}\x{8c}\x{8d}\x{8e}\x{8f}\x{90}\x{91}\x{92}\x{93}\x{94}\x{95}\x{96}\x{97}\x{98}\x{99}\x{9a}\x{9b}\x{9c}\x{9d}\x{9e}\x{9f}\x{a0}\x{a1}\x{a2}\x{a3}\x{a4}\x{a5}\x{a6}\x{a7}\x{a8}\x{a9}\x{aa}\x{ab}\x{ac}\x{ad}\x{ae}\x{af}\x{b0}\x{b1}\x{b2}\x{b3}\x{b4}\x{b5}\x{b6}\x{b7}\x{b8}\x{b9}\x{ba}\x{bb}\x{bc}\x{bd}\x{be}\x{bf}\x{c0}\x{c1}\x{c2}\x{c3}\x{c4}\x{c5}\x{c6}\x{c7}\x{c8}\x{c9}\x{ca}\x{cb}\x{cc}\x{cd}\x{ce}\x{cf}\x{d0}\x{d1}\x{d2}\x{d3}\x{d4}\x{d5}\x{d6}\x{d7}\x{d8}\x{d9}\x{da}\x{db}\x{dc}\x{dd}\x{de}\x{df}\x{e0}\x{e1}\x{e2}\x{e3}\x{e4}\x{e5}\x{e6}\x{e7}\x{e8}\x{e9}\x{ea}\x{eb}\x{ec}\x{ed}\x{ee}\x{ef}\x{f0}\x{f1}\x{f2}\x{f3}\x{f4}\x{f5}\x{f6}\x{f7}\x{f8}\x{f9}\x{fa}\x{fb}\x{fc}\x{fd}\x{fe}\x{ff}\x{20ac}'; 1511eac174f2Safresh1 $want = convert_to_native($want); 1512eac174f2Safresh1 $want = <<"EOT"; 1513b8851fccSafresh1#\$VAR1 = [ 1514eac174f2Safresh1# "$want" 1515898184e3Ssthen#]; 1516898184e3SsthenEOT 1517898184e3Ssthen 1518898184e3Ssthen $foo = [ join "", map chr, 0..255, 0x20ac ]; 1519898184e3Ssthen local $Data::Dumper::Useqq = 1; 1520eac174f2Safresh1 TEST_BOTH(q(Data::Dumper::DumperX($foo)), 1521eac174f2Safresh1 'All latin1 characters with utf8 flag including a wide character: DumperX', 1522eac174f2Safresh1 $want); 1523898184e3Ssthen} 1524898184e3Ssthen 1525b8851fccSafresh1############# 1526898184e3Ssthen{ 1527*e0680481Safresh1 if (!Data::Dumper::SUPPORTS_CORE_BOOLS) { 1528*e0680481Safresh1 SKIP_BOTH("Core booleans not supported on older perls"); 1529*e0680481Safresh1 last; 1530*e0680481Safresh1 } 1531*e0680481Safresh1 my $want = <<'EOT'; 1532*e0680481Safresh1#$VAR1 = [ 1533*e0680481Safresh1# !!1, 1534*e0680481Safresh1# !!0 1535*e0680481Safresh1#]; 1536*e0680481Safresh1EOT 1537*e0680481Safresh1 1538*e0680481Safresh1 $foo = [ !!1, !!0 ]; 1539*e0680481Safresh1 TEST_BOTH(q(Data::Dumper::DumperX($foo)), 1540*e0680481Safresh1 'Booleans', 1541*e0680481Safresh1 $want); 1542*e0680481Safresh1} 1543*e0680481Safresh1 1544*e0680481Safresh1 1545*e0680481Safresh1############# 1546*e0680481Safresh1{ 1547898184e3Ssthen # If XS cannot load, the pure-Perl version cannot deparse vstrings with 1548eac174f2Safresh1 # underscores properly. 1549eac174f2Safresh1 # Says the original comment. However, the story is more complex than that. 1550eac174f2Safresh1 # 1) If *all* XS cannot load, Data::Dumper fails hard, because it needs 1551eac174f2Safresh1 # Scalar::Util. 1552eac174f2Safresh1 # 2) However, if Data::Dumper's XS cannot load, then Data::Dumper uses the 1553eac174f2Safresh1 # "Pure Perl" implementation, which uses C<sprintf "%vd", $val> and the 1554eac174f2Safresh1 # comment above applies. 1555eac174f2Safresh1 # 3) However, if we "just" set $Data::Dumper::Useperl true, then Dump *calls* 1556eac174f2Safresh1 # the "Pure Perl" (general) implementation, but that calls a helper in the 1557eac174f2Safresh1 # XS code (&_vstring) and it *does* deparse these vstrings properly 1558eac174f2Safresh1 # Meaning that for case 3, what we actually *test*, we get "VSTRINGS_CORRECT" 1559eac174f2Safresh1 # The "problem" comes that if one deletes Dumper.so and re-tests, it's case 2 1560eac174f2Safresh1 # and this test will fail, because case 2 output is: 1561eac174f2Safresh1 # 1562eac174f2Safresh1 #$a = \v65.66.67; 1563eac174f2Safresh1 #$b = \v65.66.67; 1564eac174f2Safresh1 #$c = \v65.66.67; 1565898184e3Ssthen #$d = \'ABC'; 1566eac174f2Safresh1 # 1567eac174f2Safresh1 # This is the test output removed by commit 55d1a9a4aa623c18 in Aug 2012: 1568eac174f2Safresh1 # Data::Dumper: Fix tests for pure-Perl implementation 1569eac174f2Safresh1 # 1570eac174f2Safresh1 # Father Chrysostomos fixed vstring handling in both XS and pure-Perl 1571eac174f2Safresh1 # implementations of Data::Dumper in 1572eac174f2Safresh1 # de5ef703c7d8db6517e7d56d9c018d3ad03f210e. 1573eac174f2Safresh1 # 1574eac174f2Safresh1 # He also updated the tests for the default XS implementation, but it seems 1575eac174f2Safresh1 # that he missed the test changes necessary for the pure-Perl implementation 1576eac174f2Safresh1 # which now also does the right thing. 1577eac174f2Safresh1 # 1578eac174f2Safresh1 # (But the relevant previous commit is not de5ef703c7d8 but d036e907fea3) 1579eac174f2Safresh1 # Part of the confusion here comes because at commit d036e907fea3 it was *not* 1580eac174f2Safresh1 # possible to remove Dumper.so and have Data::Dumper load - that bug was fixed 1581eac174f2Safresh1 # later (commit 1e9285c2ad54ae39, Dec 2011) 1582eac174f2Safresh1 # 1583eac174f2Safresh1 # Sigh, but even the test output added in d036e907fea3 was not correct 1584eac174f2Safresh1 # at least not consistent, as it had \v65.66.67, but the code at the time 1585eac174f2Safresh1 # generated \65.66.77 (no v). Now fixed. 1586b8851fccSafresh1 my $ABC_native = chr(65) . chr(66) . chr(67); 1587eac174f2Safresh1 my $want = $XS ? <<"VSTRINGS_CORRECT" : <<"NO_vstring_HELPER"; 1588b8851fccSafresh1#\$a = \\v65.66.67; 1589b8851fccSafresh1#\$b = \\v65.66.067; 1590b8851fccSafresh1#\$c = \\v65.66.6_7; 1591b8851fccSafresh1#\$d = \\'$ABC_native'; 159291f110e0Safresh1VSTRINGS_CORRECT 1593eac174f2Safresh1#\$a = \\v65.66.67; 1594eac174f2Safresh1#\$b = \\v65.66.67; 1595eac174f2Safresh1#\$c = \\v65.66.67; 1596eac174f2Safresh1#\$d = \\'$ABC_native'; 1597eac174f2Safresh1NO_vstring_HELPER 159891f110e0Safresh1 1599898184e3Ssthen @::_v = ( 1600898184e3Ssthen \v65.66.67, 1601eac174f2Safresh1 \(eval 'v65.66.067'), 1602898184e3Ssthen \v65.66.6_7, 1603898184e3Ssthen \~v190.189.188 1604898184e3Ssthen ); 160591f110e0Safresh1 if ($] >= 5.010) { 1606eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs(\@::_v, [qw(a b c d)])), 1607eac174f2Safresh1 'vstrings', 1608eac174f2Safresh1 $want); 1609898184e3Ssthen } 161091f110e0Safresh1 else { # Skip tests before 5.10. vstrings considered funny before 1611eac174f2Safresh1 SKIP_BOTH("vstrings considered funny before 5.10.0"); 161291f110e0Safresh1 } 161391f110e0Safresh1} 1614898184e3Ssthen 1615b8851fccSafresh1############# 1616898184e3Ssthen{ 1617898184e3Ssthen # [perl #107372] blessed overloaded globs 1618eac174f2Safresh1 my $want = <<'EOW'; 1619898184e3Ssthen#$VAR1 = bless( \*::finkle, 'overtest' ); 1620898184e3SsthenEOW 1621898184e3Ssthen { 1622898184e3Ssthen package overtest; 1623898184e3Ssthen use overload fallback=>1, q\""\=>sub{"oaoaa"}; 1624898184e3Ssthen } 1625eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([bless \*finkle, "overtest"])), 1626eac174f2Safresh1 'blessed overloaded globs', 1627eac174f2Safresh1 $want); 1628898184e3Ssthen} 1629b8851fccSafresh1############# 16306fb12b70Safresh1{ 16316fb12b70Safresh1 # [perl #74798] uncovered behaviour 1632eac174f2Safresh1 my $want = <<'EOW'; 16336fb12b70Safresh1#$VAR1 = "\0000"; 16346fb12b70Safresh1EOW 16356fb12b70Safresh1 local $Data::Dumper::Useqq = 1; 1636eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs(["\x000"])), 1637eac174f2Safresh1 "\\ octal followed by digit", 1638eac174f2Safresh1 $want); 16396fb12b70Safresh1 1640eac174f2Safresh1 $want = <<'EOW'; 16416fb12b70Safresh1#$VAR1 = "\x{100}\0000"; 16426fb12b70Safresh1EOW 16436fb12b70Safresh1 local $Data::Dumper::Useqq = 1; 1644eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs(["\x{100}\x000"])), 1645eac174f2Safresh1 "\\ octal followed by digit unicode", 1646eac174f2Safresh1 $want); 16476fb12b70Safresh1 1648eac174f2Safresh1 $want = <<'EOW'; 16496fb12b70Safresh1#$VAR1 = "\0\x{660}"; 16506fb12b70Safresh1EOW 1651eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs(["\\x00\\x{0660}"])), 1652eac174f2Safresh1 "\\ octal followed by unicode digit", 1653eac174f2Safresh1 $want); 16546fb12b70Safresh1 16556fb12b70Safresh1 # [perl #118933 - handling of digits 1656eac174f2Safresh1 $want = <<'EOW'; 16576fb12b70Safresh1#$VAR1 = 0; 16586fb12b70Safresh1#$VAR2 = 1; 16596fb12b70Safresh1#$VAR3 = 90; 16606fb12b70Safresh1#$VAR4 = -10; 16616fb12b70Safresh1#$VAR5 = "010"; 16626fb12b70Safresh1#$VAR6 = 112345678; 16636fb12b70Safresh1#$VAR7 = "1234567890"; 16646fb12b70Safresh1EOW 1665eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([0, 1, 90, -10, "010", "112345678", "1234567890" ])), 1666eac174f2Safresh1 "numbers and number-like scalars", 1667eac174f2Safresh1 $want); 1668eac174f2Safresh1} 1669eac174f2Safresh1############# 1670eac174f2Safresh1{ 1671eac174f2Safresh1 # [github #18614 - handling of Unicode characters in regexes] 1672eac174f2Safresh1 # [github #18764 - ... without breaking subsequent Latin-1] 1673eac174f2Safresh1 if ($] lt '5.010') { 1674eac174f2Safresh1 SKIP_BOTH("Incomplete support for UTF-8 in old perls"); 1675eac174f2Safresh1 last; 1676eac174f2Safresh1 } 1677eac174f2Safresh1 my $want = <<"EOW"; 1678eac174f2Safresh1#\$VAR1 = [ 1679eac174f2Safresh1# "\\x{41f}", 1680eac174f2Safresh1# qr/\x{8b80}/, 1681eac174f2Safresh1# qr/\x{41f}/, 1682eac174f2Safresh1# qr/\x{b6}/, 1683eac174f2Safresh1# '\xb6' 1684eac174f2Safresh1#]; 1685eac174f2Safresh1EOW 1686eac174f2Safresh1 if ($] lt '5.010001') { 1687eac174f2Safresh1 $want =~ s!qr/!qr/(?-xism:!g; 1688eac174f2Safresh1 $want =~ s!/,!)/,!g; 1689eac174f2Safresh1 } 1690eac174f2Safresh1 elsif ($] gt '5.014') { 1691eac174f2Safresh1 $want =~ s{/(,?)$}{/u$1}mg; 1692eac174f2Safresh1 } 1693eac174f2Safresh1 my $want_xs = $want; 1694eac174f2Safresh1 $want_xs =~ s/'\xb6'/"\\x{b6}"/; 1695eac174f2Safresh1 $want_xs =~ s<([[:^ascii:]])> <sprintf '\\x{%x}', ord $1>ge; 1696eac174f2Safresh1 TEST_BOTH(qq(Data::Dumper->Dumpxs([ [qq/\x{41f}/, qr/\x{8b80}/, qr/\x{41f}/, qr/\x{b6}/, "\xb6"] ])), 1697eac174f2Safresh1 "string with Unicode + regexp with Unicode", 1698eac174f2Safresh1 $want, $want_xs); 1699eac174f2Safresh1} 1700eac174f2Safresh1############# 1701eac174f2Safresh1{ 1702eac174f2Safresh1 # [more perl #58608 tests] 1703eac174f2Safresh1 my $bs = "\\\\"; 1704eac174f2Safresh1 my $want = <<"EOW"; 1705eac174f2Safresh1#\$VAR1 = [ 1706eac174f2Safresh1# qr/ \\/ /, 1707eac174f2Safresh1# qr/ \\?\\/ /, 1708eac174f2Safresh1# qr/ $bs\\/ /, 1709eac174f2Safresh1# qr/ $bs:\\/ /, 1710eac174f2Safresh1# qr/ \\?$bs:\\/ /, 1711eac174f2Safresh1# qr/ $bs$bs\\/ /, 1712eac174f2Safresh1# qr/ $bs$bs:\\/ /, 1713eac174f2Safresh1# qr/ $bs$bs$bs\\/ / 1714eac174f2Safresh1#]; 1715eac174f2Safresh1EOW 1716eac174f2Safresh1 if ($] lt '5.010001') { 1717eac174f2Safresh1 $want =~ s!qr/!qr/(?-xism:!g; 1718eac174f2Safresh1 $want =~ s! /! )/!g; 1719eac174f2Safresh1 } 1720eac174f2Safresh1 TEST_BOTH(qq(Data::Dumper->Dumpxs([ [qr! / !, qr! \\?/ !, qr! $bs/ !, qr! $bs:/ !, qr! \\?$bs:/ !, qr! $bs$bs/ !, qr! $bs$bs:/ !, qr! $bs$bs$bs/ !, ] ])), 1721eac174f2Safresh1 "more perl #58608", 1722eac174f2Safresh1 $want); 1723eac174f2Safresh1} 1724eac174f2Safresh1############# 1725eac174f2Safresh1{ 1726eac174f2Safresh1 # [github #18614, github #18764, perl #58608 corner cases] 1727eac174f2Safresh1 if ($] lt '5.010') { 1728eac174f2Safresh1 SKIP_BOTH("Incomplete support for UTF-8 in old perls"); 1729eac174f2Safresh1 last; 1730eac174f2Safresh1 } 1731eac174f2Safresh1 my $bs = "\\\\"; 1732eac174f2Safresh1 my $want = <<"EOW"; 1733eac174f2Safresh1#\$VAR1 = [ 1734eac174f2Safresh1# "\\x{2e18}", 1735eac174f2Safresh1# qr/ \x{203d}\\/ /, 1736eac174f2Safresh1# qr/ \\\x{203d}\\/ /, 1737eac174f2Safresh1# qr/ \\\x{203d}$bs:\\/ /, 1738eac174f2Safresh1# '\xB6' 1739eac174f2Safresh1#]; 1740eac174f2Safresh1EOW 1741eac174f2Safresh1 if ($] lt '5.010001') { 1742eac174f2Safresh1 $want =~ s!qr/!qr/(?-xism:!g; 1743eac174f2Safresh1 $want =~ s!/,!)/,!g; 1744eac174f2Safresh1 } 1745eac174f2Safresh1 elsif ($] gt '5.014') { 1746eac174f2Safresh1 $want =~ s{/(,?)$}{/u$1}mg; 1747eac174f2Safresh1 } 1748eac174f2Safresh1 my $want_xs = $want; 1749eac174f2Safresh1 $want_xs =~ s/'\x{B6}'/"\\x{b6}"/; 1750eac174f2Safresh1 $want_xs =~ s/\x{203D}/\\x{203d}/g; 1751eac174f2Safresh1 TEST_BOTH(qq(Data::Dumper->Dumpxs([ [ '\x{2e18}', qr! \x{203d}/ !, qr! \\\x{203d}/ !, qr! \\\x{203d}$bs:/ !, "\xb6"] ])), 1752eac174f2Safresh1 "github #18614, github #18764, perl #58608 corner cases", 1753eac174f2Safresh1 $want, $want_xs); 1754eac174f2Safresh1} 1755eac174f2Safresh1############# 1756eac174f2Safresh1{ 1757eac174f2Safresh1 # [CPAN #84569] 1758eac174f2Safresh1 my $dollar = '${\q($)}'; 1759eac174f2Safresh1 my $want = <<"EOW"; 1760eac174f2Safresh1#\$VAR1 = [ 1761eac174f2Safresh1# "\\x{2e18}", 1762eac174f2Safresh1# qr/^\$/, 1763eac174f2Safresh1# qr/^\$/, 1764eac174f2Safresh1# qr/${dollar}foo/, 1765eac174f2Safresh1# qr/\\\$foo/, 1766eac174f2Safresh1# qr/$dollar \x{B6} /u, 1767eac174f2Safresh1# qr/$dollar \x{203d} /u, 1768eac174f2Safresh1# qr/\\\$ \x{203d} /u, 1769eac174f2Safresh1# qr/\\\\$dollar \x{203d} /u, 1770eac174f2Safresh1# qr/ \$| \x{203d} /u, 1771eac174f2Safresh1# qr/ (\$) \x{203d} /u, 1772eac174f2Safresh1# '\xB6' 1773eac174f2Safresh1#]; 1774eac174f2Safresh1EOW 1775eac174f2Safresh1 if ($] lt '5.014') { 1776eac174f2Safresh1 $want =~ s{/u,$}{/,}mg; 1777eac174f2Safresh1 } 1778eac174f2Safresh1 if ($] lt '5.010001') { 1779eac174f2Safresh1 $want =~ s!qr/!qr/(?-xism:!g; 1780eac174f2Safresh1 $want =~ s!/,!)/,!g; 1781eac174f2Safresh1 } 1782eac174f2Safresh1 my $want_xs = $want; 1783eac174f2Safresh1 $want_xs =~ s/'\x{B6}'/"\\x{b6}"/; 1784eac174f2Safresh1 $want_xs =~ s/\x{B6}/\\x{b6}/; 1785eac174f2Safresh1 $want_xs =~ s/\x{203D}/\\x{203d}/g; 1786eac174f2Safresh1 my $have = <<"EOT"; 1787eac174f2Safresh1Data::Dumper->Dumpxs([ [ 1788eac174f2Safresh1 "\\x{2e18}", 1789eac174f2Safresh1 qr/^\$/, 1790eac174f2Safresh1 qr'^\$', 1791eac174f2Safresh1 qr'\$foo', 1792eac174f2Safresh1 qr/\\\$foo/, 1793eac174f2Safresh1 qr'\$ \x{B6} ', 1794eac174f2Safresh1 qr'\$ \x{203d} ', 1795eac174f2Safresh1 qr/\\\$ \x{203d} /, 1796eac174f2Safresh1 qr'\\\\\$ \x{203d} ', 1797eac174f2Safresh1 qr/ \$| \x{203d} /, 1798eac174f2Safresh1 qr/ (\$) \x{203d} /, 1799eac174f2Safresh1 '\xB6' 1800eac174f2Safresh1] ]); 1801eac174f2Safresh1EOT 1802eac174f2Safresh1 TEST_BOTH($have, "CPAN #84569", $want, $want_xs); 18036fb12b70Safresh1} 1804b8851fccSafresh1############# 18056fb12b70Safresh1{ 18066fb12b70Safresh1 # [perl #82948] 18076fb12b70Safresh1 # re::regexp_pattern was moved to universal.c in v5.10.0-252-g192c1e2 18086fb12b70Safresh1 # and apparently backported to maint-5.10 1809eac174f2Safresh1 my $want = $] > 5.010 ? <<'NEW' : <<'OLD'; 18106fb12b70Safresh1#$VAR1 = qr/abc/; 18116fb12b70Safresh1#$VAR2 = qr/abc/i; 18126fb12b70Safresh1NEW 18136fb12b70Safresh1#$VAR1 = qr/(?-xism:abc)/; 18146fb12b70Safresh1#$VAR2 = qr/(?i-xsm:abc)/; 18156fb12b70Safresh1OLD 1816eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([ qr/abc/, qr/abc/i ])), "qr// xs", $want); 18176fb12b70Safresh1} 1818b8851fccSafresh1############# 1819b8851fccSafresh1 1820b8851fccSafresh1{ 1821b8851fccSafresh1 sub foo {} 1822eac174f2Safresh1 my $want = <<'EOW'; 1823b8851fccSafresh1#*a = sub { "DUMMY" }; 1824b8851fccSafresh1#$b = \&a; 1825b8851fccSafresh1EOW 1826b8851fccSafresh1 1827eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->new([ \&foo, \\&foo ], [ "*a", "b" ])->Dumpxs), 1828eac174f2Safresh1 "name of code in *foo", 1829eac174f2Safresh1 $want); 1830b8851fccSafresh1} 1831b8851fccSafresh1############# [perl #124091] 1832b8851fccSafresh1{ 1833eac174f2Safresh1 my $want = <<'EOT'; 1834b8851fccSafresh1#$VAR1 = "\n"; 1835b8851fccSafresh1EOT 1836b8851fccSafresh1 local $Data::Dumper::Useqq = 1; 1837eac174f2Safresh1 TEST_BOTH(qq(Data::Dumper::DumperX("\n")), 1838eac174f2Safresh1 '\n alone', 1839eac174f2Safresh1 $want); 1840b8851fccSafresh1} 18419f11ffb7Safresh1############# 1842eac174f2Safresh1{ 1843eac174f2Safresh1 no strict 'refs'; 1844eac174f2Safresh1 @globs = map { $_, \$_ } map { *$_ } map { $_, "s::$_" } 18459f11ffb7Safresh1 "foo", "\1bar", "L\x{e9}on", "m\x{100}cron", "snow\x{2603}"; 1846eac174f2Safresh1} 1847eac174f2Safresh1 1848eac174f2Safresh1{ 1849eac174f2Safresh1 my $want = change_glob_expectation(<<'EOT'); 18509f11ffb7Safresh1#$globs = [ 18519f11ffb7Safresh1# *::foo, 18529f11ffb7Safresh1# \*::foo, 18539f11ffb7Safresh1# *s::foo, 18549f11ffb7Safresh1# \*s::foo, 18559f11ffb7Safresh1# *{"::\1bar"}, 18569f11ffb7Safresh1# \*{"::\1bar"}, 18579f11ffb7Safresh1# *{"s::\1bar"}, 18589f11ffb7Safresh1# \*{"s::\1bar"}, 18599f11ffb7Safresh1# *{"::L\351on"}, 18609f11ffb7Safresh1# \*{"::L\351on"}, 18619f11ffb7Safresh1# *{"s::L\351on"}, 18629f11ffb7Safresh1# \*{"s::L\351on"}, 18639f11ffb7Safresh1# *{"::m\x{100}cron"}, 18649f11ffb7Safresh1# \*{"::m\x{100}cron"}, 18659f11ffb7Safresh1# *{"s::m\x{100}cron"}, 18669f11ffb7Safresh1# \*{"s::m\x{100}cron"}, 18679f11ffb7Safresh1# *{"::snow\x{2603}"}, 18689f11ffb7Safresh1# \*{"::snow\x{2603}"}, 18699f11ffb7Safresh1# *{"s::snow\x{2603}"}, 18709f11ffb7Safresh1# \*{"s::snow\x{2603}"} 18719f11ffb7Safresh1#]; 18729f11ffb7Safresh1EOT 18739f11ffb7Safresh1 local $Data::Dumper::Useqq = 1; 187456d68f1eSafresh1 if (ord("A") == 65) { 1875eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([\@globs], ["globs"])), 'globs: Dumpxs()', 1876eac174f2Safresh1 $want); 18779f11ffb7Safresh1 } 187856d68f1eSafresh1 else { 1879eac174f2Safresh1 SKIP_BOTH("ASCII-dependent test"); 188056d68f1eSafresh1 } 188156d68f1eSafresh1} 18829f11ffb7Safresh1############# 1883eac174f2Safresh1{ 1884eac174f2Safresh1 my $want = change_glob_expectation(<<'EOT'); 18859f11ffb7Safresh1#$v = { 18869f11ffb7Safresh1# a => \*::ppp, 18879f11ffb7Safresh1# b => \*{'::a/b'}, 18889f11ffb7Safresh1# c => \*{"::a\x{2603}b"} 18899f11ffb7Safresh1#}; 18909f11ffb7Safresh1#*::ppp = { 18919f11ffb7Safresh1# a => 1 18929f11ffb7Safresh1#}; 18939f11ffb7Safresh1#*{'::a/b'} = { 18949f11ffb7Safresh1# b => 3 18959f11ffb7Safresh1#}; 18969f11ffb7Safresh1#*{"::a\x{2603}b"} = { 18979f11ffb7Safresh1# c => 5 18989f11ffb7Safresh1#}; 18999f11ffb7Safresh1EOT 19009f11ffb7Safresh1 *ppp = { a => 1 }; 1901eac174f2Safresh1 { 1902eac174f2Safresh1 no strict 'refs'; 19039f11ffb7Safresh1 *{"a/b"} = { b => 3 }; 19049f11ffb7Safresh1 *{"a\x{2603}b"} = { c => 5 }; 1905eac174f2Safresh1 $v = { a => \*ppp, b => \*{"a/b"}, c => \*{"a\x{2603}b"} }; 19069f11ffb7Safresh1 } 1907eac174f2Safresh1 local $Data::Dumper::Purity = 1; 1908eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([$v], ["v"])), 1909eac174f2Safresh1 'glob purity: Dumpxs()', 1910eac174f2Safresh1 $want); 1911eac174f2Safresh1 $want =~ tr/'/"/; 1912eac174f2Safresh1 local $Data::Dumper::Useqq = 1; 1913eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([$v], ["v"])), 1914eac174f2Safresh1 'glob purity, useqq: Dumpxs()', 1915eac174f2Safresh1 $want); 1916eac174f2Safresh1} 1917eac174f2Safresh1############# 1918eac174f2Safresh1{ 1919eac174f2Safresh1 my $want = <<'EOT'; 1920eac174f2Safresh1#$3 = {}; 1921eac174f2Safresh1#$bang = []; 1922eac174f2Safresh1EOT 1923eac174f2Safresh1 { 1924eac174f2Safresh1 package fish; 1925eac174f2Safresh1 1926eac174f2Safresh1 use overload '""' => sub { return "bang" }; 1927eac174f2Safresh1 1928eac174f2Safresh1 sub new { 1929eac174f2Safresh1 return bless qr//; 1930eac174f2Safresh1 } 1931eac174f2Safresh1 } 1932eac174f2Safresh1 # 4.5/1.5 generates the *NV* 3.0, which doesn't set SVf_POK true in 5.20.0+ 1933eac174f2Safresh1 # overloaded strings never set SVf_POK true 1934eac174f2Safresh1 TEST_BOTH(q(Data::Dumper->Dumpxs([{}, []], [4.5/1.5, fish->new()])), 1935eac174f2Safresh1 'names that are not simple strings: Dumpxs()', 1936eac174f2Safresh1 $want); 1937eac174f2Safresh1} 1938eac174f2Safresh1 1939eac174f2Safresh1done_testing(); 1940