summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStan Lo <stan.lo@shopify.com>2022-12-02 01:05:07 +0000
committergit <svn-admin@ruby-lang.org>2022-12-02 01:05:22 +0000
commit8abf9e6ad0390e384ab47243ed4ece62a4d9cea0 (patch)
treeedf5574ee0767c980d34757f640203452b2554a9
parent85a1c67a6550641e5de96cdbee1713be3f1e8882 (diff)
[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
-rw-r--r--test/irb/test_debug_cmd.rb258
-rw-r--r--test/irb/yamatanooroti/test_rendering.rb223
2 files changed, 258 insertions, 223 deletions
diff --git a/test/irb/test_debug_cmd.rb b/test/irb/test_debug_cmd.rb
new file mode 100644
index 0000000000..50ce904657
--- /dev/null
+++ b/test/irb/test_debug_cmd.rb
@@ -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
diff --git a/test/irb/yamatanooroti/test_rendering.rb b/test/irb/yamatanooroti/test_rendering.rb
index 6d1a0a1d77..9e09948869 100644
--- a/test/irb/yamatanooroti/test_rendering.rb
+++ b/test/irb/yamatanooroti/test_rendering.rb
@@ -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