This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
3167535d78dc687c327cbb9ab837106c449a3cae
[perl5.git] / t / lib / dumper.t
1 #!./perl -w
2 #
3 # testsuite for Data::Dumper
4 #
5
6 BEGIN {
7     chdir 't' if -d 't';
8     unshift @INC, '../lib' if -d '../lib';
9 }
10
11 use Data::Dumper;
12 use Config;
13 my $Is_ebcdic = defined($Config{'ebcdic'}) && $Config{'ebcdic'} eq 'define';
14
15 $Data::Dumper::Pad = "#";
16 my $TMAX;
17 my $XS;
18 my $TNUM = 0;
19 my $WANT = '';
20
21 sub TEST {
22   my $string = shift;
23   my $t = eval $string;
24   ++$TNUM;
25   $t =~ s/([A-Z]+)\(0x[0-9a-f]+\)/$1(0xdeadbeef)/g
26       if ($WANT =~ /deadbeef/);
27   if ($Is_ebcdic) {
28       # these data need massaging with non ascii character sets
29       # because of hashing order differences
30       $WANT = join("\n",sort(split(/\n/,$WANT)));
31       $WANT =~ s/\,$//mg;
32       $t    = join("\n",sort(split(/\n/,$t)));
33       $t    =~ s/\,$//mg;
34   }
35   print( ($t eq $WANT and not $@) ? "ok $TNUM\n"
36         : "not ok $TNUM\n--Expected--\n$WANT\n--Got--\n$@$t\n");
37
38   ++$TNUM;
39   eval "$t";
40   print $@ ? "not ok $TNUM\n# \$@ says: $@\n" : "ok $TNUM\n";
41
42   $t = eval $string;
43   ++$TNUM;
44   $t =~ s/([A-Z]+)\(0x[0-9a-f]+\)/$1(0xdeadbeef)/g
45       if ($WANT =~ /deadbeef/);
46   if ($Is_ebcdic) {
47       # here too there are hashing order differences
48       $WANT = join("\n",sort(split(/\n/,$WANT)));
49       $WANT =~ s/\,$//mg;
50       $t    = join("\n",sort(split(/\n/,$t)));
51       $t    =~ s/\,$//mg;
52   }
53   print( ($t eq $WANT and not $@) ? "ok $TNUM\n"
54         : "not ok $TNUM\n--Expected--\n$WANT\n--Got--\n$@$t\n");
55 }
56
57 if (defined &Data::Dumper::Dumpxs) {
58   print "### XS extension loaded, will run XS tests\n";
59   $TMAX = 186; $XS = 1;
60 }
61 else {
62   print "### XS extensions not loaded, will NOT run XS tests\n";
63   $TMAX = 93; $XS = 0;
64 }
65
66 print "1..$TMAX\n";
67
68 #############
69 #############
70
71 @c = ('c');
72 $c = \@c;
73 $b = {};
74 $a = [1, $b, $c];
75 $b->{a} = $a;
76 $b->{b} = $a->[1];
77 $b->{c} = $a->[2];
78
79 ############# 1
80 ##
81 $WANT = <<'EOT';
82 #$a = [
83 #       1,
84 #       {
85 #         'a' => $a,
86 #         'b' => $a->[1],
87 #         'c' => [
88 #                  'c'
89 #                ]
90 #       },
91 #       $a->[1]{'c'}
92 #     ];
93 #$b = $a->[1];
94 #$c = $a->[1]{'c'};
95 EOT
96
97 TEST q(Data::Dumper->Dump([$a,$b,$c], [qw(a b c)]));
98 TEST q(Data::Dumper->Dumpxs([$a,$b,$c], [qw(a b c)])) if $XS;
99
100
101 ############# 7
102 ##
103 $WANT = <<'EOT';
104 #@a = (
105 #       1,
106 #       {
107 #         'a' => [],
108 #         'b' => {},
109 #         'c' => [
110 #                  'c'
111 #                ]
112 #       },
113 #       []
114 #     );
115 #$a[1]{'a'} = \@a;
116 #$a[1]{'b'} = $a[1];
117 #$a[2] = $a[1]{'c'};
118 #$b = $a[1];
119 EOT
120
121 $Data::Dumper::Purity = 1;         # fill in the holes for eval
122 TEST q(Data::Dumper->Dump([$a, $b], [qw(*a b)])); # print as @a
123 TEST q(Data::Dumper->Dumpxs([$a, $b], [qw(*a b)])) if $XS;
124
125 ############# 13
126 ##
127 $WANT = <<'EOT';
128 #%b = (
129 #       'a' => [
130 #                1,
131 #                {},
132 #                [
133 #                  'c'
134 #                ]
135 #              ],
136 #       'b' => {},
137 #       'c' => []
138 #     );
139 #$b{'a'}[1] = \%b;
140 #$b{'b'} = \%b;
141 #$b{'c'} = $b{'a'}[2];
142 #$a = $b{'a'};
143 EOT
144
145 TEST q(Data::Dumper->Dump([$b, $a], [qw(*b a)])); # print as %b
146 TEST q(Data::Dumper->Dumpxs([$b, $a], [qw(*b a)])) if $XS;
147
148 ############# 19
149 ##
150 $WANT = <<'EOT';
151 #$a = [
152 #  1,
153 #  {
154 #    'a' => [],
155 #    'b' => {},
156 #    'c' => []
157 #  },
158 #  []
159 #];
160 #$a->[1]{'a'} = $a;
161 #$a->[1]{'b'} = $a->[1];
162 #$a->[1]{'c'} = \@c;
163 #$a->[2] = \@c;
164 #$b = $a->[1];
165 EOT
166
167 $Data::Dumper::Indent = 1;
168 TEST q(
169        $d = Data::Dumper->new([$a,$b], [qw(a b)]);
170        $d->Seen({'*c' => $c});
171        $d->Dump;
172       );
173 if ($XS) {
174   TEST q(
175          $d = Data::Dumper->new([$a,$b], [qw(a b)]);
176          $d->Seen({'*c' => $c});
177          $d->Dumpxs;
178         );
179 }
180
181
182 ############# 25
183 ##
184 $WANT = <<'EOT';
185 #$a = [
186 #       #0
187 #       1,
188 #       #1
189 #       {
190 #         a => $a,
191 #         b => $a->[1],
192 #         c => [
193 #                #0
194 #                'c'
195 #              ]
196 #       },
197 #       #2
198 #       $a->[1]{c}
199 #     ];
200 #$b = $a->[1];
201 EOT
202
203 $d->Indent(3);
204 $d->Purity(0)->Quotekeys(0);
205 TEST q( $d->Reset; $d->Dump );
206
207 TEST q( $d->Reset; $d->Dumpxs ) if $XS;
208
209 ############# 31
210 ##
211 $WANT = <<'EOT';
212 #$VAR1 = [
213 #  1,
214 #  {
215 #    'a' => [],
216 #    'b' => {},
217 #    'c' => [
218 #      'c'
219 #    ]
220 #  },
221 #  []
222 #];
223 #$VAR1->[1]{'a'} = $VAR1;
224 #$VAR1->[1]{'b'} = $VAR1->[1];
225 #$VAR1->[2] = $VAR1->[1]{'c'};
226 EOT
227
228 TEST q(Dumper($a));
229 TEST q(Data::Dumper::DumperX($a)) if $XS;
230
231 ############# 37
232 ##
233 $WANT = <<'EOT';
234 #[
235 #  1,
236 #  {
237 #    a => $VAR1,
238 #    b => $VAR1->[1],
239 #    c => [
240 #      'c'
241 #    ]
242 #  },
243 #  $VAR1->[1]{c}
244 #]
245 EOT
246
247 {
248   local $Data::Dumper::Purity = 0;
249   local $Data::Dumper::Quotekeys = 0;
250   local $Data::Dumper::Terse = 1;
251   TEST q(Dumper($a));
252   TEST q(Data::Dumper::DumperX($a)) if $XS;
253 }
254
255
256 ############# 43
257 ##
258 $WANT = <<'EOT';
259 #$VAR1 = {
260 #  "abc\0'\efg" => "mno\0"
261 #};
262 EOT
263
264 $foo = { "abc\000\'\efg" => "mno\000" };
265 {
266   local $Data::Dumper::Useqq = 1;
267   TEST q(Dumper($foo));
268 }
269
270   $WANT = <<"EOT";
271 #\$VAR1 = {
272 #  'abc\0\\'\efg' => 'mno\0'
273 #};
274 EOT
275
276   {
277     local $Data::Dumper::Useqq = 1;
278     TEST q(Data::Dumper::DumperX($foo)) if $XS;   # cheat
279   }
280
281
282
283 #############
284 #############
285
286 {
287   package main;
288   use Data::Dumper;
289   $foo = 5;
290   @foo = (10,\*foo);
291   %foo = (a=>1,b=>\$foo,c=>\@foo);
292   $foo{d} = \%foo;
293   $foo[2] = \%foo;
294
295 ############# 49
296 ##
297   $WANT = <<'EOT';
298 #$foo = \*::foo;
299 #*::foo = \5;
300 #*::foo = [
301 #           #0
302 #           10,
303 #           #1
304 #           do{my $o},
305 #           #2
306 #           {
307 #             'a' => 1,
308 #             'b' => do{my $o},
309 #             'c' => [],
310 #             'd' => {}
311 #           }
312 #         ];
313 #*::foo{ARRAY}->[1] = $foo;
314 #*::foo{ARRAY}->[2]{'b'} = *::foo{SCALAR};
315 #*::foo{ARRAY}->[2]{'c'} = *::foo{ARRAY};
316 #*::foo{ARRAY}->[2]{'d'} = *::foo{ARRAY}->[2];
317 #*::foo = *::foo{ARRAY}->[2];
318 #@bar = @{*::foo{ARRAY}};
319 #%baz = %{*::foo{ARRAY}->[2]};
320 EOT
321
322   $Data::Dumper::Purity = 1;
323   $Data::Dumper::Indent = 3;
324   TEST q(Data::Dumper->Dump([\\*foo, \\@foo, \\%foo], ['*foo', '*bar', '*baz']));
325   TEST q(Data::Dumper->Dumpxs([\\*foo, \\@foo, \\%foo], ['*foo', '*bar', '*baz'])) if $XS;
326
327 ############# 55
328 ##
329   $WANT = <<'EOT';
330 #$foo = \*::foo;
331 #*::foo = \5;
332 #*::foo = [
333 #  10,
334 #  do{my $o},
335 #  {
336 #    'a' => 1,
337 #    'b' => do{my $o},
338 #    'c' => [],
339 #    'd' => {}
340 #  }
341 #];
342 #*::foo{ARRAY}->[1] = $foo;
343 #*::foo{ARRAY}->[2]{'b'} = *::foo{SCALAR};
344 #*::foo{ARRAY}->[2]{'c'} = *::foo{ARRAY};
345 #*::foo{ARRAY}->[2]{'d'} = *::foo{ARRAY}->[2];
346 #*::foo = *::foo{ARRAY}->[2];
347 #$bar = *::foo{ARRAY};
348 #$baz = *::foo{ARRAY}->[2];
349 EOT
350
351   $Data::Dumper::Indent = 1;
352   TEST q(Data::Dumper->Dump([\\*foo, \\@foo, \\%foo], ['foo', 'bar', 'baz']));
353   TEST q(Data::Dumper->Dumpxs([\\*foo, \\@foo, \\%foo], ['foo', 'bar', 'baz'])) if $XS;
354
355 ############# 61
356 ##
357   $WANT = <<'EOT';
358 #@bar = (
359 #  10,
360 #  \*::foo,
361 #  {}
362 #);
363 #*::foo = \5;
364 #*::foo = \@bar;
365 #*::foo = {
366 #  'a' => 1,
367 #  'b' => do{my $o},
368 #  'c' => [],
369 #  'd' => {}
370 #};
371 #*::foo{HASH}->{'b'} = *::foo{SCALAR};
372 #*::foo{HASH}->{'c'} = \@bar;
373 #*::foo{HASH}->{'d'} = *::foo{HASH};
374 #$bar[2] = *::foo{HASH};
375 #%baz = %{*::foo{HASH}};
376 #$foo = $bar[1];
377 EOT
378
379   TEST q(Data::Dumper->Dump([\\@foo, \\%foo, \\*foo], ['*bar', '*baz', '*foo']));
380   TEST q(Data::Dumper->Dumpxs([\\@foo, \\%foo, \\*foo], ['*bar', '*baz', '*foo'])) if $XS;
381
382 ############# 67
383 ##
384   $WANT = <<'EOT';
385 #$bar = [
386 #  10,
387 #  \*::foo,
388 #  {}
389 #];
390 #*::foo = \5;
391 #*::foo = $bar;
392 #*::foo = {
393 #  'a' => 1,
394 #  'b' => do{my $o},
395 #  'c' => [],
396 #  'd' => {}
397 #};
398 #*::foo{HASH}->{'b'} = *::foo{SCALAR};
399 #*::foo{HASH}->{'c'} = $bar;
400 #*::foo{HASH}->{'d'} = *::foo{HASH};
401 #$bar->[2] = *::foo{HASH};
402 #$baz = *::foo{HASH};
403 #$foo = $bar->[1];
404 EOT
405
406   TEST q(Data::Dumper->Dump([\\@foo, \\%foo, \\*foo], ['bar', 'baz', 'foo']));
407   TEST q(Data::Dumper->Dumpxs([\\@foo, \\%foo, \\*foo], ['bar', 'baz', 'foo'])) if $XS;
408
409 ############# 73
410 ##
411   $WANT = <<'EOT';
412 #$foo = \*::foo;
413 #@bar = (
414 #  10,
415 #  $foo,
416 #  {
417 #    a => 1,
418 #    b => \5,
419 #    c => \@bar,
420 #    d => $bar[2]
421 #  }
422 #);
423 #%baz = %{$bar[2]};
424 EOT
425
426   $Data::Dumper::Purity = 0;
427   $Data::Dumper::Quotekeys = 0;
428   TEST q(Data::Dumper->Dump([\\*foo, \\@foo, \\%foo], ['*foo', '*bar', '*baz']));
429   TEST q(Data::Dumper->Dumpxs([\\*foo, \\@foo, \\%foo], ['*foo', '*bar', '*baz'])) if $XS;
430
431 ############# 79
432 ##
433   $WANT = <<'EOT';
434 #$foo = \*::foo;
435 #$bar = [
436 #  10,
437 #  $foo,
438 #  {
439 #    a => 1,
440 #    b => \5,
441 #    c => $bar,
442 #    d => $bar->[2]
443 #  }
444 #];
445 #$baz = $bar->[2];
446 EOT
447
448   TEST q(Data::Dumper->Dump([\\*foo, \\@foo, \\%foo], ['foo', 'bar', 'baz']));
449   TEST q(Data::Dumper->Dumpxs([\\*foo, \\@foo, \\%foo], ['foo', 'bar', 'baz'])) if $XS;
450
451 }
452
453 #############
454 #############
455 {
456   package main;
457   @dogs = ( 'Fido', 'Wags' );
458   %kennel = (
459             First => \$dogs[0],
460             Second =>  \$dogs[1],
461            );
462   $dogs[2] = \%kennel;
463   $mutts = \%kennel;
464   $mutts = $mutts;         # avoid warning
465   
466 ############# 85
467 ##
468   $WANT = <<'EOT';
469 #%kennels = (
470 #  First => \'Fido',
471 #  Second => \'Wags'
472 #);
473 #@dogs = (
474 #  ${$kennels{First}},
475 #  ${$kennels{Second}},
476 #  \%kennels
477 #);
478 #%mutts = %kennels;
479 EOT
480
481   TEST q(
482          $d = Data::Dumper->new([\\%kennel, \\@dogs, $mutts],
483                                 [qw(*kennels *dogs *mutts)] );
484          $d->Dump;
485         );
486   if ($XS) {
487     TEST q(
488            $d = Data::Dumper->new([\\%kennel, \\@dogs, $mutts],
489                                   [qw(*kennels *dogs *mutts)] );
490            $d->Dumpxs;
491           );
492   }
493   
494 ############# 91
495 ##
496   $WANT = <<'EOT';
497 #%kennels = %kennels;
498 #@dogs = @dogs;
499 #%mutts = %kennels;
500 EOT
501
502   TEST q($d->Dump);
503   TEST q($d->Dumpxs) if $XS;
504   
505 ############# 97
506 ##
507   $WANT = <<'EOT';
508 #%kennels = (
509 #  First => \'Fido',
510 #  Second => \'Wags'
511 #);
512 #@dogs = (
513 #  ${$kennels{First}},
514 #  ${$kennels{Second}},
515 #  \%kennels
516 #);
517 #%mutts = %kennels;
518 EOT
519
520   
521   TEST q($d->Reset; $d->Dump);
522   if ($XS) {
523     TEST q($d->Reset; $d->Dumpxs);
524   }
525
526 ############# 103
527 ##
528   $WANT = <<'EOT';
529 #@dogs = (
530 #  'Fido',
531 #  'Wags',
532 #  {
533 #    First => \$dogs[0],
534 #    Second => \$dogs[1]
535 #  }
536 #);
537 #%kennels = %{$dogs[2]};
538 #%mutts = %{$dogs[2]};
539 EOT
540
541   TEST q(
542          $d = Data::Dumper->new([\\@dogs, \\%kennel, $mutts],
543                                 [qw(*dogs *kennels *mutts)] );
544          $d->Dump;
545         );
546   if ($XS) {
547     TEST q(
548            $d = Data::Dumper->new([\\@dogs, \\%kennel, $mutts],
549                                   [qw(*dogs *kennels *mutts)] );
550            $d->Dumpxs;
551           );
552   }
553   
554 ############# 109
555 ##
556   TEST q($d->Reset->Dump);
557   if ($XS) {
558     TEST q($d->Reset->Dumpxs);
559   }
560
561 ############# 115
562 ##
563   $WANT = <<'EOT';
564 #@dogs = (
565 #  'Fido',
566 #  'Wags',
567 #  {
568 #    First => \'Fido',
569 #    Second => \'Wags'
570 #  }
571 #);
572 #%kennels = (
573 #  First => \'Fido',
574 #  Second => \'Wags'
575 #);
576 EOT
577
578   TEST q(
579          $d = Data::Dumper->new( [\@dogs, \%kennel], [qw(*dogs *kennels)] );
580          $d->Deepcopy(1)->Dump;
581         );
582   if ($XS) {
583     TEST q($d->Reset->Dumpxs);
584   }
585   
586 }
587
588 {
589
590 sub z { print "foo\n" }
591 $c = [ \&z ];
592
593 ############# 121
594 ##
595   $WANT = <<'EOT';
596 #$a = $b;
597 #$c = [
598 #  $b
599 #];
600 EOT
601
602 TEST q(Data::Dumper->new([\&z,$c],['a','c'])->Seen({'b' => \&z})->Dump;);
603 TEST q(Data::Dumper->new([\&z,$c],['a','c'])->Seen({'b' => \&z})->Dumpxs;)
604         if $XS;
605
606 ############# 127
607 ##
608   $WANT = <<'EOT';
609 #$a = \&b;
610 #$c = [
611 #  \&b
612 #];
613 EOT
614
615 TEST q(Data::Dumper->new([\&z,$c],['a','c'])->Seen({'*b' => \&z})->Dump;);
616 TEST q(Data::Dumper->new([\&z,$c],['a','c'])->Seen({'*b' => \&z})->Dumpxs;)
617         if $XS;
618
619 ############# 133
620 ##
621   $WANT = <<'EOT';
622 #*a = \&b;
623 #@c = (
624 #  \&b
625 #);
626 EOT
627
628 TEST q(Data::Dumper->new([\&z,$c],['*a','*c'])->Seen({'*b' => \&z})->Dump;);
629 TEST q(Data::Dumper->new([\&z,$c],['*a','*c'])->Seen({'*b' => \&z})->Dumpxs;)
630         if $XS;
631
632 }
633
634 {
635   $a = [];
636   $a->[1] = \$a->[0];
637
638 ############# 139
639 ##
640   $WANT = <<'EOT';
641 #@a = (
642 #  undef,
643 #  do{my $o}
644 #);
645 #$a[1] = \$a[0];
646 EOT
647
648 TEST q(Data::Dumper->new([$a],['*a'])->Purity(1)->Dump;);
649 TEST q(Data::Dumper->new([$a],['*a'])->Purity(1)->Dumpxs;)
650         if $XS;
651 }
652
653 {
654   $a = \\\\\'foo';
655   $b = $$$a;
656
657 ############# 145
658 ##
659   $WANT = <<'EOT';
660 #$a = \\\\\'foo';
661 #$b = ${${$a}};
662 EOT
663
664 TEST q(Data::Dumper->new([$a,$b],['a','b'])->Purity(1)->Dump;);
665 TEST q(Data::Dumper->new([$a,$b],['a','b'])->Purity(1)->Dumpxs;)
666         if $XS;
667 }
668
669 {
670   $a = [{ a => \$b }, { b => undef }];
671   $b = [{ c => \$b }, { d => \$a }];
672
673 ############# 151
674 ##
675   $WANT = <<'EOT';
676 #$a = [
677 #  {
678 #    a => \[
679 #        {
680 #          c => do{my $o}
681 #        },
682 #        {
683 #          d => \[]
684 #        }
685 #      ]
686 #  },
687 #  {
688 #    b => undef
689 #  }
690 #];
691 #${$a->[0]{a}}->[0]->{c} = $a->[0]{a};
692 #${${$a->[0]{a}}->[1]->{d}} = $a;
693 #$b = ${$a->[0]{a}};
694 EOT
695
696 TEST q(Data::Dumper->new([$a,$b],['a','b'])->Purity(1)->Dump;);
697 TEST q(Data::Dumper->new([$a,$b],['a','b'])->Purity(1)->Dumpxs;)
698         if $XS;
699 }
700
701 {
702   $a = [[[[\\\\\'foo']]]];
703   $b = $a->[0][0];
704   $c = $${$b->[0][0]};
705
706 ############# 157
707 ##
708   $WANT = <<'EOT';
709 #$a = [
710 #  [
711 #    [
712 #      [
713 #        \\\\\'foo'
714 #      ]
715 #    ]
716 #  ]
717 #];
718 #$b = $a->[0][0];
719 #$c = ${${$a->[0][0][0][0]}};
720 EOT
721
722 TEST q(Data::Dumper->new([$a,$b,$c],['a','b','c'])->Purity(1)->Dump;);
723 TEST q(Data::Dumper->new([$a,$b,$c],['a','b','c'])->Purity(1)->Dumpxs;)
724         if $XS;
725 }
726
727 {
728     $f = "pearl";
729     $e = [        $f ];
730     $d = { 'e' => $e };
731     $c = [        $d ];
732     $b = { 'c' => $c };
733     $a = { 'b' => $b };
734
735 ############# 163
736 ##
737   $WANT = <<'EOT';
738 #$a = {
739 #  b => {
740 #    c => [
741 #      {
742 #        e => 'ARRAY(0xdeadbeef)'
743 #      }
744 #    ]
745 #  }
746 #};
747 #$b = $a->{b};
748 #$c = $a->{b}{c};
749 EOT
750
751 TEST q(Data::Dumper->new([$a,$b,$c],['a','b','c'])->Maxdepth(4)->Dump;);
752 TEST q(Data::Dumper->new([$a,$b,$c],['a','b','c'])->Maxdepth(4)->Dumpxs;)
753         if $XS;
754
755 ############# 169
756 ##
757   $WANT = <<'EOT';
758 #$a = {
759 #  b => 'HASH(0xdeadbeef)'
760 #};
761 #$b = $a->{b};
762 #$c = [
763 #  'HASH(0xdeadbeef)'
764 #];
765 EOT
766
767 TEST q(Data::Dumper->new([$a,$b,$c],['a','b','c'])->Maxdepth(1)->Dump;);
768 TEST q(Data::Dumper->new([$a,$b,$c],['a','b','c'])->Maxdepth(1)->Dumpxs;)
769         if $XS;
770 }
771
772 {
773     $a = \$a;
774     $b = [$a];
775
776 ############# 175
777 ##
778   $WANT = <<'EOT';
779 #$b = [
780 #  \$b->[0]
781 #];
782 EOT
783
784 TEST q(Data::Dumper->new([$b],['b'])->Purity(0)->Dump;);
785 TEST q(Data::Dumper->new([$b],['b'])->Purity(0)->Dumpxs;)
786         if $XS;
787
788 ############# 181
789 ##
790   $WANT = <<'EOT';
791 #$b = [
792 #  \do{my $o}
793 #];
794 #${$b->[0]} = $b->[0];
795 EOT
796
797
798 TEST q(Data::Dumper->new([$b],['b'])->Purity(1)->Dump;);
799 TEST q(Data::Dumper->new([$b],['b'])->Purity(1)->Dumpxs;)
800         if $XS;
801 }