byebug 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. data/.gitignore +10 -0
  2. data/.travis.yml +8 -0
  3. data/AUTHORS +10 -0
  4. data/CHANGELOG.md +2 -0
  5. data/CONTRIBUTING.md +1 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +20 -0
  8. data/README.md +5 -0
  9. data/Rakefile +28 -0
  10. data/bin/byebug +395 -0
  11. data/byebug.gemspec +29 -0
  12. data/doc/hanoi.rb +35 -0
  13. data/doc/primes.rb +28 -0
  14. data/doc/rdebug-emacs.texi +1030 -0
  15. data/doc/test-tri2.rb +18 -0
  16. data/doc/tri3.rb +8 -0
  17. data/doc/triangle.rb +12 -0
  18. data/ext/byebug/breakpoint.c +476 -0
  19. data/ext/byebug/byebug.c +512 -0
  20. data/ext/byebug/byebug.h +131 -0
  21. data/ext/byebug/context.c +424 -0
  22. data/ext/byebug/extconf.rb +21 -0
  23. data/ext/byebug/locker.c +53 -0
  24. data/lib/byebug.rb +404 -0
  25. data/lib/byebug/command.rb +232 -0
  26. data/lib/byebug/commands/breakpoints.rb +153 -0
  27. data/lib/byebug/commands/catchpoint.rb +56 -0
  28. data/lib/byebug/commands/condition.rb +49 -0
  29. data/lib/byebug/commands/continue.rb +38 -0
  30. data/lib/byebug/commands/control.rb +110 -0
  31. data/lib/byebug/commands/display.rb +122 -0
  32. data/lib/byebug/commands/edit.rb +48 -0
  33. data/lib/byebug/commands/enable.rb +202 -0
  34. data/lib/byebug/commands/eval.rb +176 -0
  35. data/lib/byebug/commands/finish.rb +43 -0
  36. data/lib/byebug/commands/frame.rb +303 -0
  37. data/lib/byebug/commands/help.rb +56 -0
  38. data/lib/byebug/commands/info.rb +462 -0
  39. data/lib/byebug/commands/irb.rb +123 -0
  40. data/lib/byebug/commands/jump.rb +66 -0
  41. data/lib/byebug/commands/kill.rb +51 -0
  42. data/lib/byebug/commands/list.rb +94 -0
  43. data/lib/byebug/commands/method.rb +84 -0
  44. data/lib/byebug/commands/quit.rb +39 -0
  45. data/lib/byebug/commands/reload.rb +40 -0
  46. data/lib/byebug/commands/save.rb +90 -0
  47. data/lib/byebug/commands/set.rb +210 -0
  48. data/lib/byebug/commands/show.rb +246 -0
  49. data/lib/byebug/commands/skip.rb +35 -0
  50. data/lib/byebug/commands/source.rb +36 -0
  51. data/lib/byebug/commands/stepping.rb +83 -0
  52. data/lib/byebug/commands/threads.rb +189 -0
  53. data/lib/byebug/commands/tmate.rb +36 -0
  54. data/lib/byebug/commands/trace.rb +56 -0
  55. data/lib/byebug/commands/variables.rb +199 -0
  56. data/lib/byebug/context.rb +58 -0
  57. data/lib/byebug/helper.rb +69 -0
  58. data/lib/byebug/interface.rb +223 -0
  59. data/lib/byebug/processor.rb +468 -0
  60. data/lib/byebug/version.rb +3 -0
  61. data/man/rdebug.1 +241 -0
  62. data/test/breakpoints_test.rb +357 -0
  63. data/test/conditions_test.rb +77 -0
  64. data/test/continue_test.rb +44 -0
  65. data/test/display_test.rb +141 -0
  66. data/test/edit_test.rb +56 -0
  67. data/test/eval_test.rb +92 -0
  68. data/test/examples/breakpoint1.rb +15 -0
  69. data/test/examples/breakpoint2.rb +7 -0
  70. data/test/examples/conditions.rb +4 -0
  71. data/test/examples/continue.rb +4 -0
  72. data/test/examples/display.rb +5 -0
  73. data/test/examples/edit.rb +3 -0
  74. data/test/examples/edit2.rb +3 -0
  75. data/test/examples/eval.rb +4 -0
  76. data/test/examples/finish.rb +20 -0
  77. data/test/examples/frame.rb +20 -0
  78. data/test/examples/frame_threads.rb +31 -0
  79. data/test/examples/help.rb +2 -0
  80. data/test/examples/info.rb +38 -0
  81. data/test/examples/info2.rb +3 -0
  82. data/test/examples/info_threads.rb +48 -0
  83. data/test/examples/irb.rb +6 -0
  84. data/test/examples/jump.rb +14 -0
  85. data/test/examples/kill.rb +2 -0
  86. data/test/examples/list.rb +12 -0
  87. data/test/examples/method.rb +15 -0
  88. data/test/examples/post_mortem.rb +19 -0
  89. data/test/examples/quit.rb +2 -0
  90. data/test/examples/reload.rb +6 -0
  91. data/test/examples/restart.rb +6 -0
  92. data/test/examples/save.rb +3 -0
  93. data/test/examples/set.rb +3 -0
  94. data/test/examples/set_annotate.rb +12 -0
  95. data/test/examples/settings.rb +1 -0
  96. data/test/examples/show.rb +2 -0
  97. data/test/examples/source.rb +3 -0
  98. data/test/examples/stepping.rb +21 -0
  99. data/test/examples/thread.rb +32 -0
  100. data/test/examples/tmate.rb +10 -0
  101. data/test/examples/trace.rb +7 -0
  102. data/test/examples/trace_threads.rb +20 -0
  103. data/test/examples/variables.rb +26 -0
  104. data/test/finish_test.rb +48 -0
  105. data/test/frame_test.rb +143 -0
  106. data/test/help_test.rb +50 -0
  107. data/test/info_test.rb +313 -0
  108. data/test/irb_test.rb +81 -0
  109. data/test/jump_test.rb +70 -0
  110. data/test/kill_test.rb +48 -0
  111. data/test/list_test.rb +145 -0
  112. data/test/method_test.rb +70 -0
  113. data/test/post_mortem_test.rb +27 -0
  114. data/test/quit_test.rb +56 -0
  115. data/test/reload_test.rb +44 -0
  116. data/test/restart_test.rb +164 -0
  117. data/test/save_test.rb +92 -0
  118. data/test/set_test.rb +177 -0
  119. data/test/show_test.rb +293 -0
  120. data/test/source_test.rb +45 -0
  121. data/test/stepping_test.rb +130 -0
  122. data/test/support/breakpoint.rb +13 -0
  123. data/test/support/context.rb +14 -0
  124. data/test/support/matchers.rb +67 -0
  125. data/test/support/mocha_extensions.rb +72 -0
  126. data/test/support/processor.rb +7 -0
  127. data/test/support/test_dsl.rb +206 -0
  128. data/test/support/test_interface.rb +68 -0
  129. data/test/test_helper.rb +10 -0
  130. data/test/tmate_test.rb +44 -0
  131. data/test/trace_test.rb +159 -0
  132. data/test/variables_test.rb +119 -0
  133. metadata +265 -0
@@ -0,0 +1,48 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe "Finish Command" do
4
+ include TestDsl
5
+
6
+ it "must stop at the next frame by default" do
7
+ enter 'break 16', 'cont', 'finish'
8
+ debug_file('finish') { state.line.must_equal 13 }
9
+ end
10
+
11
+ it "must stop at the #0 frame by default" do
12
+ enter 'break 16', 'cont', 'finish 0'
13
+ debug_file('finish') { state.line.must_equal 13 }
14
+ end
15
+
16
+ it "must stop at the specified frame" do
17
+ enter 'break 16', 'cont', 'finish 1'
18
+ debug_file('finish') { state.line.must_equal 9 }
19
+ end
20
+
21
+ it "must stop at the next frame if the current frame was changed" do
22
+ enter 'break 16', 'cont', 'up', 'finish'
23
+ debug_file('finish') { state.line.must_equal 9 }
24
+ end
25
+
26
+ describe "not a number is specified for frame" do
27
+ before { enter 'break 16', 'cont', 'finish foo' }
28
+
29
+ it "must show an error" do
30
+ debug_file('finish')
31
+ check_output_includes "Finish argument 'foo' needs to be a number."
32
+ end
33
+
34
+ it "must be on the same line" do
35
+ debug_file('finish') { state.line.must_equal 16 }
36
+ end
37
+ end
38
+
39
+ describe "Post Mortem" do
40
+ it "must not work in post-mortem mode" do
41
+ skip("No post morten mode for now")
42
+ #enter 'cont', 'finish'
43
+ #debug_file "post_mortem"
44
+ #check_output_includes 'Unknown command: "finish". Try "help".', interface.error_queue
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,143 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe "Frame Command" do
4
+ include TestDsl
5
+
6
+ it "must go up" do
7
+ enter 'break 16', 'cont', 'up'
8
+ debug_file('frame') { state.line.must_equal 12 }
9
+ end
10
+
11
+ it "must go up by specific number of frames" do
12
+ enter 'break 16', 'cont', 'up 2'
13
+ debug_file('frame') { state.line.must_equal 8 }
14
+ end
15
+
16
+ it "must go down" do
17
+ enter 'break 16', 'cont', 'up', 'down'
18
+ debug_file('frame') { state.line.must_equal 16 }
19
+ end
20
+
21
+ it "must go down by specific number of frames" do
22
+ enter 'break 16', 'cont', 'up 3', 'down 2'
23
+ debug_file('frame') { state.line.must_equal 12 }
24
+ end
25
+
26
+ it "must set frame" do
27
+ enter 'break 16', 'cont', 'frame 2'
28
+ debug_file('frame') { state.line.must_equal 8 }
29
+ end
30
+
31
+ it "must set frame to the first one by default" do
32
+ enter 'break 16', 'cont', 'up', 'frame'
33
+ debug_file('frame') { state.line.must_equal 16 }
34
+ end
35
+
36
+ it "must print current stack frame when without arguments" do
37
+ enter 'break A.d', 'cont', 'up', 'frame'
38
+ debug_file('frame') { check_output_includes "#0", "A::d" }
39
+ # XXX: Deal with arguments
40
+ #check_output_includes "#0 ", "A.d(e#String)"
41
+ #check_output_includes "#0 ", "A.d"
42
+ end
43
+
44
+ it "must set frame to the first one" do
45
+ enter 'break 16', 'cont', 'up', 'frame 0'
46
+ debug_file('frame') { state.line.must_equal 16 }
47
+ end
48
+
49
+ it "must set frame to the last one" do
50
+ enter 'break 16', 'cont', 'frame -1'
51
+ debug_file('frame') { state.line.must_equal 20 }
52
+ end
53
+
54
+ it "must not set frame if the frame number is too low" do
55
+ enter 'break 16', 'cont', 'down'
56
+ debug_file('frame') { state.line.must_equal 16 }
57
+ check_output_includes "Adjusting would put us beyond the newest (innermost) frame.", interface.error_queue
58
+ end
59
+
60
+ it "must not set frame if the frame number is too high" do
61
+ enter 'break 16', 'cont', 'up 100'
62
+ debug_file('frame') { state.line.must_equal 16 }
63
+ check_output_includes "Adjusting would put us beyond the oldest (initial) frame.", interface.error_queue
64
+ end
65
+
66
+ describe "full path settings" do
67
+ temporary_change_hash_value(Byebug::Command.settings, :full_path, false)
68
+
69
+ def short_path(fullpath)
70
+ separator = File::ALT_SEPARATOR || File::SEPARATOR
71
+ "...#{separator}" + fullpath.split(separator)[-3..-1].join(separator)
72
+ end
73
+
74
+ it "must display current backtrace with full path = true" do
75
+ enter 'set fullpath', 'break 16', 'cont', 'where'
76
+ debug_file('frame')
77
+ check_output_includes(
78
+ "-->", "#0", "A.d(e#String)", "at line #{fullpath('frame')}:16",
79
+ "#1", "A.c", "at line #{fullpath('frame')}:12"
80
+ )
81
+ end
82
+
83
+ it "must display current backtrace with full path = false" do
84
+ enter 'set nofullpath', 'break 16', 'cont', 'where'
85
+ debug_file('frame')
86
+ check_output_includes(
87
+ "-->", "#0", "A.d(e#String)", "at line #{short_path(fullpath('frame'))}:16",
88
+ "#1", "A.c", "at line #{short_path(fullpath('frame'))}:12"
89
+ )
90
+ end
91
+ end
92
+
93
+ describe "display backtrace with callstyle" do
94
+ temporary_change_hash_value(Byebug::Command.settings, :callstyle, :last)
95
+
96
+ it "must display current backtrace" do
97
+ enter 'set callstyle last', 'break 16', 'cont', 'where'
98
+ debug_file('frame')
99
+ check_output_includes(
100
+ "-->", "#0", "A.d(e#String)", "at line #{fullpath('frame')}:16",
101
+ "#1", "A.c", "at line #{fullpath('frame')}:12",
102
+ "#2", "A.b", "at line #{fullpath('frame')}:8",
103
+ "#3", "A.a", "at line #{fullpath('frame')}:5"
104
+ )
105
+ end
106
+
107
+ it "must display current backtrace" do
108
+ enter 'set callstyle short', 'break 25', 'cont', 'where'
109
+ debug_file('frame')
110
+ check_output_includes(
111
+ "-->", "#0", "d(e)", "at line #{fullpath('frame')}:16",
112
+ "#1", "c", "at line #{fullpath('frame')}:12",
113
+ "#2", "b", "at line #{fullpath('frame')}:8",
114
+ "#3", "a", "at line #{fullpath('frame')}:5"
115
+ )
116
+ end
117
+
118
+ # NOTE: We also have support of 'tracked' callstyle in the code,
119
+ # but for some reason it is not set by the 'set' command
120
+ it "must not set 'tracked' callstyle" do
121
+ enter 'set callstyle tracked'
122
+ debug_file('frame')
123
+ check_output_includes "Invalid call style tracked. Should be one of: 'short' or 'last'."
124
+ Byebug::Command.settings[:callstyle].must_equal :last
125
+ end
126
+ end
127
+
128
+ it "must change frame in another thread"
129
+ it "must not change frame in another thread if specified thread doesn't exist"
130
+
131
+ describe "Post Mortem" do
132
+ # TODO: This test fails with "Segmentation fault". Probably need to fix it somehow, or forbid this
133
+ # command in the post mortem mode. Seems like state.context.frame_file and state.context.frame_line
134
+ # cause that.
135
+ it "must work in post-mortem mode" do
136
+ skip("No post morten mode for now")
137
+ #enter 'cont', "frame"
138
+ #debug_file "post_mortem"
139
+ #pi
140
+ end
141
+ end
142
+
143
+ end
@@ -0,0 +1,50 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe "Help Command" do
4
+ include TestDsl
5
+ include Columnize
6
+
7
+ let(:available_commands) do
8
+ Byebug::Command.commands.select(&:event).map(&:help_command).flatten.uniq.sort
9
+ end
10
+
11
+ it "must show help how to use 'help'" do
12
+ temporary_change_hash_value(Byebug::HelpCommand.settings, :width, 50) do
13
+ enter 'help'
14
+ debug_file('help')
15
+ check_output_includes(
16
+ "Type 'help <command-name>' for help on a specific command",
17
+ "Available commands:",
18
+ columnize(available_commands, 50)
19
+ )
20
+ end
21
+ end
22
+
23
+ it "must show help when use shortcut" do
24
+ enter 'h'
25
+ debug_file('help')
26
+ check_output_includes "Type 'help <command-name>' for help on a specific command"
27
+ end
28
+
29
+ it "must show an error if undefined command is specified" do
30
+ enter 'help foobar'
31
+ debug_file('help')
32
+ check_output_includes 'Undefined command: "foobar". Try "help".', interface.error_queue
33
+ end
34
+
35
+ it "must show a command's help" do
36
+ enter 'help break'
37
+ debug_file('help')
38
+ check_output_includes Byebug::AddBreakpoint.help(nil).split("\n").map { |l| l.gsub(/^ +/, '') }.join("\n")
39
+ end
40
+
41
+ describe "Post Mortem" do
42
+ it "must work in post-mortem mode" do
43
+ skip("No post morten mode for now")
44
+ #enter 'cont', 'help'
45
+ #debug_file "post_mortem"
46
+ #check_output_includes "Available commands:"
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,313 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe "Info Command" do
4
+ include TestDsl
5
+ include Columnize
6
+
7
+ describe "Args info" do
8
+ temporary_change_hash_value(Byebug::InfoCommand.settings, :width, 15)
9
+
10
+ it "must show info about all args" do
11
+ skip ("XXX: How to handle args in the new API?")
12
+ #enter 'break 3', 'cont', 'info args'
13
+ #debug_file 'info'
14
+ #check_output_includes 'a = "aaaaaaa...', 'b = "b"'
15
+ end
16
+ end
17
+
18
+ describe "Breakpoints info" do
19
+ it "must show info about all breakpoints" do
20
+ enter 'break 7', 'break 9 if a == b', 'info breakpoints'
21
+ debug_file 'info'
22
+ check_output_includes(
23
+ "Num Enb What",
24
+ /\d+ y at #{fullpath('info')}:7/,
25
+ /\d+ y at #{fullpath('info')}:9 if a == b/
26
+ )
27
+ end
28
+
29
+ it "must show info about specific breakpoint" do
30
+ enter 'break 7', 'break 9', ->{"info breakpoints #{breakpoint.id}"}
31
+ debug_file 'info'
32
+ check_output_includes "Num Enb What", /\d+ y at #{fullpath('info')}:7/
33
+ check_output_doesnt_include /\d+ y at #{fullpath('info')}:9/
34
+ end
35
+
36
+ it "must show an error if no breakpoints are found" do
37
+ enter 'info breakpoints'
38
+ debug_file 'info'
39
+ check_output_includes "No breakpoints."
40
+ end
41
+
42
+ it "must show an error if no breakpoints are found" do
43
+ enter 'break 7', 'info breakpoints 123'
44
+ debug_file 'info'
45
+ check_output_includes "No breakpoints found among list given.", interface.error_queue
46
+ end
47
+
48
+ it "must show hit count" do
49
+ enter 'break 9', 'cont', 'info breakpoints'
50
+ debug_file 'info'
51
+ check_output_includes /\d+ y at #{fullpath('info')}:9/, "breakpoint already hit 1 time"
52
+ end
53
+ end
54
+
55
+ describe "Display info" do
56
+ it "must show all display expressions" do
57
+ enter 'display 3 + 3', 'display a + b', 'info display'
58
+ debug_file 'info'
59
+ check_output_includes(
60
+ "Auto-display expressions now in effect:",
61
+ "Num Enb Expression",
62
+ "1: y 3 + 3",
63
+ "2: y a + b"
64
+ )
65
+ end
66
+
67
+ it "must show a message if there are no display expressions created" do
68
+ enter 'info display'
69
+ debug_file 'info'
70
+ check_output_includes "There are no auto-display expressions now."
71
+ end
72
+ end
73
+
74
+ describe "Files info" do
75
+ let(:files) { (LineCache.cached_files + SCRIPT_LINES__.keys).uniq.sort }
76
+ it "must show all files read in" do
77
+ enter 'info files'
78
+ debug_file 'info'
79
+ check_output_includes files.map { |f| "File #{f}" }
80
+ end
81
+
82
+ it "must show all files read in using 'info file' too" do
83
+ enter 'info file'
84
+ debug_file 'info'
85
+ check_output_includes files.map { |f| "File #{f}" }
86
+ end
87
+
88
+ it "must show explicitly loaded files" do
89
+ enter 'info files stat'
90
+ debug_file 'info'
91
+ check_output_includes "File #{fullpath('info')}", LineCache.stat(fullpath('info')).mtime.to_s
92
+ end
93
+ end
94
+
95
+ describe "File info" do
96
+ let(:file) { fullpath('info') }
97
+ let(:filename) { "File #{file}" }
98
+ let(:lines) { "#{LineCache.size(file)} lines" }
99
+ let(:mtime) { LineCache.stat(file).mtime.to_s }
100
+ let(:sha1) { LineCache.sha1(file) }
101
+ let(:breakpoint_line_numbers) do
102
+ columnize(LineCache.trace_line_numbers(file).to_a.sort, Byebug::InfoCommand.settings[:width])
103
+ end
104
+
105
+ it "must show basic info about the file" do
106
+ enter "info file #{file} basic"
107
+ debug_file 'info'
108
+ check_output_includes filename, lines
109
+ check_output_doesnt_include breakpoint_line_numbers, mtime, sha1
110
+ end
111
+
112
+ it "must show number of lines" do
113
+ enter "info file #{file} lines"
114
+ debug_file 'info'
115
+ check_output_includes filename, lines
116
+ check_output_doesnt_include breakpoint_line_numbers, mtime, sha1
117
+ end
118
+
119
+ it "must show mtime of the file" do
120
+ enter "info file #{file} mtime"
121
+ debug_file 'info'
122
+ check_output_includes filename, mtime
123
+ check_output_doesnt_include lines, breakpoint_line_numbers, sha1
124
+ end
125
+
126
+ it "must show sha1 of the file" do
127
+ enter "info file #{file} sha1"
128
+ debug_file 'info'
129
+ check_output_includes filename, sha1
130
+ check_output_doesnt_include lines, breakpoint_line_numbers, mtime
131
+ end
132
+
133
+ it "must show breakpoints in the file" do
134
+ enter 'break 5', 'break 7', "info file #{file} breakpoints"
135
+ debug_file 'info'
136
+ check_output_includes(
137
+ filename, "breakpoint line numbers:", breakpoint_line_numbers,
138
+ /Breakpoint \d+ at #{file}:5/, /Breakpoint \d+ at #{file}:7/
139
+ )
140
+ check_output_doesnt_include lines, mtime, sha1
141
+ end
142
+
143
+ it "must show all info about the file" do
144
+ enter "info file #{file} all"
145
+ debug_file 'info'
146
+ check_output_includes filename, lines, breakpoint_line_numbers, mtime, sha1
147
+ end
148
+
149
+ it "must not show info about the file if the file is not loaded" do
150
+ enter "info file #{fullpath('info2')} basic"
151
+ debug_file 'info'
152
+ check_output_includes "File #{fullpath('info2')} is not cached"
153
+ end
154
+
155
+ it "must not show any info if the parameter is invalid" do
156
+ enter "info file #{file} blabla"
157
+ debug_file 'info'
158
+ check_output_includes "Invalid parameter blabla", interface.error_queue
159
+ end
160
+ end
161
+
162
+ describe "Instance variables info" do
163
+ it "must show instance variables" do
164
+ enter 'break 21', 'cont', 'info instance_variables'
165
+ debug_file 'info'
166
+ check_output_includes '@bla = "blabla"', '@foo = "bar"'
167
+ end
168
+ end
169
+
170
+ describe "Line info" do
171
+ it "must show the current line" do
172
+ enter 'break 21', 'cont', 'info line'
173
+ debug_file 'info'
174
+ check_output_includes "Line 21 of \"#{fullpath('info')}\""
175
+ end
176
+ end
177
+
178
+ # describe "Locals info" do
179
+ # it "must show the current local variables" do
180
+ # temporary_change_hash_value(Byebug::InfoCommand.settings, :width, 12) do
181
+ # enter 'break 21', 'cont', 'info locals'
182
+ # debug_file 'info'
183
+ # check_output_includes 'a = "1111...', 'b = 2'
184
+ # end
185
+ # end
186
+
187
+ # it "must fail if the local variable doesn't respond to #to_s or to #inspect" do
188
+ # enter 'break 26', 'cont', 'info locals'
189
+ # debug_file 'info'
190
+ # check_output_includes "*Error in evaluation*"
191
+ # end
192
+ # end
193
+
194
+ describe "Program info" do
195
+ it "must show the initial stop reason" do
196
+ enter 'info program'
197
+ debug_file 'info'
198
+ check_output_includes "It stopped after stepping, next'ing or initial start."
199
+ end
200
+
201
+ it "must show the step stop reason" do
202
+ enter 'step', 'info program'
203
+ debug_file 'info'
204
+ check_output_includes "Program stopped.", "It stopped after stepping, next'ing or initial start."
205
+ end
206
+
207
+ it "must show the breakpoint stop reason" do
208
+ enter 'break 7', 'cont', 'info program'
209
+ debug_file 'info'
210
+ check_output_includes "Program stopped.", "It stopped at a breakpoint."
211
+ end
212
+
213
+ it "must show the catchpoint stop reason"
214
+
215
+ it "must show the unknown stop reason" do
216
+ enter 'break 7', 'cont', ->{context.stubs(:stop_reason).returns("blabla"); 'info program'}
217
+ debug_file 'info'
218
+ check_output_includes "Program stopped.", "unknown reason: blabla"
219
+ end
220
+
221
+ it "must show an error if the program is crashed"
222
+ end
223
+
224
+ describe "Stack info" do
225
+ it "must show stack info" do
226
+ enter 'break 20', 'cont', 'info stack'
227
+ debug_file 'info'
228
+ check_output_includes(
229
+ "-->", "#0", "A.a", "at line #{fullpath('info')}:20",
230
+ "#1", "at line #{fullpath('info')}:30"
231
+ )
232
+ end
233
+ end
234
+
235
+ # describe "Thread info" do
236
+ # it "must show threads info when without args" # TODO: Unreliable due to race conditions, need to fix to be reliable
237
+ # # enter 'break 48', 'cont', 'info threads'
238
+ # # debug_file 'info'
239
+ # # check_output_includes /#<Thread:\S+ run>/, /#<Thread:\S+ run>/
240
+ # # end
241
+ #
242
+ # it "must show thread info" do
243
+ # thread_number = nil
244
+ # enter ->{thread_number = context.thnum; "info thread #{context.thnum}"}
245
+ # debug_file 'info'
246
+ # check_output_includes "+", thread_number.to_s, /#<Thread:\S+ run>/
247
+ # end
248
+ #
249
+ # it "must show verbose thread info" do # TODO: Unreliable due to race conditions, need to fix to be reliable
250
+ # enter 'break 20', 'cont', ->{"info thread #{context.thnum} verbose"}
251
+ # debug_file 'info'
252
+ # check_output_includes /#<Thread:\S+ run>/, "#0", "A.a", "at line #{fullpath('info')}:20"
253
+ # end
254
+ #
255
+ # it "must show error when unknown parameter is used" do
256
+ # enter ->{"info thread #{context.thnum} blabla"}
257
+ # debug_file 'info'
258
+ # check_output_includes "'terse' or 'verbose' expected. Got 'blabla'", interface.error_queue
259
+ # end
260
+ # end
261
+
262
+ describe "Global Variables info" do
263
+ it "must show global variables" do
264
+ skip("XXX: handle global variables, XXX: Fix warning in test")
265
+ #enter 'info global_variables'
266
+ #debug_file 'info'
267
+ #check_output_includes "$$ = #{Process.pid}"
268
+ end
269
+ end
270
+
271
+ describe "Variables info" do
272
+ it "must show all variables" do
273
+ temporary_change_hash_value(Byebug::InfoCommand.settings, :width, 30) do
274
+ enter 'break 21', 'cont', 'info variables'
275
+ debug_file 'info'
276
+ check_output_includes(
277
+ 'a = "1111111111111111111111...',
278
+ "b = 2",
279
+ /self = #<A:\S+.../,
280
+ '@bla = "blabla"',
281
+ '@foo = "bar"'
282
+ )
283
+ end
284
+ end
285
+
286
+ it "must fail if the variable doesn't respond to #to_s or to #inspect" do
287
+ enter 'break 26', 'cont', 'info variables'
288
+ debug_file 'info'
289
+ check_output_includes(
290
+ 'a = *Error in evaluation*',
291
+ /self = #<A:\S+.../,
292
+ '@bla = "blabla"',
293
+ '@foo = "bar"'
294
+ )
295
+ end
296
+
297
+ it "must handle printf strings correctly" do
298
+ enter 'break 32', 'cont', 'info variables'
299
+ debug_file 'info'
300
+ check_output_includes 'e = "%%.2f"'
301
+ end
302
+ end
303
+
304
+ describe "Post Mortem" do
305
+ it "must work in post-mortem mode" do
306
+ skip("No post morten mode for now")
307
+ #enter 'cont', 'info line'
308
+ #debug_file "post_mortem"
309
+ #check_output_includes "Line 8 of \"#{fullpath('post_mortem')}\""
310
+ end
311
+ end
312
+
313
+ end