This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Setting $_ to multiline glob in @INC filter
[perl5.git] / lib / perl5db.t
1 #!./perl
2
3 BEGIN {
4     chdir 't' if -d 't';
5     @INC = '../lib';
6     require './test.pl';
7 }
8
9 use strict;
10 use warnings;
11 use Config;
12
13 BEGIN {
14     if (! -c "/dev/null") {
15         print "1..0 # Skip: no /dev/null\n";
16         exit 0;
17     }
18
19     my $dev_tty = '/dev/tty';
20     $dev_tty = 'TT:' if ($^O eq 'VMS');
21     if (! -c $dev_tty) {
22         print "1..0 # Skip: no $dev_tty\n";
23         exit 0;
24     }
25     if ($ENV{PERL5DB}) {
26         print "1..0 # Skip: \$ENV{PERL5DB} is already set to '$ENV{PERL5DB}'\n";
27         exit 0;
28     }
29     $ENV{PERL_RL} = 'Perl'; # Suppress system Term::ReadLine::Gnu
30 }
31
32 plan(119);
33
34 my $rc_filename = '.perldb';
35
36 sub rc {
37     open my $rc_fh, '>', $rc_filename
38         or die $!;
39     print {$rc_fh} @_;
40     close ($rc_fh);
41
42     # overly permissive perms gives "Must not source insecure rcfile"
43     # and hangs at the DB(1> prompt
44     chmod 0644, $rc_filename;
45 }
46
47 sub _slurp
48 {
49     my $filename = shift;
50
51     open my $in, '<', $filename
52         or die "Cannot open '$filename' for slurping - $!";
53
54     local $/;
55     my $contents = <$in>;
56
57     close($in);
58
59     return $contents;
60 }
61
62 my $out_fn = 'db.out';
63
64 sub _out_contents
65 {
66     return _slurp($out_fn);
67 }
68
69
70 # Test for Proxy constants
71 {
72     rc(
73         <<'EOF',
74
75 &parse_options("NonStop=0 ReadLine=0 TTY=db.out LineInfo=db.out");
76
77 sub afterinit {
78     push(@DB::typeahead,
79         'm main->s1',
80         'q',
81     );
82 }
83
84 EOF
85     );
86
87     my $output = runperl(switches => [ '-d' ], stderr => 1, progfile => '../lib/perl5db/t/proxy-constants');
88     is($output, "", "proxy constant subroutines");
89 }
90
91 # [perl #66110] Call a subroutine inside a regex
92 {
93     local $ENV{PERLDB_OPTS} = "ReadLine=0 NonStop=1";
94     my $output = runperl(switches => [ '-d' ], stderr => 1, progfile => '../lib/perl5db/t/rt-66110');
95     like($output, "All tests successful.", "[perl #66110]");
96 }
97 # [ perl #116769] Frame=2
98 {
99     local $ENV{PERLDB_OPTS} = "frame=2 nonstop";
100     my $output = runperl( switches => [ '-d' ], prog => 'print q{success}' );
101     is( $?, 0, '[perl #116769] frame=2 does not crash debugger, exit == 0' );
102     like( $output, 'success' , '[perl #116769] code is run' );
103 }
104 # [ perl #116771] autotrace
105 {
106     local $ENV{PERLDB_OPTS} = "autotrace nonstop";
107     my $output = runperl( switches => [ '-d' ], prog => 'print q{success}' );
108     is( $?, 0, '[perl #116771] autotrace does not crash debugger, exit == 0' );
109     like( $output, 'success' , '[perl #116771] code is run' );
110 }
111 # [ perl #41461] Frame=2 noTTY
112 {
113     local $ENV{PERLDB_OPTS} = "frame=2 noTTY nonstop";
114     rc('');
115     my $output = runperl( switches => [ '-d' ], prog => 'print q{success}' );
116     is( $?, 0, '[perl #41461] frame=2 noTTY does not crash debugger, exit == 0' );
117     like( $output, 'success' , '[perl #41461] code is run' );
118 }
119
120 package DebugWrap;
121
122 sub new {
123     my $class = shift;
124
125     my $self = bless {}, $class;
126
127     $self->_init(@_);
128
129     return $self;
130 }
131
132 sub _cmds {
133     my $self = shift;
134
135     if (@_) {
136         $self->{_cmds} = shift;
137     }
138
139     return $self->{_cmds};
140 }
141
142 sub _prog {
143     my $self = shift;
144
145     if (@_) {
146         $self->{_prog} = shift;
147     }
148
149     return $self->{_prog};
150 }
151
152 sub _output {
153     my $self = shift;
154
155     if (@_) {
156         $self->{_output} = shift;
157     }
158
159     return $self->{_output};
160 }
161
162 sub _include_t
163 {
164     my $self = shift;
165
166     if (@_)
167     {
168         $self->{_include_t} = shift;
169     }
170
171     return $self->{_include_t};
172 }
173
174 sub _stderr_val
175 {
176     my $self = shift;
177
178     if (@_)
179     {
180         $self->{_stderr_val} = shift;
181     }
182
183     return $self->{_stderr_val};
184 }
185
186 sub field
187 {
188     my $self = shift;
189
190     if (@_)
191     {
192         $self->{field} = shift;
193     }
194
195     return $self->{field};
196 }
197
198 sub _switches
199 {
200     my $self = shift;
201
202     if (@_)
203     {
204         $self->{_switches} = shift;
205     }
206
207     return $self->{_switches};
208 }
209
210 sub _contents
211 {
212     my $self = shift;
213
214     if (@_)
215     {
216         $self->{_contents} = shift;
217     }
218
219     return $self->{_contents};
220 }
221
222 sub _init
223 {
224     my ($self, $args) = @_;
225
226     my $cmds = $args->{cmds};
227
228     if (ref($cmds) ne 'ARRAY') {
229         die "cmds must be an array of commands.";
230     }
231
232     $self->_cmds($cmds);
233
234     my $prog = $args->{prog};
235
236     if (ref($prog) ne '' or !defined($prog)) {
237         die "prog should be a path to a program file.";
238     }
239
240     $self->_prog($prog);
241
242     $self->_include_t($args->{include_t} ? 1 : 0);
243
244     $self->_stderr_val(exists($args->{stderr}) ? $args->{stderr} : 1);
245
246     if (exists($args->{switches}))
247     {
248         $self->_switches($args->{switches});
249     }
250
251     $self->_run();
252
253     return;
254 }
255
256 sub _quote
257 {
258     my ($self, $str) = @_;
259
260     $str =~ s/(["\@\$\\])/\\$1/g;
261     $str =~ s/\n/\\n/g;
262     $str =~ s/\r/\\r/g;
263
264     return qq{"$str"};
265 }
266
267 sub _run {
268     my $self = shift;
269
270     my $rc = qq{&parse_options("NonStop=0 TTY=db.out LineInfo=db.out");\n};
271
272     $rc .= join('',
273         map { "$_\n"}
274         (q#sub afterinit {#,
275          q#push (@DB::typeahead,#,
276          (map { $self->_quote($_) . "," } @{$self->_cmds()}),
277          q#);#,
278          q#}#,
279         )
280     );
281
282     # I guess two objects like that cannot be used at the same time.
283     # Oh well.
284     ::rc($rc);
285
286     my $output =
287         ::runperl(
288             switches =>
289             [
290                 ($self->_switches ? (@{$self->_switches()}) : ('-d')),
291                 ($self->_include_t ? ('-I', '../lib/perl5db/t') : ())
292             ],
293             (defined($self->_stderr_val())
294                 ? (stderr => $self->_stderr_val())
295                 : ()
296             ),
297             progfile => $self->_prog()
298         );
299
300     $self->_output($output);
301
302     $self->_contents(::_out_contents());
303
304     return;
305 }
306
307 sub get_output
308 {
309     return shift->_output();
310 }
311
312 sub output_like {
313     my ($self, $re, $msg) = @_;
314
315     local $::Level = $::Level + 1;
316     ::like($self->_output(), $re, $msg);
317 }
318
319 sub output_unlike {
320     my ($self, $re, $msg) = @_;
321
322     local $::Level = $::Level + 1;
323     ::unlike($self->_output(), $re, $msg);
324 }
325
326 sub contents_like {
327     my ($self, $re, $msg) = @_;
328
329     local $::Level = $::Level + 1;
330     ::like($self->_contents(), $re, $msg);
331 }
332
333 sub contents_unlike {
334     my ($self, $re, $msg) = @_;
335
336     local $::Level = $::Level + 1;
337     ::unlike($self->_contents(), $re, $msg);
338 }
339
340 package main;
341
342 {
343     local $ENV{PERLDB_OPTS} = "ReadLine=0";
344     my $target = '../lib/perl5db/t/eval-line-bug';
345     my $wrapper = DebugWrap->new(
346         {
347             cmds =>
348             [
349                 'b 23',
350                 'n',
351                 'n',
352                 'n',
353                 'c', # line 23
354                 'n',
355                 "p \@{'main::_<$target'}",
356                 'q',
357             ],
358             prog => $target,
359         }
360     );
361     $wrapper->contents_like(
362         qr/sub factorial/,
363         'The ${main::_<filename} variable in the debugger was not destroyed',
364     );
365 }
366
367 sub _calc_generic_wrapper
368 {
369     my $args = shift;
370
371     my $extra_opts = delete($args->{extra_opts});
372     $extra_opts ||= '';
373     local $ENV{PERLDB_OPTS} = "ReadLine=0" . $extra_opts;
374     return DebugWrap->new(
375         {
376             cmds => delete($args->{cmds}),
377             prog => delete($args->{prog}),
378             %$args,
379         }
380     );
381 }
382
383 sub _calc_new_var_wrapper
384 {
385     my ($args) = @_;
386     return _calc_generic_wrapper(
387         {
388             cmds =>
389             [
390                 'b 23',
391                 'c',
392                 '$new_var = "Foo"',
393                 'x "new_var = <$new_var>\\n"',
394                 'q',
395             ],
396             %$args,
397         }
398     );
399 }
400
401 sub _calc_threads_wrapper
402 {
403     my $args = shift;
404
405     return _calc_new_var_wrapper(
406         {
407             switches => [ '-dt', ],
408             stderr => 1,
409             %$args
410         }
411     );
412 }
413
414 {
415     _calc_new_var_wrapper({ prog => '../lib/perl5db/t/eval-line-bug'})
416         ->contents_like(
417             qr/new_var = <Foo>/,
418             "no strict 'vars' in evaluated lines.",
419         );
420 }
421
422 {
423     _calc_new_var_wrapper(
424         {
425             prog => '../lib/perl5db/t/lvalue-bug',
426             stderr => undef(),
427         },
428     )->output_like(
429             qr/foo is defined/,
430              'lvalue subs work in the debugger',
431          );
432 }
433
434 {
435     _calc_new_var_wrapper(
436         {
437             prog =>  '../lib/perl5db/t/symbol-table-bug',
438             extra_opts => "NonStop=1",
439             stderr => undef(),
440         }
441     )->output_like(
442         qr/Undefined symbols 0/,
443         'there are no undefined values in the symbol table',
444     );
445 }
446
447 SKIP:
448 {
449     if ( $Config{usethreads} ) {
450         skip('This perl has threads, skipping non-threaded debugger tests');
451     }
452     else {
453         my $error = 'This Perl not built to support threads';
454         _calc_threads_wrapper(
455             {
456                 prog => '../lib/perl5db/t/eval-line-bug',
457             }
458         )->output_like(
459             qr/\Q$error\E/,
460             'Perl debugger correctly complains that it was not built with threads',
461         );
462     }
463 }
464
465 SKIP:
466 {
467     if ( $Config{usethreads} ) {
468         _calc_threads_wrapper(
469             {
470                 prog =>  '../lib/perl5db/t/symbol-table-bug',
471             }
472         )->output_like(
473             qr/Undefined symbols 0/,
474             'there are no undefined values in the symbol table when running with thread support',
475         );
476     }
477     else {
478         skip("This perl is not threaded, skipping threaded debugger tests");
479     }
480 }
481
482 # Test [perl #61222]
483 {
484     local $ENV{PERLDB_OPTS};
485     my $wrapper = DebugWrap->new(
486         {
487             cmds =>
488             [
489                 'm Pie',
490                 'q',
491             ],
492             prog => '../lib/perl5db/t/rt-61222',
493         }
494     );
495
496     $wrapper->contents_unlike(qr/INCORRECT/, "[perl #61222]");
497 }
498
499 sub _calc_trace_wrapper
500 {
501     my ($args) = @_;
502
503     return _calc_generic_wrapper(
504         {
505             cmds =>
506             [
507                 't 2',
508                 'c',
509                 'q',
510             ],
511             %$args,
512         }
513     );
514 }
515
516 # [perl 104168] level option for tracing
517 {
518     my $wrapper = _calc_trace_wrapper({ prog =>  '../lib/perl5db/t/rt-104168' });
519     $wrapper->contents_like(qr/level 2/, "[perl #104168] - level 2 appears");
520     $wrapper->contents_unlike(qr/baz/, "[perl #104168] - no 'baz'");
521 }
522
523 # taint tests
524 {
525     my $wrapper = _calc_trace_wrapper(
526         {
527             prog => '../lib/perl5db/t/taint',
528             extra_opts => ' NonStop=1',
529             switches => [ '-d', '-T', ],
530         }
531     );
532
533     my $output = $wrapper->get_output();
534     chomp $output if $^O eq 'VMS'; # newline guaranteed at EOF
535     is($output, '[$^X][done]', "taint");
536 }
537
538 # Testing that we can set a line in the middle of the file.
539 {
540     my $wrapper = DebugWrap->new(
541         {
542             cmds =>
543             [
544                 'b ../lib/perl5db/t/MyModule.pm:12',
545                 'c',
546                 q/do { use IO::Handle; STDOUT->autoflush(1); print "Var=$var\n"; }/,
547                 'c',
548                 'q',
549             ],
550             include_t => 1,
551             prog => '../lib/perl5db/t/filename-line-breakpoint'
552         }
553     );
554
555     $wrapper->output_like(qr/
556         ^Var=Bar$
557             .*
558         ^In\ MyModule\.$
559             .*
560         ^In\ Main\ File\.$
561             .*
562         /msx,
563         "Can set breakpoint in a line in the middle of the file.");
564 }
565
566 # Testing that we can set a breakpoint
567 {
568     my $wrapper = DebugWrap->new(
569         {
570             prog => '../lib/perl5db/t/breakpoint-bug',
571             cmds =>
572             [
573                 'b 6',
574                 'c',
575                 q/do { use IO::Handle; STDOUT->autoflush(1); print "X={$x}\n"; }/,
576                 'c',
577                 'q',
578             ],
579         },
580     );
581
582     $wrapper->output_like(
583         qr/X=\{Two\}/msx,
584         "Can set breakpoint in a line."
585     );
586 }
587
588 # Testing that we can disable a breakpoint at a numeric line.
589 {
590     my $wrapper = DebugWrap->new(
591         {
592             prog =>  '../lib/perl5db/t/disable-breakpoints-1',
593             cmds =>
594             [
595                 'b 7',
596                 'b 11',
597                 'disable 7',
598                 'c',
599                 q/print "X={$x}\n";/,
600                 'c',
601                 'q',
602             ],
603         }
604     );
605
606     $wrapper->output_like(qr/X=\{SecondVal\}/ms,
607         "Can set breakpoint in a line.");
608 }
609
610 # Testing that we can re-enable a breakpoint at a numeric line.
611 {
612     my $wrapper = DebugWrap->new(
613         {
614             prog =>  '../lib/perl5db/t/disable-breakpoints-2',
615             cmds =>
616             [
617                 'b 8',
618                 'b 24',
619                 'disable 24',
620                 'c',
621                 'enable 24',
622                 'c',
623                 q/print "X={$x}\n";/,
624                 'c',
625                 'q',
626             ],
627         },
628     );
629
630     $wrapper->output_like(
631         qr/
632         X=\{SecondValOneHundred\}
633         /msx,
634         "Can set breakpoint in a line."
635     );
636 }
637 # clean up.
638
639 # Disable and enable for breakpoints on outer files.
640 {
641     my $wrapper = DebugWrap->new(
642         {
643             cmds =>
644             [
645                 'b 10',
646                 'b ../lib/perl5db/t/EnableModule.pm:14',
647                 'disable ../lib/perl5db/t/EnableModule.pm:14',
648                 'c',
649                 'enable ../lib/perl5db/t/EnableModule.pm:14',
650                 'c',
651                 q/print "X={$x}\n";/,
652                 'c',
653                 'q',
654             ],
655             prog =>  '../lib/perl5db/t/disable-breakpoints-3',
656             include_t => 1,
657         }
658     );
659
660     $wrapper->output_like(qr/
661         X=\{SecondValTwoHundred\}
662         /msx,
663         "Can set breakpoint in a line.");
664 }
665
666 # Testing that the prompt with the information appears.
667 {
668     my $wrapper = DebugWrap->new(
669         {
670             cmds => ['q'],
671             prog => '../lib/perl5db/t/disable-breakpoints-1',
672         }
673     );
674
675     $wrapper->contents_like(qr/
676         ^main::\([^\)]*\bdisable-breakpoints-1:2\):\n
677         2:\s+my\ \$x\ =\ "One";\n
678         /msx,
679         "Prompt should display the first line of code.");
680 }
681
682 # Testing that R (restart) and "B *" work.
683 {
684     my $wrapper = DebugWrap->new(
685         {
686             cmds =>
687             [
688                 'b 13',
689                 'c',
690                 'B *',
691                 'b 9',
692                 'R',
693                 'c',
694                 q/print "X={$x};dummy={$dummy}\n";/,
695                 'q',
696             ],
697             prog =>  '../lib/perl5db/t/disable-breakpoints-1',
698         }
699     );
700
701     $wrapper->output_like(qr/
702         X=\{FirstVal\};dummy=\{1\}
703         /msx,
704         "Restart and delete all breakpoints work properly.");
705 }
706
707 {
708     my $wrapper = DebugWrap->new(
709         {
710             cmds =>
711             [
712                 'c 15',
713                 q/print "X={$x}\n";/,
714                 'c',
715                 'q',
716             ],
717             prog =>  '../lib/perl5db/t/disable-breakpoints-1',
718         }
719     );
720
721     $wrapper->output_like(qr/
722         X=\{ThirdVal\}
723         /msx,
724         "'c line_num' is working properly.");
725 }
726
727 {
728     my $wrapper = DebugWrap->new(
729         {
730             cmds =>
731             [
732                 'n',
733                 'n',
734                 'b . $exp > 200',
735                 'c',
736                 q/print "Exp={$exp}\n";/,
737                 'q',
738             ],
739             prog => '../lib/perl5db/t/break-on-dot',
740         }
741     );
742
743     $wrapper->output_like(qr/
744         Exp=\{256\}
745         /msx,
746         "'b .' is working correctly.");
747 }
748
749 # Testing that the prompt with the information appears inside a subroutine call.
750 # See https://rt.perl.org/rt3/Ticket/Display.html?id=104820
751 {
752     my $wrapper = DebugWrap->new(
753         {
754             cmds =>
755             [
756                 'c back',
757                 'q',
758             ],
759             prog => '../lib/perl5db/t/with-subroutine',
760         }
761     );
762
763     $wrapper->contents_like(
764         qr/
765         ^main::back\([^\)\n]*\bwith-subroutine:15\):[\ \t]*\n
766         ^15:\s*print\ "hello\ back\\n";
767         /msx,
768         "Prompt should display the line of code inside a subroutine.");
769 }
770
771 # Checking that the p command works.
772 {
773     my $wrapper = DebugWrap->new(
774         {
775             cmds =>
776             [
777                 'p "<<<" . (4*6) . ">>>"',
778                 'q',
779             ],
780             prog => '../lib/perl5db/t/with-subroutine',
781         }
782     );
783
784     $wrapper->contents_like(
785         qr/<<<24>>>/,
786         "p command works.");
787 }
788
789 # Tests for x.
790 {
791     my $wrapper = DebugWrap->new(
792         {
793             cmds =>
794             [
795                 q/x {500 => 600}/,
796                 'q',
797             ],
798             prog => '../lib/perl5db/t/with-subroutine',
799         }
800     );
801
802     $wrapper->contents_like(
803         # qr/^0\s+HASH\([^\)]+\)\n\s+500 => 600\n/,
804         qr/^0\s+HASH\([^\)]+\)\n\s+500 => 600\n/ms,
805         "x command test."
806     );
807 }
808
809 # Tests for x with @_
810 {
811     my $wrapper = DebugWrap->new(
812         {
813             cmds =>
814             [
815                 'b 10',
816                 'c',
817                 'x @_',
818                 'q',
819             ],
820             prog => '../lib/perl5db/t/test-passing-at-underscore-to-x-etc',
821         }
822     );
823
824     $wrapper->contents_like(
825         # qr/^0\s+HASH\([^\)]+\)\n\s+500 => 600\n/,
826         qr/Arg1.*?Capsula.*GreekHumor.*Socrates/ms,
827         q/x command test with '@_'./,
828     );
829 }
830
831 # Tests for mutating @_
832 {
833     my $wrapper = DebugWrap->new(
834         {
835             cmds =>
836             [
837                 'b 10',
838                 'c',
839                 'shift(@_)',
840                 'print "\n\n\n(((" . join(",", @_) . ")))\n\n\n"',
841                 'q',
842             ],
843             prog => '../lib/perl5db/t/test-passing-at-underscore-to-x-etc',
844         }
845     );
846
847     $wrapper->output_like(
848         qr/^\(\(\(Capsula,GreekHumor,Socrates\)\)\)$/ms,
849         q/Mutating '@_'./,
850     );
851 }
852
853 # Tests for x with AutoTrace=1.
854 {
855     my $wrapper = DebugWrap->new(
856         {
857             cmds =>
858             [
859                 'n',
860                 'o AutoTrace=1',
861                 # So it may fail.
862                 q/x "failure"/,
863                 q/x \$x/,
864                 'q',
865             ],
866             prog => '../lib/perl5db/t/with-subroutine',
867         }
868     );
869
870     $wrapper->contents_like(
871         # qr/^0\s+HASH\([^\)]+\)\n\s+500 => 600\n/,
872         qr/^0\s+SCALAR\([^\)]+\)\n\s+-> 'hello world'\n/ms,
873         "x after AutoTrace=1 command is working."
874     );
875 }
876
877 # Tests for "T" (stack trace).
878 {
879     my $prog_fn = '../lib/perl5db/t/rt-104168';
880     my $wrapper = DebugWrap->new(
881         {
882             prog => $prog_fn,
883             cmds =>
884             [
885                 'c baz',
886                 'T',
887                 'q',
888             ],
889         }
890     );
891     my $re_text = join('',
892         map {
893         sprintf(
894             "%s = %s\\(\\) called from file " .
895             "'" . quotemeta($prog_fn) . "' line %s\\n",
896             (map { quotemeta($_) } @$_)
897             )
898         }
899         (
900             ['.', 'main::baz', 14,],
901             ['.', 'main::bar', 9,],
902             ['.', 'main::foo', 6],
903         )
904     );
905     $wrapper->contents_like(
906         # qr/^0\s+HASH\([^\)]+\)\n\s+500 => 600\n/,
907         qr/^$re_text/ms,
908         "T command test."
909     );
910 }
911
912 # Test for s.
913 {
914     my $wrapper = DebugWrap->new(
915         {
916             cmds =>
917             [
918                 'b 9',
919                 'c',
920                 's',
921                 q/print "X={$x};dummy={$dummy}\n";/,
922                 'q',
923             ],
924             prog => '../lib/perl5db/t/disable-breakpoints-1'
925         }
926     );
927
928     $wrapper->output_like(qr/
929         X=\{SecondVal\};dummy=\{1\}
930         /msx,
931         'test for s - single step',
932     );
933 }
934
935 {
936     my $wrapper = DebugWrap->new(
937         {
938             cmds =>
939             [
940                 'n',
941                 'n',
942                 'b . $exp > 200',
943                 'c',
944                 q/print "Exp={$exp}\n";/,
945                 'q',
946             ],
947             prog => '../lib/perl5db/t/break-on-dot'
948         }
949     );
950
951     $wrapper->output_like(qr/
952         Exp=\{256\}
953         /msx,
954         "'b .' is working correctly.");
955 }
956
957 {
958     my $prog_fn = '../lib/perl5db/t/rt-104168';
959     my $wrapper = DebugWrap->new(
960         {
961             cmds =>
962             [
963                 's',
964                 'q',
965             ],
966             prog => $prog_fn,
967         }
968     );
969
970     $wrapper->contents_like(
971         qr/
972         ^main::foo\([^\)\n]*\brt-104168:9\):[\ \t]*\n
973         ^9:\s*bar\(\);
974         /msx,
975         'Test for the s command.',
976     );
977 }
978
979 {
980     my $wrapper = DebugWrap->new(
981         {
982             cmds =>
983             [
984                 's uncalled_subroutine()',
985                 'c',
986                 'q',
987             ],
988
989             prog => '../lib/perl5db/t/uncalled-subroutine'}
990     );
991
992     $wrapper->output_like(
993         qr/<1,2,3,4,5>\n/,
994         'uncalled_subroutine was called after s EXPR()',
995         );
996 }
997
998 {
999     my $wrapper = DebugWrap->new(
1000         {
1001             cmds =>
1002             [
1003                 'n uncalled_subroutine()',
1004                 'c',
1005                 'q',
1006             ],
1007             prog => '../lib/perl5db/t/uncalled-subroutine',
1008         }
1009     );
1010
1011     $wrapper->output_like(
1012         qr/<1,2,3,4,5>\n/,
1013         'uncalled_subroutine was called after n EXPR()',
1014         );
1015 }
1016
1017 {
1018     my $wrapper = DebugWrap->new(
1019         {
1020             cmds =>
1021             [
1022                 'b fact',
1023                 'c',
1024                 'c',
1025                 'c',
1026                 'n',
1027                 'print "<$n>"',
1028                 'q',
1029             ],
1030             prog => '../lib/perl5db/t/fact',
1031         }
1032     );
1033
1034     $wrapper->output_like(
1035         qr/<3>/,
1036         'b subroutine works fine',
1037     );
1038 }
1039
1040 # Test for n with lvalue subs
1041 DebugWrap->new({
1042     cmds =>
1043     [
1044         'n', 'print "<$x>"',
1045         'n', 'print "<$x>"',
1046         'q',
1047     ],
1048     prog => '../lib/perl5db/t/lsub-n',
1049 })->output_like(
1050     qr/<1><11>/,
1051     'n steps over lvalue subs',
1052 );
1053
1054 # Test for 'M' (module list).
1055 {
1056     my $wrapper = DebugWrap->new(
1057         {
1058             cmds =>
1059             [
1060                 'M',
1061                 'q',
1062             ],
1063             prog => '../lib/perl5db/t/load-modules'
1064         }
1065     );
1066
1067     $wrapper->contents_like(
1068         qr[Scalar/Util\.pm],
1069         'M (module list) works fine',
1070     );
1071 }
1072
1073 {
1074     my $wrapper = DebugWrap->new(
1075         {
1076             cmds =>
1077             [
1078                 'b 14',
1079                 'c',
1080                 '$flag = 1;',
1081                 'r',
1082                 'print "Var=$var\n";',
1083                 'q',
1084             ],
1085             prog => '../lib/perl5db/t/test-r-statement',
1086         }
1087     );
1088
1089     $wrapper->output_like(
1090         qr/
1091             ^Foo$
1092                 .*?
1093             ^Bar$
1094                 .*?
1095             ^Var=Test$
1096         /msx,
1097         'r statement is working properly.',
1098     );
1099 }
1100
1101 {
1102     my $wrapper = DebugWrap->new(
1103         {
1104             cmds =>
1105             [
1106                 'l',
1107                 'q',
1108             ],
1109             prog => '../lib/perl5db/t/test-l-statement-1',
1110         }
1111     );
1112
1113     $wrapper->contents_like(
1114         qr/
1115             ^1==>\s+\$x\ =\ 1;\n
1116             2:\s+print\ "1\\n";\n
1117             3\s*\n
1118             4:\s+\$x\ =\ 2;\n
1119             5:\s+print\ "2\\n";\n
1120         /msx,
1121         'l statement is working properly (test No. 1).',
1122     );
1123 }
1124
1125 {
1126     my $wrapper = DebugWrap->new(
1127         {
1128             cmds =>
1129             [
1130                 'l',
1131                 q/# After l 1/,
1132                 'l',
1133                 q/# After l 2/,
1134                 '-',
1135                 q/# After -/,
1136                 'q',
1137             ],
1138             prog => '../lib/perl5db/t/test-l-statement-1',
1139         }
1140     );
1141
1142     my $first_l_out = qr/
1143         1==>\s+\$x\ =\ 1;\n
1144         2:\s+print\ "1\\n";\n
1145         3\s*\n
1146         4:\s+\$x\ =\ 2;\n
1147         5:\s+print\ "2\\n";\n
1148         6\s*\n
1149         7:\s+\$x\ =\ 3;\n
1150         8:\s+print\ "3\\n";\n
1151         9\s*\n
1152         10:\s+\$x\ =\ 4;\n
1153     /msx;
1154
1155     my $second_l_out = qr/
1156         11:\s+print\ "4\\n";\n
1157         12\s*\n
1158         13:\s+\$x\ =\ 5;\n
1159         14:\s+print\ "5\\n";\n
1160         15\s*\n
1161         16:\s+\$x\ =\ 6;\n
1162         17:\s+print\ "6\\n";\n
1163         18\s*\n
1164         19:\s+\$x\ =\ 7;\n
1165         20:\s+print\ "7\\n";\n
1166     /msx;
1167     $wrapper->contents_like(
1168         qr/
1169             ^$first_l_out
1170             [^\n]*?DB<\d+>\ \#\ After\ l\ 1\n
1171             [\ \t]*\n
1172             [^\n]*?DB<\d+>\ l\s*\n
1173             $second_l_out
1174             [^\n]*?DB<\d+>\ \#\ After\ l\ 2\n
1175             [\ \t]*\n
1176             [^\n]*?DB<\d+>\ -\s*\n
1177             $first_l_out
1178             [^\n]*?DB<\d+>\ \#\ After\ -\n
1179         /msx,
1180         'l followed by l and then followed by -',
1181     );
1182 }
1183
1184 {
1185     my $wrapper = DebugWrap->new(
1186         {
1187             cmds =>
1188             [
1189                 'l fact',
1190                 'q',
1191             ],
1192             prog => '../lib/perl5db/t/test-l-statement-2',
1193         }
1194     );
1195
1196     my $first_l_out = qr/
1197         6\s+sub\ fact\ \{\n
1198         7:\s+my\ \$n\ =\ shift;\n
1199         8:\s+if\ \(\$n\ >\ 1\)\ \{\n
1200         9:\s+return\ \$n\ \*\ fact\(\$n\ -\ 1\);
1201     /msx;
1202
1203     $wrapper->contents_like(
1204         qr/
1205             DB<1>\s+l\ fact\n
1206             $first_l_out
1207         /msx,
1208         'l subroutine_name',
1209     );
1210 }
1211
1212 {
1213     my $wrapper = DebugWrap->new(
1214         {
1215             cmds =>
1216             [
1217                 'b fact',
1218                 'c',
1219                 # Repeat several times to avoid @typeahead problems.
1220                 '.',
1221                 '.',
1222                 '.',
1223                 '.',
1224                 'q',
1225             ],
1226             prog => '../lib/perl5db/t/test-l-statement-2',
1227         }
1228     );
1229
1230     my $line_out = qr /
1231         ^main::fact\([^\n]*?:7\):\n
1232         ^7:\s+my\ \$n\ =\ shift;\n
1233     /msx;
1234
1235     $wrapper->contents_like(
1236         qr/
1237             $line_out
1238             $line_out
1239         /msx,
1240         'Test the "." command',
1241     );
1242 }
1243
1244 # Testing that the f command works.
1245 {
1246     my $wrapper = DebugWrap->new(
1247         {
1248             cmds =>
1249             [
1250                 'f ../lib/perl5db/t/MyModule.pm',
1251                 'b 12',
1252                 'c',
1253                 q/do { use IO::Handle; STDOUT->autoflush(1); print "Var=$var\n"; }/,
1254                 'c',
1255                 'q',
1256             ],
1257             include_t => 1,
1258             prog => '../lib/perl5db/t/filename-line-breakpoint'
1259         }
1260     );
1261
1262     $wrapper->output_like(qr/
1263         ^Var=Bar$
1264             .*
1265         ^In\ MyModule\.$
1266             .*
1267         ^In\ Main\ File\.$
1268             .*
1269         /msx,
1270         "f command is working.",
1271     );
1272 }
1273
1274 # We broke the /pattern/ command because apparently the CORE::eval-s inside
1275 # lib/perl5db.pl cannot handle lexical variable properly. So we now fix this
1276 # bug.
1277 #
1278 # TODO :
1279 #
1280 # 1. Go over the rest of the "eval"s in lib/perl5db.t and see if they cause
1281 # problems.
1282 {
1283     my $wrapper = DebugWrap->new(
1284         {
1285             cmds =>
1286             [
1287                 '/for/',
1288                 'q',
1289             ],
1290             prog => '../lib/perl5db/t/eval-line-bug',
1291         }
1292     );
1293
1294     $wrapper->contents_like(
1295         qr/12: \s* for\ my\ \$q\ \(1\ \.\.\ 10\)\ \{/msx,
1296         "/pat/ command is working and found a match.",
1297     );
1298 }
1299
1300 {
1301     my $wrapper = DebugWrap->new(
1302         {
1303             cmds =>
1304             [
1305                 'b 22',
1306                 'c',
1307                 '?for?',
1308                 'q',
1309             ],
1310             prog => '../lib/perl5db/t/eval-line-bug',
1311         }
1312     );
1313
1314     $wrapper->contents_like(
1315         qr/12: \s* for\ my\ \$q\ \(1\ \.\.\ 10\)\ \{/msx,
1316         "?pat? command is working and found a match.",
1317     );
1318 }
1319
1320 # Test the L command.
1321 {
1322     my $wrapper = DebugWrap->new(
1323         {
1324             cmds =>
1325             [
1326                 'b 6',
1327                 'b 13 ($q == 5)',
1328                 'L',
1329                 'q',
1330             ],
1331             prog => '../lib/perl5db/t/eval-line-bug',
1332         }
1333     );
1334
1335     $wrapper->contents_like(
1336         qr#
1337         ^\S*?eval-line-bug:\n
1338         \s*6:\s*my\ \$i\ =\ 5;\n
1339         \s*break\ if\ \(1\)\n
1340         \s*13:\s*\$i\ \+=\ \$q;\n
1341         \s*break\ if\ \(\(\$q\ ==\ 5\)\)\n
1342         #msx,
1343         "L command is listing breakpoints",
1344     );
1345 }
1346
1347 # Test the L command for watch expressions.
1348 {
1349     my $wrapper = DebugWrap->new(
1350         {
1351             cmds =>
1352             [
1353                 'w (5+6)',
1354                 'L',
1355                 'q',
1356             ],
1357             prog => '../lib/perl5db/t/eval-line-bug',
1358         }
1359     );
1360
1361     $wrapper->contents_like(
1362         qr#
1363         ^Watch-expressions:\n
1364         \s*\(5\+6\)\n
1365         #msx,
1366         "L command is listing watch expressions",
1367     );
1368 }
1369
1370 {
1371     my $wrapper = DebugWrap->new(
1372         {
1373             cmds =>
1374             [
1375                 'w (5+6)',
1376                 'w (11*23)',
1377                 'W (5+6)',
1378                 'L',
1379                 'q',
1380             ],
1381             prog => '../lib/perl5db/t/eval-line-bug',
1382         }
1383     );
1384
1385     $wrapper->contents_like(
1386         qr#
1387         ^Watch-expressions:\n
1388         \s*\(11\*23\)\n
1389         ^auto\(
1390         #msx,
1391         "L command is not listing deleted watch expressions",
1392     );
1393 }
1394
1395 # Test the L command.
1396 {
1397     my $wrapper = DebugWrap->new(
1398         {
1399             cmds =>
1400             [
1401                 'b 6',
1402                 'a 13 print $i',
1403                 'L',
1404                 'q',
1405             ],
1406             prog => '../lib/perl5db/t/eval-line-bug',
1407         }
1408     );
1409
1410     $wrapper->contents_like(
1411         qr#
1412         ^\S*?eval-line-bug:\n
1413         \s*6:\s*my\ \$i\ =\ 5;\n
1414         \s*break\ if\ \(1\)\n
1415         \s*13:\s*\$i\ \+=\ \$q;\n
1416         \s*action:\s+print\ \$i\n
1417         #msx,
1418         "L command is listing actions and breakpoints",
1419     );
1420 }
1421
1422 {
1423     my $wrapper = DebugWrap->new(
1424         {
1425             cmds =>
1426             [
1427                 'S',
1428                 'q',
1429             ],
1430             prog =>  '../lib/perl5db/t/rt-104168',
1431         }
1432     );
1433
1434     $wrapper->contents_like(
1435         qr#
1436         ^main::bar\n
1437         main::baz\n
1438         main::foo\n
1439         #msx,
1440         "S command - 1",
1441     );
1442 }
1443
1444 {
1445     my $wrapper = DebugWrap->new(
1446         {
1447             cmds =>
1448             [
1449                 'S ^main::ba',
1450                 'q',
1451             ],
1452             prog =>  '../lib/perl5db/t/rt-104168',
1453         }
1454     );
1455
1456     $wrapper->contents_like(
1457         qr#
1458         ^main::bar\n
1459         main::baz\n
1460         auto\(
1461         #msx,
1462         "S command with regex",
1463     );
1464 }
1465
1466 {
1467     my $wrapper = DebugWrap->new(
1468         {
1469             cmds =>
1470             [
1471                 'S !^main::ba',
1472                 'q',
1473             ],
1474             prog =>  '../lib/perl5db/t/rt-104168',
1475         }
1476     );
1477
1478     $wrapper->contents_unlike(
1479         qr#
1480         ^main::ba
1481         #msx,
1482         "S command with negative regex",
1483     );
1484
1485     $wrapper->contents_like(
1486         qr#
1487         ^main::foo\n
1488         #msx,
1489         "S command with negative regex - what it still matches",
1490     );
1491 }
1492
1493 # Test the 'a' command.
1494 {
1495     my $wrapper = DebugWrap->new(
1496         {
1497             cmds =>
1498             [
1499                 'a 13 print "\nVar<Q>=$q\n"',
1500                 'c',
1501                 'q',
1502             ],
1503             prog => '../lib/perl5db/t/eval-line-bug',
1504         }
1505     );
1506
1507     $wrapper->output_like(qr#
1508         \nVar<Q>=1\n
1509         \nVar<Q>=2\n
1510         \nVar<Q>=3\n
1511         #msx,
1512         "a command is working",
1513     );
1514 }
1515
1516 # Test the 'a' command with no line number.
1517 {
1518     my $wrapper = DebugWrap->new(
1519         {
1520             cmds =>
1521             [
1522                 'n',
1523                 q/a print "Hello " . (3 * 4) . "\n";/,
1524                 'c',
1525                 'q',
1526             ],
1527             prog => '../lib/perl5db/t/test-a-statement-1',
1528         }
1529     );
1530
1531     $wrapper->output_like(qr#
1532         (?:^Hello\ 12\n.*?){4}
1533         #msx,
1534         "a command with no line number is working",
1535     );
1536 }
1537
1538 # Test the 'A' command
1539 {
1540     my $wrapper = DebugWrap->new(
1541         {
1542             cmds =>
1543             [
1544                 'a 13 print "\nVar<Q>=$q\n"',
1545                 'A 13',
1546                 'c',
1547                 'q',
1548             ],
1549             prog => '../lib/perl5db/t/eval-line-bug',
1550         }
1551     );
1552
1553     $wrapper->output_like(
1554         qr#\A\z#msx, # The empty string.
1555         "A command (for removing actions) is working",
1556     );
1557 }
1558
1559 # Test the 'A *' command
1560 {
1561     my $wrapper = DebugWrap->new(
1562         {
1563             cmds =>
1564             [
1565                 'a 6 print "\nFail!\n"',
1566                 'a 13 print "\nVar<Q>=$q\n"',
1567                 'A *',
1568                 'c',
1569                 'q',
1570             ],
1571             prog => '../lib/perl5db/t/eval-line-bug',
1572         }
1573     );
1574
1575     $wrapper->output_like(
1576         qr#\A\z#msx, # The empty string.
1577         "'A *' command (for removing all actions) is working",
1578     );
1579 }
1580
1581 {
1582     my $wrapper = DebugWrap->new(
1583         {
1584             cmds =>
1585             [
1586                 'n',
1587                 'w $foo',
1588                 'c',
1589                 'print "\nIDX=<$idx>\n"',
1590                 'q',
1591             ],
1592             prog => '../lib/perl5db/t/test-w-statement-1',
1593         }
1594     );
1595
1596
1597     $wrapper->contents_like(qr#
1598         \$foo\ changed:\n
1599         \s+old\ value:\s+'1'\n
1600         \s+new\ value:\s+'2'\n
1601         #msx,
1602         'w command - watchpoint changed',
1603     );
1604     $wrapper->output_like(qr#
1605         \nIDX=<20>\n
1606         #msx,
1607         "w command - correct output from IDX",
1608     );
1609 }
1610
1611 {
1612     my $wrapper = DebugWrap->new(
1613         {
1614             cmds =>
1615             [
1616                 'n',
1617                 'w $foo',
1618                 'W $foo',
1619                 'c',
1620                 'print "\nIDX=<$idx>\n"',
1621                 'q',
1622             ],
1623             prog => '../lib/perl5db/t/test-w-statement-1',
1624         }
1625     );
1626
1627     $wrapper->contents_unlike(qr#
1628         \$foo\ changed:
1629         #msx,
1630         'W command - watchpoint was deleted',
1631     );
1632
1633     $wrapper->output_like(qr#
1634         \nIDX=<>\n
1635         #msx,
1636         "W command - stopped at end.",
1637     );
1638 }
1639
1640 # Test the W * command.
1641 {
1642     my $wrapper = DebugWrap->new(
1643         {
1644             cmds =>
1645             [
1646                 'n',
1647                 'w $foo',
1648                 'w ($foo*$foo)',
1649                 'W *',
1650                 'c',
1651                 'print "\nIDX=<$idx>\n"',
1652                 'q',
1653             ],
1654             prog => '../lib/perl5db/t/test-w-statement-1',
1655         }
1656     );
1657
1658     $wrapper->contents_unlike(qr#
1659         \$foo\ changed:
1660         #msx,
1661         '"W *" command - watchpoint was deleted',
1662     );
1663
1664     $wrapper->output_like(qr#
1665         \nIDX=<>\n
1666         #msx,
1667         '"W *" command - stopped at end.',
1668     );
1669 }
1670
1671 # Test the 'o' command (without further arguments).
1672 {
1673     my $wrapper = DebugWrap->new(
1674         {
1675             cmds =>
1676             [
1677                 'o',
1678                 'q',
1679             ],
1680             prog => '../lib/perl5db/t/test-w-statement-1',
1681         }
1682     );
1683
1684     $wrapper->contents_like(qr#
1685         ^\s*warnLevel\ =\ '1'\n
1686         #msx,
1687         q#"o" command (without arguments) displays warnLevel#,
1688     );
1689
1690     $wrapper->contents_like(qr#
1691         ^\s*signalLevel\ =\ '1'\n
1692         #msx,
1693         q#"o" command (without arguments) displays signalLevel#,
1694     );
1695
1696     $wrapper->contents_like(qr#
1697         ^\s*dieLevel\ =\ '1'\n
1698         #msx,
1699         q#"o" command (without arguments) displays dieLevel#,
1700     );
1701
1702     $wrapper->contents_like(qr#
1703         ^\s*hashDepth\ =\ 'N/A'\n
1704         #msx,
1705         q#"o" command (without arguments) displays hashDepth#,
1706     );
1707 }
1708
1709 # Test the 'o' query command.
1710 {
1711     my $wrapper = DebugWrap->new(
1712         {
1713             cmds =>
1714             [
1715                 'o hashDepth? signalLevel?',
1716                 'q',
1717             ],
1718             prog => '../lib/perl5db/t/test-w-statement-1',
1719         }
1720     );
1721
1722     $wrapper->contents_unlike(qr#warnLevel#,
1723         q#"o" query command does not display warnLevel#,
1724     );
1725
1726     $wrapper->contents_like(qr#
1727         ^\s*signalLevel\ =\ '1'\n
1728         #msx,
1729         q#"o" query command displays signalLevel#,
1730     );
1731
1732     $wrapper->contents_unlike(qr#dieLevel#,
1733         q#"o" query command does not display dieLevel#,
1734     );
1735
1736     $wrapper->contents_like(qr#
1737         ^\s*hashDepth\ =\ 'N/A'\n
1738         #msx,
1739         q#"o" query command displays hashDepth#,
1740     );
1741 }
1742
1743 # Test the 'o' set command.
1744 {
1745     my $wrapper = DebugWrap->new(
1746         {
1747             cmds =>
1748             [
1749                 'o signalLevel=0',
1750                 'o',
1751                 'q',
1752             ],
1753             prog => '../lib/perl5db/t/test-w-statement-1',
1754         }
1755     );
1756
1757     $wrapper->contents_like(qr/
1758         ^\s*(signalLevel\ =\ '0'\n)
1759         .*?
1760         ^\s*\1
1761         /msx,
1762         q#o set command works#,
1763     );
1764
1765     $wrapper->contents_like(qr#
1766         ^\s*hashDepth\ =\ 'N/A'\n
1767         #msx,
1768         q#o set command - hashDepth#,
1769     );
1770 }
1771
1772 # Test the '<' and "< ?" commands.
1773 {
1774     my $wrapper = DebugWrap->new(
1775         {
1776             cmds =>
1777             [
1778                 q/< print "\nX=<$x>\n"/,
1779                 q/b 7/,
1780                 q/< ?/,
1781                 'c',
1782                 'q',
1783             ],
1784             prog => '../lib/perl5db/t/disable-breakpoints-1',
1785         }
1786     );
1787
1788     $wrapper->contents_like(qr/
1789         ^pre-perl\ commands:\n
1790         \s*<\ --\ print\ "\\nX=<\$x>\\n"\n
1791         /msx,
1792         q#Test < and < ? commands - contents.#,
1793     );
1794
1795     $wrapper->output_like(qr#
1796         ^X=<FirstVal>\n
1797         #msx,
1798         q#Test < and < ? commands - output.#,
1799     );
1800 }
1801
1802 # Test the '< *' command.
1803 {
1804     my $wrapper = DebugWrap->new(
1805         {
1806             cmds =>
1807             [
1808                 q/< print "\nX=<$x>\n"/,
1809                 q/b 7/,
1810                 q/< */,
1811                 'c',
1812                 'q',
1813             ],
1814             prog => '../lib/perl5db/t/disable-breakpoints-1',
1815         }
1816     );
1817
1818     $wrapper->output_unlike(qr/FirstVal/,
1819         q#Test the '< *' command.#,
1820     );
1821 }
1822
1823 # Test the '>' and "> ?" commands.
1824 {
1825     my $wrapper = DebugWrap->new(
1826         {
1827             cmds =>
1828             [
1829                 q/$::foo = 500;/,
1830                 q/> print "\nFOO=<$::foo>\n"/,
1831                 q/b 7/,
1832                 q/> ?/,
1833                 'c',
1834                 'q',
1835             ],
1836             prog => '../lib/perl5db/t/disable-breakpoints-1',
1837         }
1838     );
1839
1840     $wrapper->contents_like(qr/
1841         ^post-perl\ commands:\n
1842         \s*>\ --\ print\ "\\nFOO=<\$::foo>\\n"\n
1843         /msx,
1844         q#Test > and > ? commands - contents.#,
1845     );
1846
1847     $wrapper->output_like(qr#
1848         ^FOO=<500>\n
1849         #msx,
1850         q#Test > and > ? commands - output.#,
1851     );
1852 }
1853
1854 # Test the '> *' command.
1855 {
1856     my $wrapper = DebugWrap->new(
1857         {
1858             cmds =>
1859             [
1860                 q/> print "\nFOO=<$::foo>\n"/,
1861                 q/b 7/,
1862                 q/> */,
1863                 'c',
1864                 'q',
1865             ],
1866             prog => '../lib/perl5db/t/disable-breakpoints-1',
1867         }
1868     );
1869
1870     $wrapper->output_unlike(qr/FOO=/,
1871         q#Test the '> *' command.#,
1872     );
1873 }
1874
1875 # Test the < and > commands together
1876 {
1877     my $wrapper = DebugWrap->new(
1878         {
1879             cmds =>
1880             [
1881                 q/$::lorem = 0;/,
1882                 q/< $::lorem += 10;/,
1883                 q/> print "\nLOREM=<$::lorem>\n"/,
1884                 q/b 7/,
1885                 q/b 5/,
1886                 'c',
1887                 'c',
1888                 'q',
1889             ],
1890             prog => '../lib/perl5db/t/disable-breakpoints-1',
1891         }
1892     );
1893
1894     $wrapper->output_like(qr#
1895         ^LOREM=<10>\n
1896         #msx,
1897         q#Test < and > commands. #,
1898     );
1899 }
1900
1901 # Test the { ? and { [command] commands.
1902 {
1903     my $wrapper = DebugWrap->new(
1904         {
1905             cmds =>
1906             [
1907                 '{ ?',
1908                 '{ l',
1909                 '{ ?',
1910                 q/b 5/,
1911                 q/c/,
1912                 q/q/,
1913             ],
1914             prog => '../lib/perl5db/t/disable-breakpoints-1',
1915         }
1916     );
1917
1918     $wrapper->contents_like(qr#
1919         ^No\ pre-debugger\ actions\.\n
1920         .*?
1921         ^pre-debugger\ commands:\n
1922         \s+\{\ --\ l\n
1923         .*?
1924         ^5==>b\s+\$x\ =\ "FirstVal";\n
1925         6\s*\n
1926         7:\s+\$dummy\+\+;\n
1927         8\s*\n
1928         9:\s+\$x\ =\ "SecondVal";\n
1929
1930         #msx,
1931         'Test the pre-prompt debugger commands',
1932     );
1933 }
1934
1935 # Test the { * command.
1936 {
1937     my $wrapper = DebugWrap->new(
1938         {
1939             cmds =>
1940             [
1941                 '{ q',
1942                 '{ *',
1943                 q/b 5/,
1944                 q/c/,
1945                 q/print (("One" x 5), "\n");/,
1946                 q/q/,
1947             ],
1948             prog => '../lib/perl5db/t/disable-breakpoints-1',
1949         }
1950     );
1951
1952     $wrapper->contents_like(qr#
1953         ^All\ \{\ actions\ cleared\.\n
1954         #msx,
1955         'Test the { * command',
1956     );
1957
1958     $wrapper->output_like(qr/OneOneOneOneOne/,
1959         '{ * test - output is OK.',
1960     );
1961 }
1962
1963 # Test the ! command.
1964 {
1965     my $wrapper = DebugWrap->new(
1966         {
1967             cmds =>
1968             [
1969                 'l 3-5',
1970                 '!',
1971                 'q',
1972             ],
1973             prog => '../lib/perl5db/t/disable-breakpoints-1',
1974         }
1975     );
1976
1977     $wrapper->contents_like(qr#
1978         (^3:\s+my\ \$dummy\ =\ 0;\n
1979         4\s*\n
1980         5:\s+\$x\ =\ "FirstVal";)\n
1981         .*?
1982         ^l\ 3-5\n
1983         \1
1984         #msx,
1985         'Test the ! command (along with l 3-5)',
1986     );
1987 }
1988
1989 # Test the ! -number command.
1990 {
1991     my $wrapper = DebugWrap->new(
1992         {
1993             cmds =>
1994             [
1995                 'l 3-5',
1996                 'l 2',
1997                 '! -1',
1998                 'q',
1999             ],
2000             prog => '../lib/perl5db/t/disable-breakpoints-1',
2001         }
2002     );
2003
2004     $wrapper->contents_like(qr#
2005         (^3:\s+my\ \$dummy\ =\ 0;\n
2006         4\s*\n
2007         5:\s+\$x\ =\ "FirstVal";)\n
2008         .*?
2009         ^2==\>\s+my\ \$x\ =\ "One";\n
2010         .*?
2011         ^l\ 3-5\n
2012         \1
2013         #msx,
2014         'Test the ! -n command (along with l)',
2015     );
2016 }
2017
2018 # Test the 'source' command.
2019 {
2020     my $wrapper = DebugWrap->new(
2021         {
2022             cmds =>
2023             [
2024                 'source ../lib/perl5db/t/source-cmd-test.perldb',
2025                 # If we have a 'q' here, then the typeahead will override the
2026                 # input, and so it won't be reached - solution:
2027                 # put a q inside the .perldb commands.
2028                 # ( This may be a bug or a misfeature. )
2029             ],
2030             prog => '../lib/perl5db/t/disable-breakpoints-1',
2031         }
2032     );
2033
2034     $wrapper->contents_like(qr#
2035         ^3:\s+my\ \$dummy\ =\ 0;\n
2036         4\s*\n
2037         5:\s+\$x\ =\ "FirstVal";\n
2038         6\s*\n
2039         7:\s+\$dummy\+\+;\n
2040         8\s*\n
2041         9:\s+\$x\ =\ "SecondVal";\n
2042         10\s*\n
2043         #msx,
2044         'Test the source command (along with l)',
2045     );
2046 }
2047
2048 # Test the 'source' command being traversed from withing typeahead.
2049 {
2050     my $wrapper = DebugWrap->new(
2051         {
2052             cmds =>
2053             [
2054                 'source ../lib/perl5db/t/source-cmd-test-no-q.perldb',
2055                 'q',
2056             ],
2057             prog => '../lib/perl5db/t/disable-breakpoints-1',
2058         }
2059     );
2060
2061     $wrapper->contents_like(qr#
2062         ^3:\s+my\ \$dummy\ =\ 0;\n
2063         4\s*\n
2064         5:\s+\$x\ =\ "FirstVal";\n
2065         6\s*\n
2066         7:\s+\$dummy\+\+;\n
2067         8\s*\n
2068         9:\s+\$x\ =\ "SecondVal";\n
2069         10\s*\n
2070         #msx,
2071         'Test the source command inside a typeahead',
2072     );
2073 }
2074
2075 # Test the 'H -number' command.
2076 {
2077     my $wrapper = DebugWrap->new(
2078         {
2079             cmds =>
2080             [
2081                 'l 1-10',
2082                 'l 5-10',
2083                 'x "Hello World"',
2084                 'l 1-5',
2085                 'b 3',
2086                 'x (20+4)',
2087                 'H -7',
2088                 'q',
2089             ],
2090             prog => '../lib/perl5db/t/disable-breakpoints-1',
2091         }
2092     );
2093
2094     $wrapper->contents_like(qr#
2095         ^\d+:\s+H\ -7\n
2096         \d+:\s+x\ \(20\+4\)\n
2097         \d+:\s+b\ 3\n
2098         \d+:\s+l\ 1-5\n
2099         \d+:\s+x\ "Hello\ World"\n
2100         \d+:\s+l\ 5-10\n
2101         \d+:\s+l\ 1-10\n
2102         #msx,
2103         'Test the H -num command',
2104     );
2105 }
2106
2107 # Add a test for H (without arguments)
2108 {
2109     my $wrapper = DebugWrap->new(
2110         {
2111             cmds =>
2112             [
2113                 'l 1-10',
2114                 'l 5-10',
2115                 'x "Hello World"',
2116                 'l 1-5',
2117                 'b 3',
2118                 'x (20+4)',
2119                 'H',
2120                 'q',
2121             ],
2122             prog => '../lib/perl5db/t/disable-breakpoints-1',
2123         }
2124     );
2125
2126     $wrapper->contents_like(qr#
2127         ^\d+:\s+x\ \(20\+4\)\n
2128         \d+:\s+b\ 3\n
2129         \d+:\s+l\ 1-5\n
2130         \d+:\s+x\ "Hello\ World"\n
2131         \d+:\s+l\ 5-10\n
2132         \d+:\s+l\ 1-10\n
2133         #msx,
2134         'Test the H command (without a number.)',
2135     );
2136 }
2137
2138 {
2139     my $wrapper = DebugWrap->new(
2140         {
2141             cmds =>
2142             [
2143                 '= quit q',
2144                 '= foobar l',
2145                 'foobar',
2146                 'quit',
2147             ],
2148             prog => '../lib/perl5db/t/test-l-statement-1',
2149         }
2150     );
2151
2152     $wrapper->contents_like(
2153         qr/
2154             ^1==>\s+\$x\ =\ 1;\n
2155             2:\s+print\ "1\\n";\n
2156             3\s*\n
2157             4:\s+\$x\ =\ 2;\n
2158             5:\s+print\ "2\\n";\n
2159         /msx,
2160         'Test the = (command alias) command.',
2161     );
2162 }
2163
2164 # Test the m statement.
2165 {
2166     my $wrapper = DebugWrap->new(
2167         {
2168             cmds =>
2169             [
2170                 'm main',
2171                 'q',
2172             ],
2173             prog => '../lib/perl5db/t/disable-breakpoints-1',
2174         }
2175     );
2176
2177     $wrapper->contents_like(qr#
2178         ^via\ UNIVERSAL:\ DOES$
2179         #msx,
2180         "Test m for main - 1",
2181     );
2182
2183     $wrapper->contents_like(qr#
2184         ^via\ UNIVERSAL:\ can$
2185         #msx,
2186         "Test m for main - 2",
2187     );
2188 }
2189
2190 # Test the m statement.
2191 {
2192     my $wrapper = DebugWrap->new(
2193         {
2194             cmds =>
2195             [
2196                 'b 41',
2197                 'c',
2198                 'm $obj',
2199                 'q',
2200             ],
2201             prog => '../lib/perl5db/t/test-m-statement-1',
2202         }
2203     );
2204
2205     $wrapper->contents_like(qr#^greet$#ms,
2206         "Test m for obj - 1",
2207     );
2208
2209     $wrapper->contents_like(qr#^via UNIVERSAL: can$#ms,
2210         "Test m for obj - 1",
2211     );
2212 }
2213
2214 # Test the M command.
2215 {
2216     my $wrapper = DebugWrap->new(
2217         {
2218             cmds =>
2219             [
2220                 'M',
2221                 'q',
2222             ],
2223             prog => '../lib/perl5db/t/test-m-statement-1',
2224         }
2225     );
2226
2227     $wrapper->contents_like(qr#
2228         ^'strict\.pm'\ =>\ '\d+\.\d+\ from
2229         #msx,
2230         "Test M",
2231     );
2232
2233 }
2234
2235 # Test the recallCommand option.
2236 {
2237     my $wrapper = DebugWrap->new(
2238         {
2239             cmds =>
2240             [
2241                 'o recallCommand=%',
2242                 'l 3-5',
2243                 'l 2',
2244                 '% -1',
2245                 'q',
2246             ],
2247             prog => '../lib/perl5db/t/disable-breakpoints-1',
2248         }
2249     );
2250
2251     $wrapper->contents_like(qr#
2252         (^3:\s+my\ \$dummy\ =\ 0;\n
2253         4\s*\n
2254         5:\s+\$x\ =\ "FirstVal";)\n
2255         .*?
2256         ^2==\>\s+my\ \$x\ =\ "One";\n
2257         .*?
2258         ^l\ 3-5\n
2259         \1
2260         #msx,
2261         'Test the o recallCommand option',
2262     );
2263 }
2264
2265 # Test the dieLevel option
2266 {
2267     my $wrapper = DebugWrap->new(
2268         {
2269             cmds =>
2270             [
2271                 q/o dieLevel='1'/,
2272                 q/c/,
2273                 'q',
2274             ],
2275             prog => '../lib/perl5db/t/test-dieLevel-option-1',
2276         }
2277     );
2278
2279     $wrapper->output_like(qr#
2280         ^This\ program\ dies\.\ at\ \S+\ line\ 18\.\n
2281         .*?
2282         ^\s+main::baz\(\)\ called\ at\ \S+\ line\ 13\n
2283         \s+main::bar\(\)\ called\ at\ \S+\ line\ 7\n
2284         \s+main::foo\(\)\ called\ at\ \S+\ line\ 21\n
2285         #msx,
2286         'Test the o dieLevel option',
2287     );
2288 }
2289
2290 # Test the warnLevel option
2291 {
2292     my $wrapper = DebugWrap->new(
2293         {
2294             cmds =>
2295             [
2296                 q/o warnLevel='1'/,
2297                 q/c/,
2298                 'q',
2299             ],
2300             prog => '../lib/perl5db/t/test-warnLevel-option-1',
2301         }
2302     );
2303
2304     $wrapper->contents_like(qr#
2305         ^This\ is\ not\ a\ warning\.\ at\ \S+\ line\ 18\.\n
2306         .*?
2307         ^\s+main::baz\(\)\ called\ at\ \S+\ line\ 13\n
2308         \s+main::bar\(\)\ called\ at\ \S+\ line\ 25\n
2309         \s+main::myfunc\(\)\ called\ at\ \S+\ line\ 28\n
2310         #msx,
2311         'Test the o warnLevel option',
2312     );
2313 }
2314
2315 # Test the t command
2316 {
2317     my $wrapper = DebugWrap->new(
2318         {
2319             cmds =>
2320             [
2321                 't',
2322                 'c',
2323                 'q',
2324             ],
2325             prog => '../lib/perl5db/t/disable-breakpoints-1',
2326         }
2327     );
2328
2329     $wrapper->contents_like(qr/
2330         ^main::\([^:]+:15\):\n
2331         15:\s+\$dummy\+\+;\n
2332         main::\([^:]+:17\):\n
2333         17:\s+\$x\ =\ "FourthVal";\n
2334         /msx,
2335         'Test the t command (without a number.)',
2336     );
2337 }
2338
2339 # Test the o AutoTrace command
2340 {
2341     my $wrapper = DebugWrap->new(
2342         {
2343             cmds =>
2344             [
2345                 'o AutoTrace',
2346                 'c',
2347                 'q',
2348             ],
2349             prog => '../lib/perl5db/t/disable-breakpoints-1',
2350         }
2351     );
2352
2353     $wrapper->contents_like(qr/
2354         ^main::\([^:]+:15\):\n
2355         15:\s+\$dummy\+\+;\n
2356         main::\([^:]+:17\):\n
2357         17:\s+\$x\ =\ "FourthVal";\n
2358         /msx,
2359         'Test the o AutoTrace command',
2360     );
2361 }
2362
2363 # Test the t command with function calls
2364 {
2365     my $wrapper = DebugWrap->new(
2366         {
2367             cmds =>
2368             [
2369                 't',
2370                 'b 18',
2371                 'c',
2372                 'x ["foo"]',
2373                 'x ["bar"]',
2374                 'q',
2375             ],
2376             prog => '../lib/perl5db/t/test-warnLevel-option-1',
2377         }
2378     );
2379
2380     $wrapper->contents_like(qr/
2381         ^main::\([^:]+:28\):\n
2382         28:\s+myfunc\(\);\n
2383         main::myfunc\([^:]+:25\):\n
2384         25:\s+bar\(\);\n
2385         /msx,
2386         'Test the t command with function calls.',
2387     );
2388 }
2389
2390 # Test the o AutoTrace command with function calls
2391 {
2392     my $wrapper = DebugWrap->new(
2393         {
2394             cmds =>
2395             [
2396                 'o AutoTrace',
2397                 'b 18',
2398                 'c',
2399                 'x ["foo"]',
2400                 'x ["bar"]',
2401                 'q',
2402             ],
2403             prog => '../lib/perl5db/t/test-warnLevel-option-1',
2404         }
2405     );
2406
2407     $wrapper->contents_like(qr/
2408         ^main::\([^:]+:28\):\n
2409         28:\s+myfunc\(\);\n
2410         main::myfunc\([^:]+:25\):\n
2411         25:\s+bar\(\);\n
2412         /msx,
2413         'Test the t command with function calls.',
2414     );
2415 }
2416
2417 # Test the final message.
2418 {
2419     my $wrapper = DebugWrap->new(
2420         {
2421             cmds =>
2422             [
2423                 'c',
2424                 'q',
2425             ],
2426             prog => '../lib/perl5db/t/test-warnLevel-option-1',
2427         }
2428     );
2429
2430     $wrapper->contents_like(qr/
2431         ^Debugged\ program\ terminated\.
2432         /msx,
2433         'Test the final "Debugged program terminated" message.',
2434     );
2435 }
2436
2437 # Test the o inhibit_exit=0 command
2438 {
2439     my $wrapper = DebugWrap->new(
2440         {
2441             cmds =>
2442             [
2443                 'o inhibit_exit=0',
2444                 'n',
2445                 'n',
2446                 'n',
2447                 'n',
2448                 'q',
2449             ],
2450             prog => '../lib/perl5db/t/test-warnLevel-option-1',
2451         }
2452     );
2453
2454     $wrapper->contents_unlike(qr/
2455         ^Debugged\ program\ terminated\.
2456         /msx,
2457         'Test the o inhibit_exit=0 command.',
2458     );
2459 }
2460
2461 # Test the o PrintRet=1 option
2462 {
2463     my $wrapper = DebugWrap->new(
2464         {
2465             cmds =>
2466             [
2467                 'o PrintRet=1',
2468                 'b 29',
2469                 'c',
2470                 q/$x = 's';/,
2471                 'b 10',
2472                 'c',
2473                 'r',
2474                 'q',
2475             ],
2476             prog => '../lib/perl5db/t/test-PrintRet-option-1',
2477         }
2478     );
2479
2480     $wrapper->contents_like(
2481         qr/scalar context return from main::return_scalar: 20024/,
2482         "Test o PrintRet=1",
2483     );
2484 }
2485
2486 # Test the o PrintRet=0 option
2487 {
2488     my $wrapper = DebugWrap->new(
2489         {
2490             cmds =>
2491             [
2492                 'o PrintRet=0',
2493                 'b 29',
2494                 'c',
2495                 q/$x = 's';/,
2496                 'b 10',
2497                 'c',
2498                 'r',
2499                 'q',
2500             ],
2501             prog => '../lib/perl5db/t/test-PrintRet-option-1',
2502         }
2503     );
2504
2505     $wrapper->contents_unlike(
2506         qr/scalar context/,
2507         "Test o PrintRet=0",
2508     );
2509 }
2510
2511 # Test the o PrintRet=1 option in list context
2512 {
2513     my $wrapper = DebugWrap->new(
2514         {
2515             cmds =>
2516             [
2517                 'o PrintRet=1',
2518                 'b 29',
2519                 'c',
2520                 q/$x = 'l';/,
2521                 'b 17',
2522                 'c',
2523                 'r',
2524                 'q',
2525             ],
2526             prog => '../lib/perl5db/t/test-PrintRet-option-1',
2527         }
2528     );
2529
2530     $wrapper->contents_like(
2531         qr/list context return from main::return_list:\n0\s*'Foo'\n1\s*'Bar'\n2\s*'Baz'\n/,
2532         "Test o PrintRet=1 in list context",
2533     );
2534 }
2535
2536 # Test the o PrintRet=0 option in list context
2537 {
2538     my $wrapper = DebugWrap->new(
2539         {
2540             cmds =>
2541             [
2542                 'o PrintRet=0',
2543                 'b 29',
2544                 'c',
2545                 q/$x = 'l';/,
2546                 'b 17',
2547                 'c',
2548                 'r',
2549                 'q',
2550             ],
2551             prog => '../lib/perl5db/t/test-PrintRet-option-1',
2552         }
2553     );
2554
2555     $wrapper->contents_unlike(
2556         qr/list context/,
2557         "Test o PrintRet=0 in list context",
2558     );
2559 }
2560
2561 # Test the o PrintRet=1 option in void context
2562 {
2563     my $wrapper = DebugWrap->new(
2564         {
2565             cmds =>
2566             [
2567                 'o PrintRet=1',
2568                 'b 29',
2569                 'c',
2570                 q/$x = 'v';/,
2571                 'b 24',
2572                 'c',
2573                 'r',
2574                 'q',
2575             ],
2576             prog => '../lib/perl5db/t/test-PrintRet-option-1',
2577         }
2578     );
2579
2580     $wrapper->contents_like(
2581         qr/void context return from main::return_void/,
2582         "Test o PrintRet=1 in void context",
2583     );
2584 }
2585
2586 # Test the o PrintRet=1 option in void context
2587 {
2588     my $wrapper = DebugWrap->new(
2589         {
2590             cmds =>
2591             [
2592                 'o PrintRet=0',
2593                 'b 29',
2594                 'c',
2595                 q/$x = 'v';/,
2596                 'b 24',
2597                 'c',
2598                 'r',
2599                 'q',
2600             ],
2601             prog => '../lib/perl5db/t/test-PrintRet-option-1',
2602         }
2603     );
2604
2605     $wrapper->contents_unlike(
2606         qr/void context/,
2607         "Test o PrintRet=0 in void context",
2608     );
2609 }
2610
2611 # Test the o frame option.
2612 {
2613     my $wrapper = DebugWrap->new(
2614         {
2615             cmds =>
2616             [
2617                 # This is to avoid getting the "Debugger program terminated"
2618                 # junk that interferes with the normal output.
2619                 'o inhibit_exit=0',
2620                 'b 10',
2621                 'c',
2622                 'o frame=255',
2623                 'c',
2624                 'q',
2625             ],
2626             prog => '../lib/perl5db/t/test-frame-option-1',
2627         }
2628     );
2629
2630     $wrapper->contents_like(
2631         qr/
2632             in\s*\.=main::my_other_func\(3,\ 1200\)\ from.*?
2633             out\s*\.=main::my_other_func\(3,\ 1200\)\ from
2634         /msx,
2635         "Test o PrintRet=0 in void context",
2636     );
2637 }
2638
2639 { # test t expr
2640     my $wrapper = DebugWrap->new(
2641         {
2642             cmds =>
2643             [
2644                 # This is to avoid getting the "Debugger program terminated"
2645                 # junk that interferes with the normal output.
2646                 'o inhibit_exit=0',
2647                 't fact(3)',
2648                 'q',
2649             ],
2650             prog => '../lib/perl5db/t/fact',
2651         }
2652     );
2653
2654     $wrapper->contents_like(
2655         qr/
2656             (?:^main::fact.*return\ \$n\ \*\ fact\(\$n\ -\ 1\);.*)
2657         /msx,
2658         "Test t expr",
2659     );
2660 }
2661
2662 # Test the w for lexical variables expression.
2663 {
2664     my $wrapper = DebugWrap->new(
2665         {
2666             cmds =>
2667             [
2668                 # This is to avoid getting the "Debugger program terminated"
2669                 # junk that interferes with the normal output.
2670                 'w $exp',
2671                 'n',
2672                 'n',
2673                 'n',
2674                 'n',
2675                 'q',
2676             ],
2677             prog => '../lib/perl5db/t/break-on-dot',
2678         }
2679     );
2680
2681     $wrapper->contents_like(
2682         qr/
2683 \s+old\ value:\s+'1'\n
2684 \s+new\ value:\s+'2'\n
2685         /msx,
2686         "Test w for lexical values.",
2687     );
2688 }
2689
2690 # Test the perldoc command
2691 # We don't actually run the program, but we need to provide one to the wrapper.
2692 SKIP:
2693 {
2694     $^O eq "linux"
2695         or skip "man errors aren't especially portable", 1;
2696     local $ENV{LANG} = "C";
2697     local $ENV{LC_MESSAGE} = "C";
2698     local $ENV{LC_ALL} = "C";
2699     my $wrapper = DebugWrap->new(
2700         {
2701             cmds =>
2702             [
2703                 'perldoc perlrules',
2704                 'q',
2705             ],
2706             prog => '../lib/perl5db/t/fact',
2707         }
2708     );
2709
2710     $wrapper->output_like(
2711         qr/No manual entry for perlrules/,
2712         'perldoc command works fine',
2713     );
2714 }
2715
2716 END {
2717     1 while unlink ($rc_filename, $out_fn);
2718 }