зеркало из https://github.com/github/ruby.git
[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:
Родитель
85a1c67a65
Коммит
8abf9e6ad0
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче