diff options
-rw-r--r-- | test/irb/test_cmd.rb | 609 |
1 files changed, 312 insertions, 297 deletions
diff --git a/test/irb/test_cmd.rb b/test/irb/test_cmd.rb index 719a2bbf8f..b909de56e5 100644 --- a/test/irb/test_cmd.rb +++ b/test/irb/test_cmd.rb @@ -7,23 +7,6 @@ require_relative "helper" module TestIRB class CommandTestCase < TestCase - def execute_lines(*lines, conf: {}, main: self, irb_path: nil) - IRB.init_config(nil) - IRB.conf[:VERBOSE] = false - IRB.conf[:PROMPT_MODE] = :SIMPLE - IRB.conf.merge!(conf) - input = TestInputMethod.new(lines) - irb = IRB::Irb.new(IRB::WorkSpace.new(main), input) - irb.context.return_format = "=> %s\n" - irb.context.irb_path = irb_path if irb_path - IRB.conf[:MAIN_CONTEXT] = irb.context - capture_output do - irb.eval_input - end - end - end - - class ExtendCommandTest < CommandTestCase def setup @pwd = Dir.pwd @tmpdir = File.join(Dir.tmpdir, "test_reline_config_#{$$}") @@ -50,148 +33,182 @@ module TestIRB restore_encodings end - class InfoCommandTest < ExtendCommandTest - def setup - super - @locals_backup = ENV.delete("LANG"), ENV.delete("LC_ALL") + def execute_lines(*lines, conf: {}, main: self, irb_path: nil) + IRB.init_config(nil) + IRB.conf[:VERBOSE] = false + IRB.conf[:PROMPT_MODE] = :SIMPLE + IRB.conf.merge!(conf) + input = TestInputMethod.new(lines) + irb = IRB::Irb.new(IRB::WorkSpace.new(main), input) + irb.context.return_format = "=> %s\n" + irb.context.irb_path = irb_path if irb_path + IRB.conf[:MAIN_CONTEXT] = irb.context + capture_output do + irb.eval_input end + end + end - def teardown - super - ENV["LANG"], ENV["LC_ALL"] = @locals_backup - end + class CommnadAliasTest < CommandTestCase + def test_vars_with_aliases + @foo = "foo" + $bar = "bar" + out, err = execute_lines( + "@foo\n", + "$bar\n", + ) + assert_empty err + assert_match(/"foo"/, out) + assert_match(/"bar"/, out) + ensure + remove_instance_variable(:@foo) + $bar = nil + end + end - def test_irb_info_multiline - FileUtils.touch("#{@tmpdir}/.inputrc") - FileUtils.touch("#{@tmpdir}/.irbrc") + class InfoTest < CommandTestCase + def setup + super + @locals_backup = ENV.delete("LANG"), ENV.delete("LC_ALL") + end - out, err = execute_lines( - "irb_info", - conf: { USE_MULTILINE: true, USE_SINGLELINE: false } - ) + def teardown + super + ENV["LANG"], ENV["LC_ALL"] = @locals_backup + end - expected = %r{ - Ruby\sversion:\s.+\n - IRB\sversion:\sirb\s.+\n - InputMethod:\sAbstract\sInputMethod\n - \.irbrc\spath:\s.+\n - RUBY_PLATFORM:\s.+\n - East\sAsian\sAmbiguous\sWidth:\s\d\n - #{@is_win ? 'Code\spage:\s\d+\n' : ''} - }x + def test_irb_info_multiline + FileUtils.touch("#{@tmpdir}/.inputrc") + FileUtils.touch("#{@tmpdir}/.irbrc") - assert_empty err - assert_match expected, out - end + out, err = execute_lines( + "irb_info", + conf: { USE_MULTILINE: true, USE_SINGLELINE: false } + ) - def test_irb_info_singleline - FileUtils.touch("#{@tmpdir}/.inputrc") - FileUtils.touch("#{@tmpdir}/.irbrc") + expected = %r{ + Ruby\sversion:\s.+\n + IRB\sversion:\sirb\s.+\n + InputMethod:\sAbstract\sInputMethod\n + \.irbrc\spath:\s.+\n + RUBY_PLATFORM:\s.+\n + East\sAsian\sAmbiguous\sWidth:\s\d\n + #{@is_win ? 'Code\spage:\s\d+\n' : ''} + }x - out, err = execute_lines( - "irb_info", - conf: { USE_MULTILINE: false, USE_SINGLELINE: true } - ) + assert_empty err + assert_match expected, out + end - expected = %r{ - Ruby\sversion:\s.+\n - IRB\sversion:\sirb\s.+\n - InputMethod:\sAbstract\sInputMethod\n - \.irbrc\spath:\s.+\n - RUBY_PLATFORM:\s.+\n - East\sAsian\sAmbiguous\sWidth:\s\d\n - #{@is_win ? 'Code\spage:\s\d+\n' : ''} - }x + def test_irb_info_singleline + FileUtils.touch("#{@tmpdir}/.inputrc") + FileUtils.touch("#{@tmpdir}/.irbrc") - assert_empty err - assert_match expected, out - end + out, err = execute_lines( + "irb_info", + conf: { USE_MULTILINE: false, USE_SINGLELINE: true } + ) - def test_irb_info_multiline_without_rc_files - inputrc_backup = ENV["INPUTRC"] - ENV["INPUTRC"] = "unknown_inpurc" - ext_backup = IRB::IRBRC_EXT - IRB.__send__(:remove_const, :IRBRC_EXT) - IRB.const_set(:IRBRC_EXT, "unknown_ext") + expected = %r{ + Ruby\sversion:\s.+\n + IRB\sversion:\sirb\s.+\n + InputMethod:\sAbstract\sInputMethod\n + \.irbrc\spath:\s.+\n + RUBY_PLATFORM:\s.+\n + East\sAsian\sAmbiguous\sWidth:\s\d\n + #{@is_win ? 'Code\spage:\s\d+\n' : ''} + }x - out, err = execute_lines( - "irb_info", - conf: { USE_MULTILINE: true, USE_SINGLELINE: false } - ) + assert_empty err + assert_match expected, out + end - expected = %r{ - Ruby\sversion:\s.+\n - IRB\sversion:\sirb\s.+\n - InputMethod:\sAbstract\sInputMethod\n - RUBY_PLATFORM:\s.+\n - East\sAsian\sAmbiguous\sWidth:\s\d\n - #{@is_win ? 'Code\spage:\s\d+\n' : ''} - }x + def test_irb_info_multiline_without_rc_files + inputrc_backup = ENV["INPUTRC"] + ENV["INPUTRC"] = "unknown_inpurc" + ext_backup = IRB::IRBRC_EXT + IRB.__send__(:remove_const, :IRBRC_EXT) + IRB.const_set(:IRBRC_EXT, "unknown_ext") - assert_empty err - assert_match expected, out - ensure - ENV["INPUTRC"] = inputrc_backup - IRB.__send__(:remove_const, :IRBRC_EXT) - IRB.const_set(:IRBRC_EXT, ext_backup) - end + out, err = execute_lines( + "irb_info", + conf: { USE_MULTILINE: true, USE_SINGLELINE: false } + ) - def test_irb_info_singleline_without_rc_files - inputrc_backup = ENV["INPUTRC"] - ENV["INPUTRC"] = "unknown_inpurc" - ext_backup = IRB::IRBRC_EXT - IRB.__send__(:remove_const, :IRBRC_EXT) - IRB.const_set(:IRBRC_EXT, "unknown_ext") + expected = %r{ + Ruby\sversion:\s.+\n + IRB\sversion:\sirb\s.+\n + InputMethod:\sAbstract\sInputMethod\n + RUBY_PLATFORM:\s.+\n + East\sAsian\sAmbiguous\sWidth:\s\d\n + #{@is_win ? 'Code\spage:\s\d+\n' : ''} + }x - out, err = execute_lines( - "irb_info", - conf: { USE_MULTILINE: false, USE_SINGLELINE: true } - ) + assert_empty err + assert_match expected, out + ensure + ENV["INPUTRC"] = inputrc_backup + IRB.__send__(:remove_const, :IRBRC_EXT) + IRB.const_set(:IRBRC_EXT, ext_backup) + end - expected = %r{ - Ruby\sversion:\s.+\n - IRB\sversion:\sirb\s.+\n - InputMethod:\sAbstract\sInputMethod\n - RUBY_PLATFORM:\s.+\n - East\sAsian\sAmbiguous\sWidth:\s\d\n - #{@is_win ? 'Code\spage:\s\d+\n' : ''} - }x + def test_irb_info_singleline_without_rc_files + inputrc_backup = ENV["INPUTRC"] + ENV["INPUTRC"] = "unknown_inpurc" + ext_backup = IRB::IRBRC_EXT + IRB.__send__(:remove_const, :IRBRC_EXT) + IRB.const_set(:IRBRC_EXT, "unknown_ext") - assert_empty err - assert_match expected, out - ensure - ENV["INPUTRC"] = inputrc_backup - IRB.__send__(:remove_const, :IRBRC_EXT) - IRB.const_set(:IRBRC_EXT, ext_backup) - end + out, err = execute_lines( + "irb_info", + conf: { USE_MULTILINE: false, USE_SINGLELINE: true } + ) - def test_irb_info_lang - FileUtils.touch("#{@tmpdir}/.inputrc") - FileUtils.touch("#{@tmpdir}/.irbrc") - ENV["LANG"] = "ja_JP.UTF-8" - ENV["LC_ALL"] = "en_US.UTF-8" + expected = %r{ + Ruby\sversion:\s.+\n + IRB\sversion:\sirb\s.+\n + InputMethod:\sAbstract\sInputMethod\n + RUBY_PLATFORM:\s.+\n + East\sAsian\sAmbiguous\sWidth:\s\d\n + #{@is_win ? 'Code\spage:\s\d+\n' : ''} + }x - out, err = execute_lines( - "irb_info", - conf: { USE_MULTILINE: true, USE_SINGLELINE: false } - ) + assert_empty err + assert_match expected, out + ensure + ENV["INPUTRC"] = inputrc_backup + IRB.__send__(:remove_const, :IRBRC_EXT) + IRB.const_set(:IRBRC_EXT, ext_backup) + end - expected = %r{ - Ruby\sversion: .+\n - IRB\sversion:\sirb .+\n - InputMethod:\sAbstract\sInputMethod\n - \.irbrc\spath: .+\n - RUBY_PLATFORM: .+\n - LANG\senv:\sja_JP\.UTF-8\n - LC_ALL\senv:\sen_US\.UTF-8\n - East\sAsian\sAmbiguous\sWidth:\s\d\n - }x + def test_irb_info_lang + FileUtils.touch("#{@tmpdir}/.inputrc") + FileUtils.touch("#{@tmpdir}/.irbrc") + ENV["LANG"] = "ja_JP.UTF-8" + ENV["LC_ALL"] = "en_US.UTF-8" - assert_empty err - assert_match expected, out - end + out, err = execute_lines( + "irb_info", + conf: { USE_MULTILINE: true, USE_SINGLELINE: false } + ) + + expected = %r{ + Ruby\sversion: .+\n + IRB\sversion:\sirb .+\n + InputMethod:\sAbstract\sInputMethod\n + \.irbrc\spath: .+\n + RUBY_PLATFORM: .+\n + LANG\senv:\sja_JP\.UTF-8\n + LC_ALL\senv:\sen_US\.UTF-8\n + East\sAsian\sAmbiguous\sWidth:\s\d\n + }x + + assert_empty err + assert_match expected, out end + end + class MeasureTest < CommandTestCase def test_measure conf = { PROMPT: { @@ -349,7 +366,9 @@ module TestIRB assert_match(/\A=> 3\nBLOCK is added\.\n=> nil\naaa\n=> 3\nBLOCK is added.\naaa\n=> nil\nbbb\n=> 3\n=> nil\n=> 3\n/, out) assert_empty(c.class_variables) end + end + class IrbSourceTest < CommandTestCase def test_irb_source File.write("#{@tmpdir}/a.rb", "a = 'hi'\n") out, err = execute_lines( @@ -375,7 +394,9 @@ module TestIRB assert_empty err assert_match(/Please specify the file name./, out) end + end + class IrbLoadTest < CommandTestCase def test_irb_load File.write("#{@tmpdir}/a.rb", "a = 'hi'\n") out, err = execute_lines( @@ -402,7 +423,92 @@ module TestIRB assert_empty err assert_match(/Please specify the file name./, out) end + end + + class ShowSourceTest < CommandTestCase + def test_show_source + out, err = execute_lines( + "show_source IRB.conf\n", + ) + assert_empty err + assert_match(%r[/irb\.rb], out) + end + + def test_show_source_method + out, err = execute_lines( + "p show_source('IRB.conf')\n", + ) + assert_empty err + assert_match(%r[/irb\.rb], out) + end + + def test_show_source_string + out, err = execute_lines( + "show_source 'IRB.conf'\n", + ) + assert_empty err + assert_match(%r[/irb\.rb], out) + end + + def test_show_source_alias + out, err = execute_lines( + "$ 'IRB.conf'\n", + conf: { COMMAND_ALIASES: { :'$' => :show_source } } + ) + assert_empty err + assert_match(%r[/irb\.rb], out) + end + + def test_show_source_end_finder + pend if RUBY_ENGINE == 'truffleruby' + eval(code = <<-EOS, binding, __FILE__, __LINE__ + 1) + def show_source_test_method + unless true + end + end unless defined?(show_source_test_method) + EOS + + out, err = execute_lines( + "show_source '#{self.class.name}#show_source_test_method'\n", + ) + + assert_empty err + assert_include(out, code) + end + end + class WhereamiTest < CommandTestCase + def test_whereami + out, err = execute_lines( + "whereami\n", + ) + assert_empty err + assert_match(/^From: .+ @ line \d+ :\n/, out) + end + + def test_whereami_alias + out, err = execute_lines( + "@\n", + ) + assert_empty err + assert_match(/^From: .+ @ line \d+ :\n/, out) + end + end + + + class ShowCmdsTest < CommandTestCase + def test_show_cmds + out, err = execute_lines( + "show_cmds\n" + ) + + assert_empty err + assert_match(/List all available commands and their description/, out) + assert_match(/Start the debugger of debug\.gem/, out) + end + end + + class LsTest < CommandTestCase def test_ls out, err = execute_lines( "class P\n", @@ -488,205 +594,114 @@ module TestIRB assert_match(/Numeric#methods:\s+/, out) assert_match(/Integer#methods:\s+/, out) end + end - def test_show_source - out, err = execute_lines( - "show_source IRB.conf\n", - ) - assert_empty err - assert_match(%r[/irb\.rb], out) - end + class ShowDocTest < CommandTestCase + def test_help_and_show_doc + ["help", "show_doc"].each do |cmd| + out, _ = execute_lines( + "#{cmd} String#gsub\n", + "\n", + ) - def test_show_source_method - out, err = execute_lines( - "p show_source('IRB.conf')\n", - ) - assert_empty err - assert_match(%r[/irb\.rb], out) + # the former is what we'd get without document content installed, like on CI + # the latter is what we may get locally + possible_rdoc_output = [/Nothing known about String#gsub/, /gsub\(pattern\)/] + assert(possible_rdoc_output.any? { |output| output.match?(out) }, "Expect the `#{cmd}` command to match one of the possible outputs. Got:\n#{out}") + end + ensure + # this is the only way to reset the redefined method without coupling the test with its implementation + EnvUtil.suppress_warning { load "irb/cmd/help.rb" } end - def test_show_source_string - out, err = execute_lines( - "show_source 'IRB.conf'\n", - ) - assert_empty err - assert_match(%r[/irb\.rb], out) + def test_show_doc_without_rdoc + out, _ = without_rdoc do + execute_lines( + "show_doc String#gsub\n", + "\n", + ) + end + + # if it fails to require rdoc, it only returns the command object + assert_match(/=> IRB::ExtendCommand::Help\n/, out) + ensure + # this is the only way to reset the redefined method without coupling the test with its implementation + EnvUtil.suppress_warning { load "irb/cmd/help.rb" } end + end - def test_show_source_alias - out, err = execute_lines( - "$ 'IRB.conf'\n", - conf: { COMMAND_ALIASES: { :'$' => :show_source } } - ) - assert_empty err - assert_match(%r[/irb\.rb], out) + class EditTest < CommandTestCase + def setup + @original_editor = ENV["EDITOR"] + # noop the command so nothing gets executed + ENV["EDITOR"] = ": code" end - def test_show_source_end_finder - pend if RUBY_ENGINE == 'truffleruby' - eval(code = <<-EOS, binding, __FILE__, __LINE__ + 1) - def show_source_test_method - unless true - end - end unless defined?(show_source_test_method) - EOS + def teardown + ENV["EDITOR"] = @original_editor + end + def test_edit_without_arg out, err = execute_lines( - "show_source 'TestIRB::ExtendCommandTest#show_source_test_method'\n", + "edit", + irb_path: __FILE__ ) assert_empty err - assert_include(out, code) + assert_match("path: #{__FILE__}", out) + assert_match("command: ': code'", out) end - def test_whereami + def test_edit_with_path out, err = execute_lines( - "whereami\n", + "edit #{__FILE__}" ) + assert_empty err - assert_match(/^From: .+ @ line \d+ :\n/, out) + assert_match("path: #{__FILE__}", out) + assert_match("command: ': code'", out) end - def test_whereami_alias + def test_edit_with_non_existing_path out, err = execute_lines( - "@\n", + "edit test_cmd_non_existing_path.rb" ) + assert_empty err - assert_match(/^From: .+ @ line \d+ :\n/, out) + assert_match(/Can not find file: test_cmd_non_existing_path\.rb/, out) end - def test_vars_with_aliases - @foo = "foo" - $bar = "bar" + def test_edit_with_constant + # const_source_location is supported after Ruby 2.7 + omit if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0') || RUBY_ENGINE == 'truffleruby' + out, err = execute_lines( - "@foo\n", - "$bar\n", + "edit IRB::Irb" ) + assert_empty err - assert_match(/"foo"/, out) - assert_match(/"bar"/, out) - ensure - remove_instance_variable(:@foo) - $bar = nil + assert_match(/path: .*\/lib\/irb\.rb/, out) + assert_match("command: ': code'", out) end - def test_show_cmds + def test_edit_with_class_method out, err = execute_lines( - "show_cmds\n" + "edit IRB.start" ) assert_empty err - assert_match(/List all available commands and their description/, out) - assert_match(/Start the debugger of debug\.gem/, out) - end - - class ShowDocTest < CommandTestCase - def test_help_and_show_doc - ["help", "show_doc"].each do |cmd| - out, _ = execute_lines( - "#{cmd} String#gsub\n", - "\n", - ) - - # the former is what we'd get without document content installed, like on CI - # the latter is what we may get locally - possible_rdoc_output = [/Nothing known about String#gsub/, /gsub\(pattern\)/] - assert(possible_rdoc_output.any? { |output| output.match?(out) }, "Expect the `#{cmd}` command to match one of the possible outputs. Got:\n#{out}") - end - ensure - # this is the only way to reset the redefined method without coupling the test with its implementation - EnvUtil.suppress_warning { load "irb/cmd/help.rb" } - end - - def test_show_doc_without_rdoc - out, _ = without_rdoc do - execute_lines( - "show_doc String#gsub\n", - "\n", - ) - end - - # if it fails to require rdoc, it only returns the command object - assert_match(/=> IRB::ExtendCommand::Help\n/, out) - ensure - # this is the only way to reset the redefined method without coupling the test with its implementation - EnvUtil.suppress_warning { load "irb/cmd/help.rb" } - end + assert_match(/path: .*\/lib\/irb\.rb/, out) + assert_match("command: ': code'", out) end - class EditTest < CommandTestCase - def setup - @original_editor = ENV["EDITOR"] - # noop the command so nothing gets executed - ENV["EDITOR"] = ": code" - end - - def teardown - ENV["EDITOR"] = @original_editor - end - - def test_edit_without_arg - out, err = execute_lines( - "edit", - irb_path: __FILE__ - ) - - assert_empty err - assert_match("path: #{__FILE__}", out) - assert_match("command: ': code'", out) - end - - def test_edit_with_path - out, err = execute_lines( - "edit #{__FILE__}" - ) - - assert_empty err - assert_match("path: #{__FILE__}", out) - assert_match("command: ': code'", out) - end - - def test_edit_with_non_existing_path - out, err = execute_lines( - "edit test_cmd_non_existing_path.rb" - ) - - assert_empty err - assert_match(/Can not find file: test_cmd_non_existing_path\.rb/, out) - end - - def test_edit_with_constant - # const_source_location is supported after Ruby 2.7 - omit if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0') || RUBY_ENGINE == 'truffleruby' - - out, err = execute_lines( - "edit IRB::Irb" - ) - - assert_empty err - assert_match(/path: .*\/lib\/irb\.rb/, out) - assert_match("command: ': code'", out) - end - - def test_edit_with_class_method - out, err = execute_lines( - "edit IRB.start" - ) - - assert_empty err - assert_match(/path: .*\/lib\/irb\.rb/, out) - assert_match("command: ': code'", out) - end - - def test_edit_with_instance_method - out, err = execute_lines( - "edit IRB::Irb#run" - ) + def test_edit_with_instance_method + out, err = execute_lines( + "edit IRB::Irb#run" + ) - assert_empty err - assert_match(/path: .*\/lib\/irb\.rb/, out) - assert_match("command: ': code'", out) - end + assert_empty err + assert_match(/path: .*\/lib\/irb\.rb/, out) + assert_match("command: ': code'", out) end end end |