Skip to content

Commit

Permalink
Add debug command tests that don't require yamatanooroti
Browse files Browse the repository at this point in the history
  • Loading branch information
st0012 committed Dec 1, 2022
1 parent 78d7141 commit e17cf57
Showing 1 changed file with 249 additions and 0 deletions.
249 changes: 249 additions & 0 deletions test/irb/test_debug_cmd.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
# frozen_string_literal: false

require "pty" unless RUBY_ENGINE == 'truffleruby'
require "tempfile"

require_relative "helper"

module TestIRB
class DebugCommandTestCase < TestCase
IRB_AND_DEBUGGER_OPTIONS = {
"RUBY_DEBUG_NO_RELINE" => "true", "NO_COLOR" => "true", "RUBY_DEBUG_HISTORY_FILE" => '', "USE_SINGLELINE" => "true"
}

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}"
@commands = []
lines = []

yield

PTY.spawn(IRB_AND_DEBUGGER_OPTIONS, 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 }
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

0 comments on commit e17cf57

Please sign in to comment.