Skip to content

Commit 78a8aa8

Browse files
authored
Test debug commands without yamatanooroti (#464)
* Add debug command tests that don't require yamatanooroti * Remove debug command related yamatanooroti tests As discussed in #449 (review), we should avoid adding new tests that need yamatanooroti because it's not maintained by the Ruby org. And since debug commands are now tested in `test/irb/test_debug_cmd.rb`, we don't need these tests anymore. * Test against latest debug gem
1 parent e0ec5e1 commit 78a8aa8

File tree

3 files changed

+259
-224
lines changed

3 files changed

+259
-224
lines changed

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ group :development do
1111
gem "stackprof" if is_unix && !is_truffleruby
1212
gem "test-unit"
1313
gem "reline", github: "ruby/reline" if ENV["WITH_LATEST_RELINE"] == "true"
14-
gem "debug"
14+
gem "debug", github: "ruby/debug"
1515
end

test/irb/test_debug_cmd.rb

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
# frozen_string_literal: true
2+
3+
require "pty" unless RUBY_ENGINE == 'truffleruby'
4+
require "tempfile"
5+
require "tmpdir"
6+
7+
require_relative "helper"
8+
9+
module TestIRB
10+
class DebugCommandTestCase < TestCase
11+
IRB_AND_DEBUGGER_OPTIONS = {
12+
"RUBY_DEBUG_NO_RELINE" => "true", "NO_COLOR" => "true", "RUBY_DEBUG_HISTORY_FILE" => ''
13+
}
14+
15+
def test_backtrace
16+
omit if RUBY_ENGINE == 'truffleruby'
17+
write_ruby <<~'RUBY'
18+
def foo
19+
binding.irb
20+
end
21+
foo
22+
RUBY
23+
24+
output = run_ruby_file do
25+
type "backtrace"
26+
type "q!"
27+
end
28+
29+
assert_match(/\(rdbg:irb\) backtrace/, output)
30+
assert_match(/Object#foo at #{@ruby_file.to_path}/, output)
31+
end
32+
33+
def test_debug
34+
omit if RUBY_ENGINE == 'truffleruby'
35+
write_ruby <<~'ruby'
36+
binding.irb
37+
puts "hello"
38+
ruby
39+
40+
output = run_ruby_file do
41+
type "debug"
42+
type "next"
43+
type "continue"
44+
end
45+
46+
assert_match(/\(rdbg\) next/, output)
47+
assert_match(/=> 2\| puts "hello"/, output)
48+
end
49+
50+
def test_next
51+
omit if RUBY_ENGINE == 'truffleruby'
52+
write_ruby <<~'ruby'
53+
binding.irb
54+
puts "hello"
55+
ruby
56+
57+
output = run_ruby_file do
58+
type "next"
59+
type "continue"
60+
end
61+
62+
assert_match(/\(rdbg:irb\) next/, output)
63+
assert_match(/=> 2\| puts "hello"/, output)
64+
end
65+
66+
def test_break
67+
omit if RUBY_ENGINE == 'truffleruby'
68+
write_ruby <<~'RUBY'
69+
binding.irb
70+
puts "Hello"
71+
RUBY
72+
73+
output = run_ruby_file do
74+
type "break 2"
75+
type "continue"
76+
type "continue"
77+
end
78+
79+
assert_match(/\(rdbg:irb\) break/, output)
80+
assert_match(/=> 2\| puts "Hello"/, output)
81+
end
82+
83+
def test_delete
84+
omit if RUBY_ENGINE == 'truffleruby'
85+
write_ruby <<~'RUBY'
86+
binding.irb
87+
puts "Hello"
88+
binding.irb
89+
puts "World"
90+
RUBY
91+
92+
output = run_ruby_file do
93+
type "break 4"
94+
type "continue"
95+
type "delete 0"
96+
type "continue"
97+
end
98+
99+
assert_match(/\(rdbg:irb\) delete/, output)
100+
assert_match(/deleted: #0 BP - Line/, output)
101+
end
102+
103+
def test_step
104+
omit if RUBY_ENGINE == 'truffleruby'
105+
write_ruby <<~'RUBY'
106+
def foo
107+
puts "Hello"
108+
end
109+
binding.irb
110+
foo
111+
RUBY
112+
113+
output = run_ruby_file do
114+
type "step"
115+
type "continue"
116+
end
117+
118+
assert_match(/\(rdbg:irb\) step/, output)
119+
assert_match(/=> 2| puts "Hello"/, output)
120+
end
121+
122+
def test_continue
123+
omit if RUBY_ENGINE == 'truffleruby'
124+
write_ruby <<~'RUBY'
125+
binding.irb
126+
puts "Hello"
127+
binding.irb
128+
puts "World"
129+
RUBY
130+
131+
output = run_ruby_file do
132+
type "continue"
133+
type "continue"
134+
end
135+
136+
assert_match(/\(rdbg:irb\) continue/, output)
137+
assert_match(/=> 3: binding.irb/, output)
138+
end
139+
140+
def test_finish
141+
omit if RUBY_ENGINE == 'truffleruby'
142+
write_ruby <<~'RUBY'
143+
def foo
144+
binding.irb
145+
puts "Hello"
146+
end
147+
foo
148+
RUBY
149+
150+
output = run_ruby_file do
151+
type "finish"
152+
type "continue"
153+
end
154+
155+
assert_match(/\(rdbg:irb\) finish/, output)
156+
assert_match(/=> 4\| end/, output)
157+
end
158+
159+
def test_info
160+
omit if RUBY_ENGINE == 'truffleruby'
161+
write_ruby <<~'RUBY'
162+
def foo
163+
a = "He" + "llo"
164+
binding.irb
165+
end
166+
foo
167+
RUBY
168+
169+
output = run_ruby_file do
170+
type "info"
171+
type "continue"
172+
end
173+
174+
assert_match(/\(rdbg:irb\) info/, output)
175+
assert_match(/%self = main/, output)
176+
assert_match(/a = "Hello"/, output)
177+
end
178+
179+
def test_catch
180+
omit if RUBY_ENGINE == 'truffleruby'
181+
write_ruby <<~'RUBY'
182+
binding.irb
183+
1 / 0
184+
RUBY
185+
186+
output = run_ruby_file do
187+
type "catch ZeroDivisionError"
188+
type "continue"
189+
type "continue"
190+
end
191+
192+
assert_match(/\(rdbg:irb\) catch/, output)
193+
assert_match(/Stop by #0 BP - Catch "ZeroDivisionError"/, output)
194+
end
195+
196+
private
197+
198+
def run_ruby_file(&block)
199+
cmd = "ruby -Ilib #{@ruby_file.to_path}"
200+
tmp_dir = Dir.mktmpdir
201+
rc_file = File.open(File.join(tmp_dir, ".irbrc"), "w+")
202+
rc_file.write("IRB.conf[:USE_SINGLELINE] = true")
203+
rc_file.close
204+
205+
@commands = []
206+
lines = []
207+
208+
yield
209+
210+
PTY.spawn(IRB_AND_DEBUGGER_OPTIONS.merge("IRBRC" => rc_file.to_path), cmd) do |read, write, pid|
211+
Timeout.timeout(3) do
212+
while line = safe_gets(read)
213+
lines << line
214+
215+
# means the breakpoint is triggered
216+
if line.match?(/binding\.irb/)
217+
while command = @commands.shift
218+
write.puts(command)
219+
end
220+
end
221+
end
222+
end
223+
end
224+
225+
lines.join
226+
rescue Timeout::Error
227+
message = <<~MSG
228+
Test timedout.
229+
230+
#{'=' * 30} OUTPUT #{'=' * 30}
231+
#{lines.map { |l| " #{l}" }.join}
232+
#{'=' * 27} END OF OUTPUT #{'=' * 27}
233+
MSG
234+
assert_block(message) { false }
235+
ensure
236+
File.unlink(@ruby_file) if @ruby_file
237+
FileUtils.remove_entry tmp_dir
238+
end
239+
240+
# read.gets could raise exceptions on some platforms
241+
# https://github.com/ruby/ruby/blob/master/ext/pty/pty.c#L729-L736
242+
def safe_gets(read)
243+
read.gets
244+
rescue Errno::EIO
245+
nil
246+
end
247+
248+
def type(command)
249+
@commands << command
250+
end
251+
252+
def write_ruby(program)
253+
@ruby_file = Tempfile.create(%w{irb- .rb})
254+
@ruby_file.write(program)
255+
@ruby_file.close
256+
end
257+
end
258+
end

0 commit comments

Comments
 (0)