[ruby/irb] Test debug commands without yamatanooroti

(https://github.com/ruby/irb/pull/464)

* Add debug command tests that don't require yamatanooroti

* Remove debug command related yamatanooroti tests

As discussed in https://github.com/ruby/irb/pull/449#pullrequestreview-1187255149,
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

https://github.com/ruby/irb/commit/78a8aa8834
This commit is contained in:
Stan Lo 2022-12-02 01:05:07 +00:00 коммит произвёл git
Родитель 85a1c67a65
Коммит 8abf9e6ad0
2 изменённых файлов: 258 добавлений и 223 удалений

258
test/irb/test_debug_cmd.rb Normal file
Просмотреть файл

@ -0,0 +1,258 @@
# frozen_string_literal: true
require "pty" unless RUBY_ENGINE == 'truffleruby'
require "tempfile"
require "tmpdir"
require_relative "helper"
module TestIRB
class DebugCommandTestCase < TestCase
IRB_AND_DEBUGGER_OPTIONS = {
"RUBY_DEBUG_NO_RELINE" => "true", "NO_COLOR" => "true", "RUBY_DEBUG_HISTORY_FILE" => ''
}
def test_backtrace
omit if RUBY_ENGINE == 'truffleruby'
write_ruby <<~'RUBY'
def foo
binding.irb
end
foo
RUBY
output = run_ruby_file do
type "backtrace"
type "q!"
end
assert_match(/\(rdbg:irb\) backtrace/, output)
assert_match(/Object#foo at #{@ruby_file.to_path}/, output)
end
def test_debug
omit if RUBY_ENGINE == 'truffleruby'
write_ruby <<~'ruby'
binding.irb
puts "hello"
ruby
output = run_ruby_file do
type "debug"
type "next"
type "continue"
end
assert_match(/\(rdbg\) next/, output)
assert_match(/=> 2\| puts "hello"/, output)
end
def test_next
omit if RUBY_ENGINE == 'truffleruby'
write_ruby <<~'ruby'
binding.irb
puts "hello"
ruby
output = run_ruby_file do
type "next"
type "continue"
end
assert_match(/\(rdbg:irb\) next/, output)
assert_match(/=> 2\| puts "hello"/, output)
end
def test_break
omit if RUBY_ENGINE == 'truffleruby'
write_ruby <<~'RUBY'
binding.irb
puts "Hello"
RUBY
output = run_ruby_file do
type "break 2"
type "continue"
type "continue"
end
assert_match(/\(rdbg:irb\) break/, output)
assert_match(/=> 2\| puts "Hello"/, output)
end
def test_delete
omit if RUBY_ENGINE == 'truffleruby'
write_ruby <<~'RUBY'
binding.irb
puts "Hello"
binding.irb
puts "World"
RUBY
output = run_ruby_file do
type "break 4"
type "continue"
type "delete 0"
type "continue"
end
assert_match(/\(rdbg:irb\) delete/, output)
assert_match(/deleted: #0 BP - Line/, output)
end
def test_step
omit if RUBY_ENGINE == 'truffleruby'
write_ruby <<~'RUBY'
def foo
puts "Hello"
end
binding.irb
foo
RUBY
output = run_ruby_file do
type "step"
type "continue"
end
assert_match(/\(rdbg:irb\) step/, output)
assert_match(/=> 2| puts "Hello"/, output)
end
def test_continue
omit if RUBY_ENGINE == 'truffleruby'
write_ruby <<~'RUBY'
binding.irb
puts "Hello"
binding.irb
puts "World"
RUBY
output = run_ruby_file do
type "continue"
type "continue"
end
assert_match(/\(rdbg:irb\) continue/, output)
assert_match(/=> 3: binding.irb/, output)
end
def test_finish
omit if RUBY_ENGINE == 'truffleruby'
write_ruby <<~'RUBY'
def foo
binding.irb
puts "Hello"
end
foo
RUBY
output = run_ruby_file do
type "finish"
type "continue"
end
assert_match(/\(rdbg:irb\) finish/, output)
assert_match(/=> 4\| end/, output)
end
def test_info
omit if RUBY_ENGINE == 'truffleruby'
write_ruby <<~'RUBY'
def foo
a = "He" + "llo"
binding.irb
end
foo
RUBY
output = run_ruby_file do
type "info"
type "continue"
end
assert_match(/\(rdbg:irb\) info/, output)
assert_match(/%self = main/, output)
assert_match(/a = "Hello"/, output)
end
def test_catch
omit if RUBY_ENGINE == 'truffleruby'
write_ruby <<~'RUBY'
binding.irb
1 / 0
RUBY
output = run_ruby_file do
type "catch ZeroDivisionError"
type "continue"
type "continue"
end
assert_match(/\(rdbg:irb\) catch/, output)
assert_match(/Stop by #0 BP - Catch "ZeroDivisionError"/, output)
end
private
def run_ruby_file(&block)
cmd = "ruby -Ilib #{@ruby_file.to_path}"
tmp_dir = Dir.mktmpdir
rc_file = File.open(File.join(tmp_dir, ".irbrc"), "w+")
rc_file.write("IRB.conf[:USE_SINGLELINE] = true")
rc_file.close
@commands = []
lines = []
yield
PTY.spawn(IRB_AND_DEBUGGER_OPTIONS.merge("IRBRC" => rc_file.to_path), cmd) do |read, write, pid|
Timeout.timeout(3) do
while line = safe_gets(read)
lines << line
# means the breakpoint is triggered
if line.match?(/binding\.irb/)
while command = @commands.shift
write.puts(command)
end
end
end
end
end
lines.join
rescue Timeout::Error
message = <<~MSG
Test timedout.
#{'=' * 30} OUTPUT #{'=' * 30}
#{lines.map { |l| " #{l}" }.join}
#{'=' * 27} END OF OUTPUT #{'=' * 27}
MSG
assert_block(message) { false }
ensure
File.unlink(@ruby_file) if @ruby_file
FileUtils.remove_entry tmp_dir
end
# read.gets could raise exceptions on some platforms
# https://github.com/ruby/ruby/blob/master/ext/pty/pty.c#L729-L736
def safe_gets(read)
read.gets
rescue Errno::EIO
nil
end
def type(command)
@commands << command
end
def write_ruby(program)
@ruby_file = Tempfile.create(%w{irb- .rb})
@ruby_file.write(program)
@ruby_file.close
end
end
end

Просмотреть файл

@ -17,8 +17,6 @@ begin
@irbrc_backup = ENV['IRBRC']
@irbrc_file = ENV['IRBRC'] = File.join(@tmpdir, 'temporaty_irbrc')
File.unlink(@irbrc_file) if File.exist?(@irbrc_file)
@ruby_file = File.join(@tmpdir, 'ruby_file.rb')
File.unlink(@ruby_file) if File.exist?(@ruby_file)
end
def teardown
@ -237,234 +235,13 @@ begin
EOC
end
def test_debug
write_ruby <<~'RUBY'
puts "start IRB"
binding.irb
puts "Hello"
RUBY
start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@ruby_file}}, startup_message: 'start IRB')
write("debug\n")
write("next\n")
close
assert_include_screen(<<~EOC)
(rdbg) next # command
[1, 3] in #{@ruby_file}
1| puts "start IRB"
2| binding.irb
=> 3| puts "Hello"
EOC
end
def test_break
write_ruby <<~'RUBY'
puts "start IRB"
binding.irb
puts "Hello"
puts "World"
RUBY
start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@ruby_file}}, startup_message: 'start IRB')
write("break 3\n")
write("continue\n")
close
assert_include_screen(<<~EOC)
(rdbg:irb) break 3
#0 BP - Line #{@ruby_file}:3 (line)
EOC
assert_include_screen(<<~EOC)
(rdbg) continue # command
[1, 4] in #{@ruby_file}
1| puts "start IRB"
2| binding.irb
=> 3| puts "Hello"
4| puts "World"
=>#0 <main> at #{@ruby_file}:3
Stop by #0 BP - Line #{@ruby_file}:3 (line)
EOC
end
def test_delete
write_ruby <<~'RUBY'
puts "start IRB"
binding.irb
puts "Hello"
binding.irb
puts "World"
RUBY
start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@ruby_file}}, startup_message: 'start IRB')
write("break 5\n")
write("continue\n")
write("delete 0\n")
close
assert_include_screen(<<~EOC.strip)
(rdbg:irb) delete 0
deleted: #0 BP - Line
EOC
end
def test_next
write_ruby <<~'RUBY'
puts "start IRB"
binding.irb
puts "Hello"
puts "World"
RUBY
start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@ruby_file}}, startup_message: 'start IRB')
write("next\n")
close
assert_include_screen(<<~EOC)
(rdbg:irb) next
[1, 4] in #{@ruby_file}
1| puts "start IRB"
2| binding.irb
=> 3| puts "Hello"
4| puts "World"
=>#0 <main> at #{@ruby_file}:3
EOC
end
def test_step
write_ruby <<~'RUBY'
puts "start IRB"
def foo
puts "Hello"
end
binding.irb
foo
puts "World"
RUBY
start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@ruby_file}}, startup_message: 'start IRB')
write("step\n")
close
assert_include_screen(<<~EOC)
(rdbg:irb) step
[1, 7] in #{@ruby_file}
1| puts "start IRB"
2| def foo
=> 3| puts "Hello"
4| end
5| binding.irb
EOC
end
def test_continue
write_ruby <<~'RUBY'
puts "start IRB"
binding.irb
puts "Hello"
binding.irb
puts "World"
RUBY
start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@ruby_file}}, startup_message: 'start IRB')
write("continue\n")
close
assert_include_screen(<<~EOC)
(rdbg:irb) continue
Hello
From: #{@ruby_file} @ line 4 :
1: puts "start IRB"
2: binding.irb
3: puts "Hello"
=> 4: binding.irb
5: puts "World"
EOC
end
def test_finish
write_ruby <<~'RUBY'
puts "start IRB"
def foo
binding.irb
puts "Hello"
end
foo
puts "World"
RUBY
start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@ruby_file}}, startup_message: 'start IRB')
write("finish\n")
close
assert_include_screen(<<~EOC)
(rdbg:irb) finish
Hello
[1, 7] in #{@ruby_file}
1| puts "start IRB"
2| def foo
3| binding.irb
4| puts "Hello"
=> 5| end
6| foo
EOC
end
def test_backtrace
write_ruby <<~'RUBY'
puts "start IRB"
def foo
binding.irb
end
foo
RUBY
start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@ruby_file}}, startup_message: 'start IRB')
write("backtrace\n")
close
assert_include_screen(<<~EOC)
(rdbg:irb) backtrace
=>#0 Object#foo at #{@ruby_file}:3
#1 <main> at #{@ruby_file}:5
EOC
end
def test_info
write_ruby <<~'RUBY'
puts "start IRB"
a = 1
binding.irb
RUBY
start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@ruby_file}}, startup_message: 'start IRB')
write("info\n")
close
assert_include_screen(<<~EOC)
(rdbg:irb) info
%self = main
a = 1
EOC
end
def test_catch
write_ruby <<~'RUBY'
puts "start IRB"
binding.irb
raise NotImplementedError
RUBY
start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@ruby_file}}, startup_message: 'start IRB')
write("catch NotImplementedError\n")
write("continue\n")
close
assert_include_screen(<<~EOC)
Stop by #0 BP - Catch "NotImplementedError"
EOC
end
private
def assert_include_screen(expected)
assert_include(result.join("\n"), expected)
end
def write_irbrc(content)
File.open(@irbrc_file, 'w') do |f|
f.write content
end
end
def write_ruby(content)
File.open(@ruby_file, 'w') do |f|
f.write content
end
end
end
rescue LoadError, NameError
# On Ruby repository, this test suit doesn't run because Ruby repo doesn't