summaryrefslogtreecommitdiff
path: root/test/irb
diff options
context:
space:
mode:
Diffstat (limited to 'test/irb')
-rw-r--r--test/irb/command/test_force_exit.rb63
-rw-r--r--test/irb/command/test_help.rb66
-rw-r--r--test/irb/command/test_show_source.rb397
-rw-r--r--test/irb/helper.rb219
-rw-r--r--test/irb/test_color.rb274
-rw-r--r--test/irb/test_color_printer.rb69
-rw-r--r--test/irb/test_command.rb1043
-rw-r--r--test/irb/test_completion.rb311
-rw-r--r--test/irb/test_context.rb721
-rw-r--r--test/irb/test_debugger_integration.rb462
-rw-r--r--test/irb/test_eval_history.rb69
-rw-r--r--test/irb/test_evaluation.rb44
-rw-r--r--test/irb/test_history.rb491
-rw-r--r--test/irb/test_init.rb310
-rw-r--r--test/irb/test_input_method.rb173
-rw-r--r--test/irb/test_irb.rb806
-rw-r--r--test/irb/test_locale.rb118
-rw-r--r--test/irb/test_nesting_parser.rb341
-rw-r--r--test/irb/test_option.rb13
-rw-r--r--test/irb/test_raise_exception.rb74
-rw-r--r--test/irb/test_ruby_lex.rb242
-rw-r--r--test/irb/test_tracer.rb90
-rw-r--r--test/irb/test_type_completor.rb88
-rw-r--r--test/irb/test_workspace.rb127
-rw-r--r--test/irb/yamatanooroti/test_rendering.rb517
25 files changed, 0 insertions, 7128 deletions
diff --git a/test/irb/command/test_force_exit.rb b/test/irb/command/test_force_exit.rb
deleted file mode 100644
index 9e86c644d6..0000000000
--- a/test/irb/command/test_force_exit.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-# frozen_string_literal: false
-require 'irb'
-
-require_relative "../helper"
-
-module TestIRB
- class ForceExitTest < IntegrationTestCase
- def test_forced_exit_finishes_process_immediately
- write_ruby <<~'ruby'
- puts "First line"
- puts "Second line"
- binding.irb
- puts "Third line"
- binding.irb
- puts "Fourth line"
- ruby
-
- output = run_ruby_file do
- type "123"
- type "456"
- type "exit!"
- end
-
- assert_match(/First line\r\n/, output)
- assert_match(/Second line\r\n/, output)
- assert_match(/irb\(main\):001> 123/, output)
- assert_match(/irb\(main\):002> 456/, output)
- refute_match(/Third line\r\n/, output)
- refute_match(/Fourth line\r\n/, output)
- end
-
- def test_forced_exit_in_nested_sessions
- write_ruby <<~'ruby'
- def foo
- binding.irb
- end
-
- binding.irb
- binding.irb
- ruby
-
- output = run_ruby_file do
- type "123"
- type "foo"
- type "exit!"
- end
-
- assert_match(/irb\(main\):001> 123/, output)
- end
-
- def test_forced_exit_out_of_irb_session
- write_ruby <<~'ruby'
- at_exit { puts 'un' + 'reachable' }
- binding.irb
- exit! # this will call exit! method overrided by command
- ruby
- output = run_ruby_file do
- type "exit"
- end
- assert_not_include(output, 'unreachable')
- end
- end
-end
diff --git a/test/irb/command/test_help.rb b/test/irb/command/test_help.rb
deleted file mode 100644
index c82c43a4c5..0000000000
--- a/test/irb/command/test_help.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-require "tempfile"
-require_relative "../helper"
-
-module TestIRB
- class HelpTest < IntegrationTestCase
- def setup
- super
-
- write_rc <<~'RUBY'
- IRB.conf[:USE_PAGER] = false
- RUBY
-
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
- end
-
- def test_help
- out = run_ruby_file do
- type "help"
- type "exit"
- end
-
- assert_match(/List all available commands/, out)
- assert_match(/Start the debugger of debug\.gem/, out)
- end
-
- def test_command_help
- out = run_ruby_file do
- type "help ls"
- type "exit"
- end
-
- assert_match(/Usage: ls \[obj\]/, out)
- end
-
- def test_command_help_not_found
- out = run_ruby_file do
- type "help foo"
- type "exit"
- end
-
- assert_match(/Can't find command `foo`\. Please check the command name and try again\./, out)
- end
-
- def test_show_cmds
- out = run_ruby_file do
- type "help"
- type "exit"
- end
-
- assert_match(/List all available commands/, out)
- assert_match(/Start the debugger of debug\.gem/, out)
- end
-
- def test_help_lists_user_aliases
- out = run_ruby_file do
- type "help"
- type "exit"
- end
-
- assert_match(/\$\s+Alias for `show_source`/, out)
- assert_match(/@\s+Alias for `whereami`/, out)
- end
- end
-end
diff --git a/test/irb/command/test_show_source.rb b/test/irb/command/test_show_source.rb
deleted file mode 100644
index d014c78fc4..0000000000
--- a/test/irb/command/test_show_source.rb
+++ /dev/null
@@ -1,397 +0,0 @@
-# frozen_string_literal: false
-require 'irb'
-
-require_relative "../helper"
-
-module TestIRB
- class ShowSourceTest < IntegrationTestCase
- def setup
- super
-
- write_rc <<~'RUBY'
- IRB.conf[:USE_PAGER] = false
- RUBY
- end
-
- def test_show_source
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "show_source IRB.conf"
- type "exit"
- end
-
- assert_match(%r[/irb\/init\.rb], out)
- end
-
- def test_show_source_alias
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "$ IRB.conf"
- type "exit"
- end
-
- assert_match(%r[/irb\/init\.rb], out)
- end
-
- def test_show_source_with_missing_signature
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "show_source foo"
- type "exit"
- end
-
- assert_match(%r[Couldn't locate a definition for foo], out)
- end
-
- def test_show_source_with_missing_constant
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "show_source Foo"
- type "exit"
- end
-
- assert_match(%r[Couldn't locate a definition for Foo], out)
- end
-
- def test_show_source_string
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "show_source 'IRB.conf'"
- type "exit"
- end
-
- assert_match(%r[/irb\/init\.rb], out)
- end
-
- def test_show_source_method_s
- write_ruby <<~RUBY
- class Baz
- def foo
- end
- end
-
- class Bar < Baz
- def foo
- super
- end
- end
-
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "show_source Bar#foo -s"
- type "exit"
- end
-
- assert_match(%r[#{@ruby_file.to_path}:2\s+def foo\r\n end\r\n], out)
- end
-
- def test_show_source_method_s_with_incorrect_signature
- write_ruby <<~RUBY
- class Baz
- def foo
- end
- end
-
- class Bar < Baz
- def foo
- super
- end
- end
-
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "show_source Bar#fooo -s"
- type "exit"
- end
-
- assert_match(%r[Error: Couldn't locate a super definition for Bar#fooo], out)
- end
-
- def test_show_source_private_method
- write_ruby <<~RUBY
- class Bar
- private def foo
- end
- end
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "show_source Bar#foo"
- type "exit"
- end
-
- assert_match(%r[#{@ruby_file.to_path}:2\s+private def foo\r\n end\r\n], out)
- end
-
- def test_show_source_private_singleton_method
- write_ruby <<~RUBY
- class Bar
- private def foo
- end
- end
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "bar = Bar.new"
- type "show_source bar.foo"
- type "exit"
- end
-
- assert_match(%r[#{@ruby_file.to_path}:2\s+private def foo\r\n end\r\n], out)
- end
-
- def test_show_source_method_multiple_s
- write_ruby <<~RUBY
- class Baz
- def foo
- end
- end
-
- class Bar < Baz
- def foo
- super
- end
- end
-
- class Bob < Bar
- def foo
- super
- end
- end
-
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "show_source Bob#foo -ss"
- type "exit"
- end
-
- assert_match(%r[#{@ruby_file.to_path}:2\s+def foo\r\n end\r\n], out)
- end
-
- def test_show_source_method_no_instance_method
- write_ruby <<~RUBY
- class Baz
- end
-
- class Bar < Baz
- def foo
- super
- end
- end
-
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "show_source Bar#foo -s"
- type "exit"
- end
-
- assert_match(%r[Error: Couldn't locate a super definition for Bar#foo], out)
- end
-
- def test_show_source_method_exceeds_super_chain
- write_ruby <<~RUBY
- class Baz
- def foo
- end
- end
-
- class Bar < Baz
- def foo
- super
- end
- end
-
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "show_source Bar#foo -ss"
- type "exit"
- end
-
- assert_match(%r[Error: Couldn't locate a super definition for Bar#foo], out)
- end
-
- def test_show_source_method_accidental_characters
- write_ruby <<~'RUBY'
- class Baz
- def foo
- end
- end
-
- class Bar < Baz
- def foo
- super
- end
- end
-
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "show_source Bar#foo -sddddd"
- type "exit"
- end
-
- assert_match(%r[#{@ruby_file.to_path}:2\s+def foo\r\n end], out)
- end
-
- def test_show_source_receiver_super
- write_ruby <<~RUBY
- class Baz
- def foo
- end
- end
-
- class Bar < Baz
- def foo
- super
- end
- end
-
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "bar = Bar.new"
- type "show_source bar.foo -s"
- type "exit"
- end
-
- assert_match(%r[#{@ruby_file.to_path}:2\s+def foo\r\n end], out)
- end
-
- def test_show_source_with_double_colons
- write_ruby <<~RUBY
- class Foo
- end
-
- class Foo
- class Bar
- end
- end
-
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "show_source ::Foo"
- type "exit"
- end
-
- assert_match(%r[#{@ruby_file.to_path}:1\s+class Foo\r\nend], out)
-
- out = run_ruby_file do
- type "show_source ::Foo::Bar"
- type "exit"
- end
-
- assert_match(%r[#{@ruby_file.to_path}:5\s+class Bar\r\n end], out)
- end
-
- def test_show_source_keep_script_lines
- pend unless defined?(RubyVM.keep_script_lines)
-
- write_ruby <<~RUBY
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "def foo; end"
- type "show_source foo"
- type "exit"
- end
-
- assert_match(%r[#{@ruby_file.to_path}\(irb\):1\s+def foo; end], out)
- end
-
- def test_show_source_unavailable_source
- write_ruby <<~RUBY
- binding.irb
- RUBY
-
- out = run_ruby_file do
- type "RubyVM.keep_script_lines = false if defined?(RubyVM.keep_script_lines)"
- type "def foo; end"
- type "show_source foo"
- type "exit"
- end
- assert_match(%r[#{@ruby_file.to_path}\(irb\):2\s+Source not available], out)
- end
-
- def test_show_source_shows_binary_source
- write_ruby <<~RUBY
- # io-console is an indirect dependency of irb
- require "io/console"
-
- binding.irb
- RUBY
-
- out = run_ruby_file do
- # IO::ConsoleMode is defined in io-console gem's C extension
- type "show_source IO::ConsoleMode"
- type "exit"
- end
-
- # A safeguard to make sure the test subject is actually defined
- refute_match(/NameError/, out)
- assert_match(%r[Defined in binary file:.+io/console], out)
- end
-
- def test_show_source_with_constant_lookup
- write_ruby <<~RUBY
- X = 1
- module M
- Y = 1
- Z = 2
- end
- class A
- Z = 1
- Array = 1
- class B
- include M
- Object.new.instance_eval { binding.irb }
- end
- end
- RUBY
-
- out = run_ruby_file do
- type "show_source X"
- type "show_source Y"
- type "show_source Z"
- type "show_source Array"
- type "exit"
- end
-
- assert_match(%r[#{@ruby_file.to_path}:1\s+X = 1], out)
- assert_match(%r[#{@ruby_file.to_path}:3\s+Y = 1], out)
- assert_match(%r[#{@ruby_file.to_path}:7\s+Z = 1], out)
- assert_match(%r[#{@ruby_file.to_path}:8\s+Array = 1], out)
- end
- end
-end
diff --git a/test/irb/helper.rb b/test/irb/helper.rb
deleted file mode 100644
index 1614b42adb..0000000000
--- a/test/irb/helper.rb
+++ /dev/null
@@ -1,219 +0,0 @@
-require "test/unit"
-require "pathname"
-require "rubygems"
-
-begin
- require_relative "../lib/helper"
- require_relative "../lib/envutil"
-rescue LoadError # ruby/ruby defines helpers differently
-end
-
-begin
- require "pty"
-rescue LoadError # some platforms don't support PTY
-end
-
-module IRB
- class InputMethod; end
-end
-
-module TestIRB
- RUBY_3_4 = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.4.0.dev")
- class TestCase < Test::Unit::TestCase
- class TestInputMethod < ::IRB::InputMethod
- attr_reader :list, :line_no
-
- def initialize(list = [])
- @line_no = 0
- @list = list
- end
-
- def gets
- @list[@line_no]&.tap {@line_no += 1}
- end
-
- def eof?
- @line_no >= @list.size
- end
-
- def encoding
- Encoding.default_external
- end
-
- def reset
- @line_no = 0
- end
- end
-
- def ruby_core?
- !Pathname(__dir__).join("../../", "irb.gemspec").exist?
- end
-
- def save_encodings
- @default_encoding = [Encoding.default_external, Encoding.default_internal]
- @stdio_encodings = [STDIN, STDOUT, STDERR].map {|io| [io.external_encoding, io.internal_encoding] }
- end
-
- def restore_encodings
- EnvUtil.suppress_warning do
- Encoding.default_external, Encoding.default_internal = *@default_encoding
- [STDIN, STDOUT, STDERR].zip(@stdio_encodings) do |io, encs|
- io.set_encoding(*encs)
- end
- end
- end
-
- def without_rdoc(&block)
- ::Kernel.send(:alias_method, :irb_original_require, :require)
-
- ::Kernel.define_method(:require) do |name|
- raise LoadError, "cannot load such file -- rdoc (test)" if name.match?("rdoc") || name.match?(/^rdoc\/.*/)
- ::Kernel.send(:irb_original_require, name)
- end
-
- yield
- ensure
- EnvUtil.suppress_warning {
- ::Kernel.send(:alias_method, :require, :irb_original_require)
- ::Kernel.undef_method :irb_original_require
- }
- end
- end
-
- class IntegrationTestCase < TestCase
- LIB = File.expand_path("../../lib", __dir__)
- TIMEOUT_SEC = 3
-
- def setup
- @envs = {}
- @tmpfiles = []
-
- unless defined?(PTY)
- omit "Integration tests require PTY."
- end
-
- if ruby_core?
- omit "This test works only under ruby/irb"
- end
-
- write_rc <<~RUBY
- IRB.conf[:USE_PAGER] = false
- RUBY
- end
-
- def teardown
- @tmpfiles.each do |tmpfile|
- File.unlink(tmpfile)
- end
- end
-
- def run_ruby_file(&block)
- cmd = [EnvUtil.rubybin, "-I", LIB, @ruby_file.to_path]
- tmp_dir = Dir.mktmpdir
-
- @commands = []
- lines = []
-
- yield
-
- # Test should not depend on user's irbrc file
- @envs["HOME"] ||= tmp_dir
- @envs["XDG_CONFIG_HOME"] ||= tmp_dir
- @envs["IRBRC"] = nil unless @envs.key?("IRBRC")
-
- PTY.spawn(@envs.merge("TERM" => "dumb"), *cmd) do |read, write, pid|
- Timeout.timeout(TIMEOUT_SEC) 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
- ensure
- read.close
- write.close
- kill_safely(pid)
- 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
- 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#L721-L728
- def safe_gets(read)
- read.gets
- rescue Errno::EIO
- nil
- end
-
- def kill_safely pid
- return if wait_pid pid, TIMEOUT_SEC
-
- Process.kill :TERM, pid
- return if wait_pid pid, 0.2
-
- Process.kill :KILL, pid
- Process.waitpid(pid)
- rescue Errno::EPERM, Errno::ESRCH
- end
-
- def wait_pid pid, sec
- total_sec = 0.0
- wait_sec = 0.001 # 1ms
-
- while total_sec < sec
- if Process.waitpid(pid, Process::WNOHANG) == pid
- return true
- end
- sleep wait_sec
- total_sec += wait_sec
- wait_sec *= 2
- end
-
- false
- rescue Errno::ECHILD
- true
- end
-
- def type(command)
- @commands << command
- end
-
- def write_ruby(program)
- @ruby_file = Tempfile.create(%w{irb- .rb})
- @tmpfiles << @ruby_file
- @ruby_file.write(program)
- @ruby_file.close
- end
-
- def write_rc(content)
- # Append irbrc content if a tempfile for it already exists
- if @irbrc
- @irbrc = File.open(@irbrc, "a")
- else
- @irbrc = Tempfile.new('irbrc')
- @tmpfiles << @irbrc
- end
-
- @irbrc.write(content)
- @irbrc.close
- @envs['IRBRC'] = @irbrc.path
- end
- end
-end
diff --git a/test/irb/test_color.rb b/test/irb/test_color.rb
deleted file mode 100644
index 72e036eab7..0000000000
--- a/test/irb/test_color.rb
+++ /dev/null
@@ -1,274 +0,0 @@
-# frozen_string_literal: false
-require 'irb/color'
-require 'stringio'
-
-require_relative "helper"
-
-module TestIRB
- class ColorTest < TestCase
- CLEAR = "\e[0m"
- BOLD = "\e[1m"
- UNDERLINE = "\e[4m"
- REVERSE = "\e[7m"
- RED = "\e[31m"
- GREEN = "\e[32m"
- YELLOW = "\e[33m"
- BLUE = "\e[34m"
- MAGENTA = "\e[35m"
- CYAN = "\e[36m"
-
- def setup
- super
- if IRB.respond_to?(:conf)
- @colorize, IRB.conf[:USE_COLORIZE] = IRB.conf[:USE_COLORIZE], true
- end
- end
-
- def teardown
- if instance_variable_defined?(:@colorize)
- IRB.conf[:USE_COLORIZE] = @colorize
- end
- super
- end
-
- def test_colorize
- text = "text"
- {
- [:BOLD] => "#{BOLD}#{text}#{CLEAR}",
- [:UNDERLINE] => "#{UNDERLINE}#{text}#{CLEAR}",
- [:REVERSE] => "#{REVERSE}#{text}#{CLEAR}",
- [:RED] => "#{RED}#{text}#{CLEAR}",
- [:GREEN] => "#{GREEN}#{text}#{CLEAR}",
- [:YELLOW] => "#{YELLOW}#{text}#{CLEAR}",
- [:BLUE] => "#{BLUE}#{text}#{CLEAR}",
- [:MAGENTA] => "#{MAGENTA}#{text}#{CLEAR}",
- [:CYAN] => "#{CYAN}#{text}#{CLEAR}",
- }.each do |seq, result|
- assert_equal_with_term(result, text, seq: seq)
-
- assert_equal_with_term(text, text, seq: seq, tty: false)
- assert_equal_with_term(text, text, seq: seq, colorable: false)
- assert_equal_with_term(result, text, seq: seq, tty: false, colorable: true)
- end
- end
-
- def test_colorize_code
- # Common behaviors. Warn parser error, but do not warn compile error.
- tests = {
- "1" => "#{BLUE}#{BOLD}1#{CLEAR}",
- "2.3" => "#{MAGENTA}#{BOLD}2.3#{CLEAR}",
- "7r" => "#{BLUE}#{BOLD}7r#{CLEAR}",
- "8i" => "#{BLUE}#{BOLD}8i#{CLEAR}",
- "['foo', :bar]" => "[#{RED}#{BOLD}'#{CLEAR}#{RED}foo#{CLEAR}#{RED}#{BOLD}'#{CLEAR}, #{YELLOW}:#{CLEAR}#{YELLOW}bar#{CLEAR}]",
- "class A; end" => "#{GREEN}class#{CLEAR} #{BLUE}#{BOLD}#{UNDERLINE}A#{CLEAR}; #{GREEN}end#{CLEAR}",
- "def self.foo; bar; end" => "#{GREEN}def#{CLEAR} #{CYAN}#{BOLD}self#{CLEAR}.#{BLUE}#{BOLD}foo#{CLEAR}; bar; #{GREEN}end#{CLEAR}",
- 'erb = ERB.new("a#{nil}b", trim_mode: "-")' => "erb = #{BLUE}#{BOLD}#{UNDERLINE}ERB#{CLEAR}.new(#{RED}#{BOLD}\"#{CLEAR}#{RED}a#{CLEAR}#{RED}\#{#{CLEAR}#{CYAN}#{BOLD}nil#{CLEAR}#{RED}}#{CLEAR}#{RED}b#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}, #{MAGENTA}trim_mode:#{CLEAR} #{RED}#{BOLD}\"#{CLEAR}#{RED}-#{CLEAR}#{RED}#{BOLD}\"#{CLEAR})",
- "# comment" => "#{BLUE}#{BOLD}# comment#{CLEAR}",
- "def f;yield(hello);end" => "#{GREEN}def#{CLEAR} #{BLUE}#{BOLD}f#{CLEAR};#{GREEN}yield#{CLEAR}(hello);#{GREEN}end#{CLEAR}",
- '"##@var]"' => "#{RED}#{BOLD}\"#{CLEAR}#{RED}\##{CLEAR}#{RED}\##{CLEAR}@var#{RED}]#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}",
- '"foo#{a} #{b}"' => "#{RED}#{BOLD}\"#{CLEAR}#{RED}foo#{CLEAR}#{RED}\#{#{CLEAR}a#{RED}}#{CLEAR}#{RED} #{CLEAR}#{RED}\#{#{CLEAR}b#{RED}}#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}",
- '/r#{e}g/' => "#{RED}#{BOLD}/#{CLEAR}#{RED}r#{CLEAR}#{RED}\#{#{CLEAR}e#{RED}}#{CLEAR}#{RED}g#{CLEAR}#{RED}#{BOLD}/#{CLEAR}",
- "'a\nb'" => "#{RED}#{BOLD}'#{CLEAR}#{RED}a#{CLEAR}\n#{RED}b#{CLEAR}#{RED}#{BOLD}'#{CLEAR}",
- "%[str]" => "#{RED}#{BOLD}%[#{CLEAR}#{RED}str#{CLEAR}#{RED}#{BOLD}]#{CLEAR}",
- "%Q[str]" => "#{RED}#{BOLD}%Q[#{CLEAR}#{RED}str#{CLEAR}#{RED}#{BOLD}]#{CLEAR}",
- "%q[str]" => "#{RED}#{BOLD}%q[#{CLEAR}#{RED}str#{CLEAR}#{RED}#{BOLD}]#{CLEAR}",
- "%x[cmd]" => "#{RED}#{BOLD}%x[#{CLEAR}#{RED}cmd#{CLEAR}#{RED}#{BOLD}]#{CLEAR}",
- "%r[reg]" => "#{RED}#{BOLD}%r[#{CLEAR}#{RED}reg#{CLEAR}#{RED}#{BOLD}]#{CLEAR}",
- "%w[a b]" => "#{RED}#{BOLD}%w[#{CLEAR}#{RED}a#{CLEAR} #{RED}b#{CLEAR}#{RED}#{BOLD}]#{CLEAR}",
- "%W[a b]" => "#{RED}#{BOLD}%W[#{CLEAR}#{RED}a#{CLEAR} #{RED}b#{CLEAR}#{RED}#{BOLD}]#{CLEAR}",
- "%s[a b]" => "#{YELLOW}%s[#{CLEAR}#{YELLOW}a b#{CLEAR}#{YELLOW}]#{CLEAR}",
- "%i[c d]" => "#{YELLOW}%i[#{CLEAR}#{YELLOW}c#{CLEAR}#{YELLOW} #{CLEAR}#{YELLOW}d#{CLEAR}#{YELLOW}]#{CLEAR}",
- "%I[c d]" => "#{YELLOW}%I[#{CLEAR}#{YELLOW}c#{CLEAR}#{YELLOW} #{CLEAR}#{YELLOW}d#{CLEAR}#{YELLOW}]#{CLEAR}",
- "{'a': 1}" => "{#{RED}#{BOLD}'#{CLEAR}#{RED}a#{CLEAR}#{RED}#{BOLD}':#{CLEAR} #{BLUE}#{BOLD}1#{CLEAR}}",
- ":Struct" => "#{YELLOW}:#{CLEAR}#{YELLOW}Struct#{CLEAR}",
- '"#{}"' => "#{RED}#{BOLD}\"#{CLEAR}#{RED}\#{#{CLEAR}#{RED}}#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}",
- ':"a#{}b"' => "#{YELLOW}:\"#{CLEAR}#{YELLOW}a#{CLEAR}#{YELLOW}\#{#{CLEAR}#{YELLOW}}#{CLEAR}#{YELLOW}b#{CLEAR}#{YELLOW}\"#{CLEAR}",
- ':"a#{ def b; end; \'c\' + "#{ :d }" }e"' => "#{YELLOW}:\"#{CLEAR}#{YELLOW}a#{CLEAR}#{YELLOW}\#{#{CLEAR} #{GREEN}def#{CLEAR} #{BLUE}#{BOLD}b#{CLEAR}; #{GREEN}end#{CLEAR}; #{RED}#{BOLD}'#{CLEAR}#{RED}c#{CLEAR}#{RED}#{BOLD}'#{CLEAR} + #{RED}#{BOLD}\"#{CLEAR}#{RED}\#{#{CLEAR} #{YELLOW}:#{CLEAR}#{YELLOW}d#{CLEAR} #{RED}}#{CLEAR}#{RED}#{BOLD}\"#{CLEAR} #{YELLOW}}#{CLEAR}#{YELLOW}e#{CLEAR}#{YELLOW}\"#{CLEAR}",
- "[__FILE__, __LINE__, __ENCODING__]" => "[#{CYAN}#{BOLD}__FILE__#{CLEAR}, #{CYAN}#{BOLD}__LINE__#{CLEAR}, #{CYAN}#{BOLD}__ENCODING__#{CLEAR}]",
- ":self" => "#{YELLOW}:#{CLEAR}#{YELLOW}self#{CLEAR}",
- ":class" => "#{YELLOW}:#{CLEAR}#{YELLOW}class#{CLEAR}",
- "[:end, 2]" => "[#{YELLOW}:#{CLEAR}#{YELLOW}end#{CLEAR}, #{BLUE}#{BOLD}2#{CLEAR}]",
- "[:>, 3]" => "[#{YELLOW}:#{CLEAR}#{YELLOW}>#{CLEAR}, #{BLUE}#{BOLD}3#{CLEAR}]",
- "[:`, 4]" => "[#{YELLOW}:#{CLEAR}#{YELLOW}`#{CLEAR}, #{BLUE}#{BOLD}4#{CLEAR}]",
- ":Hello ? world : nil" => "#{YELLOW}:#{CLEAR}#{YELLOW}Hello#{CLEAR} ? world : #{CYAN}#{BOLD}nil#{CLEAR}",
- 'raise "foo#{bar}baz"' => "raise #{RED}#{BOLD}\"#{CLEAR}#{RED}foo#{CLEAR}#{RED}\#{#{CLEAR}bar#{RED}}#{CLEAR}#{RED}baz#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}",
- '["#{obj.inspect}"]' => "[#{RED}#{BOLD}\"#{CLEAR}#{RED}\#{#{CLEAR}obj.inspect#{RED}}#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}]",
- 'URI.parse "#{}"' => "#{BLUE}#{BOLD}#{UNDERLINE}URI#{CLEAR}.parse #{RED}#{BOLD}\"#{CLEAR}#{RED}\#{#{CLEAR}#{RED}}#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}",
- "begin\nrescue\nend" => "#{GREEN}begin#{CLEAR}\n#{GREEN}rescue#{CLEAR}\n#{GREEN}end#{CLEAR}",
- "foo %w[bar]" => "foo #{RED}#{BOLD}%w[#{CLEAR}#{RED}bar#{CLEAR}#{RED}#{BOLD}]#{CLEAR}",
- "foo %i[bar]" => "foo #{YELLOW}%i[#{CLEAR}#{YELLOW}bar#{CLEAR}#{YELLOW}]#{CLEAR}",
- "foo :@bar, baz, :@@qux, :$quux" => "foo #{YELLOW}:#{CLEAR}#{YELLOW}@bar#{CLEAR}, baz, #{YELLOW}:#{CLEAR}#{YELLOW}@@qux#{CLEAR}, #{YELLOW}:#{CLEAR}#{YELLOW}$quux#{CLEAR}",
- "`echo`" => "#{RED}#{BOLD}`#{CLEAR}#{RED}echo#{CLEAR}#{RED}#{BOLD}`#{CLEAR}",
- "\t" => "\t", # not ^I
- "foo(*%W(bar))" => "foo(*#{RED}#{BOLD}%W(#{CLEAR}#{RED}bar#{CLEAR}#{RED}#{BOLD})#{CLEAR})",
- "$stdout" => "#{GREEN}#{BOLD}$stdout#{CLEAR}",
- "__END__" => "#{GREEN}__END__#{CLEAR}",
- "foo\n__END__\nbar" => "foo\n#{GREEN}__END__#{CLEAR}\nbar",
- "foo\n<<A\0\0bar\nA\nbaz" => "foo\n#{RED}<<A#{CLEAR}^@^@bar\n#{RED}A#{CLEAR}\nbaz",
- "<<A+1\nA" => "#{RED}<<A#{CLEAR}+#{BLUE}#{BOLD}1#{CLEAR}\n#{RED}A#{CLEAR}",
- }
-
- tests.merge!({
- "4.5.6" => "#{MAGENTA}#{BOLD}4.5#{CLEAR}#{RED}#{REVERSE}.6#{CLEAR}",
- "\e[0m\n" => "#{RED}#{REVERSE}^[#{CLEAR}[#{BLUE}#{BOLD}0#{CLEAR}#{RED}#{REVERSE}m#{CLEAR}\n",
- "<<EOS\nhere\nEOS" => "#{RED}<<EOS#{CLEAR}\n#{RED}here#{CLEAR}\n#{RED}EOS#{CLEAR}",
- })
-
- # specific to Ruby 3.0+
- if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0.0')
- tests.merge!({
- "[1]]]\u0013" => "[#{BLUE}#{BOLD}1#{CLEAR}]#{RED}#{REVERSE}]#{CLEAR}#{RED}#{REVERSE}]#{CLEAR}#{RED}#{REVERSE}^S#{CLEAR}",
- })
- tests.merge!({
- "def req(true) end" => "#{GREEN}def#{CLEAR} #{BLUE}#{BOLD}req#{CLEAR}(#{RED}#{REVERSE}true#{CLEAR}) #{RED}#{REVERSE}end#{CLEAR}",
- "nil = 1" => "#{RED}#{REVERSE}nil#{CLEAR} = #{BLUE}#{BOLD}1#{CLEAR}",
- "alias $x $1" => "#{GREEN}alias#{CLEAR} #{GREEN}#{BOLD}$x#{CLEAR} #{RED}#{REVERSE}$1#{CLEAR}",
- "class bad; end" => "#{GREEN}class#{CLEAR} #{RED}#{REVERSE}bad#{CLEAR}; #{GREEN}end#{CLEAR}",
- "def req(@a) end" => "#{GREEN}def#{CLEAR} #{BLUE}#{BOLD}req#{CLEAR}(#{RED}#{REVERSE}@a#{CLEAR}) #{GREEN}end#{CLEAR}",
- })
- if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.2.0')
- tests.merge!({
- "def req(true) end" => "#{GREEN}def#{CLEAR} #{BLUE}#{BOLD}req#{CLEAR}(#{RED}#{REVERSE}true#{CLEAR}#{RED}#{REVERSE})#{CLEAR} #{RED}#{REVERSE}end#{CLEAR}",
- })
- end
- else
- tests.merge!({
- "[1]]]\u0013" => "[#{BLUE}#{BOLD}1#{CLEAR}]#{RED}#{REVERSE}]#{CLEAR}]^S",
- "def req(true) end" => "#{GREEN}def#{CLEAR} #{BLUE}#{BOLD}req#{CLEAR}(#{RED}#{REVERSE}true#{CLEAR}) end",
- "nil = 1" => "#{CYAN}#{BOLD}nil#{CLEAR} = #{BLUE}#{BOLD}1#{CLEAR}",
- "alias $x $1" => "#{GREEN}alias#{CLEAR} #{GREEN}#{BOLD}$x#{CLEAR} $1",
- "class bad; end" => "#{GREEN}class#{CLEAR} bad; #{GREEN}end#{CLEAR}",
- "def req(@a) end" => "#{GREEN}def#{CLEAR} #{BLUE}#{BOLD}req#{CLEAR}(@a) #{GREEN}end#{CLEAR}",
- })
- end
-
- tests.each do |code, result|
- assert_equal_with_term(result, code, complete: true)
- assert_equal_with_term(result, code, complete: false)
-
- assert_equal_with_term(code, code, complete: true, tty: false)
- assert_equal_with_term(code, code, complete: false, tty: false)
-
- assert_equal_with_term(code, code, complete: true, colorable: false)
-
- assert_equal_with_term(code, code, complete: false, colorable: false)
-
- assert_equal_with_term(result, code, complete: true, tty: false, colorable: true)
-
- assert_equal_with_term(result, code, complete: false, tty: false, colorable: true)
- end
- end
-
- def test_colorize_code_with_local_variables
- code = "a /(b +1)/i"
- result_without_lvars = "a #{RED}#{BOLD}/#{CLEAR}#{RED}(b +1)#{CLEAR}#{RED}#{BOLD}/i#{CLEAR}"
- result_with_lvar = "a /(b #{BLUE}#{BOLD}+1#{CLEAR})/i"
- result_with_lvars = "a /(b +#{BLUE}#{BOLD}1#{CLEAR})/i"
-
- assert_equal_with_term(result_without_lvars, code)
- assert_equal_with_term(result_with_lvar, code, local_variables: ['a'])
- assert_equal_with_term(result_with_lvars, code, local_variables: ['a', 'b'])
- end
-
- def test_colorize_code_complete_true
- # `complete: true` behaviors. Warn end-of-file.
- {
- "'foo' + 'bar" => "#{RED}#{BOLD}'#{CLEAR}#{RED}foo#{CLEAR}#{RED}#{BOLD}'#{CLEAR} + #{RED}#{BOLD}'#{CLEAR}#{RED}#{REVERSE}bar#{CLEAR}",
- "('foo" => "(#{RED}#{BOLD}'#{CLEAR}#{RED}#{REVERSE}foo#{CLEAR}",
- }.each do |code, result|
- assert_equal_with_term(result, code, complete: true)
-
- assert_equal_with_term(code, code, complete: true, tty: false)
-
- assert_equal_with_term(code, code, complete: true, colorable: false)
-
- assert_equal_with_term(result, code, complete: true, tty: false, colorable: true)
- end
- end
-
- def test_colorize_code_complete_false
- # `complete: false` behaviors. Do not warn end-of-file.
- {
- "'foo' + 'bar" => "#{RED}#{BOLD}'#{CLEAR}#{RED}foo#{CLEAR}#{RED}#{BOLD}'#{CLEAR} + #{RED}#{BOLD}'#{CLEAR}#{RED}bar#{CLEAR}",
- "('foo" => "(#{RED}#{BOLD}'#{CLEAR}#{RED}foo#{CLEAR}",
- }.each do |code, result|
- assert_equal_with_term(result, code, complete: false)
-
- assert_equal_with_term(code, code, complete: false, tty: false)
-
- assert_equal_with_term(code, code, complete: false, colorable: false)
-
- assert_equal_with_term(result, code, complete: false, tty: false, colorable: true)
- end
- end
-
- def test_inspect_colorable
- {
- 1 => true,
- 2.3 => true,
- ['foo', :bar] => true,
- (a = []; a << a; a) => false,
- (h = {}; h[h] = h; h) => false,
- { a: 4 } => true,
- /reg/ => true,
- (1..3) => true,
- Object.new => false,
- Struct => true,
- Test => true,
- Struct.new(:a) => false,
- Struct.new(:a).new(1) => false,
- }.each do |object, result|
- assert_equal(result, IRB::Color.inspect_colorable?(object), "Case: inspect_colorable?(#{object.inspect})")
- end
- end
-
- private
-
- def with_term(tty: true)
- stdout = $stdout
- io = StringIO.new
- def io.tty?; true; end if tty
- $stdout = io
-
- env = ENV.to_h.dup
- ENV['TERM'] = 'xterm-256color'
-
- yield
- ensure
- $stdout = stdout
- ENV.replace(env) if env
- end
-
- def assert_equal_with_term(result, code, seq: nil, tty: true, **opts)
- actual = with_term(tty: tty) do
- if seq
- IRB::Color.colorize(code, seq, **opts)
- else
- IRB::Color.colorize_code(code, **opts)
- end
- end
- message = -> {
- args = [code.dump]
- args << seq.inspect if seq
- opts.each {|kwd, val| args << "#{kwd}: #{val}"}
- "Case: colorize#{seq ? "" : "_code"}(#{args.join(', ')})\nResult: #{humanized_literal(actual)}"
- }
- assert_equal(result, actual, message)
- end
-
- def humanized_literal(str)
- str
- .gsub(CLEAR, '@@@{CLEAR}')
- .gsub(BOLD, '@@@{BOLD}')
- .gsub(UNDERLINE, '@@@{UNDERLINE}')
- .gsub(REVERSE, '@@@{REVERSE}')
- .gsub(RED, '@@@{RED}')
- .gsub(GREEN, '@@@{GREEN}')
- .gsub(YELLOW, '@@@{YELLOW}')
- .gsub(BLUE, '@@@{BLUE}')
- .gsub(MAGENTA, '@@@{MAGENTA}')
- .gsub(CYAN, '@@@{CYAN}')
- .dump.gsub(/@@@/, '#')
- end
- end
-end
diff --git a/test/irb/test_color_printer.rb b/test/irb/test_color_printer.rb
deleted file mode 100644
index c2c624d868..0000000000
--- a/test/irb/test_color_printer.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# frozen_string_literal: false
-require 'irb/color_printer'
-require 'stringio'
-
-require_relative "helper"
-
-module TestIRB
- class ColorPrinterTest < TestCase
- CLEAR = "\e[0m"
- BOLD = "\e[1m"
- RED = "\e[31m"
- GREEN = "\e[32m"
- BLUE = "\e[34m"
- CYAN = "\e[36m"
-
- def setup
- super
- if IRB.respond_to?(:conf)
- @colorize, IRB.conf[:USE_COLORIZE] = IRB.conf[:USE_COLORIZE], true
- end
- @get_screen_size = Reline.method(:get_screen_size)
- Reline.instance_eval { undef :get_screen_size }
- def Reline.get_screen_size
- [36, 80]
- end
- end
-
- def teardown
- Reline.instance_eval { undef :get_screen_size }
- Reline.define_singleton_method(:get_screen_size, @get_screen_size)
- if instance_variable_defined?(:@colorize)
- IRB.conf[:USE_COLORIZE] = @colorize
- end
- super
- end
-
- IRBTestColorPrinter = Struct.new(:a)
-
- def test_color_printer
- {
- 1 => "#{BLUE}#{BOLD}1#{CLEAR}\n",
- "a\nb" => %[#{RED}#{BOLD}"#{CLEAR}#{RED}a\\nb#{CLEAR}#{RED}#{BOLD}"#{CLEAR}\n],
- IRBTestColorPrinter.new('test') => "#{GREEN}#<struct TestIRB::ColorPrinterTest::IRBTestColorPrinter#{CLEAR} a#{GREEN}=#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}#{RED}test#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}#{GREEN}>#{CLEAR}\n",
- Ripper::Lexer.new('1').scan => "[#{GREEN}#<Ripper::Lexer::Elem:#{CLEAR} on_int@1:0 END token: #{RED}#{BOLD}\"#{CLEAR}#{RED}1#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}#{GREEN}>#{CLEAR}]\n",
- Class.new{define_method(:pretty_print){|q| q.text("[__FILE__, __LINE__, __ENCODING__]")}}.new => "[#{CYAN}#{BOLD}__FILE__#{CLEAR}, #{CYAN}#{BOLD}__LINE__#{CLEAR}, #{CYAN}#{BOLD}__ENCODING__#{CLEAR}]\n",
- }.each do |object, result|
- actual = with_term { IRB::ColorPrinter.pp(object, '') }
- assert_equal(result, actual, "Case: IRB::ColorPrinter.pp(#{object.inspect}, '')")
- end
- end
-
- private
-
- def with_term
- stdout = $stdout
- io = StringIO.new
- def io.tty?; true; end
- $stdout = io
-
- env = ENV.to_h.dup
- ENV['TERM'] = 'xterm-256color'
-
- yield
- ensure
- $stdout = stdout
- ENV.replace(env) if env
- end
- end
-end
diff --git a/test/irb/test_command.rb b/test/irb/test_command.rb
deleted file mode 100644
index 03fdd37855..0000000000
--- a/test/irb/test_command.rb
+++ /dev/null
@@ -1,1043 +0,0 @@
-# frozen_string_literal: false
-require "irb"
-
-require_relative "helper"
-
-module TestIRB
- class CommandTestCase < TestCase
- def setup
- @pwd = Dir.pwd
- @tmpdir = File.join(Dir.tmpdir, "test_reline_config_#{$$}")
- begin
- Dir.mkdir(@tmpdir)
- rescue Errno::EEXIST
- FileUtils.rm_rf(@tmpdir)
- Dir.mkdir(@tmpdir)
- end
- Dir.chdir(@tmpdir)
- @home_backup = ENV["HOME"]
- ENV["HOME"] = @tmpdir
- @xdg_config_home_backup = ENV.delete("XDG_CONFIG_HOME")
- save_encodings
- IRB.instance_variable_get(:@CONF).clear
- IRB.instance_variable_set(:@existing_rc_name_generators, nil)
- @is_win = (RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/)
- end
-
- def teardown
- ENV["XDG_CONFIG_HOME"] = @xdg_config_home_backup
- ENV["HOME"] = @home_backup
- Dir.chdir(@pwd)
- FileUtils.rm_rf(@tmpdir)
- restore_encodings
- end
-
- def execute_lines(*lines, conf: {}, main: self, irb_path: nil)
- capture_output do
- IRB.init_config(nil)
- IRB.conf[:VERBOSE] = false
- IRB.conf[:PROMPT_MODE] = :SIMPLE
- IRB.conf[:USE_PAGER] = false
- 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
- irb.eval_input
- end
- end
- end
-
- class FrozenObjectTest < CommandTestCase
- def test_calling_command_on_a_frozen_main
- main = Object.new.freeze
-
- out, err = execute_lines(
- "irb_info",
- main: main
- )
- assert_empty(err)
- assert_match(/RUBY_PLATFORM/, out)
- end
- end
-
- class InfoTest < CommandTestCase
- def setup
- super
- @locals_backup = ENV.delete("LANG"), ENV.delete("LC_ALL")
- end
-
- def teardown
- super
- ENV["LANG"], ENV["LC_ALL"] = @locals_backup
- end
-
- def test_irb_info_multiline
- FileUtils.touch("#{@tmpdir}/.inputrc")
- FileUtils.touch("#{@tmpdir}/.irbrc")
- FileUtils.touch("#{@tmpdir}/_irbrc")
-
- out, err = execute_lines(
- "irb_info",
- conf: { USE_MULTILINE: true, USE_SINGLELINE: false }
- )
-
- expected = %r{
- Ruby\sversion:\s.+\n
- IRB\sversion:\sirb\s.+\n
- InputMethod:\sAbstract\sInputMethod\n
- Completion: .+\n
- \.irbrc\spaths:.*\.irbrc.*_irbrc\n
- RUBY_PLATFORM:\s.+\n
- East\sAsian\sAmbiguous\sWidth:\s\d\n
- #{@is_win ? 'Code\spage:\s\d+\n' : ''}
- }x
-
- assert_empty err
- assert_match expected, out
- end
-
- def test_irb_info_singleline
- FileUtils.touch("#{@tmpdir}/.inputrc")
- FileUtils.touch("#{@tmpdir}/.irbrc")
-
- out, err = execute_lines(
- "irb_info",
- conf: { USE_MULTILINE: false, USE_SINGLELINE: true }
- )
-
- expected = %r{
- Ruby\sversion:\s.+\n
- IRB\sversion:\sirb\s.+\n
- InputMethod:\sAbstract\sInputMethod\n
- Completion: .+\n
- \.irbrc\spaths:\s.+\n
- RUBY_PLATFORM:\s.+\n
- East\sAsian\sAmbiguous\sWidth:\s\d\n
- #{@is_win ? 'Code\spage:\s\d+\n' : ''}
- }x
-
- assert_empty err
- assert_match expected, out
- end
-
- 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")
-
- out, err = execute_lines(
- "irb_info",
- conf: { USE_MULTILINE: true, USE_SINGLELINE: false }
- )
-
- expected = %r{
- Ruby\sversion:\s.+\n
- IRB\sversion:\sirb\s.+\n
- InputMethod:\sAbstract\sInputMethod\n
- Completion: .+\n
- RUBY_PLATFORM:\s.+\n
- East\sAsian\sAmbiguous\sWidth:\s\d\n
- #{@is_win ? 'Code\spage:\s\d+\n' : ''}
- }x
-
- 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
-
- 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")
-
- out, err = execute_lines(
- "irb_info",
- conf: { USE_MULTILINE: false, USE_SINGLELINE: true }
- )
-
- expected = %r{
- Ruby\sversion:\s.+\n
- IRB\sversion:\sirb\s.+\n
- InputMethod:\sAbstract\sInputMethod\n
- Completion: .+\n
- RUBY_PLATFORM:\s.+\n
- East\sAsian\sAmbiguous\sWidth:\s\d\n
- #{@is_win ? 'Code\spage:\s\d+\n' : ''}
- }x
-
- 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
-
- 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"
-
- 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
- Completion: .+\n
- \.irbrc\spaths: .+\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 CustomCommandTestCase < CommandTestCase
- def setup
- @commands_backup = IRB::Command.commands
- IRB::ExtendCommandBundle.class_variable_set(:@@command_override_policies, nil)
- end
-
- def teardown
- IRB::ExtendCommandBundle.class_variable_set(:@@command_override_policies, nil)
- IRB::Command.instance_variable_set(:@commands, @commands_backup)
- end
- end
-
- class CommandArgTest < CustomCommandTestCase
- class PrintArgCommand < IRB::Command::Base
- category 'CommandTest'
- description 'print_command_arg'
- def execute(arg)
- puts "arg=#{arg.inspect}"
- end
- end
-
- def test_arg
- IRB::Command._register_with_aliases(:print_arg, PrintArgCommand, [:pa, IRB::ExtendCommandBundle::OVERRIDE_ALL])
- out, err = execute_lines("print_arg\n")
- assert_empty err
- assert_include(out, 'arg=""')
-
- out, err = execute_lines("print_arg \n")
- assert_empty err
- assert_include(out, 'arg=""')
-
- out, err = execute_lines("print_arg a r g\n")
- assert_empty err
- assert_include(out, 'arg="a r g"')
-
- out, err = execute_lines("print_arg a r g \n")
- assert_empty err
- assert_include(out, 'arg="a r g"')
-
- out, err = execute_lines("pa a r g \n")
- assert_empty err
- assert_include(out, 'arg="a r g"')
- end
- end
-
- class ExtendCommandBundleCompatibilityTest < CustomCommandTestCase
- class FooBarCommand < IRB::Command::Base
- category 'FooBarCategory'
- description 'foobar_description'
- def execute(_arg)
- puts "FooBar executed"
- end
- end
-
- def test_def_extend_command
- IRB::Command._register_with_aliases(:foobar, FooBarCommand, [:fbalias, IRB::ExtendCommandBundle::OVERRIDE_ALL])
- out, err = execute_lines("foobar\n")
- assert_empty err
- assert_include(out, "FooBar executed")
-
- out, err = execute_lines("fbalias\n")
- assert_empty err
- assert_include(out, "FooBar executed")
-
- out, err = execute_lines("show_cmds\n")
- assert_include(out, "FooBarCategory")
- assert_include(out, "foobar_description")
- end
- end
-
- class MeasureTest < CommandTestCase
- def test_measure
- conf = {
- PROMPT: {
- DEFAULT: {
- PROMPT_I: '> ',
- PROMPT_S: '> ',
- PROMPT_C: '> '
- }
- },
- PROMPT_MODE: :DEFAULT,
- MEASURE: false
- }
-
- c = Class.new(Object)
- out, err = execute_lines(
- "measure\n",
- "3\n",
- "measure :off\n",
- "3\n",
- "measure :on\n",
- "3\n",
- "measure :off\n",
- "3\n",
- conf: conf,
- main: c
- )
-
- assert_empty err
- assert_match(/\A(TIME is added\.\n=> nil\nprocessing time: .+\n=> 3\n=> nil\n=> 3\n){2}/, out)
- assert_empty(c.class_variables)
- end
-
- def test_measure_keeps_previous_value
- conf = {
- PROMPT: {
- DEFAULT: {
- PROMPT_I: '> ',
- PROMPT_S: '> ',
- PROMPT_C: '> '
- }
- },
- PROMPT_MODE: :DEFAULT,
- MEASURE: false
- }
-
- c = Class.new(Object)
- out, err = execute_lines(
- "measure\n",
- "3\n",
- "_\n",
- conf: conf,
- main: c
- )
-
- assert_empty err
- assert_match(/\ATIME is added\.\n=> nil\nprocessing time: .+\n=> 3\nprocessing time: .+\n=> 3/, out)
- assert_empty(c.class_variables)
- end
-
- def test_measure_enabled_by_rc
- conf = {
- PROMPT: {
- DEFAULT: {
- PROMPT_I: '> ',
- PROMPT_S: '> ',
- PROMPT_C: '> '
- }
- },
- PROMPT_MODE: :DEFAULT,
- MEASURE: true
- }
-
- out, err = execute_lines(
- "3\n",
- "measure :off\n",
- "3\n",
- conf: conf,
- )
-
- assert_empty err
- assert_match(/\Aprocessing time: .+\n=> 3\n=> nil\n=> 3\n/, out)
- end
-
- def test_measure_enabled_by_rc_with_custom
- measuring_proc = proc { |line, line_no, &block|
- time = Time.now
- result = block.()
- puts 'custom processing time: %fs' % (Time.now - time) if IRB.conf[:MEASURE]
- result
- }
- conf = {
- PROMPT: {
- DEFAULT: {
- PROMPT_I: '> ',
- PROMPT_S: '> ',
- PROMPT_C: '> '
- }
- },
- PROMPT_MODE: :DEFAULT,
- MEASURE: true,
- MEASURE_PROC: { CUSTOM: measuring_proc }
- }
-
- out, err = execute_lines(
- "3\n",
- "measure :off\n",
- "3\n",
- conf: conf,
- )
- assert_empty err
- assert_match(/\Acustom processing time: .+\n=> 3\n=> nil\n=> 3\n/, out)
- end
-
- def test_measure_with_custom
- measuring_proc = proc { |line, line_no, &block|
- time = Time.now
- result = block.()
- puts 'custom processing time: %fs' % (Time.now - time) if IRB.conf[:MEASURE]
- result
- }
- conf = {
- PROMPT: {
- DEFAULT: {
- PROMPT_I: '> ',
- PROMPT_S: '> ',
- PROMPT_C: '> '
- }
- },
- PROMPT_MODE: :DEFAULT,
- MEASURE: false,
- MEASURE_PROC: { CUSTOM: measuring_proc }
- }
- out, err = execute_lines(
- "3\n",
- "measure\n",
- "3\n",
- "measure :off\n",
- "3\n",
- conf: conf
- )
-
- assert_empty err
- assert_match(/\A=> 3\nCUSTOM is added\.\n=> nil\ncustom processing time: .+\n=> 3\n=> nil\n=> 3\n/, out)
- end
-
- def test_measure_toggle
- conf = {
- PROMPT: {
- DEFAULT: {
- PROMPT_I: '> ',
- PROMPT_S: '> ',
- PROMPT_C: '> '
- }
- },
- PROMPT_MODE: :DEFAULT,
- MEASURE: false,
- MEASURE_PROC: {
- FOO: proc { |&block| puts 'foo'; block.call },
- BAR: proc { |&block| puts 'bar'; block.call }
- }
- }
- out, err = execute_lines(
- "measure :foo\n",
- "1\n",
- "measure :on, :bar\n",
- "2\n",
- "measure :off, :foo\n",
- "3\n",
- "measure :off, :bar\n",
- "4\n",
- conf: conf
- )
-
- assert_empty err
- assert_match(/\AFOO is added\.\n=> nil\nfoo\n=> 1\nBAR is added\.\n=> nil\nbar\nfoo\n=> 2\n=> nil\nbar\n=> 3\n=> nil\n=> 4\n/, out)
- end
-
- def test_measure_with_proc_warning
- conf = {
- PROMPT: {
- DEFAULT: {
- PROMPT_I: '> ',
- PROMPT_S: '> ',
- PROMPT_C: '> '
- }
- },
- PROMPT_MODE: :DEFAULT,
- MEASURE: false,
- }
- c = Class.new(Object)
- out, err = execute_lines(
- "3\n",
- "measure do\n",
- "3\n",
- conf: conf,
- main: c
- )
-
- assert_match(/to add custom measure/, err)
- assert_match(/\A=> 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(
- "a = 'bug17564'\n",
- "a\n",
- "irb_source '#{@tmpdir}/a.rb'\n",
- "a\n",
- )
- assert_empty err
- assert_pattern_list([
- /=> "bug17564"\n/,
- /=> "bug17564"\n/,
- / => "hi"\n/,
- / => nil\n/,
- /=> "hi"\n/,
- ], out)
- end
-
- def test_irb_source_without_argument
- out, err = execute_lines(
- "irb_source\n",
- )
- 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(
- "a = 'bug17564'\n",
- "a\n",
- "irb_load '#{@tmpdir}/a.rb'\n",
- "a\n",
- )
- assert_empty err
- assert_pattern_list([
- /=> "bug17564"\n/,
- /=> "bug17564"\n/,
- / => "hi"\n/,
- / => nil\n/,
- /=> "bug17564"\n/,
- ], out)
- end
-
- def test_irb_load_without_argument
- out, err = execute_lines(
- "irb_load\n",
- )
-
- assert_empty err
- assert_match(/Please specify the file name./, out)
- end
- end
-
- class WorkspaceCommandTestCase < CommandTestCase
- def setup
- super
- # create Foo under the test class's namespace so it doesn't pollute global namespace
- self.class.class_eval <<~RUBY
- class Foo; end
- RUBY
- end
- end
-
- class CwwsTest < WorkspaceCommandTestCase
- def test_cwws_returns_the_current_workspace_object
- out, err = execute_lines(
- "cwws",
- "self.class"
- )
-
- assert_empty err
- assert_include(out, self.class.name)
- end
- end
-
- class PushwsTest < WorkspaceCommandTestCase
- def test_pushws_switches_to_new_workspace_and_pushes_the_current_one_to_the_stack
- out, err = execute_lines(
- "pushws #{self.class}::Foo.new",
- "self.class",
- "popws",
- "self.class"
- )
- assert_empty err
-
- assert_match(/=> #{self.class}::Foo\n/, out)
- assert_match(/=> #{self.class}\n$/, out)
- end
-
- def test_pushws_extends_the_new_workspace_with_command_bundle
- out, err = execute_lines(
- "pushws Object.new",
- "self.singleton_class.ancestors"
- )
- assert_empty err
- assert_include(out, "IRB::ExtendCommandBundle")
- end
-
- def test_pushws_prints_workspace_stack_when_no_arg_is_given
- out, err = execute_lines(
- "pushws",
- )
- assert_empty err
- assert_include(out, "[#<TestIRB::PushwsTe...>]")
- end
-
- def test_pushws_without_argument_swaps_the_top_two_workspaces
- out, err = execute_lines(
- "pushws #{self.class}::Foo.new",
- "self.class",
- "pushws",
- "self.class"
- )
- assert_empty err
- assert_match(/=> #{self.class}::Foo\n/, out)
- assert_match(/=> #{self.class}\n$/, out)
- end
- end
-
- class WorkspacesTest < WorkspaceCommandTestCase
- def test_workspaces_returns_the_stack_of_workspaces
- out, err = execute_lines(
- "pushws #{self.class}::Foo.new\n",
- "workspaces",
- )
-
- assert_empty err
- assert_match(/\[#<TestIRB::Workspac...>, #<TestIRB::Workspac...>\]\n/, out)
- end
- end
-
- class PopwsTest < WorkspaceCommandTestCase
- def test_popws_replaces_the_current_workspace_with_the_previous_one
- out, err = execute_lines(
- "pushws Foo.new\n",
- "popws\n",
- "cwws\n",
- "_.class",
- )
- assert_empty err
- assert_include(out, "=> #{self.class}")
- end
-
- def test_popws_prints_help_message_if_the_workspace_is_empty
- out, err = execute_lines(
- "popws\n",
- )
- assert_empty err
- assert_match(/\[#<TestIRB::PopwsTes...>\]\n/, out)
- end
- end
-
- class ChwsTest < WorkspaceCommandTestCase
- def test_chws_replaces_the_current_workspace
- out, err = execute_lines(
- "chws #{self.class}::Foo.new\n",
- "cwws\n",
- "_.class",
- )
- assert_empty err
- assert_include(out, "=> #{self.class}::Foo")
- end
-
- def test_chws_does_nothing_when_receiving_no_argument
- out, err = execute_lines(
- "chws\n",
- "cwws\n",
- "_.class",
- )
- assert_empty err
- assert_include(out, "=> #{self.class}")
- 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 LsTest < CommandTestCase
- def test_ls
- out, err = execute_lines(
- "class P\n",
- " def m() end\n",
- " def m2() end\n",
- "end\n",
-
- "class C < P\n",
- " def m1() end\n",
- " def m2() end\n",
- "end\n",
-
- "module M\n",
- " def m1() end\n",
- " def m3() end\n",
- "end\n",
-
- "module M2\n",
- " include M\n",
- " def m4() end\n",
- "end\n",
-
- "obj = C.new\n",
- "obj.instance_variable_set(:@a, 1)\n",
- "obj.extend M2\n",
- "def obj.m5() end\n",
- "ls obj\n",
- )
-
- assert_empty err
- assert_match(/^instance variables:\s+@a\n/m, out)
- assert_match(/P#methods:\s+m\n/m, out)
- assert_match(/C#methods:\s+m2\n/m, out)
- assert_match(/M#methods:\s+m1\s+m3\n/m, out)
- assert_match(/M2#methods:\s+m4\n/m, out)
- assert_match(/C.methods:\s+m5\n/m, out)
- end
-
- def test_ls_class
- out, err = execute_lines(
- "module M1\n",
- " def m2; end\n",
- " def m3; end\n",
- "end\n",
-
- "class C1\n",
- " def m1; end\n",
- " def m2; end\n",
- "end\n",
-
- "class C2 < C1\n",
- " include M1\n",
- " def m3; end\n",
- " def m4; end\n",
- " def self.m3; end\n",
- " def self.m5; end\n",
- "end\n",
- "ls C2"
- )
-
- assert_empty err
- assert_match(/C2.methods:\s+m3\s+m5\n/, out)
- assert_match(/C2#methods:\s+m3\s+m4\n.*M1#methods:\s+m2\n.*C1#methods:\s+m1\n/, out)
- assert_not_match(/Module#methods/, out)
- assert_not_match(/Class#methods/, out)
- end
-
- def test_ls_module
- out, err = execute_lines(
- "module M1\n",
- " def m1; end\n",
- " def m2; end\n",
- "end\n",
-
- "module M2\n",
- " include M1\n",
- " def m1; end\n",
- " def m3; end\n",
- " def self.m4; end\n",
- "end\n",
- "ls M2"
- )
-
- assert_empty err
- assert_match(/M2\.methods:\s+m4\n/, out)
- assert_match(/M2#methods:\s+m1\s+m3\n.*M1#methods:\s+m2\n/, out)
- assert_not_match(/Module#methods/, out)
- end
-
- def test_ls_instance
- out, err = execute_lines(
- "class Foo; def bar; end; end\n",
- "ls Foo.new"
- )
-
- assert_empty err
- assert_match(/Foo#methods:\s+bar/, out)
- # don't duplicate
- assert_not_match(/Foo#methods:\s+bar\n.*Foo#methods/, out)
- end
-
- def test_ls_grep
- out, err = execute_lines("ls 42\n")
- assert_empty err
- assert_match(/times/, out)
- assert_match(/polar/, out)
-
- [
- "ls 42, grep: /times/\n",
- "ls 42 -g times\n",
- "ls 42 -G times\n",
- ].each do |line|
- out, err = execute_lines(line)
- assert_empty err
- assert_match(/times/, out)
- assert_not_match(/polar/, out)
- end
- end
-
- def test_ls_grep_empty
- out, err = execute_lines("ls\n")
- assert_empty err
- assert_match(/assert/, out)
- assert_match(/refute/, out)
-
- [
- "ls grep: /assert/\n",
- "ls -g assert\n",
- "ls -G assert\n",
- ].each do |line|
- out, err = execute_lines(line)
- assert_empty err
- assert_match(/assert/, out)
- assert_not_match(/refute/, out)
- end
- end
-
- def test_ls_with_no_singleton_class
- out, err = execute_lines(
- "ls 42",
- )
- assert_empty err
- assert_match(/Comparable#methods:\s+/, out)
- assert_match(/Numeric#methods:\s+/, out)
- assert_match(/Integer#methods:\s+/, out)
- end
- end
-
- class ShowDocTest < CommandTestCase
- def test_show_doc
- out, err = execute_lines(
- "show_doc 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_not_include err, "[Deprecation]"
- assert(possible_rdoc_output.any? { |output| output.match?(out) }, "Expect the `show_doc` command to match one of the possible outputs. Got:\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/command/help.rb" }
- end
-
- def test_show_doc_without_rdoc
- out, err = 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(/=> nil\n/, out)
- assert_include(err, "Can't display document because `rdoc` is not installed.\n")
- ensure
- # this is the only way to reset the redefined method without coupling the test with its implementation
- EnvUtil.suppress_warning { load "irb/command/help.rb" }
- end
- end
-
- class EditTest < CommandTestCase
- def setup
- @original_visual = ENV["VISUAL"]
- @original_editor = ENV["EDITOR"]
- # noop the command so nothing gets executed
- ENV["VISUAL"] = ": code"
- ENV["EDITOR"] = ": code2"
- end
-
- def teardown
- ENV["VISUAL"] = @original_visual
- 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_without_arg_and_non_existing_irb_path
- out, err = execute_lines(
- "edit",
- irb_path: '/path/to/file.rb(irb)'
- )
-
- assert_empty err
- assert_match(/Can not find file: \/path\/to\/file\.rb\(irb\)/, 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
- 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"
- )
-
- assert_empty err
- assert_match(/path: .*\/lib\/irb\.rb/, out)
- assert_match("command: ': code'", out)
- end
-
- def test_edit_with_editor_env_var
- ENV.delete("VISUAL")
-
- out, err = execute_lines(
- "edit",
- irb_path: __FILE__
- )
-
- assert_empty err
- assert_match("path: #{__FILE__}", out)
- assert_match("command: ': code2'", out)
- end
- end
-
- class HistoryCmdTest < CommandTestCase
- def teardown
- TestInputMethod.send(:remove_const, "HISTORY") if defined?(TestInputMethod::HISTORY)
- super
- end
-
- def test_history
- TestInputMethod.const_set("HISTORY", %w[foo bar baz])
-
- out, err = without_rdoc do
- execute_lines("history")
- end
-
- assert_include(out, <<~EOF)
- 2: baz
- 1: bar
- 0: foo
- EOF
- assert_empty err
- end
-
- def test_multiline_history_with_truncation
- TestInputMethod.const_set("HISTORY", ["foo", "bar", <<~INPUT])
- [].each do |x|
- puts x
- end
- INPUT
-
- out, err = without_rdoc do
- execute_lines("hist")
- end
-
- assert_include(out, <<~EOF)
- 2: [].each do |x|
- puts x
- ...
- 1: bar
- 0: foo
- EOF
- assert_empty err
- end
-
- def test_history_grep
- TestInputMethod.const_set("HISTORY", ["foo", "bar", <<~INPUT])
- [].each do |x|
- puts x
- end
- INPUT
-
- out, err = without_rdoc do
- execute_lines("hist -g each\n")
- end
-
- assert_include(out, <<~EOF)
- 2: [].each do |x|
- puts x
- ...
- EOF
- assert_empty err
- end
-
- end
-
- class HelperMethodInsallTest < CommandTestCase
- def test_helper_method_install
- IRB::ExtendCommandBundle.module_eval do
- def foobar
- "test_helper_method_foobar"
- end
- end
-
- out, err = execute_lines("foobar.upcase")
- assert_empty err
- assert_include(out, '=> "TEST_HELPER_METHOD_FOOBAR"')
- ensure
- IRB::ExtendCommandBundle.remove_method :foobar
- end
- end
-end
diff --git a/test/irb/test_completion.rb b/test/irb/test_completion.rb
deleted file mode 100644
index 5fe7952b3d..0000000000
--- a/test/irb/test_completion.rb
+++ /dev/null
@@ -1,311 +0,0 @@
-# frozen_string_literal: false
-require "pathname"
-require "irb"
-
-require_relative "helper"
-
-module TestIRB
- class CompletionTest < TestCase
- def completion_candidates(target, bind)
- IRB::RegexpCompletor.new.completion_candidates('', target, '', bind: bind)
- end
-
- def doc_namespace(target, bind)
- IRB::RegexpCompletor.new.doc_namespace('', target, '', bind: bind)
- end
-
- class CommandCompletionTest < CompletionTest
- def test_command_completion
- assert_include(IRB::RegexpCompletor.new.completion_candidates('', 'show_s', '', bind: binding), 'show_source')
- assert_not_include(IRB::RegexpCompletor.new.completion_candidates(';', 'show_s', '', bind: binding), 'show_source')
- end
- end
-
- class MethodCompletionTest < CompletionTest
- def test_complete_string
- assert_include(completion_candidates("'foo'.up", binding), "'foo'.upcase")
- # completing 'foo bar'.up
- assert_include(completion_candidates("bar'.up", binding), "bar'.upcase")
- assert_equal("String.upcase", doc_namespace("'foo'.upcase", binding))
- end
-
- def test_complete_regexp
- assert_include(completion_candidates("/foo/.ma", binding), "/foo/.match")
- # completing /foo bar/.ma
- assert_include(completion_candidates("bar/.ma", binding), "bar/.match")
- assert_equal("Regexp.match", doc_namespace("/foo/.match", binding))
- end
-
- def test_complete_array
- assert_include(completion_candidates("[].an", binding), "[].any?")
- assert_equal("Array.any?", doc_namespace("[].any?", binding))
- end
-
- def test_complete_hash_and_proc
- # hash
- assert_include(completion_candidates("{}.an", binding), "{}.any?")
- assert_equal(["Hash.any?", "Proc.any?"], doc_namespace("{}.any?", binding))
-
- # proc
- assert_include(completion_candidates("{}.bin", binding), "{}.binding")
- assert_equal(["Hash.binding", "Proc.binding"], doc_namespace("{}.binding", binding))
- end
-
- def test_complete_numeric
- assert_include(completion_candidates("1.positi", binding), "1.positive?")
- assert_equal("Integer.positive?", doc_namespace("1.positive?", binding))
-
- assert_include(completion_candidates("1r.positi", binding), "1r.positive?")
- assert_equal("Rational.positive?", doc_namespace("1r.positive?", binding))
-
- assert_include(completion_candidates("0xFFFF.positi", binding), "0xFFFF.positive?")
- assert_equal("Integer.positive?", doc_namespace("0xFFFF.positive?", binding))
-
- assert_empty(completion_candidates("1i.positi", binding))
- end
-
- def test_complete_symbol
- assert_include(completion_candidates(":foo.to_p", binding), ":foo.to_proc")
- assert_equal("Symbol.to_proc", doc_namespace(":foo.to_proc", binding))
- end
-
- def test_complete_class
- assert_include(completion_candidates("String.ne", binding), "String.new")
- assert_equal("String.new", doc_namespace("String.new", binding))
- end
- end
-
- class RequireComepletionTest < CompletionTest
- def test_complete_require
- candidates = IRB::RegexpCompletor.new.completion_candidates("require ", "'irb", "", bind: binding)
- %w['irb/init 'irb/ruby-lex].each do |word|
- assert_include candidates, word
- end
- # Test cache
- candidates = IRB::RegexpCompletor.new.completion_candidates("require ", "'irb", "", bind: binding)
- %w['irb/init 'irb/ruby-lex].each do |word|
- assert_include candidates, word
- end
- # Test string completion not disturbed by require completion
- candidates = IRB::RegexpCompletor.new.completion_candidates("'string ", "'.", "", bind: binding)
- assert_include candidates, "'.upcase"
- end
-
- def test_complete_require_with_pathname_in_load_path
- temp_dir = Dir.mktmpdir
- File.write(File.join(temp_dir, "foo.rb"), "test")
- test_path = Pathname.new(temp_dir)
- $LOAD_PATH << test_path
-
- candidates = IRB::RegexpCompletor.new.completion_candidates("require ", "'foo", "", bind: binding)
- assert_include candidates, "'foo"
- ensure
- $LOAD_PATH.pop if test_path
- FileUtils.remove_entry(temp_dir) if temp_dir
- end
-
- def test_complete_require_with_string_convertable_in_load_path
- temp_dir = Dir.mktmpdir
- File.write(File.join(temp_dir, "foo.rb"), "test")
- object = Object.new
- object.define_singleton_method(:to_s) { temp_dir }
- $LOAD_PATH << object
-
- candidates = IRB::RegexpCompletor.new.completion_candidates("require ", "'foo", "", bind: binding)
- assert_include candidates, "'foo"
- ensure
- $LOAD_PATH.pop if object
- FileUtils.remove_entry(temp_dir) if temp_dir
- end
-
- def test_complete_require_with_malformed_object_in_load_path
- object = Object.new
- def object.to_s; raise; end
- $LOAD_PATH << object
-
- assert_nothing_raised do
- IRB::RegexpCompletor.new.completion_candidates("require ", "'foo", "", bind: binding)
- end
- ensure
- $LOAD_PATH.pop if object
- end
-
- def test_complete_require_library_name_first
- # Test that library name is completed first with subdirectories
- candidates = IRB::RegexpCompletor.new.completion_candidates("require ", "'irb", "", bind: binding)
- assert_equal "'irb", candidates.first
- end
-
- def test_complete_require_relative
- candidates = Dir.chdir(__dir__ + "/../..") do
- IRB::RegexpCompletor.new.completion_candidates("require_relative ", "'lib/irb", "", bind: binding)
- end
- %w['lib/irb/init 'lib/irb/ruby-lex].each do |word|
- assert_include candidates, word
- end
- # Test cache
- candidates = Dir.chdir(__dir__ + "/../..") do
- IRB::RegexpCompletor.new.completion_candidates("require_relative ", "'lib/irb", "", bind: binding)
- end
- %w['lib/irb/init 'lib/irb/ruby-lex].each do |word|
- assert_include candidates, word
- end
- end
- end
-
- class VariableCompletionTest < CompletionTest
- def test_complete_variable
- # Bug fix issues https://github.com/ruby/irb/issues/368
- # Variables other than `str_example` and `@str_example` are defined to ensure that irb completion does not cause unintended behavior
- str_example = ''
- @str_example = ''
- private_methods = ''
- methods = ''
- global_variables = ''
- local_variables = ''
- instance_variables = ''
-
- # suppress "assigned but unused variable" warning
- str_example.clear
- @str_example.clear
- private_methods.clear
- methods.clear
- global_variables.clear
- local_variables.clear
- instance_variables.clear
-
- assert_include(completion_candidates("str_examp", binding), "str_example")
- assert_equal("String", doc_namespace("str_example", binding))
- assert_equal("String.to_s", doc_namespace("str_example.to_s", binding))
-
- assert_include(completion_candidates("@str_examp", binding), "@str_example")
- assert_equal("String", doc_namespace("@str_example", binding))
- assert_equal("String.to_s", doc_namespace("@str_example.to_s", binding))
- end
-
- def test_complete_sort_variables
- xzy, xzy_1, xzy2 = '', '', ''
-
- xzy.clear
- xzy_1.clear
- xzy2.clear
-
- candidates = completion_candidates("xz", binding)
- assert_equal(%w[xzy xzy2 xzy_1], candidates)
- end
- end
-
- class ConstantCompletionTest < CompletionTest
- class Foo
- B3 = 1
- B1 = 1
- B2 = 1
- end
-
- def test_complete_constants
- assert_equal(["Foo"], completion_candidates("Fo", binding))
- assert_equal(["Foo::B1", "Foo::B2", "Foo::B3"], completion_candidates("Foo::B", binding))
- assert_equal(["Foo::B1.positive?"], completion_candidates("Foo::B1.pos", binding))
-
- assert_equal(["::Forwardable"], completion_candidates("::Fo", binding))
- assert_equal("Forwardable", doc_namespace("::Forwardable", binding))
- end
- end
-
- def test_not_completing_empty_string
- assert_equal([], completion_candidates("", binding))
- assert_equal([], completion_candidates(" ", binding))
- assert_equal([], completion_candidates("\t", binding))
- assert_equal(nil, doc_namespace("", binding))
- end
-
- def test_complete_symbol
- symbols = %w"UTF-16LE UTF-7".map do |enc|
- "K".force_encoding(enc).to_sym
- rescue
- end
- symbols += [:aiueo, :"aiu eo"]
- candidates = completion_candidates(":a", binding)
- assert_include(candidates, ":aiueo")
- assert_not_include(candidates, ":aiu eo")
- assert_empty(completion_candidates(":irb_unknown_symbol_abcdefg", binding))
- # Do not complete empty symbol for performance reason
- assert_empty(completion_candidates(":", binding))
- end
-
- def test_complete_invalid_three_colons
- assert_empty(completion_candidates(":::A", binding))
- assert_empty(completion_candidates(":::", binding))
- end
-
- def test_complete_absolute_constants_with_special_characters
- assert_empty(completion_candidates("::A:", binding))
- assert_empty(completion_candidates("::A.", binding))
- assert_empty(completion_candidates("::A(", binding))
- assert_empty(completion_candidates("::A)", binding))
- assert_empty(completion_candidates("::A[", binding))
- end
-
- def test_complete_reserved_words
- candidates = completion_candidates("de", binding)
- %w[def defined?].each do |word|
- assert_include candidates, word
- end
-
- candidates = completion_candidates("__", binding)
- %w[__ENCODING__ __LINE__ __FILE__].each do |word|
- assert_include candidates, word
- end
- end
-
- def test_complete_methods
- obj = Object.new
- obj.singleton_class.class_eval {
- def public_hoge; end
- private def private_hoge; end
-
- # Support for overriding #methods etc.
- def methods; end
- def private_methods; end
- def global_variables; end
- def local_variables; end
- def instance_variables; end
- }
- bind = obj.instance_exec { binding }
-
- assert_include(completion_candidates("public_hog", bind), "public_hoge")
- assert_include(doc_namespace("public_hoge", bind), "public_hoge")
-
- assert_include(completion_candidates("private_hog", bind), "private_hoge")
- assert_include(doc_namespace("private_hoge", bind), "private_hoge")
- end
- end
-
- class DeprecatedInputCompletorTest < TestCase
- def setup
- save_encodings
- @verbose, $VERBOSE = $VERBOSE, nil
- IRB.init_config(nil)
- IRB.conf[:VERBOSE] = false
- IRB.conf[:MAIN_CONTEXT] = IRB::Context.new(IRB::WorkSpace.new(binding))
- end
-
- def teardown
- restore_encodings
- $VERBOSE = @verbose
- end
-
- def test_completion_proc
- assert_include(IRB::InputCompletor::CompletionProc.call('1.ab'), '1.abs')
- assert_include(IRB::InputCompletor::CompletionProc.call('1.ab', '', ''), '1.abs')
- end
-
- def test_retrieve_completion_data
- assert_include(IRB::InputCompletor.retrieve_completion_data('1.ab'), '1.abs')
- assert_equal(IRB::InputCompletor.retrieve_completion_data('1.abs', doc_namespace: true), 'Integer.abs')
- bind = eval('a = 1; binding')
- assert_include(IRB::InputCompletor.retrieve_completion_data('a.ab', bind: bind), 'a.abs')
- assert_equal(IRB::InputCompletor.retrieve_completion_data('a.abs', bind: bind, doc_namespace: true), 'Integer.abs')
- end
- end
-end
diff --git a/test/irb/test_context.rb b/test/irb/test_context.rb
deleted file mode 100644
index aff4b5b67c..0000000000
--- a/test/irb/test_context.rb
+++ /dev/null
@@ -1,721 +0,0 @@
-# frozen_string_literal: false
-require 'tempfile'
-require 'irb'
-
-require_relative "helper"
-
-module TestIRB
- class ContextTest < TestCase
- def setup
- IRB.init_config(nil)
- IRB.conf[:USE_SINGLELINE] = false
- IRB.conf[:VERBOSE] = false
- IRB.conf[:USE_PAGER] = false
- workspace = IRB::WorkSpace.new(Object.new)
- @context = IRB::Context.new(nil, workspace, TestInputMethod.new)
-
- @get_screen_size = Reline.method(:get_screen_size)
- Reline.instance_eval { undef :get_screen_size }
- def Reline.get_screen_size
- [36, 80]
- end
- save_encodings
- end
-
- def teardown
- Reline.instance_eval { undef :get_screen_size }
- Reline.define_singleton_method(:get_screen_size, @get_screen_size)
- restore_encodings
- end
-
-
- def test_eval_input
- verbose, $VERBOSE = $VERBOSE, nil
- input = TestInputMethod.new([
- "raise 'Foo'\n",
- "_\n",
- "0\n",
- "_\n",
- ])
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
-
- expected_output =
- if RUBY_3_4
- [
- :*, /\(irb\):1:in '<main>': Foo \(RuntimeError\)\n/,
- :*, /#<RuntimeError: Foo>\n/,
- :*, /0$/,
- :*, /0$/,
- /\s*/
- ]
- else
- [
- :*, /\(irb\):1:in `<main>': Foo \(RuntimeError\)\n/,
- :*, /#<RuntimeError: Foo>\n/,
- :*, /0$/,
- :*, /0$/,
- /\s*/
- ]
- end
-
- assert_pattern_list(expected_output, out)
- ensure
- $VERBOSE = verbose
- end
-
- def test_eval_input_raise2x
- input = TestInputMethod.new([
- "raise 'Foo'\n",
- "raise 'Bar'\n",
- "_\n",
- ])
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- expected_output =
- if RUBY_3_4
- [
- :*, /\(irb\):1:in '<main>': Foo \(RuntimeError\)\n/,
- :*, /\(irb\):2:in '<main>': Bar \(RuntimeError\)\n/,
- :*, /#<RuntimeError: Bar>\n/,
- ]
- else
- [
- :*, /\(irb\):1:in `<main>': Foo \(RuntimeError\)\n/,
- :*, /\(irb\):2:in `<main>': Bar \(RuntimeError\)\n/,
- :*, /#<RuntimeError: Bar>\n/,
- ]
- end
- assert_pattern_list(expected_output, out)
- end
-
- def test_prompt_n_deprecation
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), TestInputMethod.new)
-
- _, err = capture_output do
- irb.context.prompt_n = "foo"
- irb.context.prompt_n
- end
-
- assert_include err, "IRB::Context#prompt_n is deprecated"
- assert_include err, "IRB::Context#prompt_n= is deprecated"
- end
-
- def test_output_to_pipe
- require 'stringio'
- input = TestInputMethod.new(["n=1"])
- input.instance_variable_set(:@stdout, StringIO.new)
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
- irb.context.echo_on_assignment = :truncate
- irb.context.prompt_mode = :DEFAULT
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal "=> 1\n", out
- end
-
- {
- successful: [
- [false, "class Foo < Struct.new(:bar); end; Foo.new(123)\n", /#<struct bar=123>/],
- [:p, "class Foo < Struct.new(:bar); end; Foo.new(123)\n", /#<struct bar=123>/],
- [true, "class Foo < Struct.new(:bar); end; Foo.new(123)\n", /#<struct #<Class:.*>::Foo bar=123>/],
- [:yaml, "123", /--- 123\n/],
- [:marshal, "123", Marshal.dump(123)],
- ],
- failed: [
- [false, "BasicObject.new", /#<NoMethodError: undefined method (`|')to_s' for/],
- [:p, "class Foo; undef inspect ;end; Foo.new", /#<NoMethodError: undefined method (`|')inspect' for/],
- [:yaml, "BasicObject.new", /#<NoMethodError: undefined method (`|')inspect' for/],
- [:marshal, "[Object.new, Class.new]", /#<TypeError: can't dump anonymous class #<Class:/]
- ]
- }.each do |scenario, cases|
- cases.each do |inspect_mode, input, expected|
- define_method "test_#{inspect_mode}_inspect_mode_#{scenario}" do
- verbose, $VERBOSE = $VERBOSE, nil
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), TestInputMethod.new([input]))
- irb.context.inspect_mode = inspect_mode
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_match(expected, out)
- ensure
- $VERBOSE = verbose
- end
- end
- end
-
- def test_object_inspection_handles_basic_object
- verbose, $VERBOSE = $VERBOSE, nil
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), TestInputMethod.new(["BasicObject.new"]))
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_not_match(/NoMethodError/, out)
- assert_match(/#<BasicObject:.*>/, out)
- ensure
- $VERBOSE = verbose
- end
-
- def test_object_inspection_falls_back_to_kernel_inspect_when_errored
- verbose, $VERBOSE = $VERBOSE, nil
- main = Object.new
- main.singleton_class.module_eval <<~RUBY
- class Foo
- def inspect
- raise "foo"
- end
- end
- RUBY
-
- irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new(["Foo.new"]))
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_match(/An error occurred when inspecting the object: #<RuntimeError: foo>/, out)
- assert_match(/Result of Kernel#inspect: #<#<Class:.*>::Foo:/, out)
- ensure
- $VERBOSE = verbose
- end
-
- def test_object_inspection_prints_useful_info_when_kernel_inspect_also_errored
- verbose, $VERBOSE = $VERBOSE, nil
- main = Object.new
- main.singleton_class.module_eval <<~RUBY
- class Foo
- def initialize
- # Kernel#inspect goes through instance variables with #inspect
- # So this will cause Kernel#inspect to fail
- @foo = BasicObject.new
- end
-
- def inspect
- raise "foo"
- end
- end
- RUBY
-
- irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new(["Foo.new"]))
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_match(/An error occurred when inspecting the object: #<RuntimeError: foo>/, out)
- assert_match(/An error occurred when running Kernel#inspect: #<NoMethodError: undefined method (`|')inspect' for/, out)
- ensure
- $VERBOSE = verbose
- end
-
- def test_default_config
- assert_equal(true, @context.use_autocomplete?)
- end
-
- def test_echo_on_assignment
- input = TestInputMethod.new([
- "a = 1\n",
- "a\n",
- "a, b = 2, 3\n",
- "a\n",
- "b\n",
- "b = 4\n",
- "_\n"
- ])
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
- irb.context.return_format = "=> %s\n"
-
- # The default
- irb.context.echo = true
- irb.context.echo_on_assignment = false
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("=> 1\n=> 2\n=> 3\n=> 4\n", out)
-
- # Everything is output, like before echo_on_assignment was introduced
- input.reset
- irb.context.echo = true
- irb.context.echo_on_assignment = true
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("=> 1\n=> 1\n=> [2, 3]\n=> 2\n=> 3\n=> 4\n=> 4\n", out)
-
- # Nothing is output when echo is false
- input.reset
- irb.context.echo = false
- irb.context.echo_on_assignment = false
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("", out)
-
- # Nothing is output when echo is false even if echo_on_assignment is true
- input.reset
- irb.context.echo = false
- irb.context.echo_on_assignment = true
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("", out)
- end
-
- def test_omit_on_assignment
- input = TestInputMethod.new([
- "a = [1] * 100\n",
- "a\n",
- ])
- value = [1] * 100
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
- irb.context.return_format = "=> %s\n"
-
- irb.context.echo = true
- irb.context.echo_on_assignment = false
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("=> \n#{value.pretty_inspect}", out)
-
- input.reset
- irb.context.echo = true
- irb.context.echo_on_assignment = :truncate
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("=> \n#{value.pretty_inspect[0..3]}...\n=> \n#{value.pretty_inspect}", out)
-
- input.reset
- irb.context.echo = true
- irb.context.echo_on_assignment = true
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("=> \n#{value.pretty_inspect}=> \n#{value.pretty_inspect}", out)
-
- input.reset
- irb.context.echo = false
- irb.context.echo_on_assignment = false
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("", out)
-
- input.reset
- irb.context.echo = false
- irb.context.echo_on_assignment = :truncate
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("", out)
-
- input.reset
- irb.context.echo = false
- irb.context.echo_on_assignment = true
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("", out)
- end
-
- def test_omit_multiline_on_assignment
- without_colorize do
- input = TestInputMethod.new([
- "class A; def inspect; ([?* * 1000] * 3).join(%{\\n}); end; end; a = A.new\n",
- "a\n"
- ])
- value = ([?* * 1000] * 3).join(%{\n})
- value_first_line = (?* * 1000).to_s
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
- irb.context.return_format = "=> %s\n"
-
- irb.context.echo = true
- irb.context.echo_on_assignment = false
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("=> \n#{value}\n", out)
- irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
-
- input.reset
- irb.context.echo = true
- irb.context.echo_on_assignment = :truncate
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("=> #{value_first_line[0..(input.winsize.last - 9)]}...\n=> \n#{value}\n", out)
- irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
-
- input.reset
- irb.context.echo = true
- irb.context.echo_on_assignment = true
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("=> \n#{value}\n=> \n#{value}\n", out)
- irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
-
- input.reset
- irb.context.echo = false
- irb.context.echo_on_assignment = false
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("", out)
- irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
-
- input.reset
- irb.context.echo = false
- irb.context.echo_on_assignment = :truncate
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("", out)
- irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
-
- input.reset
- irb.context.echo = false
- irb.context.echo_on_assignment = true
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("", out)
- irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
- end
- end
-
- def test_echo_on_assignment_conf
- # Default
- IRB.conf[:ECHO] = nil
- IRB.conf[:ECHO_ON_ASSIGNMENT] = nil
- without_colorize do
- input = TestInputMethod.new()
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
-
- assert(irb.context.echo?, "echo? should be true by default")
- assert_equal(:truncate, irb.context.echo_on_assignment?, "echo_on_assignment? should be :truncate by default")
-
- # Explicitly set :ECHO to false
- IRB.conf[:ECHO] = false
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
-
- refute(irb.context.echo?, "echo? should be false when IRB.conf[:ECHO] is set to false")
- assert_equal(:truncate, irb.context.echo_on_assignment?, "echo_on_assignment? should be :truncate by default")
-
- # Explicitly set :ECHO_ON_ASSIGNMENT to true
- IRB.conf[:ECHO] = nil
- IRB.conf[:ECHO_ON_ASSIGNMENT] = false
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
-
- assert(irb.context.echo?, "echo? should be true by default")
- refute(irb.context.echo_on_assignment?, "echo_on_assignment? should be false when IRB.conf[:ECHO_ON_ASSIGNMENT] is set to false")
- end
- end
-
- def test_multiline_output_on_default_inspector
- main = Object.new
- def main.inspect
- "abc\ndef"
- end
-
- without_colorize do
- input = TestInputMethod.new([
- "self"
- ])
- irb = IRB::Irb.new(IRB::WorkSpace.new(main), input)
- irb.context.return_format = "=> %s\n"
-
- # The default
- irb.context.newline_before_multiline_output = true
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("=> \nabc\ndef\n",
- out)
-
- # No newline before multiline output
- input.reset
- irb.context.newline_before_multiline_output = false
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("=> abc\ndef\n", out)
- end
- end
-
- def test_default_return_format
- IRB.conf[:PROMPT][:MY_PROMPT] = {
- :PROMPT_I => "%03n> ",
- :PROMPT_S => "%03n> ",
- :PROMPT_C => "%03n> "
- # without :RETURN
- # :RETURN => "%s\n"
- }
- IRB.conf[:PROMPT_MODE] = :MY_PROMPT
- input = TestInputMethod.new([
- "3"
- ])
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_equal("3\n",
- out)
- end
-
- def test_eval_input_with_exception
- pend if RUBY_ENGINE == 'truffleruby'
- verbose, $VERBOSE = $VERBOSE, nil
- input = TestInputMethod.new([
- "def hoge() fuga; end; def fuga() raise; end; hoge\n",
- ])
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- expected_output =
- if RUBY_3_4
- [
- :*, /\(irb\):1:in 'fuga': unhandled exception\n/,
- :*, /\tfrom \(irb\):1:in 'hoge'\n/,
- :*, /\tfrom \(irb\):1:in '<main>'\n/,
- :*
- ]
- elsif RUBY_VERSION < '3.0.0' && STDOUT.tty?
- [
- :*, /Traceback \(most recent call last\):\n/,
- :*, /\t 2: from \(irb\):1:in `<main>'\n/,
- :*, /\t 1: from \(irb\):1:in `hoge'\n/,
- :*, /\(irb\):1:in `fuga': unhandled exception\n/,
- ]
- else
- [
- :*, /\(irb\):1:in `fuga': unhandled exception\n/,
- :*, /\tfrom \(irb\):1:in `hoge'\n/,
- :*, /\tfrom \(irb\):1:in `<main>'\n/,
- :*
- ]
- end
- assert_pattern_list(expected_output, out)
- ensure
- $VERBOSE = verbose
- end
-
- def test_eval_input_with_invalid_byte_sequence_exception
- verbose, $VERBOSE = $VERBOSE, nil
- input = TestInputMethod.new([
- %Q{def hoge() fuga; end; def fuga() raise "A\\xF3B"; end; hoge\n},
- ])
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- expected_output =
- if RUBY_3_4
- [
- :*, /\(irb\):1:in 'fuga': A\\xF3B \(RuntimeError\)\n/,
- :*, /\tfrom \(irb\):1:in 'hoge'\n/,
- :*, /\tfrom \(irb\):1:in '<main>'\n/,
- :*
- ]
- elsif RUBY_VERSION < '3.0.0' && STDOUT.tty?
- [
- :*, /Traceback \(most recent call last\):\n/,
- :*, /\t 2: from \(irb\):1:in `<main>'\n/,
- :*, /\t 1: from \(irb\):1:in `hoge'\n/,
- :*, /\(irb\):1:in `fuga': A\\xF3B \(RuntimeError\)\n/,
- ]
- else
- [
- :*, /\(irb\):1:in `fuga': A\\xF3B \(RuntimeError\)\n/,
- :*, /\tfrom \(irb\):1:in `hoge'\n/,
- :*, /\tfrom \(irb\):1:in `<main>'\n/,
- :*
- ]
- end
-
- assert_pattern_list(expected_output, out)
- ensure
- $VERBOSE = verbose
- end
-
- def test_eval_input_with_long_exception
- pend if RUBY_ENGINE == 'truffleruby'
- verbose, $VERBOSE = $VERBOSE, nil
- nesting = 20
- generated_code = ''
- nesting.times do |i|
- generated_code << "def a#{i}() a#{i + 1}; end; "
- end
- generated_code << "def a#{nesting}() raise; end; a0\n"
- input = TestInputMethod.new([
- generated_code
- ])
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- if RUBY_VERSION < '3.0.0' && STDOUT.tty?
- expected = [
- :*, /Traceback \(most recent call last\):\n/,
- :*, /\t... \d+ levels...\n/,
- :*, /\t16: from \(irb\):1:in (`|')a4'\n/,
- :*, /\t15: from \(irb\):1:in (`|')a5'\n/,
- :*, /\t14: from \(irb\):1:in (`|')a6'\n/,
- :*, /\t13: from \(irb\):1:in (`|')a7'\n/,
- :*, /\t12: from \(irb\):1:in (`|')a8'\n/,
- :*, /\t11: from \(irb\):1:in (`|')a9'\n/,
- :*, /\t10: from \(irb\):1:in (`|')a10'\n/,
- :*, /\t 9: from \(irb\):1:in (`|')a11'\n/,
- :*, /\t 8: from \(irb\):1:in (`|')a12'\n/,
- :*, /\t 7: from \(irb\):1:in (`|')a13'\n/,
- :*, /\t 6: from \(irb\):1:in (`|')a14'\n/,
- :*, /\t 5: from \(irb\):1:in (`|')a15'\n/,
- :*, /\t 4: from \(irb\):1:in (`|')a16'\n/,
- :*, /\t 3: from \(irb\):1:in (`|')a17'\n/,
- :*, /\t 2: from \(irb\):1:in (`|')a18'\n/,
- :*, /\t 1: from \(irb\):1:in (`|')a19'\n/,
- :*, /\(irb\):1:in (`|')a20': unhandled exception\n/,
- ]
- else
- expected = [
- :*, /\(irb\):1:in (`|')a20': unhandled exception\n/,
- :*, /\tfrom \(irb\):1:in (`|')a19'\n/,
- :*, /\tfrom \(irb\):1:in (`|')a18'\n/,
- :*, /\tfrom \(irb\):1:in (`|')a17'\n/,
- :*, /\tfrom \(irb\):1:in (`|')a16'\n/,
- :*, /\tfrom \(irb\):1:in (`|')a15'\n/,
- :*, /\tfrom \(irb\):1:in (`|')a14'\n/,
- :*, /\tfrom \(irb\):1:in (`|')a13'\n/,
- :*, /\tfrom \(irb\):1:in (`|')a12'\n/,
- :*, /\tfrom \(irb\):1:in (`|')a11'\n/,
- :*, /\tfrom \(irb\):1:in (`|')a10'\n/,
- :*, /\tfrom \(irb\):1:in (`|')a9'\n/,
- :*, /\tfrom \(irb\):1:in (`|')a8'\n/,
- :*, /\tfrom \(irb\):1:in (`|')a7'\n/,
- :*, /\tfrom \(irb\):1:in (`|')a6'\n/,
- :*, /\tfrom \(irb\):1:in (`|')a5'\n/,
- :*, /\tfrom \(irb\):1:in (`|')a4'\n/,
- :*, /\t... \d+ levels...\n/,
- ]
- end
- assert_pattern_list(expected, out)
- ensure
- $VERBOSE = verbose
- end
-
- def test_prompt_main_escape
- main = Struct.new(:to_s).new("main\a\t\r\n")
- irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new)
- assert_equal("irb(main )>", irb.send(:format_prompt, 'irb(%m)>', nil, 1, 1))
- end
-
- def test_prompt_main_inspect_escape
- main = Struct.new(:inspect).new("main\\n\nmain")
- irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new)
- assert_equal("irb(main\\n main)>", irb.send(:format_prompt, 'irb(%M)>', nil, 1, 1))
- end
-
- def test_prompt_main_truncate
- main = Struct.new(:to_s).new("a" * 100)
- def main.inspect; to_s.inspect; end
- irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new)
- assert_equal('irb(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa...)>', irb.send(:format_prompt, 'irb(%m)>', nil, 1, 1))
- assert_equal('irb("aaaaaaaaaaaaaaaaaaaaaaaaaaaa...)>', irb.send(:format_prompt, 'irb(%M)>', nil, 1, 1))
- end
-
- def test_prompt_main_raise
- main = Object.new
- def main.to_s; raise TypeError; end
- def main.inspect; raise ArgumentError; end
- irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new)
- assert_equal("irb(!TypeError)>", irb.send(:format_prompt, 'irb(%m)>', nil, 1, 1))
- assert_equal("irb(!ArgumentError)>", irb.send(:format_prompt, 'irb(%M)>', nil, 1, 1))
- end
-
- def test_lineno
- input = TestInputMethod.new([
- "\n",
- "__LINE__\n",
- "__LINE__\n",
- "\n",
- "\n",
- "__LINE__\n",
- ])
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_pattern_list([
- :*, /\b2\n/,
- :*, /\b3\n/,
- :*, /\b6\n/,
- ], out)
- end
-
- def test_irb_path_setter
- @context.irb_path = __FILE__
- assert_equal(__FILE__, @context.irb_path)
- assert_equal("#{__FILE__}(irb)", @context.instance_variable_get(:@eval_path))
- @context.irb_path = 'file/does/not/exist'
- assert_equal('file/does/not/exist', @context.irb_path)
- assert_equal('file/does/not/exist', @context.instance_variable_get(:@eval_path))
- @context.irb_path = "#{__FILE__}(irb)"
- assert_equal("#{__FILE__}(irb)", @context.irb_path)
- assert_equal("#{__FILE__}(irb)", @context.instance_variable_get(:@eval_path))
- end
-
- def test_build_completor
- verbose, $VERBOSE = $VERBOSE, nil
- original_completor = IRB.conf[:COMPLETOR]
- IRB.conf[:COMPLETOR] = :regexp
- assert_equal 'IRB::RegexpCompletor', @context.send(:build_completor).class.name
- IRB.conf[:COMPLETOR] = :unknown
- assert_equal 'IRB::RegexpCompletor', @context.send(:build_completor).class.name
- # :type is tested in test_type_completor.rb
- ensure
- $VERBOSE = verbose
- IRB.conf[:COMPLETOR] = original_completor
- end
-
- private
-
- def without_colorize
- original_value = IRB.conf[:USE_COLORIZE]
- IRB.conf[:USE_COLORIZE] = false
- yield
- ensure
- IRB.conf[:USE_COLORIZE] = original_value
- end
- end
-end
diff --git a/test/irb/test_debugger_integration.rb b/test/irb/test_debugger_integration.rb
deleted file mode 100644
index 839a0d43f0..0000000000
--- a/test/irb/test_debugger_integration.rb
+++ /dev/null
@@ -1,462 +0,0 @@
-# frozen_string_literal: true
-
-require "tempfile"
-require "tmpdir"
-
-require_relative "helper"
-
-module TestIRB
- class DebuggerIntegrationTest < IntegrationTestCase
- def setup
- super
-
- if RUBY_ENGINE == 'truffleruby'
- omit "This test runs with ruby/debug, which doesn't work with truffleruby"
- end
-
- @envs.merge!("NO_COLOR" => "true", "RUBY_DEBUG_HISTORY_FILE" => '')
- end
-
- def test_backtrace
- write_ruby <<~'RUBY'
- def foo
- binding.irb
- end
- foo
- RUBY
-
- output = run_ruby_file do
- type "backtrace"
- type "exit!"
- end
-
- assert_match(/irb\(main\):001> backtrace/, output)
- assert_match(/Object#foo at #{@ruby_file.to_path}/, output)
- end
-
- def test_debug
- write_ruby <<~'ruby'
- binding.irb
- puts "hello"
- ruby
-
- output = run_ruby_file do
- type "debug"
- type "next"
- type "continue"
- end
-
- assert_match(/irb\(main\):001> debug/, output)
- assert_match(/irb:rdbg\(main\):002> next/, output)
- assert_match(/=> 2\| puts "hello"/, output)
- end
-
- def test_debug_command_only_runs_once
- write_ruby <<~'ruby'
- binding.irb
- ruby
-
- output = run_ruby_file do
- type "debug"
- type "debug"
- type "continue"
- end
-
- assert_match(/irb\(main\):001> debug/, output)
- assert_match(/irb:rdbg\(main\):002> debug/, output)
- assert_match(/IRB is already running with a debug session/, output)
- end
-
- def test_next
- write_ruby <<~'ruby'
- binding.irb
- puts "hello"
- ruby
-
- output = run_ruby_file do
- type "next"
- type "continue"
- end
-
- assert_match(/irb\(main\):001> next/, output)
- assert_match(/=> 2\| puts "hello"/, output)
- end
-
- def test_break
- write_ruby <<~'RUBY'
- binding.irb
- puts "Hello"
- RUBY
-
- output = run_ruby_file do
- type "break 2"
- type "continue"
- type "continue"
- end
-
- assert_match(/irb\(main\):001> break/, output)
- assert_match(/=> 2\| puts "Hello"/, output)
- end
-
- def test_delete
- 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(/irb:rdbg\(main\):003> delete/, output)
- assert_match(/deleted: #0 BP - Line/, output)
- end
-
- def test_step
- write_ruby <<~'RUBY'
- def foo
- puts "Hello"
- end
- binding.irb
- foo
- RUBY
-
- output = run_ruby_file do
- type "step"
- type "step"
- type "continue"
- end
-
- assert_match(/irb\(main\):001> step/, output)
- assert_match(/=> 5\| foo/, output)
- assert_match(/=> 2\| puts "Hello"/, output)
- end
-
- def test_long_stepping
- write_ruby <<~'RUBY'
- class Foo
- def foo(num)
- bar(num + 10)
- end
-
- def bar(num)
- num
- end
- end
-
- binding.irb
- Foo.new.foo(100)
- RUBY
-
- output = run_ruby_file do
- type "step"
- type "step"
- type "step"
- type "step"
- type "num"
- type "continue"
- end
-
- assert_match(/irb\(main\):001> step/, output)
- assert_match(/irb:rdbg\(main\):002> step/, output)
- assert_match(/irb:rdbg\(#<Foo:.*>\):003> step/, output)
- assert_match(/irb:rdbg\(#<Foo:.*>\):004> step/, output)
- assert_match(/irb:rdbg\(#<Foo:.*>\):005> num/, output)
- assert_match(/=> 110/, output)
- end
-
- def test_continue
- write_ruby <<~'RUBY'
- binding.irb
- puts "Hello"
- binding.irb
- puts "World"
- RUBY
-
- output = run_ruby_file do
- type "continue"
- type "continue"
- end
-
- assert_match(/irb\(main\):001> continue/, output)
- assert_match(/=> 3: binding.irb/, output)
- assert_match(/irb:rdbg\(main\):002> continue/, output)
- end
-
- def test_finish
- write_ruby <<~'RUBY'
- def foo
- binding.irb
- puts "Hello"
- end
- foo
- RUBY
-
- output = run_ruby_file do
- type "finish"
- type "continue"
- end
-
- assert_match(/irb\(main\):001> finish/, output)
- assert_match(/=> 4\| end/, output)
- end
-
- def test_info
- 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(/irb\(main\):001> info/, output)
- assert_match(/%self = main/, output)
- assert_match(/a = "Hello"/, output)
- end
-
- def test_catch
- write_ruby <<~'RUBY'
- binding.irb
- 1 / 0
- RUBY
-
- output = run_ruby_file do
- type "catch ZeroDivisionError"
- type "continue"
- type "continue"
- end
-
- assert_match(/irb\(main\):001> catch/, output)
- assert_match(/Stop by #0 BP - Catch "ZeroDivisionError"/, output)
- end
-
- def test_exit
- write_ruby <<~'RUBY'
- binding.irb
- puts "hello"
- RUBY
-
- output = run_ruby_file do
- type "next"
- type "exit"
- end
-
- assert_match(/irb\(main\):001> next/, output)
- end
-
- def test_quit
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "next"
- type "quit!"
- end
-
- assert_match(/irb\(main\):001> next/, output)
- end
-
- def test_prompt_line_number_continues
- write_ruby <<~'ruby'
- binding.irb
- puts "Hello"
- puts "World"
- ruby
-
- output = run_ruby_file do
- type "123"
- type "456"
- type "next"
- type "info"
- type "next"
- type "continue"
- end
-
- assert_match(/irb\(main\):003> next/, output)
- assert_match(/irb:rdbg\(main\):004> info/, output)
- assert_match(/irb:rdbg\(main\):005> next/, output)
- end
-
- def test_prompt_irb_name_is_kept
- write_rc <<~RUBY
- IRB.conf[:IRB_NAME] = "foo"
- RUBY
-
- write_ruby <<~'ruby'
- binding.irb
- puts "Hello"
- ruby
-
- output = run_ruby_file do
- type "next"
- type "continue"
- end
-
- assert_match(/foo\(main\):001> next/, output)
- assert_match(/foo:rdbg\(main\):002> continue/, output)
- end
-
- def test_irb_commands_are_available_after_moving_around_with_the_debugger
- write_ruby <<~'ruby'
- class Foo
- def bar
- puts "bar"
- end
- end
-
- binding.irb
- Foo.new.bar
- ruby
-
- output = run_ruby_file do
- # Due to the way IRB defines its commands, moving into the Foo instance from main is necessary for proper testing.
- type "next"
- type "step"
- type "irb_info"
- type "continue"
- end
-
- assert_include(output, "InputMethod: RelineInputMethod")
- end
-
- def test_help_command_is_delegated_to_the_debugger
- write_ruby <<~'ruby'
- binding.irb
- ruby
-
- output = run_ruby_file do
- type "debug"
- type "help"
- type "continue"
- end
-
- assert_include(output, "### Frame control")
- end
-
- def test_help_display_different_content_when_debugger_is_enabled
- write_ruby <<~'ruby'
- binding.irb
- ruby
-
- output = run_ruby_file do
- type "debug"
- type "help"
- type "continue"
- end
-
- # IRB's commands should still be listed
- assert_match(/help\s+List all available commands/, output)
- # debug gem's commands should be appended at the end
- assert_match(/Debugging \(from debug\.gem\)\s+### Control flow/, output)
- end
-
- def test_input_is_evaluated_in_the_context_of_the_current_thread
- write_ruby <<~'ruby'
- current_thread = Thread.current
- binding.irb
- ruby
-
- output = run_ruby_file do
- type "debug"
- type '"Threads match: #{current_thread == Thread.current}"'
- type "continue"
- end
-
- assert_match(/irb\(main\):001> debug/, output)
- assert_match(/Threads match: true/, output)
- end
-
- def test_irb_switches_debugger_interface_if_debug_was_already_activated
- write_ruby <<~'ruby'
- require 'debug'
- class Foo
- def bar
- puts "bar"
- end
- end
-
- binding.irb
- Foo.new.bar
- ruby
-
- output = run_ruby_file do
- # Due to the way IRB defines its commands, moving into the Foo instance from main is necessary for proper testing.
- type "next"
- type "step"
- type 'irb_info'
- type "continue"
- end
-
- assert_match(/irb\(main\):001> next/, output)
- assert_include(output, "InputMethod: RelineInputMethod")
- end
-
- def test_debugger_cant_be_activated_while_multi_irb_is_active
- write_ruby <<~'ruby'
- binding.irb
- a = 1
- ruby
-
- output = run_ruby_file do
- type "jobs"
- type "next"
- type "exit"
- end
-
- assert_match(/irb\(main\):001> jobs/, output)
- assert_include(output, "Can't start the debugger when IRB is running in a multi-IRB session.")
- end
-
- def test_multi_irb_commands_are_not_available_after_activating_the_debugger
- write_ruby <<~'ruby'
- binding.irb
- a = 1
- ruby
-
- output = run_ruby_file do
- type "next"
- type "jobs"
- type "continue"
- end
-
- assert_match(/irb\(main\):001> next/, output)
- assert_include(output, "Multi-IRB commands are not available when the debugger is enabled.")
- end
-
- def test_irb_passes_empty_input_to_debugger_to_repeat_the_last_command
- write_ruby <<~'ruby'
- binding.irb
- puts "foo"
- puts "bar"
- puts "baz"
- ruby
-
- output = run_ruby_file do
- type "next"
- type ""
- # Test that empty input doesn't repeat expressions
- type "123"
- type ""
- type "next"
- type ""
- type ""
- end
-
- assert_include(output, "=> 2\| puts \"foo\"")
- assert_include(output, "=> 3\| puts \"bar\"")
- assert_include(output, "=> 4\| puts \"baz\"")
- end
- end
-end
diff --git a/test/irb/test_eval_history.rb b/test/irb/test_eval_history.rb
deleted file mode 100644
index 54913ceff5..0000000000
--- a/test/irb/test_eval_history.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# frozen_string_literal: true
-require "irb"
-
-require_relative "helper"
-
-module TestIRB
- class EvalHistoryTest < TestCase
- def setup
- save_encodings
- IRB.instance_variable_get(:@CONF).clear
- end
-
- def teardown
- restore_encodings
- end
-
- 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[:USE_PAGER] = false
- 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
-
- def test_eval_history_is_disabled_by_default
- out, err = execute_lines(
- "a = 1",
- "__"
- )
-
- assert_empty(err)
- assert_match(/undefined local variable or method (`|')__'/, out)
- end
-
- def test_eval_history_can_be_retrieved_with_double_underscore
- out, err = execute_lines(
- "a = 1",
- "__",
- conf: { EVAL_HISTORY: 5 }
- )
-
- assert_empty(err)
- assert_match("=> 1\n" + "=> 1 1\n", out)
- end
-
- def test_eval_history_respects_given_limit
- out, err = execute_lines(
- "'foo'\n",
- "'bar'\n",
- "'baz'\n",
- "'xyz'\n",
- "__",
- conf: { EVAL_HISTORY: 4 }
- )
-
- assert_empty(err)
- # Because eval_history injects `__` into the history AND decide to ignore it, we only get <limit> - 1 results
- assert_match("2 \"bar\"\n" + "3 \"baz\"\n" + "4 \"xyz\"\n", out)
- end
- end
-end
diff --git a/test/irb/test_evaluation.rb b/test/irb/test_evaluation.rb
deleted file mode 100644
index adb69b2067..0000000000
--- a/test/irb/test_evaluation.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-require "tempfile"
-
-require_relative "helper"
-
-module TestIRB
- class EchoingTest < IntegrationTestCase
- def test_irb_echos_by_default
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "123123"
- type "exit"
- end
-
- assert_include(output, "=> 123123")
- end
-
- def test_irb_doesnt_echo_line_with_semicolon
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "123123;"
- type "123123 ;"
- type "123123; "
- type <<~RUBY
- if true
- 123123
- end;
- RUBY
- type "'evaluation ends'"
- type "exit"
- end
-
- assert_include(output, "=> \"evaluation ends\"")
- assert_not_include(output, "=> 123123")
- end
- end
-end
diff --git a/test/irb/test_history.rb b/test/irb/test_history.rb
deleted file mode 100644
index 63be35fdaa..0000000000
--- a/test/irb/test_history.rb
+++ /dev/null
@@ -1,491 +0,0 @@
-# frozen_string_literal: false
-require 'irb'
-require 'readline'
-require "tempfile"
-
-require_relative "helper"
-
-return if RUBY_PLATFORM.match?(/solaris|mswin|mingw/i)
-
-module TestIRB
- class HistoryTest < TestCase
- def setup
- @original_verbose, $VERBOSE = $VERBOSE, nil
- @tmpdir = Dir.mktmpdir("test_irb_history_")
- @backup_home = ENV["HOME"]
- @backup_xdg_config_home = ENV.delete("XDG_CONFIG_HOME")
- @backup_irbrc = ENV.delete("IRBRC")
- @backup_default_external = Encoding.default_external
- ENV["HOME"] = @tmpdir
- IRB.instance_variable_set(:@existing_rc_name_generators, nil)
- end
-
- def teardown
- IRB.instance_variable_set(:@existing_rc_name_generators, nil)
- ENV["HOME"] = @backup_home
- ENV["XDG_CONFIG_HOME"] = @backup_xdg_config_home
- ENV["IRBRC"] = @backup_irbrc
- Encoding.default_external = @backup_default_external
- $VERBOSE = @original_verbose
- FileUtils.rm_rf(@tmpdir)
- end
-
- class TestInputMethodWithRelineHistory < TestInputMethod
- # When IRB.conf[:USE_MULTILINE] is true, IRB::RelineInputMethod uses Reline::History
- HISTORY = Reline::History.new(Reline.core.config)
-
- include IRB::HistorySavingAbility
- end
-
- class TestInputMethodWithReadlineHistory < TestInputMethod
- # When IRB.conf[:USE_MULTILINE] is false, IRB::ReadlineInputMethod uses Readline::HISTORY
- HISTORY = Readline::HISTORY
-
- include IRB::HistorySavingAbility
- end
-
- def test_history_save_1
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- IRB.conf[:SAVE_HISTORY] = 1
- assert_history(<<~EXPECTED_HISTORY, <<~INITIAL_HISTORY, <<~INPUT)
- exit
- EXPECTED_HISTORY
- 1
- 2
- 3
- 4
- INITIAL_HISTORY
- 5
- exit
- INPUT
- end
-
- def test_history_save_100
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- IRB.conf[:SAVE_HISTORY] = 100
- assert_history(<<~EXPECTED_HISTORY, <<~INITIAL_HISTORY, <<~INPUT)
- 1
- 2
- 3
- 4
- 5
- exit
- EXPECTED_HISTORY
- 1
- 2
- 3
- 4
- INITIAL_HISTORY
- 5
- exit
- INPUT
- end
-
- def test_history_save_bignum
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- IRB.conf[:SAVE_HISTORY] = 10 ** 19
- assert_history(<<~EXPECTED_HISTORY, <<~INITIAL_HISTORY, <<~INPUT)
- 1
- 2
- 3
- 4
- 5
- exit
- EXPECTED_HISTORY
- 1
- 2
- 3
- 4
- INITIAL_HISTORY
- 5
- exit
- INPUT
- end
-
- def test_history_save_minus_as_infinity
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- IRB.conf[:SAVE_HISTORY] = -1 # infinity
- assert_history(<<~EXPECTED_HISTORY, <<~INITIAL_HISTORY, <<~INPUT)
- 1
- 2
- 3
- 4
- 5
- exit
- EXPECTED_HISTORY
- 1
- 2
- 3
- 4
- INITIAL_HISTORY
- 5
- exit
- INPUT
- end
-
- def test_history_concurrent_use_reline
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- IRB.conf[:SAVE_HISTORY] = 1
- history_concurrent_use_for_input_method(TestInputMethodWithRelineHistory)
- end
-
- def test_history_concurrent_use_readline
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- IRB.conf[:SAVE_HISTORY] = 1
- history_concurrent_use_for_input_method(TestInputMethodWithReadlineHistory)
- end
-
- def test_history_concurrent_use_not_present
- IRB.conf[:LC_MESSAGES] = IRB::Locale.new
- IRB.conf[:SAVE_HISTORY] = 1
- io = TestInputMethodWithRelineHistory.new
- io.class::HISTORY.clear
- io.load_history
- io.class::HISTORY << 'line1'
- io.class::HISTORY << 'line2'
-
- history_file = IRB.rc_file("_history")
- assert_not_send [File, :file?, history_file]
- File.write(history_file, "line0\n")
- io.save_history
- assert_equal(%w"line0 line1 line2", File.read(history_file).split)
- end
-
- def test_history_different_encodings
- IRB.conf[:SAVE_HISTORY] = 2
- Encoding.default_external = Encoding::US_ASCII
- locale = IRB::Locale.new("C")
- assert_history(<<~EXPECTED_HISTORY.encode(Encoding::US_ASCII), <<~INITIAL_HISTORY.encode(Encoding::UTF_8), <<~INPUT, locale: locale)
- ????
- exit
- EXPECTED_HISTORY
- 😀
- INITIAL_HISTORY
- exit
- INPUT
- end
-
- def test_history_does_not_raise_when_history_file_directory_does_not_exist
- backup_history_file = IRB.conf[:HISTORY_FILE]
- IRB.conf[:SAVE_HISTORY] = 1
- IRB.conf[:HISTORY_FILE] = "fake/fake/fake/history_file"
- io = TestInputMethodWithRelineHistory.new
-
- assert_warn(/history file does not exist/) do
- io.save_history
- end
-
- # assert_warn reverts $VERBOSE to EnvUtil.original_verbose, which is true in some cases
- # We want to keep $VERBOSE as nil until teardown is called
- # TODO: check if this is an assert_warn issue
- $VERBOSE = nil
- ensure
- IRB.conf[:HISTORY_FILE] = backup_history_file
- end
-
- def test_no_home_no_history_file_does_not_raise_history_save
- ENV['HOME'] = nil
- io = TestInputMethodWithRelineHistory.new
- assert_nil(IRB.rc_file('_history'))
- assert_nothing_raised do
- io.load_history
- io.save_history
- end
- end
-
- private
-
- def history_concurrent_use_for_input_method(input_method)
- assert_history(<<~EXPECTED_HISTORY, <<~INITIAL_HISTORY, <<~INPUT, input_method) do |history_file|
- exit
- 5
- exit
- EXPECTED_HISTORY
- 1
- 2
- 3
- 4
- INITIAL_HISTORY
- 5
- exit
- INPUT
- assert_history(<<~EXPECTED_HISTORY2, <<~INITIAL_HISTORY2, <<~INPUT2, input_method)
- exit
- EXPECTED_HISTORY2
- 1
- 2
- 3
- 4
- INITIAL_HISTORY2
- 5
- exit
- INPUT2
- File.utime(File.atime(history_file), File.mtime(history_file) + 2, history_file)
- end
- end
-
- def assert_history(expected_history, initial_irb_history, input, input_method = TestInputMethodWithRelineHistory, locale: IRB::Locale.new)
- IRB.conf[:LC_MESSAGES] = locale
- actual_history = nil
- history_file = IRB.rc_file("_history")
- ENV["HOME"] = @tmpdir
- File.open(history_file, "w") do |f|
- f.write(initial_irb_history)
- end
-
- io = input_method.new
- io.class::HISTORY.clear
- io.load_history
- if block_given?
- previous_history = []
- io.class::HISTORY.each { |line| previous_history << line }
- yield history_file
- io.class::HISTORY.clear
- previous_history.each { |line| io.class::HISTORY << line }
- end
- input.split.each { |line| io.class::HISTORY << line }
- io.save_history
-
- io.load_history
- File.open(history_file, "r") do |f|
- actual_history = f.read
- end
- assert_equal(expected_history, actual_history, <<~MESSAGE)
- expected:
- #{expected_history}
- but actual:
- #{actual_history}
- MESSAGE
- end
-
- def with_temp_stdio
- Tempfile.create("test_readline_stdin") do |stdin|
- Tempfile.create("test_readline_stdout") do |stdout|
- yield stdin, stdout
- end
- end
- end
- end
-
- class IRBHistoryIntegrationTest < IntegrationTestCase
- def test_history_saving_with_debug
- write_history ""
-
- write_ruby <<~'RUBY'
- def foo
- end
-
- binding.irb
-
- foo
- RUBY
-
- output = run_ruby_file do
- type "'irb session'"
- type "next"
- type "'irb:debug session'"
- type "step"
- type "irb_info"
- type "puts Reline::HISTORY.to_a.to_s"
- type "q!"
- end
-
- assert_include(output, "InputMethod: RelineInputMethod")
- # check that in-memory history is preserved across sessions
- assert_include output, %q(
- ["'irb session'", "next", "'irb:debug session'", "step", "irb_info", "puts Reline::HISTORY.to_a.to_s"]
- ).strip
-
- assert_equal <<~HISTORY, @history_file.open.read
- 'irb session'
- next
- 'irb:debug session'
- step
- irb_info
- puts Reline::HISTORY.to_a.to_s
- q!
- HISTORY
- end
-
- def test_history_saving_with_debug_without_prior_history
- tmpdir = Dir.mktmpdir("test_irb_history_")
- # Intentionally not creating the file so we test the reset counter logic
- history_file = File.join(tmpdir, "irb_history")
-
- write_rc <<~RUBY
- IRB.conf[:HISTORY_FILE] = "#{history_file}"
- RUBY
-
- write_ruby <<~'RUBY'
- def foo
- end
-
- binding.irb
-
- foo
- RUBY
-
- output = run_ruby_file do
- type "'irb session'"
- type "next"
- type "'irb:debug session'"
- type "step"
- type "irb_info"
- type "puts Reline::HISTORY.to_a.to_s"
- type "q!"
- end
-
- assert_include(output, "InputMethod: RelineInputMethod")
- # check that in-memory history is preserved across sessions
- assert_include output, %q(
- ["'irb session'", "next", "'irb:debug session'", "step", "irb_info", "puts Reline::HISTORY.to_a.to_s"]
- ).strip
-
- assert_equal <<~HISTORY, File.read(history_file)
- 'irb session'
- next
- 'irb:debug session'
- step
- irb_info
- puts Reline::HISTORY.to_a.to_s
- q!
- HISTORY
- ensure
- FileUtils.rm_rf(tmpdir)
- end
-
- def test_history_saving_with_nested_sessions
- write_history ""
-
- write_ruby <<~'RUBY'
- def foo
- binding.irb
- end
-
- binding.irb
- RUBY
-
- run_ruby_file do
- type "'outer session'"
- type "foo"
- type "'inner session'"
- type "exit"
- type "'outer session again'"
- type "exit"
- end
-
- assert_equal <<~HISTORY, @history_file.open.read
- 'outer session'
- foo
- 'inner session'
- exit
- 'outer session again'
- exit
- HISTORY
- end
-
- def test_nested_history_saving_from_inner_session_with_exit!
- write_history ""
-
- write_ruby <<~'RUBY'
- def foo
- binding.irb
- end
-
- binding.irb
- RUBY
-
- run_ruby_file do
- type "'outer session'"
- type "foo"
- type "'inner session'"
- type "exit!"
- end
-
- assert_equal <<~HISTORY, @history_file.open.read
- 'outer session'
- foo
- 'inner session'
- exit!
- HISTORY
- end
-
- def test_nested_history_saving_from_outer_session_with_exit!
- write_history ""
-
- write_ruby <<~'RUBY'
- def foo
- binding.irb
- end
-
- binding.irb
- RUBY
-
- run_ruby_file do
- type "'outer session'"
- type "foo"
- type "'inner session'"
- type "exit"
- type "'outer session again'"
- type "exit!"
- end
-
- assert_equal <<~HISTORY, @history_file.open.read
- 'outer session'
- foo
- 'inner session'
- exit
- 'outer session again'
- exit!
- HISTORY
- end
-
- def test_history_saving_with_nested_sessions_and_prior_history
- write_history <<~HISTORY
- old_history_1
- old_history_2
- old_history_3
- HISTORY
-
- write_ruby <<~'RUBY'
- def foo
- binding.irb
- end
-
- binding.irb
- RUBY
-
- run_ruby_file do
- type "'outer session'"
- type "foo"
- type "'inner session'"
- type "exit"
- type "'outer session again'"
- type "exit"
- end
-
- assert_equal <<~HISTORY, @history_file.open.read
- old_history_1
- old_history_2
- old_history_3
- 'outer session'
- foo
- 'inner session'
- exit
- 'outer session again'
- exit
- HISTORY
- end
-
- private
-
- def write_history(history)
- @history_file = Tempfile.new('irb_history')
- @history_file.write(history)
- @history_file.close
- write_rc <<~RUBY
- IRB.conf[:HISTORY_FILE] = "#{@history_file.path}"
- RUBY
- end
- end
-end
diff --git a/test/irb/test_init.rb b/test/irb/test_init.rb
deleted file mode 100644
index f11d7398c8..0000000000
--- a/test/irb/test_init.rb
+++ /dev/null
@@ -1,310 +0,0 @@
-# frozen_string_literal: false
-require "irb"
-require "fileutils"
-
-require_relative "helper"
-
-module TestIRB
- class InitTest < TestCase
- def setup
- # IRBRC is for RVM...
- @backup_env = %w[HOME XDG_CONFIG_HOME IRBRC].each_with_object({}) do |env, hash|
- hash[env] = ENV.delete(env)
- end
- ENV["HOME"] = @tmpdir = File.realpath(Dir.mktmpdir("test_irb_init_#{$$}"))
- end
-
- def reset_rc_name_generators
- IRB.instance_variable_set(:@existing_rc_name_generators, nil)
- end
-
- def teardown
- ENV.update(@backup_env)
- FileUtils.rm_rf(@tmpdir)
- IRB.conf.delete(:SCRIPT)
- reset_rc_name_generators
- end
-
- def test_setup_with_argv_preserves_global_argv
- argv = ["foo", "bar"]
- with_argv(argv) do
- IRB.setup(eval("__FILE__"), argv: %w[-f])
- assert_equal argv, ARGV
- end
- end
-
- def test_setup_with_minimum_argv_does_not_change_dollar0
- orig = $0.dup
- IRB.setup(eval("__FILE__"), argv: %w[-f])
- assert_equal orig, $0
- end
-
- def test_rc_files
- tmpdir = @tmpdir
- Dir.chdir(tmpdir) do
- home = ENV['HOME'] = "#{tmpdir}/home"
- xdg_config_home = ENV['XDG_CONFIG_HOME'] = "#{tmpdir}/xdg"
- reset_rc_name_generators
- assert_empty(IRB.irbrc_files)
- assert_equal("#{home}/.irb_history", IRB.rc_file('_history'))
- FileUtils.mkdir_p(home)
- FileUtils.mkdir_p("#{xdg_config_home}/irb")
- FileUtils.mkdir_p("#{home}/.config/irb")
- reset_rc_name_generators
- assert_empty(IRB.irbrc_files)
- assert_equal("#{xdg_config_home}/irb/irb_history", IRB.rc_file('_history'))
- home_irbrc = "#{home}/.irbrc"
- config_irbrc = "#{home}/.config/irb/irbrc"
- xdg_config_irbrc = "#{xdg_config_home}/irb/irbrc"
- [home_irbrc, config_irbrc, xdg_config_irbrc].each do |file|
- FileUtils.touch(file)
- end
- current_dir_irbrcs = %w[.irbrc irbrc _irbrc $irbrc].map { |file| "#{tmpdir}/#{file}" }
- current_dir_irbrcs.each { |file| FileUtils.touch(file) }
- reset_rc_name_generators
- assert_equal([xdg_config_irbrc, home_irbrc, *current_dir_irbrcs], IRB.irbrc_files)
- assert_equal(xdg_config_irbrc.sub(/rc$/, '_history'), IRB.rc_file('_history'))
- ENV['XDG_CONFIG_HOME'] = nil
- reset_rc_name_generators
- assert_equal([home_irbrc, config_irbrc, *current_dir_irbrcs], IRB.irbrc_files)
- assert_equal(home_irbrc.sub(/rc$/, '_history'), IRB.rc_file('_history'))
- ENV['XDG_CONFIG_HOME'] = ''
- reset_rc_name_generators
- assert_equal([home_irbrc, config_irbrc] + current_dir_irbrcs, IRB.irbrc_files)
- assert_equal(home_irbrc.sub(/rc$/, '_history'), IRB.rc_file('_history'))
- ENV['XDG_CONFIG_HOME'] = xdg_config_home
- ENV['IRBRC'] = "#{tmpdir}/.irbrc"
- reset_rc_name_generators
- assert_equal([ENV['IRBRC'], xdg_config_irbrc, home_irbrc] + (current_dir_irbrcs - [ENV['IRBRC']]), IRB.irbrc_files)
- assert_equal(ENV['IRBRC'] + '_history', IRB.rc_file('_history'))
- ENV['IRBRC'] = ENV['HOME'] = ENV['XDG_CONFIG_HOME'] = nil
- reset_rc_name_generators
- assert_equal(current_dir_irbrcs, IRB.irbrc_files)
- assert_nil(IRB.rc_file('_history'))
- end
- end
-
- def test_duplicated_rc_files
- tmpdir = @tmpdir
- Dir.chdir(tmpdir) do
- ENV['XDG_CONFIG_HOME'] = "#{ENV['HOME']}/.config"
- FileUtils.mkdir_p("#{ENV['XDG_CONFIG_HOME']}/irb")
- env_irbrc = ENV['IRBRC'] = "#{tmpdir}/_irbrc"
- xdg_config_irbrc = "#{ENV['XDG_CONFIG_HOME']}/irb/irbrc"
- home_irbrc = "#{ENV['HOME']}/.irbrc"
- current_dir_irbrc = "#{tmpdir}/irbrc"
- [env_irbrc, xdg_config_irbrc, home_irbrc, current_dir_irbrc].each do |file|
- FileUtils.touch(file)
- end
- reset_rc_name_generators
- assert_equal([env_irbrc, xdg_config_irbrc, home_irbrc, current_dir_irbrc], IRB.irbrc_files)
- end
- end
-
- def test_sigint_restore_default
- pend "This test gets stuck on Solaris for unknown reason; contribution is welcome" if RUBY_PLATFORM =~ /solaris/
- bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
- # IRB should restore SIGINT handler
- status = assert_in_out_err(bundle_exec + %w[-W0 -rirb -e Signal.trap("SIGINT","DEFAULT");binding.irb;loop{Process.kill("SIGINT",$$)} -- -f --], "exit\n", //, //)
- Process.kill("SIGKILL", status.pid) if !status.exited? && !status.stopped? && !status.signaled?
- end
-
- def test_sigint_restore_block
- bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
- # IRB should restore SIGINT handler
- status = assert_in_out_err(bundle_exec + %w[-W0 -rirb -e x=false;Signal.trap("SIGINT"){x=true};binding.irb;loop{Process.kill("SIGINT",$$);if(x);break;end} -- -f --], "exit\n", //, //)
- Process.kill("SIGKILL", status.pid) if !status.exited? && !status.stopped? && !status.signaled?
- end
-
- def test_no_color_environment_variable
- orig_no_color = ENV['NO_COLOR']
- orig_use_colorize = IRB.conf[:USE_COLORIZE]
- IRB.conf[:USE_COLORIZE] = true
-
- assert IRB.conf[:USE_COLORIZE]
-
- ENV['NO_COLOR'] = 'true'
- IRB.setup(__FILE__)
- refute IRB.conf[:USE_COLORIZE]
-
- ENV['NO_COLOR'] = ''
- IRB.setup(__FILE__)
- assert IRB.conf[:USE_COLORIZE]
-
- ENV['NO_COLOR'] = nil
- IRB.setup(__FILE__)
- assert IRB.conf[:USE_COLORIZE]
- ensure
- ENV['NO_COLOR'] = orig_no_color
- IRB.conf[:USE_COLORIZE] = orig_use_colorize
- end
-
- def test_use_autocomplete_environment_variable
- orig_use_autocomplete_env = ENV['IRB_USE_AUTOCOMPLETE']
- orig_use_autocomplete_conf = IRB.conf[:USE_AUTOCOMPLETE]
-
- ENV['IRB_USE_AUTOCOMPLETE'] = nil
- IRB.setup(__FILE__)
- assert IRB.conf[:USE_AUTOCOMPLETE]
-
- ENV['IRB_USE_AUTOCOMPLETE'] = ''
- IRB.setup(__FILE__)
- assert IRB.conf[:USE_AUTOCOMPLETE]
-
- ENV['IRB_USE_AUTOCOMPLETE'] = 'false'
- IRB.setup(__FILE__)
- refute IRB.conf[:USE_AUTOCOMPLETE]
-
- ENV['IRB_USE_AUTOCOMPLETE'] = 'true'
- IRB.setup(__FILE__)
- assert IRB.conf[:USE_AUTOCOMPLETE]
- ensure
- ENV["IRB_USE_AUTOCOMPLETE"] = orig_use_autocomplete_env
- IRB.conf[:USE_AUTOCOMPLETE] = orig_use_autocomplete_conf
- end
-
- def test_completor_environment_variable
- orig_use_autocomplete_env = ENV['IRB_COMPLETOR']
- orig_use_autocomplete_conf = IRB.conf[:COMPLETOR]
-
- ENV['IRB_COMPLETOR'] = nil
- IRB.setup(__FILE__)
- assert_equal(:regexp, IRB.conf[:COMPLETOR])
-
- ENV['IRB_COMPLETOR'] = 'regexp'
- IRB.setup(__FILE__)
- assert_equal(:regexp, IRB.conf[:COMPLETOR])
-
- ENV['IRB_COMPLETOR'] = 'type'
- IRB.setup(__FILE__)
- assert_equal(:type, IRB.conf[:COMPLETOR])
-
- ENV['IRB_COMPLETOR'] = 'regexp'
- IRB.setup(__FILE__, argv: ['--type-completor'])
- assert_equal :type, IRB.conf[:COMPLETOR]
-
- ENV['IRB_COMPLETOR'] = 'type'
- IRB.setup(__FILE__, argv: ['--regexp-completor'])
- assert_equal :regexp, IRB.conf[:COMPLETOR]
- ensure
- ENV['IRB_COMPLETOR'] = orig_use_autocomplete_env
- IRB.conf[:COMPLETOR] = orig_use_autocomplete_conf
- end
-
- def test_completor_setup_with_argv
- orig_completor_conf = IRB.conf[:COMPLETOR]
-
- # Default is :regexp
- IRB.setup(__FILE__, argv: [])
- assert_equal :regexp, IRB.conf[:COMPLETOR]
-
- IRB.setup(__FILE__, argv: ['--type-completor'])
- assert_equal :type, IRB.conf[:COMPLETOR]
-
- IRB.setup(__FILE__, argv: ['--regexp-completor'])
- assert_equal :regexp, IRB.conf[:COMPLETOR]
- ensure
- IRB.conf[:COMPLETOR] = orig_completor_conf
- end
-
- def test_noscript
- argv = %w[--noscript -- -f]
- IRB.setup(eval("__FILE__"), argv: argv)
- assert_nil IRB.conf[:SCRIPT]
- assert_equal(['-f'], argv)
-
- argv = %w[--noscript -- a]
- IRB.setup(eval("__FILE__"), argv: argv)
- assert_nil IRB.conf[:SCRIPT]
- assert_equal(['a'], argv)
-
- argv = %w[--noscript a]
- IRB.setup(eval("__FILE__"), argv: argv)
- assert_nil IRB.conf[:SCRIPT]
- assert_equal(['a'], argv)
-
- argv = %w[--script --noscript a]
- IRB.setup(eval("__FILE__"), argv: argv)
- assert_nil IRB.conf[:SCRIPT]
- assert_equal(['a'], argv)
-
- argv = %w[--noscript --script a]
- IRB.setup(eval("__FILE__"), argv: argv)
- assert_equal('a', IRB.conf[:SCRIPT])
- assert_equal([], argv)
- end
-
- def test_dash
- argv = %w[-]
- IRB.setup(eval("__FILE__"), argv: argv)
- assert_equal('-', IRB.conf[:SCRIPT])
- assert_equal([], argv)
-
- argv = %w[-- -]
- IRB.setup(eval("__FILE__"), argv: argv)
- assert_equal('-', IRB.conf[:SCRIPT])
- assert_equal([], argv)
-
- argv = %w[-- - -f]
- IRB.setup(eval("__FILE__"), argv: argv)
- assert_equal('-', IRB.conf[:SCRIPT])
- assert_equal(['-f'], argv)
- end
-
- def test_option_tracer
- argv = %w[--tracer]
- IRB.setup(eval("__FILE__"), argv: argv)
- assert_equal(true, IRB.conf[:USE_TRACER])
- end
-
- private
-
- def with_argv(argv)
- orig = ARGV.dup
- ARGV.replace(argv)
- yield
- ensure
- ARGV.replace(orig)
- end
- end
-
- class InitIntegrationTest < IntegrationTestCase
- def test_load_error_in_rc_file_is_warned
- write_rc <<~'IRBRC'
- require "file_that_does_not_exist"
- IRBRC
-
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "'foobar'"
- type "exit"
- end
-
- # IRB session should still be started
- assert_includes output, "foobar"
- assert_includes output, 'cannot load such file -- file_that_does_not_exist (LoadError)'
- end
-
- def test_normal_errors_in_rc_file_is_warned
- write_rc <<~'IRBRC'
- raise "I'm an error"
- IRBRC
-
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "'foobar'"
- type "exit"
- end
-
- # IRB session should still be started
- assert_includes output, "foobar"
- assert_includes output, 'I\'m an error (RuntimeError)'
- end
- end
-end
diff --git a/test/irb/test_input_method.rb b/test/irb/test_input_method.rb
deleted file mode 100644
index ce317b4b32..0000000000
--- a/test/irb/test_input_method.rb
+++ /dev/null
@@ -1,173 +0,0 @@
-# frozen_string_literal: false
-
-require "irb"
-require "rdoc"
-require_relative "helper"
-
-module TestIRB
- class InputMethodTest < TestCase
- def setup
- @conf_backup = IRB.conf.dup
- IRB.conf[:LC_MESSAGES] = IRB::Locale.new
- save_encodings
- end
-
- def teardown
- IRB.conf.replace(@conf_backup)
- restore_encodings
- # Reset Reline configuration overridden by RelineInputMethod.
- Reline.instance_variable_set(:@core, nil)
- end
- end
-
- class RelineInputMethodTest < InputMethodTest
- def test_initialization
- Reline.completion_proc = nil
- Reline.dig_perfect_match_proc = nil
- IRB::RelineInputMethod.new(IRB::RegexpCompletor.new)
-
- assert_nil Reline.completion_append_character
- assert_equal '', Reline.completer_quote_characters
- assert_equal IRB::InputMethod::BASIC_WORD_BREAK_CHARACTERS, Reline.basic_word_break_characters
- assert_not_nil Reline.completion_proc
- assert_not_nil Reline.dig_perfect_match_proc
- end
-
- def test_initialization_without_use_autocomplete
- original_show_doc_proc = Reline.dialog_proc(:show_doc)&.dialog_proc
- empty_proc = Proc.new {}
- Reline.add_dialog_proc(:show_doc, empty_proc)
-
- IRB.conf[:USE_AUTOCOMPLETE] = false
-
- IRB::RelineInputMethod.new(IRB::RegexpCompletor.new)
-
- refute Reline.autocompletion
- assert_equal empty_proc, Reline.dialog_proc(:show_doc).dialog_proc
- ensure
- Reline.add_dialog_proc(:show_doc, original_show_doc_proc, Reline::DEFAULT_DIALOG_CONTEXT)
- end
-
- def test_initialization_with_use_autocomplete
- original_show_doc_proc = Reline.dialog_proc(:show_doc)&.dialog_proc
- empty_proc = Proc.new {}
- Reline.add_dialog_proc(:show_doc, empty_proc)
-
- IRB.conf[:USE_AUTOCOMPLETE] = true
-
- IRB::RelineInputMethod.new(IRB::RegexpCompletor.new)
-
- assert Reline.autocompletion
- assert_not_equal empty_proc, Reline.dialog_proc(:show_doc).dialog_proc
- ensure
- Reline.add_dialog_proc(:show_doc, original_show_doc_proc, Reline::DEFAULT_DIALOG_CONTEXT)
- end
-
- def test_initialization_with_use_autocomplete_but_without_rdoc
- original_show_doc_proc = Reline.dialog_proc(:show_doc)&.dialog_proc
- empty_proc = Proc.new {}
- Reline.add_dialog_proc(:show_doc, empty_proc)
-
- IRB.conf[:USE_AUTOCOMPLETE] = true
-
- without_rdoc do
- IRB::RelineInputMethod.new(IRB::RegexpCompletor.new)
- end
-
- assert Reline.autocompletion
- # doesn't register show_doc dialog
- assert_equal empty_proc, Reline.dialog_proc(:show_doc).dialog_proc
- ensure
- Reline.add_dialog_proc(:show_doc, original_show_doc_proc, Reline::DEFAULT_DIALOG_CONTEXT)
- end
- end
-
- class DisplayDocumentTest < InputMethodTest
- def setup
- super
- @driver = RDoc::RI::Driver.new(use_stdout: true)
- end
-
- def display_document(target, bind, driver = nil)
- input_method = IRB::RelineInputMethod.new(IRB::RegexpCompletor.new)
- input_method.instance_variable_set(:@rdoc_ri_driver, driver) if driver
- input_method.instance_variable_set(:@completion_params, ['', target, '', bind])
- input_method.display_document(target)
- end
-
- def test_perfectly_matched_namespace_triggers_document_display
- omit unless has_rdoc_content?
-
- out, err = capture_output do
- display_document("String", binding, @driver)
- end
-
- assert_empty(err)
-
- assert_include(out, " S\bSt\btr\bri\bin\bng\bg")
- end
-
- def test_perfectly_matched_multiple_namespaces_triggers_document_display
- result = nil
- out, err = capture_output do
- result = display_document("{}.nil?", binding, @driver)
- end
-
- assert_empty(err)
-
- # check if there're rdoc contents (e.g. CI doesn't generate them)
- if has_rdoc_content?
- # if there's rdoc content, we can verify by checking stdout
- # rdoc generates control characters for formatting method names
- assert_include(out, "P\bPr\bro\boc\bc.\b.n\bni\bil\bl?\b?") # Proc.nil?
- assert_include(out, "H\bHa\bas\bsh\bh.\b.n\bni\bil\bl?\b?") # Hash.nil?
- else
- # this is a hacky way to verify the rdoc rendering code path because CI doesn't have rdoc content
- # if there are multiple namespaces to be rendered, PerfectMatchedProc renders the result with a document
- # which always returns the bytes rendered, even if it's 0
- assert_equal(0, result)
- end
- end
-
- def test_not_matched_namespace_triggers_nothing
- result = nil
- out, err = capture_output do
- result = display_document("Stri", binding, @driver)
- end
-
- assert_empty(err)
- assert_empty(out)
- assert_nil(result)
- end
-
- def test_perfect_matching_stops_without_rdoc
- result = nil
-
- out, err = capture_output do
- without_rdoc do
- result = display_document("String", binding)
- end
- end
-
- assert_empty(err)
- assert_not_match(/from ruby core/, out)
- assert_nil(result)
- end
-
- def test_perfect_matching_handles_nil_namespace
- out, err = capture_output do
- # symbol literal has `nil` doc namespace so it's a good test subject
- assert_nil(display_document(":aiueo", binding, @driver))
- end
-
- assert_empty(err)
- assert_empty(out)
- end
-
- private
-
- def has_rdoc_content?
- File.exist?(RDoc::RI::Paths::BASE)
- end
- end
-end
diff --git a/test/irb/test_irb.rb b/test/irb/test_irb.rb
deleted file mode 100644
index 84b9ee3644..0000000000
--- a/test/irb/test_irb.rb
+++ /dev/null
@@ -1,806 +0,0 @@
-# frozen_string_literal: true
-require "irb"
-
-require_relative "helper"
-
-module TestIRB
- class InputTest < IntegrationTestCase
- def test_symbol_aliases_are_handled_correctly
- write_ruby <<~'RUBY'
- class Foo
- end
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "$ Foo"
- type "exit!"
- end
-
- assert_include output, "From: #{@ruby_file.path}:1"
- end
-
- def test_symbol_aliases_are_handled_correctly_with_singleline_mode
- write_rc <<~RUBY
- IRB.conf[:USE_SINGLELINE] = true
- RUBY
-
- write_ruby <<~'RUBY'
- class Foo
- end
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "irb_info"
- type "$ Foo"
- type "exit!"
- end
-
- # Make sure it's tested in singleline mode
- assert_include output, "InputMethod: ReadlineInputMethod"
- assert_include output, "From: #{@ruby_file.path}:1"
- end
-
- def test_underscore_stores_last_result
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "1 + 1"
- type "_ + 10"
- type "exit!"
- end
-
- assert_include output, "=> 12"
- end
-
- def test_evaluate_with_encoding_error_without_lineno
- if RUBY_ENGINE == 'truffleruby'
- omit "Remove me after https://github.com/ruby/prism/issues/2129 is addressed and adopted in TruffleRuby"
- end
-
- if RUBY_VERSION >= "3.4."
- omit "Now raises SyntaxError"
- end
-
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type %q[:"\xAE"]
- type "exit!"
- end
-
- assert_include output, 'invalid symbol in encoding UTF-8 :"\xAE"'
- # EncodingError would be wrapped with ANSI escape sequences, so we assert it separately
- assert_include output, "EncodingError"
- end
-
- def test_evaluate_still_emits_warning
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type %q[def foo; END {}; end]
- type "exit!"
- end
-
- assert_include output, '(irb):1: warning: END in method; use at_exit'
- end
-
- def test_symbol_aliases_dont_affect_ruby_syntax
- write_ruby <<~'RUBY'
- $foo = "It's a foo"
- @bar = "It's a bar"
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "$foo"
- type "@bar"
- type "exit!"
- end
-
- assert_include output, "=> \"It's a foo\""
- assert_include output, "=> \"It's a bar\""
- end
-
- def test_empty_input_echoing_behaviour
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type ""
- type " "
- type "exit"
- end
-
- assert_not_match(/irb\(main\):001> (\r*\n)?=> nil/, output)
- assert_match(/irb\(main\):002> (\r*\n)?=> nil/, output)
- end
- end
-
- class IrbIOConfigurationTest < TestCase
- Row = Struct.new(:content, :current_line_spaces, :new_line_spaces, :indent_level)
-
- class MockIO_AutoIndent
- attr_reader :calculated_indent
-
- def initialize(*params)
- @params = params
- end
-
- def auto_indent(&block)
- @calculated_indent = block.call(*@params)
- end
- end
-
- class MockIO_DynamicPrompt
- attr_reader :prompt_list
-
- def initialize(params, &assertion)
- @params = params
- end
-
- def dynamic_prompt(&block)
- @prompt_list = block.call(@params)
- end
- end
-
- def setup
- save_encodings
- @irb = build_irb
- end
-
- def teardown
- restore_encodings
- end
-
- class AutoIndentationTest < IrbIOConfigurationTest
- def test_auto_indent
- input_with_correct_indents = [
- [%q(def each_top_level_statement), 0, 2],
- [%q( initialize_input), 2, 2],
- [%q( catch(:TERM_INPUT) do), 2, 4],
- [%q( loop do), 4, 6],
- [%q( begin), 6, 8],
- [%q( prompt), 8, 8],
- [%q( unless l = lex), 8, 10],
- [%q( throw :TERM_INPUT if @line == ''), 10, 10],
- [%q( else), 8, 10],
- [%q( @line_no += l.count("\n")), 10, 10],
- [%q( next if l == "\n"), 10, 10],
- [%q( @line.concat l), 10, 10],
- [%q( if @code_block_open or @ltype or @continue or @indent > 0), 10, 12],
- [%q( next), 12, 12],
- [%q( end), 10, 10],
- [%q( end), 8, 8],
- [%q( if @line != "\n"), 8, 10],
- [%q( @line.force_encoding(@io.encoding)), 10, 10],
- [%q( yield @line, @exp_line_no), 10, 10],
- [%q( end), 8, 8],
- [%q( break if @io.eof?), 8, 8],
- [%q( @line = ''), 8, 8],
- [%q( @exp_line_no = @line_no), 8, 8],
- [%q( ), nil, 8],
- [%q( @indent = 0), 8, 8],
- [%q( rescue TerminateLineInput), 6, 8],
- [%q( initialize_input), 8, 8],
- [%q( prompt), 8, 8],
- [%q( end), 6, 6],
- [%q( end), 4, 4],
- [%q( end), 2, 2],
- [%q(end), 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents)
- end
-
- def test_braces_on_their_own_line
- input_with_correct_indents = [
- [%q(if true), 0, 2],
- [%q( [), 2, 4],
- [%q( ]), 2, 2],
- [%q(end), 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents)
- end
-
- def test_multiple_braces_in_a_line
- input_with_correct_indents = [
- [%q([[[), 0, 6],
- [%q( ]), 4, 4],
- [%q( ]), 2, 2],
- [%q(]), 0, 0],
- [%q([<<FOO]), 0, 0],
- [%q(hello), 0, 0],
- [%q(FOO), 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents)
- end
-
- def test_a_closed_brace_and_not_closed_brace_in_a_line
- input_with_correct_indents = [
- [%q(p() {), 0, 2],
- [%q(}), 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents)
- end
-
- def test_symbols
- input_with_correct_indents = [
- [%q(:a), 0, 0],
- [%q(:A), 0, 0],
- [%q(:+), 0, 0],
- [%q(:@@a), 0, 0],
- [%q(:@a), 0, 0],
- [%q(:$a), 0, 0],
- [%q(:def), 0, 0],
- [%q(:`), 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents)
- end
-
- def test_incomplete_coding_magic_comment
- input_with_correct_indents = [
- [%q(#coding:u), 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents)
- end
-
- def test_incomplete_encoding_magic_comment
- input_with_correct_indents = [
- [%q(#encoding:u), 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents)
- end
-
- def test_incomplete_emacs_coding_magic_comment
- input_with_correct_indents = [
- [%q(# -*- coding: u), 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents)
- end
-
- def test_incomplete_vim_coding_magic_comment
- input_with_correct_indents = [
- [%q(# vim:set fileencoding=u), 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents)
- end
-
- def test_mixed_rescue
- input_with_correct_indents = [
- [%q(def m), 0, 2],
- [%q( begin), 2, 4],
- [%q( begin), 4, 6],
- [%q( x = a rescue 4), 6, 6],
- [%q( y = [(a rescue 5)]), 6, 6],
- [%q( [x, y]), 6, 6],
- [%q( rescue => e), 4, 6],
- [%q( raise e rescue 8), 6, 6],
- [%q( end), 4, 4],
- [%q( rescue), 2, 4],
- [%q( raise rescue 11), 4, 4],
- [%q( end), 2, 2],
- [%q(rescue => e), 0, 2],
- [%q( raise e rescue 14), 2, 2],
- [%q(end), 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents)
- end
-
- def test_oneliner_method_definition
- input_with_correct_indents = [
- [%q(class A), 0, 2],
- [%q( def foo0), 2, 4],
- [%q( 3), 4, 4],
- [%q( end), 2, 2],
- [%q( def foo1()), 2, 4],
- [%q( 3), 4, 4],
- [%q( end), 2, 2],
- [%q( def foo2(a, b)), 2, 4],
- [%q( a + b), 4, 4],
- [%q( end), 2, 2],
- [%q( def foo3 a, b), 2, 4],
- [%q( a + b), 4, 4],
- [%q( end), 2, 2],
- [%q( def bar0() = 3), 2, 2],
- [%q( def bar1(a) = a), 2, 2],
- [%q( def bar2(a, b) = a + b), 2, 2],
- [%q( def bar3() = :s), 2, 2],
- [%q( def bar4() = Time.now), 2, 2],
- [%q(end), 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents)
- end
-
- def test_tlambda
- input_with_correct_indents = [
- [%q(if true), 0, 2, 1],
- [%q( -> {), 2, 4, 2],
- [%q( }), 2, 2, 1],
- [%q(end), 0, 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
- end
-
- def test_corresponding_syntax_to_keyword_do_in_class
- input_with_correct_indents = [
- [%q(class C), 0, 2, 1],
- [%q( while method_name do), 2, 4, 2],
- [%q( 3), 4, 4, 2],
- [%q( end), 2, 2, 1],
- [%q( foo do), 2, 4, 2],
- [%q( 3), 4, 4, 2],
- [%q( end), 2, 2, 1],
- [%q(end), 0, 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
- end
-
- def test_corresponding_syntax_to_keyword_do
- input_with_correct_indents = [
- [%q(while i > 0), 0, 2, 1],
- [%q( 3), 2, 2, 1],
- [%q(end), 0, 0, 0],
- [%q(while true), 0, 2, 1],
- [%q( 3), 2, 2, 1],
- [%q(end), 0, 0, 0],
- [%q(while ->{i > 0}.call), 0, 2, 1],
- [%q( 3), 2, 2, 1],
- [%q(end), 0, 0, 0],
- [%q(while ->{true}.call), 0, 2, 1],
- [%q( 3), 2, 2, 1],
- [%q(end), 0, 0, 0],
- [%q(while i > 0 do), 0, 2, 1],
- [%q( 3), 2, 2, 1],
- [%q(end), 0, 0, 0],
- [%q(while true do), 0, 2, 1],
- [%q( 3), 2, 2, 1],
- [%q(end), 0, 0, 0],
- [%q(while ->{i > 0}.call do), 0, 2, 1],
- [%q( 3), 2, 2, 1],
- [%q(end), 0, 0, 0],
- [%q(while ->{true}.call do), 0, 2, 1],
- [%q( 3), 2, 2, 1],
- [%q(end), 0, 0, 0],
- [%q(foo do), 0, 2, 1],
- [%q( 3), 2, 2, 1],
- [%q(end), 0, 0, 0],
- [%q(foo true do), 0, 2, 1],
- [%q( 3), 2, 2, 1],
- [%q(end), 0, 0, 0],
- [%q(foo ->{true} do), 0, 2, 1],
- [%q( 3), 2, 2, 1],
- [%q(end), 0, 0, 0],
- [%q(foo ->{i > 0} do), 0, 2, 1],
- [%q( 3), 2, 2, 1],
- [%q(end), 0, 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
- end
-
- def test_corresponding_syntax_to_keyword_for
- input_with_correct_indents = [
- [%q(for i in [1]), 0, 2, 1],
- [%q( puts i), 2, 2, 1],
- [%q(end), 0, 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
- end
-
- def test_corresponding_syntax_to_keyword_for_with_do
- input_with_correct_indents = [
- [%q(for i in [1] do), 0, 2, 1],
- [%q( puts i), 2, 2, 1],
- [%q(end), 0, 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
- end
-
- def test_typing_incomplete_include_interpreted_as_keyword_in
- input_with_correct_indents = [
- [%q(module E), 0, 2, 1],
- [%q(end), 0, 0, 0],
- [%q(class A), 0, 2, 1],
- [%q( in), 2, 2, 1] # scenario typing `include E`
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
-
- end
-
- def test_bracket_corresponding_to_times
- input_with_correct_indents = [
- [%q(3.times { |i|), 0, 2, 1],
- [%q( puts i), 2, 2, 1],
- [%q(}), 0, 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
- end
-
- def test_do_corresponding_to_times
- input_with_correct_indents = [
- [%q(3.times do |i|), 0, 2, 1],
- [%q( puts i), 2, 2, 1],
- [%q(end), 0, 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
- end
-
- def test_bracket_corresponding_to_loop
- input_with_correct_indents = [
- ['loop {', 0, 2, 1],
- [' 3', 2, 2, 1],
- ['}', 0, 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
- end
-
- def test_do_corresponding_to_loop
- input_with_correct_indents = [
- [%q(loop do), 0, 2, 1],
- [%q( 3), 2, 2, 1],
- [%q(end), 0, 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
- end
-
- def test_embdoc_indent
- input_with_correct_indents = [
- [%q(=begin), 0, 0, 0],
- [%q(a), 0, 0, 0],
- [%q( b), 1, 1, 0],
- [%q(=end), 0, 0, 0],
- [%q(if 1), 0, 2, 1],
- [%q( 2), 2, 2, 1],
- [%q(=begin), 0, 0, 0],
- [%q(a), 0, 0, 0],
- [%q( b), 1, 1, 0],
- [%q(=end), 0, 2, 1],
- [%q( 3), 2, 2, 1],
- [%q(end), 0, 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
- end
-
- def test_heredoc_with_indent
- if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0')
- pend 'This test needs Ripper::Lexer#scan to take broken tokens'
- end
- input_with_correct_indents = [
- [%q(<<~Q+<<~R), 0, 2, 1],
- [%q(a), 2, 2, 1],
- [%q(a), 2, 2, 1],
- [%q( b), 2, 2, 1],
- [%q( b), 2, 2, 1],
- [%q( Q), 0, 2, 1],
- [%q( c), 4, 4, 1],
- [%q( c), 4, 4, 1],
- [%q( R), 0, 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
- end
-
- def test_oneliner_def_in_multiple_lines
- input_with_correct_indents = [
- [%q(def a()=[), 0, 2, 1],
- [%q( 1,), 2, 2, 1],
- [%q(].), 0, 0, 0],
- [%q(to_s), 0, 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
- end
-
- def test_broken_heredoc
- input_with_correct_indents = [
- [%q(def foo), 0, 2, 1],
- [%q( <<~Q), 2, 4, 2],
- [%q( Qend), 4, 4, 2],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
- end
-
- def test_pasted_code_keep_base_indent_spaces
- input_with_correct_indents = [
- [%q( def foo), 0, 6, 1],
- [%q( if bar), 6, 10, 2],
- [%q( [1), 10, 12, 3],
- [%q( ]+[["a), 10, 14, 4],
- [%q(b" + `c), 0, 14, 4],
- [%q(d` + /e), 0, 14, 4],
- [%q(f/ + :"g), 0, 14, 4],
- [%q(h".tap do), 0, 16, 5],
- [%q( 1), 16, 16, 5],
- [%q( end), 14, 14, 4],
- [%q( ]), 12, 12, 3],
- [%q( ]), 10, 10, 2],
- [%q( end), 8, 6, 1],
- [%q( end), 4, 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
- end
-
- def test_pasted_code_keep_base_indent_spaces_with_heredoc
- input_with_correct_indents = [
- [%q( def foo), 0, 6, 1],
- [%q( if bar), 6, 10, 2],
- [%q( [1), 10, 12, 3],
- [%q( ]+[["a), 10, 14, 4],
- [%q(b" + <<~A + <<-B + <<C), 0, 16, 5],
- [%q( a#{), 16, 18, 6],
- [%q( 1), 18, 18, 6],
- [%q( }), 16, 16, 5],
- [%q( A), 14, 16, 5],
- [%q( b#{), 16, 18, 6],
- [%q( 1), 18, 18, 6],
- [%q( }), 16, 16, 5],
- [%q( B), 14, 0, 0],
- [%q(c#{), 0, 2, 1],
- [%q(1), 2, 2, 1],
- [%q(}), 0, 0, 0],
- [%q(C), 0, 14, 4],
- [%q( ]), 12, 12, 3],
- [%q( ]), 10, 10, 2],
- [%q( end), 8, 6, 1],
- [%q( end), 4, 0, 0],
- ]
-
- assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
- end
-
- def test_heredoc_keep_indent_spaces
- (1..4).each do |indent|
- row = Row.new(' ' * indent, nil, [4, indent].max, 2)
- lines = ['def foo', ' <<~Q', row.content]
- assert_row_indenting(lines, row)
- assert_indent_level(lines, row.indent_level)
- end
- end
-
- private
-
- def assert_row_indenting(lines, row)
- actual_current_line_spaces = calculate_indenting(lines, false)
-
- error_message = <<~MSG
- Incorrect spaces calculation for line:
-
- ```
- > #{lines.last}
- ```
-
- All lines:
-
- ```
- #{lines.join("\n")}
- ```
- MSG
- assert_equal(row.current_line_spaces, actual_current_line_spaces, error_message)
-
- error_message = <<~MSG
- Incorrect spaces calculation for line after the current line:
-
- ```
- #{lines.last}
- >
- ```
-
- All lines:
-
- ```
- #{lines.join("\n")}
- ```
- MSG
- actual_next_line_spaces = calculate_indenting(lines, true)
- assert_equal(row.new_line_spaces, actual_next_line_spaces, error_message)
- end
-
- def assert_rows_with_correct_indents(rows_with_spaces, assert_indent_level: false)
- lines = []
- rows_with_spaces.map do |row|
- row = Row.new(*row)
- lines << row.content
- assert_row_indenting(lines, row)
-
- if assert_indent_level
- assert_indent_level(lines, row.indent_level)
- end
- end
- end
-
- def assert_indent_level(lines, expected)
- code = lines.map { |l| "#{l}\n" }.join # code should end with "\n"
- _tokens, opens, _ = @irb.scanner.check_code_state(code, local_variables: [])
- indent_level = @irb.scanner.calc_indent_level(opens)
- error_message = "Calculated the wrong number of indent level for:\n #{lines.join("\n")}"
- assert_equal(expected, indent_level, error_message)
- end
-
- def calculate_indenting(lines, add_new_line)
- lines = lines + [""] if add_new_line
- last_line_index = lines.length - 1
- byte_pointer = lines.last.length
-
- mock_io = MockIO_AutoIndent.new(lines, last_line_index, byte_pointer, add_new_line)
- @irb.context.auto_indent_mode = true
- @irb.context.io = mock_io
- @irb.configure_io
-
- mock_io.calculated_indent
- end
- end
-
- class DynamicPromptTest < IrbIOConfigurationTest
- def test_endless_range_at_end_of_line
- input_with_prompt = [
- ['001:0: :> ', %q(a = 3..)],
- ['002:0: :> ', %q()],
- ]
-
- assert_dynamic_prompt(input_with_prompt)
- end
-
- def test_heredoc_with_embexpr
- input_with_prompt = [
- ['001:0:":* ', %q(<<A+%W[#{<<B)],
- ['002:0:":* ', %q(#{<<C+%W[)],
- ['003:0:":* ', %q(a)],
- ['004:2:]:* ', %q(C)],
- ['005:2:]:* ', %q(a)],
- ['006:0:":* ', %q(]})],
- ['007:0:":* ', %q(})],
- ['008:0:":* ', %q(A)],
- ['009:2:]:* ', %q(B)],
- ['010:1:]:* ', %q(})],
- ['011:0: :> ', %q(])],
- ['012:0: :> ', %q()],
- ]
-
- assert_dynamic_prompt(input_with_prompt)
- end
-
- def test_heredoc_prompt_with_quotes
- input_with_prompt = [
- ["001:1:':* ", %q(<<~'A')],
- ["002:1:':* ", %q(#{foobar})],
- ["003:0: :> ", %q(A)],
- ["004:1:`:* ", %q(<<~`A`)],
- ["005:1:`:* ", %q(whoami)],
- ["006:0: :> ", %q(A)],
- ['007:1:":* ', %q(<<~"A")],
- ['008:1:":* ', %q(foobar)],
- ['009:0: :> ', %q(A)],
- ]
-
- assert_dynamic_prompt(input_with_prompt)
- end
-
- def test_backtick_method
- input_with_prompt = [
- ['001:0: :> ', %q(self.`(arg))],
- ['002:0: :> ', %q()],
- ['003:0: :> ', %q(def `(); end)],
- ['004:0: :> ', %q()],
- ]
-
- assert_dynamic_prompt(input_with_prompt)
- end
-
- def test_dynamic_prompt
- input_with_prompt = [
- ['001:1: :* ', %q(def hoge)],
- ['002:1: :* ', %q( 3)],
- ['003:0: :> ', %q(end)],
- ]
-
- assert_dynamic_prompt(input_with_prompt)
- end
-
- def test_dynamic_prompt_with_double_newline_breaking_code
- input_with_prompt = [
- ['001:1: :* ', %q(if true)],
- ['002:2: :* ', %q(%)],
- ['003:1: :* ', %q(;end)],
- ['004:1: :* ', %q(;hello)],
- ['005:0: :> ', %q(end)],
- ]
-
- assert_dynamic_prompt(input_with_prompt)
- end
-
- def test_dynamic_prompt_with_multiline_literal
- input_with_prompt = [
- ['001:1: :* ', %q(if true)],
- ['002:2:]:* ', %q( %w[)],
- ['003:2:]:* ', %q( a)],
- ['004:1: :* ', %q( ])],
- ['005:1: :* ', %q( b)],
- ['006:2:]:* ', %q( %w[)],
- ['007:2:]:* ', %q( c)],
- ['008:1: :* ', %q( ])],
- ['009:0: :> ', %q(end)],
- ]
-
- assert_dynamic_prompt(input_with_prompt)
- end
-
- def test_dynamic_prompt_with_blank_line
- input_with_prompt = [
- ['001:1:]:* ', %q(%w[)],
- ['002:1:]:* ', %q()],
- ['003:0: :> ', %q(])],
- ]
-
- assert_dynamic_prompt(input_with_prompt)
- end
-
- def assert_dynamic_prompt(input_with_prompt)
- expected_prompt_list, lines = input_with_prompt.transpose
- def @irb.generate_prompt(opens, continue, line_offset)
- ltype = @scanner.ltype_from_open_tokens(opens)
- indent = @scanner.calc_indent_level(opens)
- continue = opens.any? || continue
- line_no = @line_no + line_offset
- '%03d:%01d:%1s:%s ' % [line_no, indent, ltype, continue ? '*' : '>']
- end
- io = MockIO_DynamicPrompt.new(lines)
- @irb.context.io = io
- @irb.configure_io
-
- error_message = <<~EOM
- Expected dynamic prompt:
- #{expected_prompt_list.join("\n")}
-
- Actual dynamic prompt:
- #{io.prompt_list.join("\n")}
- EOM
- assert_equal(expected_prompt_list, io.prompt_list, error_message)
- end
- end
-
- private
-
- def build_binding
- Object.new.instance_eval { binding }
- end
-
- def build_irb
- IRB.init_config(nil)
- workspace = IRB::WorkSpace.new(build_binding)
-
- IRB.conf[:VERBOSE] = false
- IRB::Irb.new(workspace, TestInputMethod.new)
- end
- end
-end
diff --git a/test/irb/test_locale.rb b/test/irb/test_locale.rb
deleted file mode 100644
index 930a38834c..0000000000
--- a/test/irb/test_locale.rb
+++ /dev/null
@@ -1,118 +0,0 @@
-require "irb"
-require "stringio"
-
-require_relative "helper"
-
-module TestIRB
- class LocaleTestCase < TestCase
- def test_initialize_with_en
- locale = IRB::Locale.new("en_US.UTF-8")
-
- assert_equal("en", locale.lang)
- assert_equal("US", locale.territory)
- assert_equal("UTF-8", locale.encoding.name)
- assert_equal(nil, locale.modifier)
- end
-
- def test_initialize_with_ja
- locale = IRB::Locale.new("ja_JP.UTF-8")
-
- assert_equal("ja", locale.lang)
- assert_equal("JP", locale.territory)
- assert_equal("UTF-8", locale.encoding.name)
- assert_equal(nil, locale.modifier)
- end
-
- def test_initialize_with_legacy_ja_encoding_ujis
- original_stderr = $stderr
- $stderr = StringIO.new
-
- locale = IRB::Locale.new("ja_JP.ujis")
-
- assert_equal("ja", locale.lang)
- assert_equal("JP", locale.territory)
- assert_equal(Encoding::EUC_JP, locale.encoding)
- assert_equal(nil, locale.modifier)
-
- assert_include $stderr.string, "ja_JP.ujis is obsolete. use ja_JP.EUC-JP"
- ensure
- $stderr = original_stderr
- end
-
- def test_initialize_with_legacy_ja_encoding_euc
- original_stderr = $stderr
- $stderr = StringIO.new
-
- locale = IRB::Locale.new("ja_JP.euc")
-
- assert_equal("ja", locale.lang)
- assert_equal("JP", locale.territory)
- assert_equal(Encoding::EUC_JP, locale.encoding)
- assert_equal(nil, locale.modifier)
-
- assert_include $stderr.string, "ja_JP.euc is obsolete. use ja_JP.EUC-JP"
- ensure
- $stderr = original_stderr
- end
-
- %w(IRB_LANG LC_MESSAGES LC_ALL LANG).each do |env_var|
- define_method "test_initialize_with_#{env_var.downcase}" do
- original_values = {
- "IRB_LANG" => ENV["IRB_LANG"],
- "LC_MESSAGES" => ENV["LC_MESSAGES"],
- "LC_ALL" => ENV["LC_ALL"],
- "LANG" => ENV["LANG"],
- }
-
- ENV["IRB_LANG"] = ENV["LC_MESSAGES"] = ENV["LC_ALL"] = ENV["LANG"] = nil
- ENV[env_var] = "zh_TW.UTF-8"
-
- locale = IRB::Locale.new
-
- assert_equal("zh", locale.lang)
- assert_equal("TW", locale.territory)
- assert_equal("UTF-8", locale.encoding.name)
- assert_equal(nil, locale.modifier)
- ensure
- original_values.each do |key, value|
- ENV[key] = value
- end
- end
- end
-
- def test_load
- # reset Locale's internal cache
- IRB::Locale.class_variable_set(:@@loaded, [])
- # Because error.rb files define the same class, loading them causes method redefinition warnings.
- original_verbose = $VERBOSE
- $VERBOSE = nil
-
- jp_local = IRB::Locale.new("ja_JP.UTF-8")
- jp_local.load("irb/error.rb")
- msg = IRB::CantReturnToNormalMode.new.message
- assert_equal("Normalモードに戻れません.", msg)
-
- # reset Locale's internal cache
- IRB::Locale.class_variable_set(:@@loaded, [])
-
- en_local = IRB::Locale.new("en_US.UTF-8")
- en_local.load("irb/error.rb")
- msg = IRB::CantReturnToNormalMode.new.message
- assert_equal("Can't return to normal mode.", msg)
- ensure
- # before turning warnings back on, load the error.rb file again to avoid warnings in other tests
- IRB::Locale.new.load("irb/error.rb")
- $VERBOSE = original_verbose
- end
-
- def test_find
- jp_local = IRB::Locale.new("ja_JP.UTF-8")
- path = jp_local.find("irb/error.rb")
- assert_include(path, "/lib/irb/lc/ja/error.rb")
-
- en_local = IRB::Locale.new("en_US.UTF-8")
- path = en_local.find("irb/error.rb")
- assert_include(path, "/lib/irb/lc/error.rb")
- end
- end
-end
diff --git a/test/irb/test_nesting_parser.rb b/test/irb/test_nesting_parser.rb
deleted file mode 100644
index 2482d40081..0000000000
--- a/test/irb/test_nesting_parser.rb
+++ /dev/null
@@ -1,341 +0,0 @@
-# frozen_string_literal: false
-require 'irb'
-
-require_relative "helper"
-
-module TestIRB
- class NestingParserTest < TestCase
- def setup
- save_encodings
- end
-
- def teardown
- restore_encodings
- end
-
- def parse_by_line(code)
- IRB::NestingParser.parse_by_line(IRB::RubyLex.ripper_lex_without_warning(code))
- end
-
- def test_open_tokens
- code = <<~'EOS'
- class A
- def f
- if true
- tap do
- {
- x: "
- #{p(1, 2, 3
- EOS
- opens = IRB::NestingParser.open_tokens(IRB::RubyLex.ripper_lex_without_warning(code))
- assert_equal(%w[class def if do { " #{ (], opens.map(&:tok))
- end
-
- def test_parse_by_line
- code = <<~EOS
- (((((1+2
- ).to_s())).tap do (((
- EOS
- _tokens, prev_opens, next_opens, min_depth = parse_by_line(code).last
- assert_equal(%w[( ( ( ( (], prev_opens.map(&:tok))
- assert_equal(%w[( ( do ( ( (], next_opens.map(&:tok))
- assert_equal(2, min_depth)
- end
-
- def test_ruby_syntax
- code = <<~'EOS'
- class A
- 1 if 2
- 1 while 2
- 1 until 2
- 1 unless 2
- 1 rescue 2
- begin; rescue; ensure; end
- tap do; rescue; ensure; end
- class B; end
- module C; end
- def f; end
- def `; end
- def f() = 1
- %(); %w[]; %q(); %r{}; %i[]
- "#{1}"; ''; /#{1}/; `#{1}`
- :sym; :"sym"; :+; :`; :if
- [1, 2, 3]
- { x: 1, y: 2 }
- (a, (*b, c), d), e = 1, 2, 3
- ->(a){}; ->(a) do end
- -> a = -> b = :do do end do end
- if 1; elsif 2; else; end
- unless 1; end
- while 1; end
- until 1; end
- for i in j; end
- case 1; when 2; end
- puts(1, 2, 3)
- loop{|i|}
- loop do |i| end
- end
- EOS
- line_results = parse_by_line(code)
- assert_equal(code.lines.size, line_results.size)
- class_open, *inner_line_results, class_close = line_results
- assert_equal(['class'], class_open[2].map(&:tok))
- inner_line_results.each {|result| assert_equal(['class'], result[2].map(&:tok)) }
- assert_equal([], class_close[2].map(&:tok))
- end
-
- def test_multiline_string
- code = <<~EOS
- "
- aaa
- bbb
- "
- <<A
- aaa
- bbb
- A
- EOS
- line_results = parse_by_line(code)
- assert_equal(code.lines.size, line_results.size)
- string_content_line, string_opens = line_results[1]
- assert_equal("\naaa\nbbb\n", string_content_line.first.first.tok)
- assert_equal("aaa\n", string_content_line.first.last)
- assert_equal(['"'], string_opens.map(&:tok))
- heredoc_content_line, heredoc_opens = line_results[6]
- assert_equal("aaa\nbbb\n", heredoc_content_line.first.first.tok)
- assert_equal("bbb\n", heredoc_content_line.first.last)
- assert_equal(['<<A'], heredoc_opens.map(&:tok))
- _line, _prev_opens, next_opens, _min_depth = line_results.last
- assert_equal([], next_opens)
- end
-
- def test_backslash_continued_nested_symbol
- code = <<~'EOS'
- x = <<A, :\
- heredoc #{
- here
- }
- A
- =begin
- embdoc
- =end
- # comment
-
- if # this is symbol :if
- while
- EOS
- line_results = parse_by_line(code)
- assert_equal(%w[: <<A #{], line_results[2][2].map(&:tok))
- assert_equal(%w[while], line_results.last[2].map(&:tok))
- end
-
- def test_oneliner_def
- code = <<~EOC
- if true
- # normal oneliner def
- def f = 1
- def f() = 1
- def f(*) = 1
- # keyword, backtick, op
- def * = 1
- def ` = 1
- def if = 1
- def *() = 1
- def `() = 1
- def if() = 1
- # oneliner def with receiver
- def a.* = 1
- def $a.* = 1
- def @a.` = 1
- def A.` = 1
- def ((a;b;c)).*() = 1
- def ((a;b;c)).if() = 1
- def ((a;b;c)).end() = 1
- # multiline oneliner def
- def f =
- 1
- def f()
- =
- 1
- # oneliner def with comment and embdoc
- def # comment
- =begin
- embdoc
- =end
- ((a;b;c))
- . # comment
- =begin
- embdoc
- =end
- f (*) # comment
- =begin
- embdoc
- =end
- =
- 1
- # nested oneliner def
- def f(x = def f() = 1) = def f() = 1
- EOC
- _tokens, _prev_opens, next_opens, min_depth = parse_by_line(code).last
- assert_equal(['if'], next_opens.map(&:tok))
- assert_equal(1, min_depth)
- end
-
- def test_heredoc_embexpr
- code = <<~'EOS'
- <<A+<<B+<<C+(<<D+(<<E)
- #{
- <<~F+"#{<<~G}
- #{
- here
- }
- F
- G
- "
- }
- A
- B
- C
- D
- E
- )
- EOS
- line_results = parse_by_line(code)
- last_opens = line_results.last[-2]
- assert_equal([], last_opens)
- _tokens, _prev_opens, next_opens, _min_depth = line_results[4]
- assert_equal(%w[( <<E <<D <<C <<B <<A #{ " <<~G <<~F #{], next_opens.map(&:tok))
- end
-
- def test_for_in
- code = <<~EOS
- for i in j
- here
- end
- for i in j do
- here
- end
- for i in
- j do
- here
- end
- for
- # comment
- i in j do
- here
- end
- for (a;b;c).d in (a;b;c) do
- here
- end
- for i in :in + :do do
- here
- end
- for i in -> do end do
- here
- end
- EOS
- line_results = parse_by_line(code).select { |tokens,| tokens.map(&:last).include?('here') }
- assert_equal(7, line_results.size)
- line_results.each do |_tokens, _prev_opens, next_opens, _min_depth|
- assert_equal(['for'], next_opens.map(&:tok))
- end
- end
-
- def test_while_until
- base_code = <<~'EOS'
- while_or_until true
- here
- end
- while_or_until a < c
- here
- end
- while_or_until true do
- here
- end
- while_or_until
- # comment
- (a + b) <
- # comment
- c do
- here
- end
- while_or_until :\
- do do
- here
- end
- while_or_until def do; end == :do do
- here
- end
- while_or_until -> do end do
- here
- end
- EOS
- %w[while until].each do |keyword|
- code = base_code.gsub('while_or_until', keyword)
- line_results = parse_by_line(code).select { |tokens,| tokens.map(&:last).include?('here') }
- assert_equal(7, line_results.size)
- line_results.each do |_tokens, _prev_opens, next_opens, _min_depth|
- assert_equal([keyword], next_opens.map(&:tok) )
- end
- end
- end
-
- def test_undef_alias
- codes = [
- 'undef foo',
- 'alias foo bar',
- 'undef !',
- 'alias + -',
- 'alias $a $b',
- 'undef do',
- 'alias do do',
- 'undef :do',
- 'alias :do :do',
- 'undef :"#{alias do do}"',
- 'alias :"#{undef do}" do',
- 'alias do :"#{undef do}"'
- ]
- code_with_comment = <<~EOS
- undef #
- #
- do #
- alias #
- #
- do #
- #
- do #
- EOS
- code_with_heredoc = <<~EOS
- <<~A; alias
- A
- :"#{<<~A}"
- A
- do
- EOS
- [*codes, code_with_comment, code_with_heredoc].each do |code|
- opens = IRB::NestingParser.open_tokens(IRB::RubyLex.ripper_lex_without_warning('(' + code + "\nif"))
- assert_equal(%w[( if], opens.map(&:tok))
- end
- end
-
- def test_case_in
- if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0')
- pend 'This test requires ruby version that supports case-in syntax'
- end
- code = <<~EOS
- case 1
- in 1
- here
- in
- 2
- here
- end
- EOS
- line_results = parse_by_line(code).select { |tokens,| tokens.map(&:last).include?('here') }
- assert_equal(2, line_results.size)
- line_results.each do |_tokens, _prev_opens, next_opens, _min_depth|
- assert_equal(['in'], next_opens.map(&:tok))
- end
- end
- end
-end
diff --git a/test/irb/test_option.rb b/test/irb/test_option.rb
deleted file mode 100644
index fec31f384f..0000000000
--- a/test/irb/test_option.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: false
-require_relative "helper"
-
-module TestIRB
- class OptionTest < TestCase
- def test_end_of_option
- bug4117 = '[ruby-core:33574]'
- bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
- status = assert_in_out_err(bundle_exec + %w[-W0 -rirb -e IRB.start(__FILE__) -- -f --], "", //, [], bug4117)
- assert(status.success?, bug4117)
- end
- end
-end
diff --git a/test/irb/test_raise_exception.rb b/test/irb/test_raise_exception.rb
deleted file mode 100644
index 44a5ae87e1..0000000000
--- a/test/irb/test_raise_exception.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# frozen_string_literal: false
-require "tmpdir"
-
-require_relative "helper"
-
-module TestIRB
- class RaiseExceptionTest < TestCase
- def test_raise_exception_with_nil_backtrace
- bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
- assert_in_out_err(bundle_exec + %w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<-IRB, /#<Exception: foo>/, [])
- raise Exception.new("foo").tap {|e| def e.backtrace; nil; end }
-IRB
- end
-
- def test_raise_exception_with_message_exception
- bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
- expected = /#<Exception: foo>\nbacktraces are hidden because bar was raised when processing them/
- assert_in_out_err(bundle_exec + %w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<-IRB, expected, [])
- e = Exception.new("foo")
- def e.message; raise 'bar'; end
- raise e
-IRB
- end
-
- def test_raise_exception_with_message_inspect_exception
- bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
- expected = /Uninspectable exception occurred/
- assert_in_out_err(bundle_exec + %w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<-IRB, expected, [])
- e = Exception.new("foo")
- def e.message; raise; end
- def e.inspect; raise; end
- raise e
-IRB
- end
-
- def test_raise_exception_with_invalid_byte_sequence
- pend if RUBY_ENGINE == 'truffleruby' || /mswin|mingw/ =~ RUBY_PLATFORM
- bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
- assert_in_out_err(bundle_exec + %w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<~IRB, /A\\xF3B \(StandardError\)/, [])
- raise StandardError, "A\\xf3B"
- IRB
- end
-
- def test_raise_exception_with_different_encoding_containing_invalid_byte_sequence
- backup_home = ENV["HOME"]
- Dir.mktmpdir("test_irb_raise_no_backtrace_exception_#{$$}") do |tmpdir|
- ENV["HOME"] = tmpdir
-
- bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
- File.open("#{tmpdir}/euc.rb", 'w') do |f|
- f.write(<<~EOF)
- # encoding: euc-jp
-
- def raise_euc_with_invalid_byte_sequence
- raise "\xA4\xA2\\xFF"
- end
- EOF
- end
- env = {}
- %w(LC_MESSAGES LC_ALL LC_CTYPE LANG).each {|n| env[n] = "ja_JP.UTF-8" }
- # TruffleRuby warns when the locale does not exist
- env['TRUFFLERUBYOPT'] = "#{ENV['TRUFFLERUBYOPT']} --log.level=SEVERE" if RUBY_ENGINE == 'truffleruby'
- args = [env] + bundle_exec + %W[-rirb -C #{tmpdir} -W0 -e IRB.start(__FILE__) -- -f --]
- error = /raise_euc_with_invalid_byte_sequence': あ\\xFF \(RuntimeError\)/
- assert_in_out_err(args, <<~IRB, error, [], encoding: "UTF-8")
- require_relative 'euc'
- raise_euc_with_invalid_byte_sequence
- IRB
- end
- ensure
- ENV["HOME"] = backup_home
- end
- end
-end
diff --git a/test/irb/test_ruby_lex.rb b/test/irb/test_ruby_lex.rb
deleted file mode 100644
index 4e406a8ce0..0000000000
--- a/test/irb/test_ruby_lex.rb
+++ /dev/null
@@ -1,242 +0,0 @@
-# frozen_string_literal: true
-require "irb"
-
-require_relative "helper"
-
-module TestIRB
- class RubyLexTest < TestCase
- def setup
- save_encodings
- end
-
- def teardown
- restore_encodings
- end
-
- def test_interpolate_token_with_heredoc_and_unclosed_embexpr
- code = <<~'EOC'
- ①+<<A-②
- #{③*<<B/④
- #{⑤&<<C|⑥
- EOC
- ripper_tokens = Ripper.tokenize(code)
- rubylex_tokens = IRB::RubyLex.ripper_lex_without_warning(code)
- # Assert no missing part
- assert_equal(code, rubylex_tokens.map(&:tok).join)
- # Assert ripper tokens are not removed
- ripper_tokens.each do |tok|
- assert(rubylex_tokens.any? { |t| t.tok == tok && t.tok != :on_ignored_by_ripper })
- end
- # Assert interpolated token position
- rubylex_tokens.each do |t|
- row, col = t.pos
- assert_equal t.tok, code.lines[row - 1].byteslice(col, t.tok.bytesize)
- end
- end
-
- def test_local_variables_dependent_code
- lines = ["a /1#/ do", "2"]
- assert_indent_level(lines, 1)
- assert_code_block_open(lines, true)
- assert_indent_level(lines, 0, local_variables: ['a'])
- assert_code_block_open(lines, false, local_variables: ['a'])
- end
-
- def test_literal_ends_with_space
- assert_code_block_open(['% a'], true)
- assert_code_block_open(['% a '], false)
- end
-
- def test_literal_ends_with_newline
- assert_code_block_open(['%'], true)
- assert_code_block_open(['%', ''], false)
- end
-
- def test_should_continue
- assert_should_continue(['a'], false)
- assert_should_continue(['/a/'], false)
- assert_should_continue(['a;'], false)
- assert_should_continue(['<<A', 'A'], false)
- assert_should_continue(['a...'], false)
- assert_should_continue(['a\\'], true)
- assert_should_continue(['a.'], true)
- assert_should_continue(['a+'], true)
- assert_should_continue(['a; #comment', '', '=begin', 'embdoc', '=end', ''], false)
- assert_should_continue(['a+ #comment', '', '=begin', 'embdoc', '=end', ''], true)
- end
-
- def test_code_block_open_with_should_continue
- # syntax ok
- assert_code_block_open(['a'], false) # continue: false
- assert_code_block_open(['a\\'], true) # continue: true
-
- # recoverable syntax error code is not terminated
- assert_code_block_open(['a+'], true)
-
- # unrecoverable syntax error code is terminated
- assert_code_block_open(['.; a+'], false)
-
- # other syntax error that failed to determine if it is recoverable or not
- assert_code_block_open(['@; a'], false)
- assert_code_block_open(['@; a+'], true)
- assert_code_block_open(['@; (a'], true)
- end
-
- def test_broken_percent_literal
- tokens = IRB::RubyLex.ripper_lex_without_warning('%wwww')
- pos_to_index = {}
- tokens.each_with_index { |t, i|
- assert_nil(pos_to_index[t.pos], "There is already another token in the position of #{t.inspect}.")
- pos_to_index[t.pos] = i
- }
- end
-
- def test_broken_percent_literal_in_method
- tokens = IRB::RubyLex.ripper_lex_without_warning(<<~EOC.chomp)
- def foo
- %wwww
- end
- EOC
- pos_to_index = {}
- tokens.each_with_index { |t, i|
- assert_nil(pos_to_index[t.pos], "There is already another token in the position of #{t.inspect}.")
- pos_to_index[t.pos] = i
- }
- end
-
- def test_unterminated_code
- ['do', '<<A'].each do |code|
- tokens = IRB::RubyLex.ripper_lex_without_warning(code)
- assert_equal(code, tokens.map(&:tok).join, "Cannot reconstruct code from tokens")
- error_tokens = tokens.map(&:event).grep(/error/)
- assert_empty(error_tokens, 'Error tokens must be ignored if there is corresponding non-error token')
- end
- end
-
- def test_unterminated_heredoc_string_literal
- ['<<A;<<B', "<<A;<<B\n", "%W[\#{<<A;<<B", "%W[\#{<<A;<<B\n"].each do |code|
- tokens = IRB::RubyLex.ripper_lex_without_warning(code)
- string_literal = IRB::NestingParser.open_tokens(tokens).last
- assert_equal('<<A', string_literal&.tok)
- end
- end
-
- def test_indent_level_with_heredoc_and_embdoc
- reference_code = <<~EOC.chomp
- if true
- hello
- p(
- )
- EOC
- code_with_heredoc = <<~EOC.chomp
- if true
- <<~A
- A
- p(
- )
- EOC
- code_with_embdoc = <<~EOC.chomp
- if true
- =begin
- =end
- p(
- )
- EOC
- expected = 1
- assert_indent_level(reference_code.lines, expected)
- assert_indent_level(code_with_heredoc.lines, expected)
- assert_indent_level(code_with_embdoc.lines, expected)
- end
-
- def test_assignment_expression
- ruby_lex = IRB::RubyLex.new
-
- [
- "foo = bar",
- "@foo = bar",
- "$foo = bar",
- "@@foo = bar",
- "::Foo = bar",
- "a::Foo = bar",
- "Foo = bar",
- "foo.bar = 1",
- "foo[1] = bar",
- "foo += bar",
- "foo -= bar",
- "foo ||= bar",
- "foo &&= bar",
- "foo, bar = 1, 2",
- "foo.bar=(1)",
- "foo; foo = bar",
- "foo; foo = bar; ;\n ;",
- "foo\nfoo = bar",
- ].each do |exp|
- assert(
- ruby_lex.assignment_expression?(exp, local_variables: []),
- "#{exp.inspect}: should be an assignment expression"
- )
- end
-
- [
- "foo",
- "foo.bar",
- "foo[0]",
- "foo = bar; foo",
- "foo = bar\nfoo",
- ].each do |exp|
- refute(
- ruby_lex.assignment_expression?(exp, local_variables: []),
- "#{exp.inspect}: should not be an assignment expression"
- )
- end
- end
-
- def test_assignment_expression_with_local_variable
- ruby_lex = IRB::RubyLex.new
- code = "a /1;x=1#/"
- refute(ruby_lex.assignment_expression?(code, local_variables: []), "#{code}: should not be an assignment expression")
- assert(ruby_lex.assignment_expression?(code, local_variables: [:a]), "#{code}: should be an assignment expression")
- refute(ruby_lex.assignment_expression?("", local_variables: [:a]), "empty code should not be an assignment expression")
- end
-
- def test_initialising_the_old_top_level_ruby_lex
- assert_in_out_err(["--disable-gems", "-W:deprecated"], <<~RUBY, [], /warning: constant ::RubyLex is deprecated/)
- require "irb"
- ::RubyLex.new(nil)
- RUBY
- end
-
- private
-
- def assert_indent_level(lines, expected, local_variables: [])
- indent_level, _continue, _code_block_open = check_state(lines, local_variables: local_variables)
- error_message = "Calculated the wrong number of indent level for:\n #{lines.join("\n")}"
- assert_equal(expected, indent_level, error_message)
- end
-
- def assert_should_continue(lines, expected, local_variables: [])
- _indent_level, continue, _code_block_open = check_state(lines, local_variables: local_variables)
- error_message = "Wrong result of should_continue for:\n #{lines.join("\n")}"
- assert_equal(expected, continue, error_message)
- end
-
- def assert_code_block_open(lines, expected, local_variables: [])
- if RUBY_ENGINE == 'truffleruby'
- omit "Remove me after https://github.com/ruby/prism/issues/2129 is addressed and adopted in TruffleRuby"
- end
-
- _indent_level, _continue, code_block_open = check_state(lines, local_variables: local_variables)
- error_message = "Wrong result of code_block_open for:\n #{lines.join("\n")}"
- assert_equal(expected, code_block_open, error_message)
- end
-
- def check_state(lines, local_variables: [])
- code = lines.map { |l| "#{l}\n" }.join # code should end with "\n"
- ruby_lex = IRB::RubyLex.new
- tokens, opens, terminated = ruby_lex.check_code_state(code, local_variables: local_variables)
- indent_level = ruby_lex.calc_indent_level(opens)
- continue = ruby_lex.should_continue?(tokens)
- [indent_level, continue, !terminated]
- end
- end
-end
diff --git a/test/irb/test_tracer.rb b/test/irb/test_tracer.rb
deleted file mode 100644
index 540f8be131..0000000000
--- a/test/irb/test_tracer.rb
+++ /dev/null
@@ -1,90 +0,0 @@
-# frozen_string_literal: false
-require 'tempfile'
-require 'irb'
-
-require_relative "helper"
-
-module TestIRB
- class ContextWithTracerIntegrationTest < IntegrationTestCase
- def setup
- super
-
- omit "Tracer gem is not available when running on TruffleRuby" if RUBY_ENGINE == "truffleruby"
-
- @envs.merge!("NO_COLOR" => "true")
- end
-
- def example_ruby_file
- <<~'RUBY'
- class Foo
- def self.foo
- 100
- end
- end
-
- def bar(obj)
- obj.foo
- end
-
- binding.irb
- RUBY
- end
-
- def test_use_tracer_enabled_when_gem_is_unavailable
- write_rc <<~RUBY
- # Simulate the absence of the tracer gem
- ::Kernel.send(:alias_method, :irb_original_require, :require)
-
- ::Kernel.define_method(:require) do |name|
- raise LoadError, "cannot load such file -- tracer (test)" if name.match?("tracer")
- ::Kernel.send(:irb_original_require, name)
- end
-
- IRB.conf[:USE_TRACER] = true
- RUBY
-
- write_ruby example_ruby_file
-
- output = run_ruby_file do
- type "bar(Foo)"
- type "exit"
- end
-
- assert_include(output, "Tracer extension of IRB is enabled but tracer gem wasn't found.")
- end
-
- def test_use_tracer_enabled_when_gem_is_available
- write_rc <<~RUBY
- IRB.conf[:USE_TRACER] = true
- RUBY
-
- write_ruby example_ruby_file
-
- output = run_ruby_file do
- type "bar(Foo)"
- type "exit"
- end
-
- assert_include(output, "Object#bar at")
- assert_include(output, "Foo.foo at")
- assert_include(output, "Foo.foo #=> 100")
- assert_include(output, "Object#bar #=> 100")
-
- # Test that the tracer output does not include IRB's own files
- assert_not_include(output, "irb/workspace.rb")
- end
-
- def test_use_tracer_is_disabled_by_default
- write_ruby example_ruby_file
-
- output = run_ruby_file do
- type "bar(Foo)"
- type "exit"
- end
-
- assert_not_include(output, "#depth:")
- assert_not_include(output, "Foo.foo")
- end
-
- end
-end
diff --git a/test/irb/test_type_completor.rb b/test/irb/test_type_completor.rb
deleted file mode 100644
index 5ed8988b34..0000000000
--- a/test/irb/test_type_completor.rb
+++ /dev/null
@@ -1,88 +0,0 @@
-# frozen_string_literal: true
-
-# Run test only when Ruby >= 3.0 and repl_type_completor is available
-return unless RUBY_VERSION >= '3.0.0'
-return if RUBY_ENGINE == 'truffleruby' # needs endless method definition
-begin
- require 'repl_type_completor'
-rescue LoadError
- return
-end
-
-require 'irb'
-require 'tempfile'
-require_relative './helper'
-
-module TestIRB
- class TypeCompletorTest < TestCase
- DummyContext = Struct.new(:irb_path)
-
- def setup
- ReplTypeCompletor.load_rbs unless ReplTypeCompletor.rbs_loaded?
- context = DummyContext.new('(irb)')
- @completor = IRB::TypeCompletor.new(context)
- end
-
- def empty_binding
- binding
- end
-
- def assert_completion(preposing, target, binding: empty_binding, include: nil, exclude: nil)
- raise ArgumentError if include.nil? && exclude.nil?
- candidates = @completor.completion_candidates(preposing, target, '', bind: binding)
- assert ([*include] - candidates).empty?, "Expected #{candidates} to include #{include}" if include
- assert (candidates & [*exclude]).empty?, "Expected #{candidates} not to include #{exclude}" if exclude
- end
-
- def assert_doc_namespace(preposing, target, namespace, binding: empty_binding)
- @completor.completion_candidates(preposing, target, '', bind: binding)
- assert_equal namespace, @completor.doc_namespace(preposing, target, '', bind: binding)
- end
-
- def test_type_completion
- bind = eval('num = 1; binding')
- assert_completion('num.times.map(&:', 'ab', binding: bind, include: 'abs')
- assert_doc_namespace('num.chr.', 'upcase', 'String#upcase', binding: bind)
- end
-
- def test_inspect
- assert_match(/\AReplTypeCompletor.*\z/, @completor.inspect)
- end
-
- def test_empty_completion
- candidates = @completor.completion_candidates('(', ')', '', bind: binding)
- assert_equal [], candidates
- assert_doc_namespace('(', ')', nil)
- end
-
- def test_command_completion
- assert_include(@completor.completion_candidates('', 'show_s', '', bind: binding), 'show_source')
- assert_not_include(@completor.completion_candidates(';', 'show_s', '', bind: binding), 'show_source')
- end
- end
-
- class TypeCompletorIntegrationTest < IntegrationTestCase
- def test_type_completor
- write_rc <<~RUBY
- IRB.conf[:COMPLETOR] = :type
- RUBY
-
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
- output = run_ruby_file do
- type "irb_info"
- type "sleep 0.01 until ReplTypeCompletor.rbs_loaded?"
- type "completor = IRB.CurrentContext.io.instance_variable_get(:@completor);"
- type "n = 10"
- type "puts completor.completion_candidates 'a = n.abs;', 'a.b', '', bind: binding"
- type "puts completor.doc_namespace 'a = n.chr;', 'a.encoding', '', bind: binding"
- type "exit!"
- end
- assert_match(/Completion: Autocomplete, ReplTypeCompletor/, output)
- assert_match(/a\.bit_length/, output)
- assert_match(/String#encoding/, output)
- end
- end
-end
diff --git a/test/irb/test_workspace.rb b/test/irb/test_workspace.rb
deleted file mode 100644
index 199ce95a37..0000000000
--- a/test/irb/test_workspace.rb
+++ /dev/null
@@ -1,127 +0,0 @@
-# frozen_string_literal: false
-require 'tempfile'
-require 'irb'
-require 'irb/workspace'
-require 'irb/color'
-
-require_relative "helper"
-
-module TestIRB
- class WorkSpaceTest < TestCase
- def test_code_around_binding
- IRB.conf[:USE_COLORIZE] = false
- Tempfile.create('irb') do |f|
- code = <<~RUBY
- # 1
- # 2
- IRB::WorkSpace.new(binding) # 3
- # 4
- # 5
- RUBY
- f.print(code)
- f.close
-
- workspace = eval(code, binding, f.path)
- assert_equal(<<~EOS, without_term { workspace.code_around_binding })
-
- From: #{f.path} @ line 3 :
-
- 1: # 1
- 2: # 2
- => 3: IRB::WorkSpace.new(binding) # 3
- 4: # 4
- 5: # 5
-
- EOS
- end
- ensure
- IRB.conf.delete(:USE_COLORIZE)
- end
-
- def test_code_around_binding_with_existing_unreadable_file
- pend 'chmod cannot make file unreadable on windows' if windows?
- pend 'skipped in root privilege' if Process.uid == 0
-
- Tempfile.create('irb') do |f|
- code = "IRB::WorkSpace.new(binding)\n"
- f.print(code)
- f.close
-
- File.chmod(0, f.path)
-
- workspace = eval(code, binding, f.path)
- assert_equal(nil, workspace.code_around_binding)
- end
- end
-
- def test_code_around_binding_with_script_lines__
- IRB.conf[:USE_COLORIZE] = false
- with_script_lines do |script_lines|
- Tempfile.create('irb') do |f|
- code = "IRB::WorkSpace.new(binding)\n"
- script_lines[f.path] = code.split(/^/)
-
- workspace = eval(code, binding, f.path)
- assert_equal(<<~EOS, without_term { workspace.code_around_binding })
-
- From: #{f.path} @ line 1 :
-
- => 1: IRB::WorkSpace.new(binding)
-
- EOS
- end
- end
- ensure
- IRB.conf.delete(:USE_COLORIZE)
- end
-
- def test_code_around_binding_on_irb
- workspace = eval("IRB::WorkSpace.new(binding)", binding, "(irb)")
- assert_equal(nil, workspace.code_around_binding)
- end
-
-
- def test_toplevel_binding_local_variables
- bug17623 = '[ruby-core:102468]'
- bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
- top_srcdir = "#{__dir__}/../.."
- irb_path = nil
- %w[exe libexec].find do |dir|
- irb_path = "#{top_srcdir}/#{dir}/irb"
- File.exist?(irb_path)
- end or omit 'irb command not found'
- assert_in_out_err(bundle_exec + ['-W0', "-C#{top_srcdir}", '-e', <<~RUBY, '--', '-f', '--'], 'binding.local_variables', /\[:_\]/, [], bug17623)
- version = 'xyz' # typical rubygems loading file
- load('#{irb_path}')
- RUBY
- end
-
- private
-
- def with_script_lines
- script_lines = nil
- debug_lines = {}
- Object.class_eval do
- if defined?(SCRIPT_LINES__)
- script_lines = SCRIPT_LINES__
- remove_const :SCRIPT_LINES__
- end
- const_set(:SCRIPT_LINES__, debug_lines)
- end
- yield debug_lines
- ensure
- Object.class_eval do
- remove_const :SCRIPT_LINES__
- const_set(:SCRIPT_LINES__, script_lines) if script_lines
- end
- end
-
- def without_term
- env = ENV.to_h.dup
- ENV.delete('TERM')
- yield
- ensure
- ENV.replace(env)
- end
- end
-end
diff --git a/test/irb/yamatanooroti/test_rendering.rb b/test/irb/yamatanooroti/test_rendering.rb
deleted file mode 100644
index 44e07a3a12..0000000000
--- a/test/irb/yamatanooroti/test_rendering.rb
+++ /dev/null
@@ -1,517 +0,0 @@
-require 'irb'
-
-begin
- require 'yamatanooroti'
-rescue LoadError, NameError
- # On Ruby repository, this test suite doesn't run because Ruby repo doesn't
- # have the yamatanooroti gem.
- return
-end
-
-class IRB::RenderingTest < Yamatanooroti::TestCase
- def setup
- @original_term = ENV['TERM']
- @home_backup = ENV['HOME']
- @xdg_config_home_backup = ENV['XDG_CONFIG_HOME']
- ENV['TERM'] = "xterm-256color"
- @pwd = Dir.pwd
- suffix = '%010d' % Random.rand(0..65535)
- @tmpdir = File.join(File.expand_path(Dir.tmpdir), "test_irb_#{$$}_#{suffix}")
- begin
- Dir.mkdir(@tmpdir)
- rescue Errno::EEXIST
- FileUtils.rm_rf(@tmpdir)
- Dir.mkdir(@tmpdir)
- end
- @irbrc_backup = ENV['IRBRC']
- @irbrc_file = ENV['IRBRC'] = File.join(@tmpdir, 'temporaty_irbrc')
- File.unlink(@irbrc_file) if File.exist?(@irbrc_file)
- ENV['HOME'] = File.join(@tmpdir, 'home')
- ENV['XDG_CONFIG_HOME'] = File.join(@tmpdir, 'xdg_config_home')
- end
-
- def teardown
- FileUtils.rm_rf(@tmpdir)
- ENV['IRBRC'] = @irbrc_backup
- ENV['TERM'] = @original_term
- ENV['HOME'] = @home_backup
- ENV['XDG_CONFIG_HOME'] = @xdg_config_home_backup
- end
-
- def test_launch
- write_irbrc <<~'LINES'
- puts 'start IRB'
- LINES
- start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write(<<~EOC)
- 'Hello, World!'
- EOC
- close
- assert_screen(<<~EOC)
- start IRB
- irb(main):001> 'Hello, World!'
- => "Hello, World!"
- irb(main):002>
- EOC
- end
-
- def test_configuration_file_is_skipped_with_dash_f
- write_irbrc <<~'LINES'
- puts '.irbrc file should be ignored when -f is used'
- LINES
- start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb -f}, startup_message: '')
- write(<<~EOC)
- 'Hello, World!'
- EOC
- close
- assert_screen(<<~EOC)
- irb(main):001> 'Hello, World!'
- => "Hello, World!"
- irb(main):002>
- EOC
- end
-
- def test_configuration_file_is_skipped_with_dash_f_for_nested_sessions
- write_irbrc <<~'LINES'
- puts '.irbrc file should be ignored when -f is used'
- LINES
- start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb -f}, startup_message: '')
- write(<<~EOC)
- 'Hello, World!'
- binding.irb
- exit!
- EOC
- close
- assert_screen(<<~EOC)
- irb(main):001> 'Hello, World!'
- => "Hello, World!"
- irb(main):002> binding.irb
- irb(main):003> exit!
- irb(main):001>
- EOC
- end
-
- def test_nomultiline
- write_irbrc <<~'LINES'
- puts 'start IRB'
- LINES
- start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb --nomultiline}, startup_message: 'start IRB')
- write(<<~EOC)
- if true
- if false
- a = "hello
- world"
- puts a
- end
- end
- EOC
- close
- assert_screen(<<~EOC)
- start IRB
- irb(main):001> if true
- irb(main):002* if false
- irb(main):003* a = "hello
- irb(main):004" world"
- irb(main):005* puts a
- irb(main):006* end
- irb(main):007* end
- => nil
- irb(main):008>
- EOC
- end
-
- def test_multiline_paste
- write_irbrc <<~'LINES'
- puts 'start IRB'
- LINES
- start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write(<<~EOC)
- class A
- def inspect; '#<A>'; end
- def a; self; end
- def b; true; end
- end
-
- a = A.new
-
- a
- .a
- .b
- .itself
- EOC
- close
- assert_screen(<<~EOC)
- start IRB
- irb(main):001* class A
- irb(main):002* def inspect; '#<A>'; end
- irb(main):003* def a; self; end
- irb(main):004* def b; true; end
- irb(main):005> end
- => :b
- irb(main):006>
- irb(main):007> a = A.new
- => #<A>
- irb(main):008>
- irb(main):009> a
- irb(main):010> .a
- irb(main):011> .b
- irb(main):012> .itself
- => true
- irb(main):013>
- EOC
- end
-
- def test_evaluate_each_toplevel_statement_by_multiline_paste
- write_irbrc <<~'LINES'
- puts 'start IRB'
- LINES
- start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write(<<~EOC)
- class A
- def inspect; '#<A>'; end
- def b; self; end
- def c; true; end
- end
-
- a = A.new
-
- a
- .b
- # aaa
- .c
-
- (a)
- &.b()
-
- class A def b; self; end; def c; true; end; end;
- a = A.new
- a
- .b
- # aaa
- .c
- (a)
- &.b()
- .itself
- EOC
- close
- assert_screen(<<~EOC)
- start IRB
- irb(main):001* class A
- irb(main):002* def inspect; '#<A>'; end
- irb(main):003* def b; self; end
- irb(main):004* def c; true; end
- irb(main):005> end
- => :c
- irb(main):006>
- irb(main):007> a = A.new
- => #<A>
- irb(main):008>
- irb(main):009> a
- irb(main):010> .b
- irb(main):011> # aaa
- irb(main):012> .c
- => true
- irb(main):013>
- irb(main):014> (a)
- irb(main):015> &.b()
- => #<A>
- irb(main):016>
- irb(main):017> class A def b; self; end; def c; true; end; end;
- irb(main):018> a = A.new
- => #<A>
- irb(main):019> a
- irb(main):020> .b
- irb(main):021> # aaa
- irb(main):022> .c
- => true
- irb(main):023> (a)
- irb(main):024> &.b()
- irb(main):025> .itself
- => #<A>
- irb(main):026>
- EOC
- end
-
- def test_symbol_with_backtick
- write_irbrc <<~'LINES'
- puts 'start IRB'
- LINES
- start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write(<<~EOC)
- :`
- EOC
- close
- assert_screen(<<~EOC)
- start IRB
- irb(main):001> :`
- => :`
- irb(main):002>
- EOC
- end
-
- def test_autocomplete_with_multiple_doc_namespaces
- write_irbrc <<~'LINES'
- puts 'start IRB'
- LINES
- start_terminal(3, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write("{}.__id_")
- write("\C-i")
- sleep 0.2
- close
- screen = result.join("\n").sub(/\n*\z/, "\n")
- assert_match(/start\ IRB\nirb\(main\):001> {}\.__id__\n }\.__id__(?:Press )?/, screen)
- end
-
- def test_autocomplete_with_showdoc_in_gaps_on_narrow_screen_right
- rdoc_dir = File.join(@tmpdir, 'rdoc')
- system("bundle exec rdoc -r -o #{rdoc_dir}")
- write_irbrc <<~LINES
- IRB.conf[:EXTRA_DOC_DIRS] = ['#{rdoc_dir}']
- IRB.conf[:PROMPT][:MY_PROMPT] = {
- :PROMPT_I => "%03n> ",
- :PROMPT_S => "%03n> ",
- :PROMPT_C => "%03n> "
- }
- IRB.conf[:PROMPT_MODE] = :MY_PROMPT
- puts 'start IRB'
- LINES
- start_terminal(4, 19, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write("IR")
- write("\C-i")
- sleep 0.2
- close
-
- # This is because on macOS we display different shortcut for displaying the full doc
- # 'O' is for 'Option' and 'A' is for 'Alt'
- if RUBY_PLATFORM =~ /darwin/
- assert_screen(<<~EOC)
- start IRB
- 001> IRB
- IRBPress Opti
- IRB
- EOC
- else
- assert_screen(<<~EOC)
- start IRB
- 001> IRB
- IRBPress Alt+
- IRB
- EOC
- end
- end
-
- def test_autocomplete_with_showdoc_in_gaps_on_narrow_screen_left
- rdoc_dir = File.join(@tmpdir, 'rdoc')
- system("bundle exec rdoc -r -o #{rdoc_dir}")
- write_irbrc <<~LINES
- IRB.conf[:EXTRA_DOC_DIRS] = ['#{rdoc_dir}']
- IRB.conf[:PROMPT][:MY_PROMPT] = {
- :PROMPT_I => "%03n> ",
- :PROMPT_S => "%03n> ",
- :PROMPT_C => "%03n> "
- }
- IRB.conf[:PROMPT_MODE] = :MY_PROMPT
- puts 'start IRB'
- LINES
- start_terminal(4, 12, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write("IR")
- write("\C-i")
- sleep 0.2
- close
- assert_screen(<<~EOC)
- start IRB
- 001> IRB
- PressIRB
- IRB
- EOC
- end
-
- def test_assignment_expression_truncate
- write_irbrc <<~'LINES'
- puts 'start IRB'
- LINES
- start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- # Assignment expression code that turns into non-assignment expression after evaluation
- code = "a /'/i if false; a=1; x=1000.times.to_a#'.size"
- write(code + "\n")
- close
- assert_screen(<<~EOC)
- start IRB
- irb(main):001> #{code}
- =>
- [0,
- ...
- irb(main):002>
- EOC
- end
-
- def test_ctrl_c_is_handled
- write_irbrc <<~'LINES'
- puts 'start IRB'
- LINES
- start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- # Assignment expression code that turns into non-assignment expression after evaluation
- write("\C-c")
- close
- assert_screen(<<~EOC)
- start IRB
- irb(main):001>
- ^C
- irb(main):001>
- EOC
- end
-
- def test_show_cmds_with_pager_can_quit_with_ctrl_c
- write_irbrc <<~'LINES'
- puts 'start IRB'
- LINES
- start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write("help\n")
- write("G") # move to the end of the screen
- write("\C-c") # quit pager
- write("'foo' + 'bar'\n") # eval something to make sure IRB resumes
- close
-
- screen = result.join("\n").sub(/\n*\z/, "\n")
- # IRB::Abort should be rescued
- assert_not_match(/IRB::Abort/, screen)
- # IRB should resume
- assert_match(/foobar/, screen)
- end
-
- def test_pager_page_content_pages_output_when_it_does_not_fit_in_the_screen_because_of_total_length
- write_irbrc <<~'LINES'
- puts 'start IRB'
- require "irb/pager"
- LINES
- start_terminal(10, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write("IRB::Pager.page_content('a' * (80 * 8))\n")
- write("'foo' + 'bar'\n") # eval something to make sure IRB resumes
- close
-
- screen = result.join("\n").sub(/\n*\z/, "\n")
- assert_match(/a{80}/, screen)
- # because pager is invoked, foobar will not be evaluated
- assert_not_match(/foobar/, screen)
- end
-
- def test_pager_page_content_pages_output_when_it_does_not_fit_in_the_screen_because_of_screen_height
- write_irbrc <<~'LINES'
- puts 'start IRB'
- require "irb/pager"
- LINES
- start_terminal(10, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write("IRB::Pager.page_content('a\n' * 8)\n")
- write("'foo' + 'bar'\n") # eval something to make sure IRB resumes
- close
-
- screen = result.join("\n").sub(/\n*\z/, "\n")
- assert_match(/(a\n){8}/, screen)
- # because pager is invoked, foobar will not be evaluated
- assert_not_match(/foobar/, screen)
- end
-
- def test_pager_page_content_doesnt_page_output_when_it_fits_in_the_screen
- write_irbrc <<~'LINES'
- puts 'start IRB'
- require "irb/pager"
- LINES
- start_terminal(10, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write("IRB::Pager.page_content('a' * (80 * 7))\n")
- write("'foo' + 'bar'\n") # eval something to make sure IRB resumes
- close
-
- screen = result.join("\n").sub(/\n*\z/, "\n")
- assert_match(/a{80}/, screen)
- # because pager is not invoked, foobar will be evaluated
- assert_match(/foobar/, screen)
- end
-
- def test_long_evaluation_output_is_paged
- write_irbrc <<~'LINES'
- puts 'start IRB'
- require "irb/pager"
- LINES
- start_terminal(10, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write("'a' * 80 * 11\n")
- write("'foo' + 'bar'\n") # eval something to make sure IRB resumes
- close
-
- screen = result.join("\n").sub(/\n*\z/, "\n")
- assert_match(/(a{80}\n){8}/, screen)
- # because pager is invoked, foobar will not be evaluated
- assert_not_match(/foobar/, screen)
- end
-
- def test_long_evaluation_output_is_preserved_after_paging
- write_irbrc <<~'LINES'
- puts 'start IRB'
- require "irb/pager"
- LINES
- start_terminal(10, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write("'a' * 80 * 11\n")
- write("q") # quit pager
- write("'foo' + 'bar'\n") # eval something to make sure IRB resumes
- close
-
- screen = result.join("\n").sub(/\n*\z/, "\n")
- # confirm pager has exited
- assert_match(/foobar/, screen)
- # confirm output is preserved
- assert_match(/(a{80}\n){6}/, screen)
- end
-
- def test_debug_integration_hints_debugger_commands
- write_irbrc <<~'LINES'
- IRB.conf[:USE_COLORIZE] = false
- LINES
- script = Tempfile.create(["debug", ".rb"])
- script.write <<~RUBY
- puts 'start IRB'
- binding.irb
- RUBY
- script.close
- start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{script.to_path}}, startup_message: 'start IRB')
- write("debug\n")
- write("pp 1\n")
- write("pp 1")
- close
-
- screen = result.join("\n").sub(/\n*\z/, "\n")
- # submitted input shouldn't contain hint
- assert_include(screen, "irb:rdbg(main):002> pp 1\n")
- # unsubmitted input should contain hint
- assert_include(screen, "irb:rdbg(main):003> pp 1 # debug command\n")
- ensure
- File.unlink(script) if script
- end
-
- def test_debug_integration_doesnt_hint_non_debugger_commands
- write_irbrc <<~'LINES'
- IRB.conf[:USE_COLORIZE] = false
- LINES
- script = Tempfile.create(["debug", ".rb"])
- script.write <<~RUBY
- puts 'start IRB'
- binding.irb
- RUBY
- script.close
- start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{script.to_path}}, startup_message: 'start IRB')
- write("debug\n")
- write("foo")
- close
-
- screen = result.join("\n").sub(/\n*\z/, "\n")
- assert_include(screen, "irb:rdbg(main):002> foo\n")
- ensure
- File.unlink(script) if script
- end
-
- private
-
- def write_irbrc(content)
- File.open(@irbrc_file, 'w') do |f|
- f.write content
- end
- end
-end