Commit | Line | Data |
---|---|---|
823edd99 GS |
1 | #!./perl -w |
2 | # | |
3 | # testsuite for Data::Dumper | |
4 | # | |
5 | ||
2bc27c6c TR |
6 | use strict; |
7 | use warnings; | |
504f80c1 | 8 | |
823edd99 | 9 | use Data::Dumper; |
f70c35af | 10 | use Config; |
f7397e48 | 11 | use 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 | 17 | my $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; | |
23 | if (defined &Data::Dumper::Dumpxs) { | |
24 | print "### XS extension loaded, will run XS tests\n"; | |
25 | $XS = 1; | |
26 | } | |
27 | else { | |
28 | print "### XS extensions not loaded, will NOT run XS tests\n"; | |
f7397e48 NC |
29 | $XS = 0; |
30 | } | |
31 | ||
2bc27c6c TR |
32 | our ( @a, $c, $d, $foo, @foo, %foo, @globs, $v, $ping, %ping ); |
33 | our ( @dogs, %kennel, $mutts ); | |
34 | ||
35 | our ( @numbers, @strings ); | |
36 | our ( @numbers_s, @numbers_i, @numbers_is, @numbers_n, @numbers_ns, @numbers_ni, @numbers_nis ); | |
37 | our ( @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. | |
42 | sub 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 | 54 | sub 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 | 105 | sub 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 |
152 | sub 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. |
163 | sub 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 | 193 | my @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 | 203 | my $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 |
217 | EOT |
218 | ||
5b0b90a6 NC |
219 | TEST_BOTH(q(Data::Dumper->Dumpxs([$a,$b,$c], [qw(a b), 6])), |
220 | 'basic test with names: Dumpxs()', | |
221 | $want); | |
823edd99 | 222 | |
d424882c | 223 | SCOPE: { |
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]; | |
248 | EOT | |
249 | ||
250 | $Data::Dumper::Purity = 1; # fill in the holes for eval | |
5b0b90a6 NC |
251 | TEST_BOTH(q(Data::Dumper->Dumpxs([$a, $b], [qw(*a b)])), |
252 | 'Purity: basic test with dereferenced array: Dumpxs()', | |
253 | $want); | |
823edd99 | 254 | |
d424882c S |
255 | SCOPE: { |
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'}; |
280 | EOT | |
281 | ||
5b0b90a6 NC |
282 | TEST_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]; | |
303 | EOT | |
304 | ||
305 | $Data::Dumper::Indent = 1; | |
5b0b90a6 NC |
306 | TEST_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]; | |
332 | EOT | |
333 | ||
334 | $d->Indent(3); | |
335 | $d->Purity(0)->Quotekeys(0); | |
5b0b90a6 NC |
336 | TEST_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'}; | |
357 | EOT | |
358 | ||
db065c8a NC |
359 | TEST_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 | #] | |
377 | EOT | |
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 | #}; |
395 | EOT | |
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]}; | |
444 | EOT | |
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]; | |
474 | EOT | |
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]; | |
503 | EOT | |
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]; | |
531 | EOT | |
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]}; | |
552 | EOT | |
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]; | |
575 | EOT | |
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; | |
609 | EOT | |
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; | |
624 | EOT | |
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; | |
643 | EOT | |
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]}; | |
662 | EOT | |
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 | #); |
692 | EOT | |
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 |
703 | sub 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 | #]; | |
713 | EOT | |
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 | #]; | |
726 | EOT | |
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 | #); | |
739 | EOT | |
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]; | |
758 | EOT | |
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}}; | |
774 | EOT | |
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}}; | |
806 | EOT | |
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]}}; | |
832 | EOT | |
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}; | |
861 | EOT | |
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 | #]; | |
877 | EOT | |
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 | #]; | |
894 | EOT | |
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]; | |
907 | EOT | |
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}"; |
920 | EOT | |
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 | #}; | |
945 | EOT | |
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 | #}; |
975 | EOT | |
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 | #]; | |
1022 | EOT | |
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 | # }; |
1045 | EOT | |
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'; | |
1109 | EOT | |
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'; | |
1131 | EOT | |
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'; | |
1157 | EOT | |
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'; | |
1180 | EOT | |
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'; | |
1205 | EOT | |
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 |
1297 | my $VAR1 = '42 |
1298 | '; | |
1299 | EOT | |
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'; | |
1338 | EOT | |
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 | 1354 | EOT32 |
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 |
1367 | EOT64 |
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 |
1382 | EOT |
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 | 1388 | EOT |
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"'; |
1397 | EOT | |
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!'; |
1411 | EOT | |
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}}; | |
1433 | EOT | |
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 | #}; | |
1453 | EOT | |
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 | #]; | |
1471 | EOT | |
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 = []; |
1485 | EOT | |
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 | #]; |
1499 | EOT | |
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 | #]; |
1516 | EOT | |
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 | #]; | |
1536 | EOT | |
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 | 1592 | VSTRINGS_CORRECT |
a38f7399 NC |
1593 | #\$a = \\v65.66.67; |
1594 | #\$b = \\v65.66.67; | |
1595 | #\$c = \\v65.66.67; | |
2320aa73 NC |
1596 | #\$d = \\'$ABC_native'; |
1597 | NO_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' ); |
1620 | EOW | |
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"; |
1634 | EOW | |
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"; |
1642 | EOW | |
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}"; |
1650 | EOW | |
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"; | |
1664 | EOW | |
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 | #]; |
1685 | EOW | |
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 | #]; | |
1715 | EOW | |
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 | #]; |
1740 | EOW | |
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 | #]; |
1774 | EOW | |
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"; | |
1787 | Data::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 | ] ]); |
1801 | EOT | |
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; | |
1812 | NEW | |
1813 | #$VAR1 = qr/(?-xism:abc)/; | |
1814 | #$VAR2 = qr/(?i-xsm:abc)/; | |
1815 | OLD | |
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; | |
1825 | EOW | |
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"; |
1835 | EOT | |
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 | #]; | |
1872 | EOT | |
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 | #}; | |
1899 | EOT | |
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 = []; | |
1922 | EOT | |
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 | |
1939 | done_testing(); |