+# Disable and enable for breakpoints on outer files.
+{
+ my $wrapper = DebugWrap->new(
+ {
+ cmds =>
+ [
+ 'b 10',
+ 'b ../lib/perl5db/t/EnableModule.pm:14',
+ 'disable ../lib/perl5db/t/EnableModule.pm:14',
+ 'c',
+ 'enable ../lib/perl5db/t/EnableModule.pm:14',
+ 'c',
+ q/print "X={$x}\n";/,
+ 'c',
+ 'q',
+ ],
+ prog => '../lib/perl5db/t/disable-breakpoints-3',
+ include_t => 1,
+ }
+ );
+
+ $wrapper->output_like(qr/
+ X=\{SecondValTwoHundred\}
+ /msx,
+ "Can set breakpoint in a line.");
+}
+
+# Testing that the prompt with the information appears.
+{
+ my $wrapper = DebugWrap->new(
+ {
+ cmds => ['q'],
+ prog => '../lib/perl5db/t/disable-breakpoints-1',
+ }
+ );
+
+ $wrapper->contents_like(qr/
+ ^main::\([^\)]*\bdisable-breakpoints-1:2\):\n
+ 2:\s+my\ \$x\ =\ "One";\n
+ /msx,
+ "Prompt should display the first line of code.");
+}
+
+# Testing that R (restart) and "B *" work.
+{
+ my $wrapper = DebugWrap->new(
+ {
+ cmds =>
+ [
+ 'b 13',
+ 'c',
+ 'B *',
+ 'b 9',
+ 'R',
+ 'c',
+ q/print "X={$x};dummy={$dummy}\n";/,
+ 'q',
+ ],
+ prog => '../lib/perl5db/t/disable-breakpoints-1',
+ }
+ );
+
+ $wrapper->output_like(qr/
+ X=\{FirstVal\};dummy=\{1\}
+ /msx,
+ "Restart and delete all breakpoints work properly.");
+}
+
+{
+ my $wrapper = DebugWrap->new(
+ {
+ cmds =>
+ [
+ 'c 15',
+ q/print "X={$x}\n";/,
+ 'c',
+ 'q',
+ ],
+ prog => '../lib/perl5db/t/disable-breakpoints-1',
+ }
+ );
+
+ $wrapper->output_like(qr/
+ X=\{ThirdVal\}
+ /msx,
+ "'c line_num' is working properly.");
+}
+
+{
+ my $wrapper = DebugWrap->new(
+ {
+ cmds =>
+ [
+ 'n',
+ 'n',
+ 'b . $exp > 200',
+ 'c',
+ q/print "Exp={$exp}\n";/,
+ 'q',
+ ],
+ prog => '../lib/perl5db/t/break-on-dot',
+ }
+ );
+
+ $wrapper->output_like(qr/
+ Exp=\{256\}
+ /msx,
+ "'b .' is working correctly.");
+}
+
+# Testing that the prompt with the information appears inside a subroutine call.
+# See https://rt.perl.org/rt3/Ticket/Display.html?id=104820
+{
+ my $wrapper = DebugWrap->new(
+ {
+ cmds =>
+ [
+ 'c back',
+ 'q',
+ ],
+ prog => '../lib/perl5db/t/with-subroutine',
+ }
+ );
+
+ $wrapper->contents_like(
+ qr/
+ ^main::back\([^\)\n]*\bwith-subroutine:15\):[\ \t]*\n
+ ^15:\s*print\ "hello\ back\\n";
+ /msx,
+ "Prompt should display the line of code inside a subroutine.");
+}
+
+# Checking that the p command works.
+{
+ my $wrapper = DebugWrap->new(
+ {
+ cmds =>
+ [
+ 'p "<<<" . (4*6) . ">>>"',
+ 'q',
+ ],
+ prog => '../lib/perl5db/t/with-subroutine',
+ }
+ );
+
+ $wrapper->contents_like(
+ qr/<<<24>>>/,
+ "p command works.");
+}
+
+# Tests for x.
+{
+ my $wrapper = DebugWrap->new(
+ {
+ cmds =>
+ [
+ q/x {500 => 600}/,
+ 'q',
+ ],
+ prog => '../lib/perl5db/t/with-subroutine',
+ }
+ );
+
+ $wrapper->contents_like(
+ # qr/^0\s+HASH\([^\)]+\)\n\s+500 => 600\n/,
+ qr/^0\s+HASH\([^\)]+\)\n\s+500 => 600\n/ms,
+ "x command test."
+ );
+}
+
+# Tests for "T" (stack trace).
+{
+ my $prog_fn = '../lib/perl5db/t/rt-104168';
+ my $wrapper = DebugWrap->new(
+ {
+ prog => $prog_fn,
+ cmds =>
+ [
+ 'c baz',
+ 'T',
+ 'q',
+ ],
+ }
+ );
+ my $re_text = join('',
+ map {
+ sprintf(
+ "%s = %s\\(\\) called from file " .
+ "'" . quotemeta($prog_fn) . "' line %s\\n",
+ (map { quotemeta($_) } @$_)
+ )
+ }
+ (
+ ['.', 'main::baz', 14,],
+ ['.', 'main::bar', 9,],
+ ['.', 'main::foo', 6]
+ )
+ );
+ $wrapper->contents_like(
+ # qr/^0\s+HASH\([^\)]+\)\n\s+500 => 600\n/,
+ qr/^$re_text/ms,
+ "T command test."
+ );
+}
+
+# Test for s.
+{
+ my $wrapper = DebugWrap->new(
+ {
+ cmds =>
+ [
+ 'b 9',
+ 'c',
+ 's',
+ q/print "X={$x};dummy={$dummy}\n";/,
+ 'q',
+ ],
+ prog => '../lib/perl5db/t/disable-breakpoints-1'
+ }
+ );
+
+ $wrapper->output_like(qr/
+ X=\{SecondVal\};dummy=\{1\}
+ /msx,
+ 'test for s - single step',
+ );
+}
+
+{
+ my $wrapper = DebugWrap->new(
+ {
+ cmds =>
+ [
+ 'n',
+ 'n',
+ 'b . $exp > 200',
+ 'c',
+ q/print "Exp={$exp}\n";/,
+ 'q',
+ ],
+ prog => '../lib/perl5db/t/break-on-dot'
+ }
+ );
+
+ $wrapper->output_like(qr/
+ Exp=\{256\}
+ /msx,
+ "'b .' is working correctly.");
+}
+
+{
+ my $prog_fn = '../lib/perl5db/t/rt-104168';
+ my $wrapper = DebugWrap->new(
+ {
+ cmds =>
+ [
+ 's',
+ 'q',
+ ],
+ prog => $prog_fn,
+ }
+ );
+
+ $wrapper->contents_like(
+ qr/
+ ^main::foo\([^\)\n]*\brt-104168:9\):[\ \t]*\n
+ ^9:\s*bar\(\);
+ /msx,
+ 'Test for the s command.',
+ );
+}
+
+{
+ my $wrapper = DebugWrap->new(
+ {
+ cmds =>
+ [
+ 's uncalled_subroutine()',
+ 'c',
+ 'q',
+ ],
+
+ prog => '../lib/perl5db/t/uncalled-subroutine'}
+ );
+
+ $wrapper->output_like(
+ qr/<1,2,3,4,5>\n/,
+ 'uncalled_subroutine was called after s EXPR()',
+ );
+}
+
+{
+ my $wrapper = DebugWrap->new(
+ {
+ cmds =>
+ [
+ 'n uncalled_subroutine()',
+ 'c',
+ 'q',
+ ],
+ prog => '../lib/perl5db/t/uncalled-subroutine',
+ }
+ );
+
+ $wrapper->output_like(
+ qr/<1,2,3,4,5>\n/,
+ 'uncalled_subroutine was called after n EXPR()',
+ );
+}
+
+{
+ my $wrapper = DebugWrap->new(
+ {
+ cmds =>
+ [
+ 'b fact',
+ 'c',
+ 'c',
+ 'c',
+ 'n',
+ 'print "<$n>"',
+ 'q',
+ ],
+ prog => '../lib/perl5db/t/fact',
+ }
+ );
+
+ $wrapper->output_like(
+ qr/<3>/,
+ 'b subroutine works fine',
+ );
+}
+
+# Test for 'M' (module list).
+{
+ my $wrapper = DebugWrap->new(
+ {
+ cmds =>
+ [
+ 'M',
+ 'q',
+ ],
+ prog => '../lib/perl5db/t/load-modules'
+ }
+ );
+
+ $wrapper->contents_like(
+ qr[Scalar/Util\.pm],
+ 'M (module list) works fine',
+ );
+}
+
+{
+ my $wrapper = DebugWrap->new(
+ {
+ cmds =>
+ [
+ 'b 14',
+ 'c',
+ '$flag = 1;',
+ 'r',
+ 'print "Var=$var\n";',
+ 'q',
+ ],
+ prog => '../lib/perl5db/t/test-r-statement',
+ }
+ );
+
+ $wrapper->output_like(
+ qr/
+ ^Foo$
+ .*?
+ ^Bar$
+ .*?
+ ^Var=Test$
+ /msx,
+ 'r statement is working properly.',
+ );
+}
+
+{
+ my $wrapper = DebugWrap->new(
+ {
+ cmds =>
+ [
+ 'l',
+ 'q',
+ ],
+ prog => '../lib/perl5db/t/test-l-statement-1',
+ }
+ );
+
+ $wrapper->contents_like(
+ qr/
+ ^1==>\s+\$x\ =\ 1;\n
+ 2:\s+print\ "1\\n";\n
+ 3\s*\n
+ 4:\s+\$x\ =\ 2;\n
+ 5:\s+print\ "2\\n";\n
+ /msx,
+ 'l statement is working properly (test No. 1).',
+ );
+}
+