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