diff options
Diffstat (limited to 'test/reline')
| -rw-r--r-- | test/reline/helper.rb | 158 | ||||
| -rw-r--r-- | test/reline/test_ansi.rb | 72 | ||||
| -rw-r--r-- | test/reline/test_config.rb | 616 | ||||
| -rw-r--r-- | test/reline/test_face.rb | 257 | ||||
| -rw-r--r-- | test/reline/test_history.rb | 317 | ||||
| -rw-r--r-- | test/reline/test_key_actor_emacs.rb | 1743 | ||||
| -rw-r--r-- | test/reline/test_key_actor_vi.rb | 967 | ||||
| -rw-r--r-- | test/reline/test_key_stroke.rb | 111 | ||||
| -rw-r--r-- | test/reline/test_kill_ring.rb | 268 | ||||
| -rw-r--r-- | test/reline/test_line_editor.rb | 271 | ||||
| -rw-r--r-- | test/reline/test_macro.rb | 40 | ||||
| -rw-r--r-- | test/reline/test_reline.rb | 487 | ||||
| -rw-r--r-- | test/reline/test_reline_key.rb | 10 | ||||
| -rw-r--r-- | test/reline/test_string_processing.rb | 46 | ||||
| -rw-r--r-- | test/reline/test_unicode.rb | 286 | ||||
| -rw-r--r-- | test/reline/test_within_pipe.rb | 77 | ||||
| -rw-r--r-- | test/reline/windows/test_key_event_record.rb | 41 | ||||
| -rwxr-xr-x | test/reline/yamatanooroti/multiline_repl | 257 | ||||
| -rw-r--r-- | test/reline/yamatanooroti/termination_checker.rb | 26 | ||||
| -rw-r--r-- | test/reline/yamatanooroti/test_rendering.rb | 1915 |
20 files changed, 0 insertions, 7965 deletions
diff --git a/test/reline/helper.rb b/test/reline/helper.rb deleted file mode 100644 index 6f470a617f..0000000000 --- a/test/reline/helper.rb +++ /dev/null @@ -1,158 +0,0 @@ -$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) - -ENV['TERM'] = 'xterm' # for some CI environments - -require 'reline' -require 'test/unit' - -begin - require 'rbconfig' -rescue LoadError -end - -begin - # This should exist and available in load path when this file is mirrored to ruby/ruby and running at there - if File.exist?(File.expand_path('../../tool/lib/envutil.rb', __dir__)) - require 'envutil' - end -rescue LoadError -end - -module Reline - class << self - def test_mode(ansi: false) - @original_iogate = IOGate - - if defined?(RELINE_TEST_ENCODING) - encoding = RELINE_TEST_ENCODING - else - encoding = Encoding::UTF_8 - end - - if ansi - new_io_gate = ANSI.new - # Setting ANSI gate's screen size through set_screen_size will also change the tester's stdin's screen size - # Let's avoid that side-effect by stubbing the get_screen_size method - new_io_gate.define_singleton_method(:get_screen_size) do - [24, 80] - end - new_io_gate.define_singleton_method(:encoding) do - encoding - end - else - new_io_gate = Dumb.new(encoding: encoding) - end - - remove_const('IOGate') - const_set('IOGate', new_io_gate) - core.config.instance_variable_set(:@test_mode, true) - core.config.reset - end - - def test_reset - remove_const('IOGate') - const_set('IOGate', @original_iogate) - Reline.instance_variable_set(:@core, nil) - end - - # Return a executable name to spawn Ruby process. In certain build configuration, - # "ruby" may not be available. - def test_rubybin - # When this test suite is running in ruby/ruby, prefer EnvUtil result over original implementation - if const_defined?(:EnvUtil) - return EnvUtil.rubybin - end - - # The following is a simplified port of EnvUtil.rubybin in ruby/ruby - if ruby = ENV["RUBY"] - return ruby - end - ruby = "ruby" - exeext = RbConfig::CONFIG["EXEEXT"] - rubyexe = (ruby + exeext if exeext and !exeext.empty?) - if File.exist? ruby and File.executable? ruby and !File.directory? ruby - return File.expand_path(ruby) - end - if rubyexe and File.exist? rubyexe and File.executable? rubyexe - return File.expand_path(rubyexe) - end - if defined?(RbConfig.ruby) - RbConfig.ruby - else - "ruby" - end - end - end -end - -class Reline::TestCase < Test::Unit::TestCase - private def convert_str(input) - input.encode(@line_editor.encoding, Encoding::UTF_8) - end - - def omit_unless_utf8 - omit "This test is for UTF-8 but the locale is #{Reline.core.encoding}" if Reline.core.encoding != Encoding::UTF_8 - end - - def input_key_by_symbol(method_symbol, char: nil, csi: false) - char ||= csi ? "\e[A" : "\C-a" - @line_editor.input_key(Reline::Key.new(char, method_symbol, false)) - end - - def input_keys(input) - input = convert_str(input) - - key_stroke = Reline::KeyStroke.new(@config, @encoding) - input_bytes = input.bytes - until input_bytes.empty? - expanded, input_bytes = key_stroke.expand(input_bytes) - expanded.each do |key| - @line_editor.input_key(key) - end - end - end - - def set_line_around_cursor(before, after) - input_keys("\C-a\C-k") - input_keys(after) - input_keys("\C-a") - input_keys(before) - end - - def assert_line_around_cursor(before, after) - before = convert_str(before) - after = convert_str(after) - line = @line_editor.current_line - byte_pointer = @line_editor.instance_variable_get(:@byte_pointer) - actual_before = line.byteslice(0, byte_pointer) - actual_after = line.byteslice(byte_pointer..) - assert_equal([before, after], [actual_before, actual_after]) - end - - def assert_byte_pointer_size(expected) - expected = convert_str(expected) - byte_pointer = @line_editor.instance_variable_get(:@byte_pointer) - chunk = @line_editor.line.byteslice(0, byte_pointer) - assert_equal( - expected.bytesize, byte_pointer, - <<~EOM) - <#{expected.inspect} (#{expected.encoding.inspect})> expected but was - <#{chunk.inspect} (#{chunk.encoding.inspect})> in <Terminal #{Reline::Dumb.new.encoding.inspect}> - EOM - end - - def assert_line_index(expected) - assert_equal(expected, @line_editor.instance_variable_get(:@line_index)) - end - - def assert_whole_lines(expected) - assert_equal(expected, @line_editor.whole_lines) - end - - def assert_key_binding(input, method_symbol, editing_modes = [:emacs, :vi_insert, :vi_command]) - editing_modes.each do |editing_mode| - @config.editing_mode = editing_mode - assert_equal(method_symbol, @config.editing_mode.get(input.bytes)) - end - end -end diff --git a/test/reline/test_ansi.rb b/test/reline/test_ansi.rb deleted file mode 100644 index 5e28e72b06..0000000000 --- a/test/reline/test_ansi.rb +++ /dev/null @@ -1,72 +0,0 @@ -require_relative 'helper' -require 'reline' - -class Reline::ANSITest < Reline::TestCase - def setup - Reline.send(:test_mode, ansi: true) - @config = Reline::Config.new - Reline.core.io_gate.set_default_key_bindings(@config) - end - - def teardown - Reline.test_reset - end - - def test_home - assert_key_binding("\e[1~", :ed_move_to_beg) # Console (80x25) - assert_key_binding("\e[H", :ed_move_to_beg) # KDE - assert_key_binding("\e[7~", :ed_move_to_beg) # urxvt / exoterm - assert_key_binding("\eOH", :ed_move_to_beg) # GNOME - end - - def test_end - assert_key_binding("\e[4~", :ed_move_to_end) # Console (80x25) - assert_key_binding("\e[F", :ed_move_to_end) # KDE - assert_key_binding("\e[8~", :ed_move_to_end) # urxvt / exoterm - assert_key_binding("\eOF", :ed_move_to_end) # GNOME - end - - def test_delete - assert_key_binding("\e[3~", :key_delete) - end - - def test_up_arrow - assert_key_binding("\e[A", :ed_prev_history) # Console (80x25) - assert_key_binding("\eOA", :ed_prev_history) - end - - def test_down_arrow - assert_key_binding("\e[B", :ed_next_history) # Console (80x25) - assert_key_binding("\eOB", :ed_next_history) - end - - def test_right_arrow - assert_key_binding("\e[C", :ed_next_char) # Console (80x25) - assert_key_binding("\eOC", :ed_next_char) - end - - def test_left_arrow - assert_key_binding("\e[D", :ed_prev_char) # Console (80x25) - assert_key_binding("\eOD", :ed_prev_char) - end - - # Ctrl+arrow and Meta+arrow - def test_extended - assert_key_binding("\e[1;5C", :em_next_word) # Ctrl+→ - assert_key_binding("\e[1;5D", :ed_prev_word) # Ctrl+← - assert_key_binding("\e[1;3C", :em_next_word) # Meta+→ - assert_key_binding("\e[1;3D", :ed_prev_word) # Meta+← - assert_key_binding("\e\e[C", :em_next_word) # Meta+→ - assert_key_binding("\e\e[D", :ed_prev_word) # Meta+← - end - - def test_shift_tab - assert_key_binding("\e[Z", :completion_journey_up, [:emacs, :vi_insert]) - end - - # A few emacs bindings that are always mapped - def test_more_emacs - assert_key_binding("\e ", :em_set_mark, [:emacs]) - assert_key_binding("\C-x\C-x", :em_exchange_mark, [:emacs]) - end -end diff --git a/test/reline/test_config.rb b/test/reline/test_config.rb deleted file mode 100644 index 3c9094eece..0000000000 --- a/test/reline/test_config.rb +++ /dev/null @@ -1,616 +0,0 @@ -require_relative 'helper' - -class Reline::Config::Test < Reline::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) - Reline.test_mode - @config = Reline::Config.new - @inputrc_backup = ENV['INPUTRC'] - end - - def teardown - Dir.chdir(@pwd) - FileUtils.rm_rf(@tmpdir) - Reline.test_reset - @config.reset - ENV['INPUTRC'] = @inputrc_backup - end - - def get_config_variable(variable) - @config.instance_variable_get(variable) - end - - def additional_key_bindings(keymap_label) - get_config_variable(:@additional_key_bindings)[keymap_label].instance_variable_get(:@key_bindings) - end - - def registered_key_bindings(keys) - key_bindings = @config.key_bindings - keys.to_h { |key| [key, key_bindings.get(key)] } - end - - def test_read_lines - @config.read_lines(<<~LINES.lines) - set show-mode-in-prompt on - LINES - - assert_equal true, get_config_variable(:@show_mode_in_prompt) - end - - def test_read_lines_with_variable - @config.read_lines(<<~LINES.lines) - set disable-completion on - LINES - - assert_equal true, get_config_variable(:@disable_completion) - end - - def test_string_value - @config.read_lines(<<~LINES.lines) - set show-mode-in-prompt on - set emacs-mode-string Emacs - LINES - - assert_equal 'Emacs', get_config_variable(:@emacs_mode_string) - end - - def test_string_value_with_brackets - @config.read_lines(<<~LINES.lines) - set show-mode-in-prompt on - set emacs-mode-string [Emacs] - LINES - - assert_equal '[Emacs]', get_config_variable(:@emacs_mode_string) - end - - def test_string_value_with_brackets_and_quotes - @config.read_lines(<<~LINES.lines) - set show-mode-in-prompt on - set emacs-mode-string "[Emacs]" - LINES - - assert_equal '[Emacs]', get_config_variable(:@emacs_mode_string) - end - - def test_string_value_with_parens - @config.read_lines(<<~LINES.lines) - set show-mode-in-prompt on - set emacs-mode-string (Emacs) - LINES - - assert_equal '(Emacs)', get_config_variable(:@emacs_mode_string) - end - - def test_string_value_with_parens_and_quotes - @config.read_lines(<<~LINES.lines) - set show-mode-in-prompt on - set emacs-mode-string "(Emacs)" - LINES - - assert_equal '(Emacs)', get_config_variable(:@emacs_mode_string) - end - - def test_encoding_is_ascii - @config.reset - Reline.core.io_gate.instance_variable_set(:@encoding, Encoding::US_ASCII) - @config = Reline::Config.new - - assert_equal true, @config.convert_meta - end - - def test_encoding_is_not_ascii - @config = Reline::Config.new - - assert_equal false, @config.convert_meta - end - - def test_invalid_keystroke - @config.read_lines(<<~LINES.lines) - #"a": comment - a: error - "b": no-error - LINES - key_bindings = additional_key_bindings(:emacs) - assert_not_include key_bindings, 'a'.bytes - assert_not_include key_bindings, nil - assert_not_include key_bindings, [] - assert_include key_bindings, 'b'.bytes - end - - def test_bind_key - assert_equal ['input'.bytes, 'abcde'.bytes], @config.parse_key_binding('"input"', '"abcde"') - end - - def test_bind_key_with_macro - - assert_equal ['input'.bytes, :abcde], @config.parse_key_binding('"input"', 'abcde') - end - - def test_bind_key_with_escaped_chars - assert_equal ['input'.bytes, "\e \\ \" ' \a \b \d \f \n \r \t \v".bytes], @config.parse_key_binding('"input"', '"\\e \\\\ \\" \\\' \\a \\b \\d \\f \\n \\r \\t \\v"') - end - - def test_bind_key_with_ctrl_chars - assert_equal ['input'.bytes, "\C-h\C-h\C-_".bytes], @config.parse_key_binding('"input"', '"\C-h\C-H\C-_"') - assert_equal ['input'.bytes, "\C-h\C-h\C-_".bytes], @config.parse_key_binding('"input"', '"\Control-h\Control-H\Control-_"') - end - - def test_bind_key_with_meta_chars - assert_equal ['input'.bytes, "\eh\eH\e_".bytes], @config.parse_key_binding('"input"', '"\M-h\M-H\M-_"') - assert_equal ['input'.bytes, "\eh\eH\e_".bytes], @config.parse_key_binding('"input"', '"\Meta-h\Meta-H\M-_"') - end - - def test_bind_key_with_ctrl_meta_chars - assert_equal ['input'.bytes, "\e\C-h\e\C-h\e\C-_".bytes], @config.parse_key_binding('"input"', '"\M-\C-h\C-\M-H\M-\C-_"') - assert_equal ['input'.bytes, "\e\C-h\e\C-_".bytes], @config.parse_key_binding('"input"', '"\Meta-\Control-h\Control-\Meta-_"') - end - - def test_bind_key_with_octal_number - input = %w{i n p u t}.map(&:ord) - assert_equal [input, "\1".bytes], @config.parse_key_binding('"input"', '"\1"') - assert_equal [input, "\12".bytes], @config.parse_key_binding('"input"', '"\12"') - assert_equal [input, "\123".bytes], @config.parse_key_binding('"input"', '"\123"') - assert_equal [input, "\123".bytes + '4'.bytes], @config.parse_key_binding('"input"', '"\1234"') - end - - def test_bind_key_with_hexadecimal_number - input = %w{i n p u t}.map(&:ord) - assert_equal [input, "\x4".bytes], @config.parse_key_binding('"input"', '"\x4"') - assert_equal [input, "\x45".bytes], @config.parse_key_binding('"input"', '"\x45"') - assert_equal [input, "\x45".bytes + '6'.bytes], @config.parse_key_binding('"input"', '"\x456"') - end - - def test_include - File.open('included_partial', 'wt') do |f| - f.write(<<~PARTIAL_LINES) - set show-mode-in-prompt on - PARTIAL_LINES - end - @config.read_lines(<<~LINES.lines) - $include included_partial - LINES - - assert_equal true, get_config_variable(:@show_mode_in_prompt) - end - - def test_include_expand_path - home_backup = ENV['HOME'] - File.open('included_partial', 'wt') do |f| - f.write(<<~PARTIAL_LINES) - set show-mode-in-prompt on - PARTIAL_LINES - end - ENV['HOME'] = Dir.pwd - @config.read_lines(<<~LINES.lines) - $include ~/included_partial - LINES - - assert_equal true, get_config_variable(:@show_mode_in_prompt) - ensure - ENV['HOME'] = home_backup - end - - def test_if - @config.read_lines(<<~LINES.lines) - $if Ruby - set vi-cmd-mode-string (cmd) - $else - set vi-cmd-mode-string [cmd] - $endif - LINES - - assert_equal '(cmd)', get_config_variable(:@vi_cmd_mode_string) - end - - def test_if_with_false - @config.read_lines(<<~LINES.lines) - $if Python - set vi-cmd-mode-string (cmd) - $else - set vi-cmd-mode-string [cmd] - $endif - LINES - - assert_equal '[cmd]', get_config_variable(:@vi_cmd_mode_string) - end - - def test_if_with_indent - %w[Ruby Reline].each do |cond| - @config.read_lines(<<~LINES.lines) - set vi-cmd-mode-string {cmd} - $if #{cond} - set vi-cmd-mode-string (cmd) - $else - set vi-cmd-mode-string [cmd] - $endif - LINES - - assert_equal '(cmd)', get_config_variable(:@vi_cmd_mode_string) - end - end - - def test_nested_if_else - @config.read_lines(<<~LINES.lines) - $if Ruby - "\x1": "O" - $if NotRuby - "\x2": "X" - $else - "\x3": "O" - $if Ruby - "\x4": "O" - $else - "\x5": "X" - $endif - "\x6": "O" - $endif - "\x7": "O" - $else - "\x8": "X" - $if NotRuby - "\x9": "X" - $else - "\xA": "X" - $endif - "\xB": "X" - $endif - "\xC": "O" - LINES - keys = [0x1, 0x3, 0x4, 0x6, 0x7, 0xC] - key_bindings = keys.to_h { |k| [[k], ['O'.ord]] } - assert_equal(key_bindings, additional_key_bindings(:emacs)) - end - - def test_unclosed_if - e = assert_raise(Reline::Config::InvalidInputrc) do - @config.read_lines(<<~LINES.lines, "INPUTRC") - $if Ruby - LINES - end - assert_equal "INPUTRC:1: unclosed if", e.message - end - - def test_unmatched_else - e = assert_raise(Reline::Config::InvalidInputrc) do - @config.read_lines(<<~LINES.lines, "INPUTRC") - $else - LINES - end - assert_equal "INPUTRC:1: unmatched else", e.message - end - - def test_unmatched_endif - e = assert_raise(Reline::Config::InvalidInputrc) do - @config.read_lines(<<~LINES.lines, "INPUTRC") - $endif - LINES - end - assert_equal "INPUTRC:1: unmatched endif", e.message - end - - def test_if_with_mode - @config.read_lines(<<~LINES.lines) - $if mode=emacs - "\C-e": history-search-backward # comment - $else - "\C-f": history-search-forward - $endif - LINES - - assert_equal({[5] => :history_search_backward}, additional_key_bindings(:emacs)) - assert_equal({}, additional_key_bindings(:vi_insert)) - assert_equal({}, additional_key_bindings(:vi_command)) - end - - def test_else - @config.read_lines(<<~LINES.lines) - $if mode=vi - "\C-e": history-search-backward # comment - $else - "\C-f": history-search-forward - $endif - LINES - - assert_equal({[6] => :history_search_forward}, additional_key_bindings(:emacs)) - assert_equal({}, additional_key_bindings(:vi_insert)) - assert_equal({}, additional_key_bindings(:vi_command)) - end - - def test_if_with_invalid_mode - @config.read_lines(<<~LINES.lines) - $if mode=vim - "\C-e": history-search-backward - $else - "\C-f": history-search-forward # comment - $endif - LINES - - assert_equal({[6] => :history_search_forward}, additional_key_bindings(:emacs)) - assert_equal({}, additional_key_bindings(:vi_insert)) - assert_equal({}, additional_key_bindings(:vi_command)) - end - - def test_mode_label_differs_from_keymap_label - @config.read_lines(<<~LINES.lines) - # Sets mode_label and keymap_label to vi - set editing-mode vi - # Change keymap_label to emacs. mode_label is still vi. - set keymap emacs - # condition=true because current mode_label is vi - $if mode=vi - # sets keybinding to current keymap_label=emacs - "\C-e": history-search-backward - $endif - LINES - assert_equal({[5] => :history_search_backward}, additional_key_bindings(:emacs)) - assert_equal({}, additional_key_bindings(:vi_insert)) - assert_equal({}, additional_key_bindings(:vi_command)) - end - - def test_if_without_else_condition - @config.read_lines(<<~LINES.lines) - set editing-mode vi - $if mode=vi - "\C-e": history-search-backward - $endif - LINES - - assert_equal({}, additional_key_bindings(:emacs)) - assert_equal({[5] => :history_search_backward}, additional_key_bindings(:vi_insert)) - assert_equal({}, additional_key_bindings(:vi_command)) - end - - def test_default_key_bindings - @config.add_default_key_binding('abcd'.bytes, 'EFGH'.bytes) - @config.read_lines(<<~'LINES'.lines) - "abcd": "ABCD" - "ijkl": "IJKL" - LINES - - expected = { 'abcd'.bytes => 'ABCD'.bytes, 'ijkl'.bytes => 'IJKL'.bytes } - assert_equal expected, registered_key_bindings(expected.keys) - end - - def test_additional_key_bindings - @config.read_lines(<<~'LINES'.lines) - "ef": "EF" - "gh": "GH" - LINES - - expected = { 'ef'.bytes => 'EF'.bytes, 'gh'.bytes => 'GH'.bytes } - assert_equal expected, registered_key_bindings(expected.keys) - end - - def test_unquoted_additional_key_bindings - @config.read_lines(<<~'LINES'.lines) - Meta-a: "Ma" - Control-b: "Cb" - Meta-Control-c: "MCc" - Control-Meta-d: "CMd" - M-C-e: "MCe" - C-M-f: "CMf" - LINES - - expected = { "\ea".bytes => 'Ma'.bytes, "\C-b".bytes => 'Cb'.bytes, "\e\C-c".bytes => 'MCc'.bytes, "\e\C-d".bytes => 'CMd'.bytes, "\e\C-e".bytes => 'MCe'.bytes, "\e\C-f".bytes => 'CMf'.bytes } - assert_equal expected, registered_key_bindings(expected.keys) - end - - def test_additional_key_bindings_with_nesting_and_comment_out - @config.read_lines(<<~'LINES'.lines) - #"ab": "AB" - #"cd": "cd" - "ef": "EF" - "gh": "GH" - LINES - - expected = { 'ef'.bytes => 'EF'.bytes, 'gh'.bytes => 'GH'.bytes } - assert_equal expected, registered_key_bindings(expected.keys) - end - - def test_additional_key_bindings_for_other_keymap - @config.read_lines(<<~'LINES'.lines) - set keymap vi-command - "ab": "AB" - set keymap vi-insert - "cd": "CD" - set keymap emacs - "ef": "EF" - set editing-mode vi # keymap changes to be vi-insert - LINES - - expected = { 'cd'.bytes => 'CD'.bytes } - assert_equal expected, registered_key_bindings(expected.keys) - end - - def test_additional_key_bindings_for_auxiliary_emacs_keymaps - @config.read_lines(<<~'LINES'.lines) - set keymap emacs - "ab": "AB" - set keymap emacs-standard - "cd": "CD" - set keymap emacs-ctlx - "ef": "EF" - set keymap emacs-meta - "gh": "GH" - set editing-mode emacs # keymap changes to be emacs - LINES - - expected = { - 'ab'.bytes => 'AB'.bytes, - 'cd'.bytes => 'CD'.bytes, - "\C-xef".bytes => 'EF'.bytes, - "\egh".bytes => 'GH'.bytes, - } - assert_equal expected, registered_key_bindings(expected.keys) - end - - def test_key_bindings_with_reset - # @config.reset is called after each readline. - # inputrc file is read once, so key binding shouldn't be cleared by @config.reset - @config.add_default_key_binding('default'.bytes, 'DEFAULT'.bytes) - @config.read_lines(<<~'LINES'.lines) - "additional": "ADDITIONAL" - LINES - @config.reset - expected = { 'default'.bytes => 'DEFAULT'.bytes, 'additional'.bytes => 'ADDITIONAL'.bytes } - assert_equal expected, registered_key_bindings(expected.keys) - end - - def test_history_size - @config.read_lines(<<~LINES.lines) - set history-size 5000 - LINES - - assert_equal 5000, get_config_variable(:@history_size) - history = Reline::History.new(@config) - history << "a\n" - assert_equal 1, history.size - end - - def test_empty_inputrc_env - inputrc_backup = ENV['INPUTRC'] - ENV['INPUTRC'] = '' - assert_nothing_raised do - @config.read - end - ensure - ENV['INPUTRC'] = inputrc_backup - end - - def test_inputrc - inputrc_backup = ENV['INPUTRC'] - expected = "#{@tmpdir}/abcde" - ENV['INPUTRC'] = expected - assert_equal expected, @config.inputrc_path - ensure - ENV['INPUTRC'] = inputrc_backup - end - - def test_inputrc_raw_value - @config.read_lines(<<~'LINES'.lines) - set editing-mode vi ignored-string - set vi-ins-mode-string aaa aaa - set vi-cmd-mode-string bbb ccc # comment - LINES - assert_equal :vi_insert, get_config_variable(:@editing_mode_label) - assert_equal 'aaa aaa', @config.vi_ins_mode_string - assert_equal 'bbb ccc # comment', @config.vi_cmd_mode_string - end - - def test_inputrc_with_utf8 - # This file is encoded by UTF-8 so this heredoc string is also UTF-8. - @config.read_lines(<<~'LINES'.lines) - set editing-mode vi - set vi-cmd-mode-string 🍸 - set vi-ins-mode-string 🍶 - LINES - assert_equal '🍸', @config.vi_cmd_mode_string - assert_equal '🍶', @config.vi_ins_mode_string - rescue Reline::ConfigEncodingConversionError - # do nothing - end - - def test_inputrc_with_eucjp - @config.read_lines(<<~"LINES".encode(Encoding::EUC_JP).lines) - set editing-mode vi - set vi-cmd-mode-string ォャッ - set vi-ins-mode-string 能 - LINES - assert_equal 'ォャッ'.encode(Reline.encoding_system_needs), @config.vi_cmd_mode_string - assert_equal '能'.encode(Reline.encoding_system_needs), @config.vi_ins_mode_string - rescue Reline::ConfigEncodingConversionError - # do nothing - end - - def test_empty_inputrc - assert_nothing_raised do - @config.read_lines([]) - end - end - - def test_xdg_config_home - home_backup = ENV['HOME'] - xdg_config_home_backup = ENV['XDG_CONFIG_HOME'] - inputrc_backup = ENV['INPUTRC'] - xdg_config_home = File.expand_path("#{@tmpdir}/.config/example_dir") - expected = File.expand_path("#{xdg_config_home}/readline/inputrc") - FileUtils.mkdir_p(File.dirname(expected)) - FileUtils.touch(expected) - ENV['HOME'] = @tmpdir - ENV['XDG_CONFIG_HOME'] = xdg_config_home - ENV['INPUTRC'] = '' - assert_equal expected, @config.inputrc_path - ensure - FileUtils.rm(expected) - ENV['XDG_CONFIG_HOME'] = xdg_config_home_backup - ENV['HOME'] = home_backup - ENV['INPUTRC'] = inputrc_backup - end - - def test_empty_xdg_config_home - home_backup = ENV['HOME'] - xdg_config_home_backup = ENV['XDG_CONFIG_HOME'] - inputrc_backup = ENV['INPUTRC'] - ENV['HOME'] = @tmpdir - ENV['XDG_CONFIG_HOME'] = '' - ENV['INPUTRC'] = '' - expected = File.expand_path('~/.config/readline/inputrc') - FileUtils.mkdir_p(File.dirname(expected)) - FileUtils.touch(expected) - assert_equal expected, @config.inputrc_path - ensure - FileUtils.rm(expected) - ENV['XDG_CONFIG_HOME'] = xdg_config_home_backup - ENV['HOME'] = home_backup - ENV['INPUTRC'] = inputrc_backup - end - - def test_relative_xdg_config_home - home_backup = ENV['HOME'] - xdg_config_home_backup = ENV['XDG_CONFIG_HOME'] - inputrc_backup = ENV['INPUTRC'] - ENV['HOME'] = @tmpdir - ENV['INPUTRC'] = '' - expected = File.expand_path('~/.config/readline/inputrc') - FileUtils.mkdir_p(File.dirname(expected)) - FileUtils.touch(expected) - result = Dir.chdir(@tmpdir) do - xdg_config_home = ".config/example_dir" - ENV['XDG_CONFIG_HOME'] = xdg_config_home - inputrc = "#{xdg_config_home}/readline/inputrc" - FileUtils.mkdir_p(File.dirname(inputrc)) - FileUtils.touch(inputrc) - @config.inputrc_path - end - assert_equal expected, result - FileUtils.rm(expected) - ENV['XDG_CONFIG_HOME'] = xdg_config_home_backup - ENV['HOME'] = home_backup - ENV['INPUTRC'] = inputrc_backup - end - - def test_reload - inputrc = "#{@tmpdir}/inputrc" - ENV['INPUTRC'] = inputrc - - File.write(inputrc, "set emacs-mode-string !") - @config.read - assert_equal '!', @config.emacs_mode_string - - File.write(inputrc, "set emacs-mode-string ?") - @config.reload - assert_equal '?', @config.emacs_mode_string - - File.write(inputrc, "") - @config.reload - assert_equal '@', @config.emacs_mode_string - end -end diff --git a/test/reline/test_face.rb b/test/reline/test_face.rb deleted file mode 100644 index 8fa2be8fa4..0000000000 --- a/test/reline/test_face.rb +++ /dev/null @@ -1,257 +0,0 @@ -# frozen_string_literal: true - -require_relative 'helper' - -class Reline::Face::Test < Reline::TestCase - RESET_SGR = "\e[0m" - - def setup - @colorterm_backup = ENV['COLORTERM'] - ENV['COLORTERM'] = 'truecolor' - end - - def teardown - Reline::Face.reset_to_initial_configs - ENV['COLORTERM'] = @colorterm_backup - end - - class WithInsufficientSetupTest < self - def setup - super - Reline::Face.config(:my_insufficient_config) do |face| - end - @face = Reline::Face[:my_insufficient_config] - end - - def test_my_insufficient_config_line - assert_equal RESET_SGR, @face[:default] - assert_equal RESET_SGR, @face[:enhanced] - assert_equal RESET_SGR, @face[:scrollbar] - end - - def test_my_insufficient_configs - my_configs = Reline::Face.configs[:my_insufficient_config] - assert_equal( - { - default: { style: :reset, escape_sequence: RESET_SGR }, - enhanced: { style: :reset, escape_sequence: RESET_SGR }, - scrollbar: { style: :reset, escape_sequence: RESET_SGR } - }, - my_configs - ) - end - end - - class WithSetupTest < self - def setup - super - Reline::Face.config(:my_config) do |face| - face.define :default, foreground: :blue - face.define :enhanced, foreground: "#FF1020", background: :black, style: [:bold, :underlined] - end - Reline::Face.config(:another_config) do |face| - face.define :another_label, foreground: :red - end - @face = Reline::Face[:my_config] - end - - def test_now_there_are_four_configs - assert_equal %i(default completion_dialog my_config another_config), Reline::Face.configs.keys - end - - def test_resetting_config_discards_user_defined_configs - Reline::Face.reset_to_initial_configs - assert_equal %i(default completion_dialog), Reline::Face.configs.keys - end - - def test_my_configs - my_configs = Reline::Face.configs[:my_config] - assert_equal( - { - default: { - escape_sequence: "#{RESET_SGR}\e[34m", foreground: :blue - }, - enhanced: { - background: :black, - foreground: "#FF1020", - style: [:bold, :underlined], - escape_sequence: "\e[0m\e[38;2;255;16;32;40;1;4m" - }, - scrollbar: { - style: :reset, - escape_sequence: "\e[0m" - } - }, - my_configs - ) - end - - def test_my_config_line - assert_equal "#{RESET_SGR}\e[34m", @face[:default] - end - - def test_my_config_enhanced - assert_equal "#{RESET_SGR}\e[38;2;255;16;32;40;1;4m", @face[:enhanced] - end - - def test_not_respond_to_another_label - assert_equal false, @face.respond_to?(:another_label) - end - end - - class WithoutSetupTest < self - def test_my_config_default - Reline::Face.config(:my_config) do |face| - # do nothing - end - face = Reline::Face[:my_config] - assert_equal RESET_SGR, face[:default] - end - - def test_style_does_not_exist - face = Reline::Face[:default] - assert_raise ArgumentError do - face[:style_does_not_exist] - end - end - - def test_invalid_keyword - assert_raise ArgumentError do - Reline::Face.config(:invalid_config) do |face| - face.define :default, invalid_keyword: :red - end - end - end - - def test_invalid_foreground_name - assert_raise ArgumentError do - Reline::Face.config(:invalid_config) do |face| - face.define :default, foreground: :invalid_name - end - end - end - - def test_invalid_background_name - assert_raise ArgumentError do - Reline::Face.config(:invalid_config) do |face| - face.define :default, background: :invalid_name - end - end - end - - def test_invalid_style_name - assert_raise ArgumentError do - Reline::Face.config(:invalid_config) do |face| - face.define :default, style: :invalid_name - end - end - end - - def test_private_constants - [:SGR_PARAMETER, :Config, :CONFIGS].each do |name| - assert_equal false, Reline::Face.constants.include?(name) - end - end - end - - class ConfigTest < self - def setup - super - @config = Reline::Face.const_get(:Config).new(:my_config) { } - end - - def teardown - super - Reline::Face.instance_variable_set(:@force_truecolor, nil) - end - - def test_rgb? - assert_equal true, @config.send(:rgb_expression?, "#FFFFFF") - end - - def test_invalid_rgb? - assert_equal false, @config.send(:rgb_expression?, "FFFFFF") - assert_equal false, @config.send(:rgb_expression?, "#FFFFF") - end - - def test_format_to_sgr_preserves_order - assert_equal( - "#{RESET_SGR}\e[37;41;1;3m", - @config.send(:format_to_sgr, foreground: :white, background: :red, style: [:bold, :italicized]) - ) - - assert_equal( - "#{RESET_SGR}\e[37;1;3;41m", - @config.send(:format_to_sgr, foreground: :white, style: [:bold, :italicized], background: :red) - ) - end - - def test_format_to_sgr_with_reset - assert_equal( - RESET_SGR, - @config.send(:format_to_sgr, style: :reset) - ) - assert_equal( - "#{RESET_SGR}\e[37;0;41m", - @config.send(:format_to_sgr, foreground: :white, style: :reset, background: :red) - ) - end - - def test_format_to_sgr_with_single_style - assert_equal( - "#{RESET_SGR}\e[37;41;1m", - @config.send(:format_to_sgr, foreground: :white, background: :red, style: :bold) - ) - end - - def test_truecolor - ENV['COLORTERM'] = 'truecolor' - assert_equal true, Reline::Face.truecolor? - ENV['COLORTERM'] = '24bit' - assert_equal true, Reline::Face.truecolor? - ENV['COLORTERM'] = nil - assert_equal false, Reline::Face.truecolor? - Reline::Face.force_truecolor - assert_equal true, Reline::Face.truecolor? - end - - def test_sgr_rgb_truecolor - ENV['COLORTERM'] = 'truecolor' - assert_equal "38;2;255;255;255", @config.send(:sgr_rgb, :foreground, "#ffffff") - assert_equal "48;2;18;52;86", @config.send(:sgr_rgb, :background, "#123456") - end - - def test_sgr_rgb_256color - ENV['COLORTERM'] = nil - assert_equal '38;5;231', @config.send(:sgr_rgb, :foreground, '#ffffff') - assert_equal '48;5;16', @config.send(:sgr_rgb, :background, '#000000') - # Color steps are [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff] - assert_equal '38;5;24', @config.send(:sgr_rgb, :foreground, '#005f87') - assert_equal '38;5;67', @config.send(:sgr_rgb, :foreground, '#5f87af') - assert_equal '48;5;110', @config.send(:sgr_rgb, :background, '#87afd7') - assert_equal '48;5;153', @config.send(:sgr_rgb, :background, '#afd7ff') - # Boundary values are [0x30, 0x73, 0x9b, 0xc3, 0xeb] - assert_equal '38;5;24', @config.send(:sgr_rgb, :foreground, '#2f729a') - assert_equal '38;5;67', @config.send(:sgr_rgb, :foreground, '#30739b') - assert_equal '48;5;110', @config.send(:sgr_rgb, :background, '#9ac2ea') - assert_equal '48;5;153', @config.send(:sgr_rgb, :background, '#9bc3eb') - end - - def test_force_truecolor_reconfigure - ENV['COLORTERM'] = nil - - Reline::Face.config(:my_config) do |face| - face.define :default, foreground: '#005f87' - face.define :enhanced, background: '#afd7ff' - end - - assert_equal "\e[0m\e[38;5;24m", Reline::Face[:my_config][:default] - assert_equal "\e[0m\e[48;5;153m", Reline::Face[:my_config][:enhanced] - - Reline::Face.force_truecolor - - assert_equal "\e[0m\e[38;2;0;95;135m", Reline::Face[:my_config][:default] - assert_equal "\e[0m\e[48;2;175;215;255m", Reline::Face[:my_config][:enhanced] - end - end -end diff --git a/test/reline/test_history.rb b/test/reline/test_history.rb deleted file mode 100644 index ea902b0653..0000000000 --- a/test/reline/test_history.rb +++ /dev/null @@ -1,317 +0,0 @@ -require_relative 'helper' -require "reline/history" - -class Reline::History::Test < Reline::TestCase - def setup - Reline.send(:test_mode) - end - - def teardown - Reline.test_reset - end - - def test_ancestors - assert_equal(Reline::History.ancestors.include?(Array), true) - end - - def test_to_s - history = history_new - expected = "HISTORY" - assert_equal(expected, history.to_s) - end - - def test_get - history, lines = lines = history_new_and_push_history(5) - lines.each_with_index do |s, i| - assert_external_string_equal(s, history[i]) - end - end - - def test_get__negative - history, lines = lines = history_new_and_push_history(5) - (1..5).each do |i| - assert_equal(lines[-i], history[-i]) - end - end - - def test_get__out_of_range - history, _ = history_new_and_push_history(5) - invalid_indexes = [5, 6, 100, -6, -7, -100] - invalid_indexes.each do |i| - assert_raise(IndexError, "i=<#{i}>") do - history[i] - end - end - - invalid_indexes = [100_000_000_000_000_000_000, - -100_000_000_000_000_000_000] - invalid_indexes.each do |i| - assert_raise(RangeError, "i=<#{i}>") do - history[i] - end - end - end - - def test_set - begin - history, _ = history_new_and_push_history(5) - 5.times do |i| - expected = "set: #{i}" - history[i] = expected - assert_external_string_equal(expected, history[i]) - end - rescue NotImplementedError - end - end - - def test_set__out_of_range - history = history_new - assert_raise(IndexError, NotImplementedError, "index=<0>") do - history[0] = "set: 0" - end - - history, _ = history_new_and_push_history(5) - invalid_indexes = [5, 6, 100, -6, -7, -100] - invalid_indexes.each do |i| - assert_raise(IndexError, NotImplementedError, "index=<#{i}>") do - history[i] = "set: #{i}" - end - end - - invalid_indexes = [100_000_000_000_000_000_000, - -100_000_000_000_000_000_000] - invalid_indexes.each do |i| - assert_raise(RangeError, NotImplementedError, "index=<#{i}>") do - history[i] = "set: #{i}" - end - end - end - - def test_push - history = history_new - 5.times do |i| - s = i.to_s - assert_equal(history, history.push(s)) - assert_external_string_equal(s, history[i]) - end - assert_equal(5, history.length) - end - - def test_push__operator - history = history_new - 5.times do |i| - s = i.to_s - assert_equal(history, history << s) - assert_external_string_equal(s, history[i]) - end - assert_equal(5, history.length) - end - - def test_push__plural - history = history_new - assert_equal(history, history.push("0", "1", "2", "3", "4")) - (0..4).each do |i| - assert_external_string_equal(i.to_s, history[i]) - end - assert_equal(5, history.length) - - assert_equal(history, history.push("5", "6", "7", "8", "9")) - (5..9).each do |i| - assert_external_string_equal(i.to_s, history[i]) - end - assert_equal(10, history.length) - end - - def test_pop - history = history_new - begin - assert_equal(nil, history.pop) - - history, lines = lines = history_new_and_push_history(5) - (1..5).each do |i| - assert_external_string_equal(lines[-i], history.pop) - assert_equal(lines.length - i, history.length) - end - - assert_equal(nil, history.pop) - rescue NotImplementedError - end - end - - def test_shift - history = history_new - begin - assert_equal(nil, history.shift) - - history, lines = lines = history_new_and_push_history(5) - (0..4).each do |i| - assert_external_string_equal(lines[i], history.shift) - assert_equal(lines.length - (i + 1), history.length) - end - - assert_equal(nil, history.shift) - rescue NotImplementedError - end - end - - def test_each - history = history_new - e = history.each do |s| - assert(false) # not reachable - end - assert_equal(history, e) - history, lines = lines = history_new_and_push_history(5) - i = 0 - e = history.each do |s| - assert_external_string_equal(history[i], s) - assert_external_string_equal(lines[i], s) - i += 1 - end - assert_equal(history, e) - end - - def test_each__enumerator - history = history_new - e = history.each - assert_instance_of(Enumerator, e) - end - - def test_length - history = history_new - assert_equal(0, history.length) - push_history(history, 1) - assert_equal(1, history.length) - push_history(history, 4) - assert_equal(5, history.length) - history.clear - assert_equal(0, history.length) - end - - def test_empty_p - history = history_new - 2.times do - assert(history.empty?) - history.push("s") - assert_equal(false, history.empty?) - history.clear - assert(history.empty?) - end - end - - def test_delete_at - begin - history, lines = lines = history_new_and_push_history(5) - (0..4).each do |i| - assert_external_string_equal(lines[i], history.delete_at(0)) - end - assert(history.empty?) - - history, lines = lines = history_new_and_push_history(5) - (1..5).each do |i| - assert_external_string_equal(lines[lines.length - i], history.delete_at(-1)) - end - assert(history.empty?) - - history, lines = lines = history_new_and_push_history(5) - assert_external_string_equal(lines[0], history.delete_at(0)) - assert_external_string_equal(lines[4], history.delete_at(3)) - assert_external_string_equal(lines[1], history.delete_at(0)) - assert_external_string_equal(lines[3], history.delete_at(1)) - assert_external_string_equal(lines[2], history.delete_at(0)) - assert(history.empty?) - rescue NotImplementedError - end - end - - def test_delete_at__out_of_range - history = history_new - assert_raise(IndexError, NotImplementedError, "index=<0>") do - history.delete_at(0) - end - - history, _ = history_new_and_push_history(5) - invalid_indexes = [5, 6, 100, -6, -7, -100] - invalid_indexes.each do |i| - assert_raise(IndexError, NotImplementedError, "index=<#{i}>") do - history.delete_at(i) - end - end - - invalid_indexes = [100_000_000_000_000_000_000, - -100_000_000_000_000_000_000] - invalid_indexes.each do |i| - assert_raise(RangeError, NotImplementedError, "index=<#{i}>") do - history.delete_at(i) - end - end - end - - def test_history_size_zero - history = history_new(history_size: 0) - assert_equal 0, history.size - history << 'aa' - history << 'bb' - assert_equal 0, history.size - history.push(*%w{aa bb cc}) - assert_equal 0, history.size - end - - def test_history_size_negative_unlimited - history = history_new(history_size: -1) - assert_equal 0, history.size - history << 'aa' - history << 'bb' - assert_equal 2, history.size - history.push(*%w{aa bb cc}) - assert_equal 5, history.size - end - - def test_history_encoding_conversion - history = history_new - text1 = String.new("a\u{65535}b\xFFc", encoding: Encoding::UTF_8) - text2 = String.new("d\xFFe", encoding: Encoding::Shift_JIS) - history.push(text1.dup, text2.dup) - expected = [text1, text2].map { |s| s.encode(Reline.encoding_system_needs, invalid: :replace, undef: :replace) } - assert_equal(expected, history.to_a) - end - - private - - def history_new(history_size: 10) - Reline::History.new(Struct.new(:history_size).new(history_size)) - end - - def push_history(history, num) - lines = [] - num.times do |i| - s = "a" - i.times do - s = s.succ - end - lines.push("#{i + 1}:#{s}") - end - history.push(*lines) - return history, lines - end - - def history_new_and_push_history(num) - history = history_new(history_size: 100) - return push_history(history, num) - end - - def assert_external_string_equal(expected, actual) - assert_equal(expected, actual) - mes = "Encoding of #{actual.inspect} is expected #{get_default_internal_encoding.inspect} but #{actual.encoding}" - assert_equal(get_default_internal_encoding, actual.encoding, mes) - end - - def get_default_internal_encoding - if encoding = Reline.core.encoding - encoding - elsif RUBY_PLATFORM =~ /mswin|mingw/ - Encoding.default_internal || Encoding::UTF_8 - else - Encoding.default_internal || Encoding.find("locale") - end - end -end diff --git a/test/reline/test_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb deleted file mode 100644 index 78b4c936b9..0000000000 --- a/test/reline/test_key_actor_emacs.rb +++ /dev/null @@ -1,1743 +0,0 @@ -require_relative 'helper' - -class Reline::KeyActor::EmacsTest < Reline::TestCase - def setup - Reline.send(:test_mode) - @prompt = '> ' - @config = Reline::Config.new # Emacs mode is default - @config.autocompletion = false - Reline::HISTORY.instance_variable_set(:@config, @config) - Reline::HISTORY.clear - @encoding = Reline.core.encoding - @line_editor = Reline::LineEditor.new(@config) - @line_editor.reset(@prompt) - end - - def teardown - Reline.test_reset - end - - def test_ed_insert_one - input_keys('a') - assert_line_around_cursor('a', '') - end - - def test_ed_insert_two - input_keys('ab') - assert_line_around_cursor('ab', '') - end - - def test_ed_insert_mbchar_one - input_keys('か') - assert_line_around_cursor('か', '') - end - - def test_ed_insert_mbchar_two - input_keys('かき') - assert_line_around_cursor('かき', '') - end - - def test_ed_insert_for_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("か\u3099") - assert_line_around_cursor("か\u3099", '') - end - - def test_ed_insert_for_plural_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("か\u3099き\u3099") - assert_line_around_cursor("か\u3099き\u3099", '') - end - - def test_move_next_and_prev - input_keys('abd') - assert_line_around_cursor('abd', '') - input_keys("\C-b") - assert_line_around_cursor('ab', 'd') - input_keys("\C-b") - assert_line_around_cursor('a', 'bd') - input_keys("\C-f") - assert_line_around_cursor('ab', 'd') - input_keys('c') - assert_line_around_cursor('abc', 'd') - end - - def test_move_next_and_prev_for_mbchar - input_keys('かきけ') - assert_line_around_cursor('かきけ', '') - input_keys("\C-b") - assert_line_around_cursor('かき', 'け') - input_keys("\C-b") - assert_line_around_cursor('か', 'きけ') - input_keys("\C-f") - assert_line_around_cursor('かき', 'け') - input_keys('く') - assert_line_around_cursor('かきく', 'け') - end - - def test_move_next_and_prev_for_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("か\u3099き\u3099け\u3099") - assert_line_around_cursor("か\u3099き\u3099け\u3099", '') - input_keys("\C-b") - assert_line_around_cursor("か\u3099き\u3099", "け\u3099") - input_keys("\C-b") - assert_line_around_cursor("か\u3099", "き\u3099け\u3099") - input_keys("\C-f") - assert_line_around_cursor("か\u3099き\u3099", "け\u3099") - input_keys("く\u3099") - assert_line_around_cursor("か\u3099き\u3099く\u3099", "け\u3099") - end - - def test_move_to_beg_end - input_keys('bcd') - assert_line_around_cursor('bcd', '') - input_keys("\C-a") - assert_line_around_cursor('', 'bcd') - input_keys('a') - assert_line_around_cursor('a', 'bcd') - input_keys("\C-e") - assert_line_around_cursor('abcd', '') - input_keys('e') - assert_line_around_cursor('abcde', '') - end - - def test_ed_newline_with_cr - input_keys('ab') - assert_line_around_cursor('ab', '') - refute(@line_editor.finished?) - input_keys("\C-m") - assert_line_around_cursor('ab', '') - assert(@line_editor.finished?) - end - - def test_ed_newline_with_lf - input_keys('ab') - assert_line_around_cursor('ab', '') - refute(@line_editor.finished?) - input_keys("\C-j") - assert_line_around_cursor('ab', '') - assert(@line_editor.finished?) - end - - def test_em_delete_prev_char - input_keys('ab') - assert_line_around_cursor('ab', '') - input_keys("\C-h") - assert_line_around_cursor('a', '') - end - - def test_em_delete_prev_char_for_mbchar - input_keys('かき') - assert_line_around_cursor('かき', '') - input_keys("\C-h") - assert_line_around_cursor('か', '') - end - - def test_em_delete_prev_char_for_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("か\u3099き\u3099") - assert_line_around_cursor("か\u3099き\u3099", '') - input_keys("\C-h") - assert_line_around_cursor("か\u3099", '') - end - - def test_bracketed_paste_insert - set_line_around_cursor('A', 'Z') - input_key_by_symbol(:insert_multiline_text, char: "abc\n\C-abc") - assert_whole_lines(['Aabc', "\C-abcZ"]) - assert_line_around_cursor("\C-abc", 'Z') - end - - def test_ed_quoted_insert - set_line_around_cursor('A', 'Z') - input_key_by_symbol(:insert_raw_char, char: "\C-a") - assert_line_around_cursor("A\C-a", 'Z') - end - - def test_ed_quoted_insert_with_vi_arg - input_keys("a\C-[3") - input_key_by_symbol(:insert_raw_char, char: "\C-a") - input_keys("b\C-[4") - input_key_by_symbol(:insert_raw_char, char: '1') - assert_line_around_cursor("a\C-a\C-a\C-ab1111", '') - end - - def test_ed_kill_line - input_keys("\C-k") - assert_line_around_cursor('', '') - input_keys('abc') - assert_line_around_cursor('abc', '') - input_keys("\C-k") - assert_line_around_cursor('abc', '') - input_keys("\C-b\C-k") - assert_line_around_cursor('ab', '') - end - - def test_em_kill_line - input_key_by_symbol(:em_kill_line) - assert_line_around_cursor('', '') - input_keys('abc') - input_key_by_symbol(:em_kill_line) - assert_line_around_cursor('', '') - input_keys('abc') - input_keys("\C-b") - input_key_by_symbol(:em_kill_line) - assert_line_around_cursor('', '') - input_keys('abc') - input_keys("\C-a") - input_key_by_symbol(:em_kill_line) - assert_line_around_cursor('', '') - end - - def test_ed_move_to_beg - input_keys('abd') - assert_line_around_cursor('abd', '') - input_keys("\C-b") - assert_line_around_cursor('ab', 'd') - input_keys('c') - assert_line_around_cursor('abc', 'd') - input_keys("\C-a") - assert_line_around_cursor('', 'abcd') - input_keys('012') - assert_line_around_cursor('012', 'abcd') - input_keys("\C-a") - assert_line_around_cursor('', '012abcd') - input_keys('ABC') - assert_line_around_cursor('ABC', '012abcd') - input_keys("\C-f" * 10 + "\C-a") - assert_line_around_cursor('', 'ABC012abcd') - input_keys('a') - assert_line_around_cursor('a', 'ABC012abcd') - end - - def test_ed_move_to_beg_with_blank - input_keys(' abc') - assert_line_around_cursor(' abc', '') - input_keys("\C-a") - assert_line_around_cursor('', ' abc') - end - - def test_ed_move_to_end - input_keys('abd') - assert_line_around_cursor('abd', '') - input_keys("\C-b") - assert_line_around_cursor('ab', 'd') - input_keys('c') - assert_line_around_cursor('abc', 'd') - input_keys("\C-e") - assert_line_around_cursor('abcd', '') - input_keys('012') - assert_line_around_cursor('abcd012', '') - input_keys("\C-e") - assert_line_around_cursor('abcd012', '') - input_keys('ABC') - assert_line_around_cursor('abcd012ABC', '') - input_keys("\C-b" * 10 + "\C-e") - assert_line_around_cursor('abcd012ABC', '') - input_keys('a') - assert_line_around_cursor('abcd012ABCa', '') - end - - def test_em_delete - input_keys('ab') - assert_line_around_cursor('ab', '') - input_keys("\C-a") - assert_line_around_cursor('', 'ab') - input_keys("\C-d") - assert_line_around_cursor('', 'b') - end - - def test_em_delete_for_mbchar - input_keys('かき') - assert_line_around_cursor('かき', '') - input_keys("\C-a") - assert_line_around_cursor('', 'かき') - input_keys("\C-d") - assert_line_around_cursor('', 'き') - end - - def test_em_delete_for_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("か\u3099き\u3099") - assert_line_around_cursor("か\u3099き\u3099", '') - input_keys("\C-a") - assert_line_around_cursor('', "か\u3099き\u3099") - input_keys("\C-d") - assert_line_around_cursor('', "き\u3099") - end - - def test_em_delete_ends_editing - input_keys("\C-d") # quit from inputing - assert_nil(@line_editor.line) - assert(@line_editor.finished?) - end - - def test_ed_clear_screen - @line_editor.instance_variable_get(:@rendered_screen).lines = [[]] - input_keys("\C-l") - assert_empty(@line_editor.instance_variable_get(:@rendered_screen).lines) - end - - def test_ed_clear_screen_with_inputted - input_keys('abc') - input_keys("\C-b") - @line_editor.instance_variable_get(:@rendered_screen).lines = [[]] - assert_line_around_cursor('ab', 'c') - input_keys("\C-l") - assert_empty(@line_editor.instance_variable_get(:@rendered_screen).lines) - assert_line_around_cursor('ab', 'c') - end - - def test_key_delete - input_keys('abc') - assert_line_around_cursor('abc', '') - input_key_by_symbol(:key_delete) - assert_line_around_cursor('abc', '') - end - - def test_key_delete_does_not_end_editing - input_key_by_symbol(:key_delete) - assert_line_around_cursor('', '') - refute(@line_editor.finished?) - end - - def test_key_delete_preserves_cursor - input_keys('abc') - input_keys("\C-b") - assert_line_around_cursor('ab', 'c') - input_key_by_symbol(:key_delete) - assert_line_around_cursor('ab', '') - end - - def test_em_next_word - assert_line_around_cursor('', '') - input_keys('abc def{bbb}ccc') - input_keys("\C-a\eF") - assert_line_around_cursor('abc', ' def{bbb}ccc') - input_keys("\eF") - assert_line_around_cursor('abc def', '{bbb}ccc') - input_keys("\eF") - assert_line_around_cursor('abc def{bbb', '}ccc') - input_keys("\eF") - assert_line_around_cursor('abc def{bbb}ccc', '') - input_keys("\eF") - assert_line_around_cursor('abc def{bbb}ccc', '') - end - - def test_em_next_word_for_mbchar - assert_line_around_cursor('', '') - input_keys('あいう かきく{さしす}たちつ') - input_keys("\C-a\eF") - assert_line_around_cursor('あいう', ' かきく{さしす}たちつ') - input_keys("\eF") - assert_line_around_cursor('あいう かきく', '{さしす}たちつ') - input_keys("\eF") - assert_line_around_cursor('あいう かきく{さしす', '}たちつ') - input_keys("\eF") - assert_line_around_cursor('あいう かきく{さしす}たちつ', '') - input_keys("\eF") - assert_line_around_cursor('あいう かきく{さしす}たちつ', '') - end - - def test_em_next_word_for_mbchar_by_plural_code_points - omit_unless_utf8 - assert_line_around_cursor("", "") - input_keys("あいう か\u3099き\u3099く\u3099{さしす}たちつ") - input_keys("\C-a\eF") - assert_line_around_cursor("あいう", " か\u3099き\u3099く\u3099{さしす}たちつ") - input_keys("\eF") - assert_line_around_cursor("あいう か\u3099き\u3099く\u3099", "{さしす}たちつ") - input_keys("\eF") - assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす", "}たちつ") - input_keys("\eF") - assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす}たちつ", "") - input_keys("\eF") - assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす}たちつ", "") - end - - def test_em_prev_word - input_keys('abc def{bbb}ccc') - assert_line_around_cursor('abc def{bbb}ccc', '') - input_keys("\eB") - assert_line_around_cursor('abc def{bbb}', 'ccc') - input_keys("\eB") - assert_line_around_cursor('abc def{', 'bbb}ccc') - input_keys("\eB") - assert_line_around_cursor('abc ', 'def{bbb}ccc') - input_keys("\eB") - assert_line_around_cursor('', 'abc def{bbb}ccc') - input_keys("\eB") - assert_line_around_cursor('', 'abc def{bbb}ccc') - end - - def test_em_prev_word_for_mbchar - input_keys('あいう かきく{さしす}たちつ') - assert_line_around_cursor('あいう かきく{さしす}たちつ', '') - input_keys("\eB") - assert_line_around_cursor('あいう かきく{さしす}', 'たちつ') - input_keys("\eB") - assert_line_around_cursor('あいう かきく{', 'さしす}たちつ') - input_keys("\eB") - assert_line_around_cursor('あいう ', 'かきく{さしす}たちつ') - input_keys("\eB") - assert_line_around_cursor('', 'あいう かきく{さしす}たちつ') - input_keys("\eB") - assert_line_around_cursor('', 'あいう かきく{さしす}たちつ') - end - - def test_em_prev_word_for_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("あいう か\u3099き\u3099く\u3099{さしす}たちつ") - assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす}たちつ", "") - input_keys("\eB") - assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす}", "たちつ") - input_keys("\eB") - assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{", "さしす}たちつ") - input_keys("\eB") - assert_line_around_cursor("あいう ", "か\u3099き\u3099く\u3099{さしす}たちつ") - input_keys("\eB") - assert_line_around_cursor("", "あいう か\u3099き\u3099く\u3099{さしす}たちつ") - input_keys("\eB") - assert_line_around_cursor("", "あいう か\u3099き\u3099く\u3099{さしす}たちつ") - end - - def test_em_delete_next_word - input_keys('abc def{bbb}ccc') - input_keys("\C-a") - assert_line_around_cursor('', 'abc def{bbb}ccc') - input_keys("\ed") - assert_line_around_cursor('', ' def{bbb}ccc') - input_keys("\ed") - assert_line_around_cursor('', '{bbb}ccc') - input_keys("\ed") - assert_line_around_cursor('', '}ccc') - input_keys("\ed") - assert_line_around_cursor('', '') - end - - def test_em_delete_next_word_for_mbchar - input_keys('あいう かきく{さしす}たちつ') - input_keys("\C-a") - assert_line_around_cursor('', 'あいう かきく{さしす}たちつ') - input_keys("\ed") - assert_line_around_cursor('', ' かきく{さしす}たちつ') - input_keys("\ed") - assert_line_around_cursor('', '{さしす}たちつ') - input_keys("\ed") - assert_line_around_cursor('', '}たちつ') - input_keys("\ed") - assert_line_around_cursor('', '') - end - - def test_em_delete_next_word_for_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("あいう か\u3099き\u3099く\u3099{さしす}たちつ") - input_keys("\C-a") - assert_line_around_cursor('', "あいう か\u3099き\u3099く\u3099{さしす}たちつ") - input_keys("\ed") - assert_line_around_cursor('', " か\u3099き\u3099く\u3099{さしす}たちつ") - input_keys("\ed") - assert_line_around_cursor('', '{さしす}たちつ') - input_keys("\ed") - assert_line_around_cursor('', '}たちつ') - input_keys("\ed") - assert_line_around_cursor('', '') - end - - def test_ed_delete_prev_word - input_keys('abc def{bbb}ccc') - assert_line_around_cursor('abc def{bbb}ccc', '') - input_keys("\e\C-H") - assert_line_around_cursor('abc def{bbb}', '') - input_keys("\e\C-H") - assert_line_around_cursor('abc def{', '') - input_keys("\e\C-H") - assert_line_around_cursor('abc ', '') - input_keys("\e\C-H") - assert_line_around_cursor('', '') - end - - def test_ed_delete_prev_word_for_mbchar - input_keys('あいう かきく{さしす}たちつ') - assert_line_around_cursor('あいう かきく{さしす}たちつ', '') - input_keys("\e\C-H") - assert_line_around_cursor('あいう かきく{さしす}', '') - input_keys("\e\C-H") - assert_line_around_cursor('あいう かきく{', '') - input_keys("\e\C-H") - assert_line_around_cursor('あいう ', '') - input_keys("\e\C-H") - assert_line_around_cursor('', '') - end - - def test_ed_delete_prev_word_for_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("あいう か\u3099き\u3099く\u3099{さしす}たちつ") - assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす}たちつ", '') - input_keys("\e\C-H") - assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす}", '') - input_keys("\e\C-H") - assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{", '') - input_keys("\e\C-H") - assert_line_around_cursor('あいう ', '') - input_keys("\e\C-H") - assert_line_around_cursor('', '') - end - - def test_ed_transpose_chars - input_keys('abc') - input_keys("\C-a") - assert_line_around_cursor('', 'abc') - input_keys("\C-t") - assert_line_around_cursor('', 'abc') - input_keys("\C-f\C-t") - assert_line_around_cursor('ba', 'c') - input_keys("\C-t") - assert_line_around_cursor('bca', '') - input_keys("\C-t") - assert_line_around_cursor('bac', '') - end - - def test_ed_transpose_chars_for_mbchar - input_keys('あかさ') - input_keys("\C-a") - assert_line_around_cursor('', 'あかさ') - input_keys("\C-t") - assert_line_around_cursor('', 'あかさ') - input_keys("\C-f\C-t") - assert_line_around_cursor('かあ', 'さ') - input_keys("\C-t") - assert_line_around_cursor('かさあ', '') - input_keys("\C-t") - assert_line_around_cursor('かあさ', '') - end - - def test_ed_transpose_chars_for_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("あか\u3099さ") - input_keys("\C-a") - assert_line_around_cursor('', "あか\u3099さ") - input_keys("\C-t") - assert_line_around_cursor('', "あか\u3099さ") - input_keys("\C-f\C-t") - assert_line_around_cursor("か\u3099あ", 'さ') - input_keys("\C-t") - assert_line_around_cursor("か\u3099さあ", '') - input_keys("\C-t") - assert_line_around_cursor("か\u3099あさ", '') - end - - def test_ed_transpose_words - input_keys('abc def') - assert_line_around_cursor('abc def', '') - input_keys("\et") - assert_line_around_cursor('def abc', '') - input_keys("\C-a\C-k") - input_keys(' abc def ') - input_keys("\C-b" * 4) - assert_line_around_cursor(' abc de', 'f ') - input_keys("\et") - assert_line_around_cursor(' def abc', ' ') - input_keys("\C-a\C-k") - input_keys(' abc def ') - input_keys("\C-b" * 6) - assert_line_around_cursor(' abc ', 'def ') - input_keys("\et") - assert_line_around_cursor(' def abc', ' ') - input_keys("\et") - assert_line_around_cursor(' abc def', '') - end - - def test_ed_transpose_words_for_mbchar - input_keys('あいう かきく') - assert_line_around_cursor('あいう かきく', '') - input_keys("\et") - assert_line_around_cursor('かきく あいう', '') - input_keys("\C-a\C-k") - input_keys(' あいう かきく ') - input_keys("\C-b" * 4) - assert_line_around_cursor(' あいう かき', 'く ') - input_keys("\et") - assert_line_around_cursor(' かきく あいう', ' ') - input_keys("\C-a\C-k") - input_keys(' あいう かきく ') - input_keys("\C-b" * 6) - assert_line_around_cursor(' あいう ', 'かきく ') - input_keys("\et") - assert_line_around_cursor(' かきく あいう', ' ') - input_keys("\et") - assert_line_around_cursor(' あいう かきく', '') - end - - def test_ed_transpose_words_with_one_word - input_keys('abc ') - assert_line_around_cursor('abc ', '') - input_keys("\et") - assert_line_around_cursor('abc ', '') - input_keys("\C-b") - assert_line_around_cursor('abc ', ' ') - input_keys("\et") - assert_line_around_cursor('abc ', ' ') - input_keys("\C-b" * 2) - assert_line_around_cursor('ab', 'c ') - input_keys("\et") - assert_line_around_cursor('ab', 'c ') - input_keys("\et") - assert_line_around_cursor('ab', 'c ') - end - - def test_ed_transpose_words_with_one_word_for_mbchar - input_keys('あいう ') - assert_line_around_cursor('あいう ', '') - input_keys("\et") - assert_line_around_cursor('あいう ', '') - input_keys("\C-b") - assert_line_around_cursor('あいう ', ' ') - input_keys("\et") - assert_line_around_cursor('あいう ', ' ') - input_keys("\C-b" * 2) - assert_line_around_cursor('あい', 'う ') - input_keys("\et") - assert_line_around_cursor('あい', 'う ') - input_keys("\et") - assert_line_around_cursor('あい', 'う ') - end - - def test_ed_digit - input_keys('0123') - assert_line_around_cursor('0123', '') - end - - def test_ed_next_and_prev_char - input_keys('abc') - assert_line_around_cursor('abc', '') - input_keys("\C-b") - assert_line_around_cursor('ab', 'c') - input_keys("\C-b") - assert_line_around_cursor('a', 'bc') - input_keys("\C-b") - assert_line_around_cursor('', 'abc') - input_keys("\C-b") - assert_line_around_cursor('', 'abc') - input_keys("\C-f") - assert_line_around_cursor('a', 'bc') - input_keys("\C-f") - assert_line_around_cursor('ab', 'c') - input_keys("\C-f") - assert_line_around_cursor('abc', '') - input_keys("\C-f") - assert_line_around_cursor('abc', '') - end - - def test_ed_next_and_prev_char_for_mbchar - input_keys('あいう') - assert_line_around_cursor('あいう', '') - input_keys("\C-b") - assert_line_around_cursor('あい', 'う') - input_keys("\C-b") - assert_line_around_cursor('あ', 'いう') - input_keys("\C-b") - assert_line_around_cursor('', 'あいう') - input_keys("\C-b") - assert_line_around_cursor('', 'あいう') - input_keys("\C-f") - assert_line_around_cursor('あ', 'いう') - input_keys("\C-f") - assert_line_around_cursor('あい', 'う') - input_keys("\C-f") - assert_line_around_cursor('あいう', '') - input_keys("\C-f") - assert_line_around_cursor('あいう', '') - end - - def test_ed_next_and_prev_char_for_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("か\u3099き\u3099く\u3099") - assert_line_around_cursor("か\u3099き\u3099く\u3099", '') - input_keys("\C-b") - assert_line_around_cursor("か\u3099き\u3099", "く\u3099") - input_keys("\C-b") - assert_line_around_cursor("か\u3099", "き\u3099く\u3099") - input_keys("\C-b") - assert_line_around_cursor('', "か\u3099き\u3099く\u3099") - input_keys("\C-b") - assert_line_around_cursor('', "か\u3099き\u3099く\u3099") - input_keys("\C-f") - assert_line_around_cursor("か\u3099", "き\u3099く\u3099") - input_keys("\C-f") - assert_line_around_cursor("か\u3099き\u3099", "く\u3099") - input_keys("\C-f") - assert_line_around_cursor("か\u3099き\u3099く\u3099", '') - input_keys("\C-f") - assert_line_around_cursor("か\u3099き\u3099く\u3099", '') - end - - def test_em_capitol_case - input_keys('abc def{bbb}ccc') - input_keys("\C-a\ec") - assert_line_around_cursor('Abc', ' def{bbb}ccc') - input_keys("\ec") - assert_line_around_cursor('Abc Def', '{bbb}ccc') - input_keys("\ec") - assert_line_around_cursor('Abc Def{Bbb', '}ccc') - input_keys("\ec") - assert_line_around_cursor('Abc Def{Bbb}Ccc', '') - end - - def test_em_capitol_case_with_complex_example - input_keys('{}#* AaA!!!cCc ') - input_keys("\C-a\ec") - assert_line_around_cursor('{}#* Aaa', '!!!cCc ') - input_keys("\ec") - assert_line_around_cursor('{}#* Aaa!!!Ccc', ' ') - input_keys("\ec") - assert_line_around_cursor('{}#* Aaa!!!Ccc ', '') - end - - def test_em_lower_case - input_keys('AbC def{bBb}CCC') - input_keys("\C-a\el") - assert_line_around_cursor('abc', ' def{bBb}CCC') - input_keys("\el") - assert_line_around_cursor('abc def', '{bBb}CCC') - input_keys("\el") - assert_line_around_cursor('abc def{bbb', '}CCC') - input_keys("\el") - assert_line_around_cursor('abc def{bbb}ccc', '') - end - - def test_em_lower_case_with_complex_example - input_keys('{}#* AaA!!!cCc ') - input_keys("\C-a\el") - assert_line_around_cursor('{}#* aaa', '!!!cCc ') - input_keys("\el") - assert_line_around_cursor('{}#* aaa!!!ccc', ' ') - input_keys("\el") - assert_line_around_cursor('{}#* aaa!!!ccc ', '') - end - - def test_em_upper_case - input_keys('AbC def{bBb}CCC') - input_keys("\C-a\eu") - assert_line_around_cursor('ABC', ' def{bBb}CCC') - input_keys("\eu") - assert_line_around_cursor('ABC DEF', '{bBb}CCC') - input_keys("\eu") - assert_line_around_cursor('ABC DEF{BBB', '}CCC') - input_keys("\eu") - assert_line_around_cursor('ABC DEF{BBB}CCC', '') - end - - def test_em_upper_case_with_complex_example - input_keys('{}#* AaA!!!cCc ') - input_keys("\C-a\eu") - assert_line_around_cursor('{}#* AAA', '!!!cCc ') - input_keys("\eu") - assert_line_around_cursor('{}#* AAA!!!CCC', ' ') - input_keys("\eu") - assert_line_around_cursor('{}#* AAA!!!CCC ', '') - end - - def test_em_delete_or_list - @line_editor.completion_proc = proc { |word| - %w{ - foo_foo - foo_bar - foo_baz - qux - }.map { |i| - i.encode(@encoding) - } - } - input_keys('fooo') - assert_line_around_cursor('fooo', '') - assert_equal(nil, @line_editor.instance_variable_get(:@menu_info)) - input_keys("\C-b") - assert_line_around_cursor('foo', 'o') - assert_equal(nil, @line_editor.instance_variable_get(:@menu_info)) - input_key_by_symbol(:em_delete_or_list) - assert_line_around_cursor('foo', '') - assert_equal(nil, @line_editor.instance_variable_get(:@menu_info)) - input_key_by_symbol(:em_delete_or_list) - assert_line_around_cursor('foo', '') - assert_equal(%w{foo_foo foo_bar foo_baz}, @line_editor.instance_variable_get(:@menu_info).list) - end - - def test_completion_duplicated_list - @line_editor.completion_proc = proc { |word| - %w{ - foo_foo - foo_foo - foo_bar - }.map { |i| - i.encode(@encoding) - } - } - input_keys('foo_') - assert_line_around_cursor('foo_', '') - assert_equal(nil, @line_editor.instance_variable_get(:@menu_info)) - input_keys("\C-i") - assert_line_around_cursor('foo_', '') - assert_equal(nil, @line_editor.instance_variable_get(:@menu_info)) - input_keys("\C-i") - assert_line_around_cursor('foo_', '') - assert_equal(%w{foo_foo foo_bar}, @line_editor.instance_variable_get(:@menu_info).list) - end - - def test_completion - @line_editor.completion_proc = proc { |word| - %w{ - foo_foo - foo_bar - foo_baz - qux - }.map { |i| - i.encode(@encoding) - } - } - input_keys('fo') - assert_line_around_cursor('fo', '') - assert_equal(nil, @line_editor.instance_variable_get(:@menu_info)) - input_keys("\C-i") - assert_line_around_cursor('foo_', '') - assert_equal(nil, @line_editor.instance_variable_get(:@menu_info)) - input_keys("\C-i") - assert_line_around_cursor('foo_', '') - assert_equal(%w{foo_foo foo_bar foo_baz}, @line_editor.instance_variable_get(:@menu_info).list) - input_keys('a') - input_keys("\C-i") - assert_line_around_cursor('foo_a', '') - input_keys("\C-h") - input_keys('b') - input_keys("\C-i") - assert_line_around_cursor('foo_ba', '') - input_keys("\C-h") - input_key_by_symbol(:complete) - assert_line_around_cursor('foo_ba', '') - input_keys("\C-h") - input_key_by_symbol(:menu_complete) - assert_line_around_cursor('foo_bar', '') - input_key_by_symbol(:menu_complete) - assert_line_around_cursor('foo_baz', '') - input_keys("\C-h") - input_key_by_symbol(:menu_complete_backward) - assert_line_around_cursor('foo_baz', '') - input_key_by_symbol(:menu_complete_backward) - assert_line_around_cursor('foo_bar', '') - end - - def test_autocompletion - @config.autocompletion = true - @line_editor.completion_proc = proc { |word| - %w{ - Readline - Regexp - RegexpError - }.map { |i| - i.encode(@encoding) - } - } - input_keys('Re') - assert_line_around_cursor('Re', '') - input_keys("\C-i") - assert_line_around_cursor('Readline', '') - input_keys("\C-i") - assert_line_around_cursor('Regexp', '') - input_key_by_symbol(:completion_journey_up) - assert_line_around_cursor('Readline', '') - input_key_by_symbol(:complete) - assert_line_around_cursor('Regexp', '') - input_key_by_symbol(:menu_complete_backward) - assert_line_around_cursor('Readline', '') - input_key_by_symbol(:menu_complete) - assert_line_around_cursor('Regexp', '') - ensure - @config.autocompletion = false - end - - def test_completion_with_indent - @line_editor.completion_proc = proc { |word| - %w{ - foo_foo - foo_bar - foo_baz - qux - }.map { |i| - i.encode(@encoding) - } - } - input_keys(' fo') - assert_line_around_cursor(' fo', '') - assert_equal(nil, @line_editor.instance_variable_get(:@menu_info)) - input_keys("\C-i") - assert_line_around_cursor(' foo_', '') - assert_equal(nil, @line_editor.instance_variable_get(:@menu_info)) - input_keys("\C-i") - assert_line_around_cursor(' foo_', '') - assert_equal(%w{foo_foo foo_bar foo_baz}, @line_editor.instance_variable_get(:@menu_info).list) - end - - def test_completion_with_perfect_match - @line_editor.completion_proc = proc { |word| - %w{ - foo - foo_bar - }.map { |i| - i.encode(@encoding) - } - } - matched = nil - @line_editor.dig_perfect_match_proc = proc { |m| - matched = m - } - input_keys('fo') - assert_line_around_cursor('fo', '') - assert_equal(Reline::LineEditor::CompletionState::NORMAL, @line_editor.instance_variable_get(:@completion_state)) - assert_equal(nil, matched) - input_keys("\C-i") - assert_line_around_cursor('foo', '') - assert_equal(Reline::LineEditor::CompletionState::MENU_WITH_PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state)) - assert_equal(nil, matched) - input_keys("\C-i") - assert_line_around_cursor('foo', '') - assert_equal(Reline::LineEditor::CompletionState::PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state)) - assert_equal(nil, matched) - input_keys("\C-i") - assert_line_around_cursor('foo', '') - assert_equal(Reline::LineEditor::CompletionState::PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state)) - assert_equal('foo', matched) - matched = nil - input_keys('_') - input_keys("\C-i") - assert_line_around_cursor('foo_bar', '') - assert_equal(Reline::LineEditor::CompletionState::PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state)) - assert_equal(nil, matched) - input_keys("\C-i") - assert_line_around_cursor('foo_bar', '') - assert_equal(Reline::LineEditor::CompletionState::PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state)) - assert_equal('foo_bar', matched) - end - - def test_continuous_completion_with_perfect_match - @line_editor.completion_proc = proc { |word| - word == 'f' ? ['foo'] : %w[foobar foobaz] - } - input_keys('f') - input_keys("\C-i") - assert_line_around_cursor('foo', '') - input_keys("\C-i") - assert_line_around_cursor('fooba', '') - end - - def test_continuous_completion_disabled_with_perfect_match - @line_editor.completion_proc = proc { |word| - word == 'f' ? ['foo'] : %w[foobar foobaz] - } - @line_editor.dig_perfect_match_proc = proc {} - input_keys('f') - input_keys("\C-i") - assert_line_around_cursor('foo', '') - input_keys("\C-i") - assert_line_around_cursor('foo', '') - end - - def test_completion_append_character - @line_editor.completion_proc = proc { |word| - %w[foo_ foo_foo foo_bar].select { |s| s.start_with? word } - } - @line_editor.completion_append_character = 'X' - input_keys('f') - input_keys("\C-i") - assert_line_around_cursor('foo_', '') - input_keys('f') - input_keys("\C-i") - assert_line_around_cursor('foo_fooX', '') - input_keys(' foo_bar') - input_keys("\C-i") - assert_line_around_cursor('foo_fooX foo_barX', '') - end - - def test_completion_with_quote_append - @line_editor.completion_proc = proc { |word| - %w[foo bar baz].select { |s| s.start_with? word } - } - set_line_around_cursor('x = "b', '') - input_keys("\C-i") - assert_line_around_cursor('x = "ba', '') - set_line_around_cursor('x = "f', ' ') - input_keys("\C-i") - assert_line_around_cursor('x = "foo', ' ') - set_line_around_cursor("x = 'f", '') - input_keys("\C-i") - assert_line_around_cursor("x = 'foo'", '') - set_line_around_cursor('"a "f', '') - input_keys("\C-i") - assert_line_around_cursor('"a "foo', '') - set_line_around_cursor('"a\\" "f', '') - input_keys("\C-i") - assert_line_around_cursor('"a\\" "foo', '') - set_line_around_cursor('"a" "f', '') - input_keys("\C-i") - assert_line_around_cursor('"a" "foo"', '') - end - - def test_completion_with_completion_ignore_case - @line_editor.completion_proc = proc { |word| - %w{ - foo_foo - foo_bar - Foo_baz - qux - }.map { |i| - i.encode(@encoding) - } - } - input_keys('fo') - assert_line_around_cursor('fo', '') - assert_equal(nil, @line_editor.instance_variable_get(:@menu_info)) - input_keys("\C-i") - assert_line_around_cursor('foo_', '') - assert_equal(nil, @line_editor.instance_variable_get(:@menu_info)) - input_keys("\C-i") - assert_line_around_cursor('foo_', '') - assert_equal(%w{foo_foo foo_bar}, @line_editor.instance_variable_get(:@menu_info).list) - @config.completion_ignore_case = true - input_keys("\C-i") - assert_line_around_cursor('foo_', '') - assert_equal(%w{foo_foo foo_bar Foo_baz}, @line_editor.instance_variable_get(:@menu_info).list) - input_keys('a') - input_keys("\C-i") - assert_line_around_cursor('foo_a', '') - input_keys("\C-h") - input_keys('b') - input_keys("\C-i") - assert_line_around_cursor('foo_ba', '') - input_keys('Z') - input_keys("\C-i") - assert_line_around_cursor('Foo_baz', '') - end - - def test_completion_in_middle_of_line - @line_editor.completion_proc = proc { |word| - %w{ - foo_foo - foo_bar - foo_baz - qux - }.map { |i| - i.encode(@encoding) - } - } - input_keys('abcde fo ABCDE') - assert_line_around_cursor('abcde fo ABCDE', '') - input_keys("\C-b" * 6 + "\C-i") - assert_line_around_cursor('abcde foo_', ' ABCDE') - input_keys("\C-b" * 2 + "\C-i") - assert_line_around_cursor('abcde foo_', 'o_ ABCDE') - end - - def test_completion_with_nil_value - @line_editor.completion_proc = proc { |word| - %w{ - foo_foo - foo_bar - Foo_baz - qux - }.map { |i| - i.encode(@encoding) - }.prepend(nil) - } - @config.completion_ignore_case = true - input_keys('fo') - assert_line_around_cursor('fo', '') - assert_equal(nil, @line_editor.instance_variable_get(:@menu_info)) - input_keys("\C-i") - assert_line_around_cursor('foo_', '') - assert_equal(nil, @line_editor.instance_variable_get(:@menu_info)) - input_keys("\C-i") - assert_line_around_cursor('foo_', '') - assert_equal(%w{foo_foo foo_bar Foo_baz}, @line_editor.instance_variable_get(:@menu_info).list) - input_keys('a') - input_keys("\C-i") - assert_line_around_cursor('foo_a', '') - input_keys("\C-h") - input_keys('b') - input_keys("\C-i") - assert_line_around_cursor('foo_ba', '') - end - - def test_em_kill_region - input_keys('abc def{bbb}ccc ddd ') - assert_line_around_cursor('abc def{bbb}ccc ddd ', '') - input_keys("\C-w") - assert_line_around_cursor('abc def{bbb}ccc ', '') - input_keys("\C-w") - assert_line_around_cursor('abc ', '') - input_keys("\C-w") - assert_line_around_cursor('', '') - input_keys("\C-w") - assert_line_around_cursor('', '') - end - - def test_em_kill_region_mbchar - input_keys('あ い う{う}う ') - assert_line_around_cursor('あ い う{う}う ', '') - input_keys("\C-w") - assert_line_around_cursor('あ い ', '') - input_keys("\C-w") - assert_line_around_cursor('あ ', '') - input_keys("\C-w") - assert_line_around_cursor('', '') - end - - def test_vi_search_prev - Reline::HISTORY.concat(%w{abc 123 AAA}) - assert_line_around_cursor('', '') - input_keys("\C-ra\C-j") - assert_line_around_cursor('', 'abc') - end - - def test_larger_histories_than_history_size - history_size = @config.history_size - @config.history_size = 2 - Reline::HISTORY.concat(%w{abc 123 AAA}) - assert_line_around_cursor('', '') - input_keys("\C-p") - assert_line_around_cursor('AAA', '') - input_keys("\C-p") - assert_line_around_cursor('123', '') - input_keys("\C-p") - assert_line_around_cursor('123', '') - ensure - @config.history_size = history_size - end - - def test_search_history_to_back - Reline::HISTORY.concat([ - '1235', # old - '12aa', - '1234' # new - ]) - assert_line_around_cursor('', '') - input_keys("\C-r123") - assert_line_around_cursor('1234', '') - input_keys("\C-ha") - assert_line_around_cursor('12aa', '') - input_keys("\C-h3") - assert_line_around_cursor('1235', '') - end - - def test_search_history_to_front - Reline::HISTORY.concat([ - '1235', # old - '12aa', - '1234' # new - ]) - assert_line_around_cursor('', '') - input_keys("\C-s123") - assert_line_around_cursor('1235', '') - input_keys("\C-ha") - assert_line_around_cursor('12aa', '') - input_keys("\C-h3") - assert_line_around_cursor('1234', '') - end - - def test_search_history_front_and_back - Reline::HISTORY.concat([ - '1235', # old - '12aa', - '1234' # new - ]) - assert_line_around_cursor('', '') - input_keys("\C-s12") - assert_line_around_cursor('1235', '') - input_keys("\C-s") - assert_line_around_cursor('12aa', '') - input_keys("\C-r") - assert_line_around_cursor('12aa', '') - input_keys("\C-r") - assert_line_around_cursor('1235', '') - end - - def test_search_history_back_and_front - Reline::HISTORY.concat([ - '1235', # old - '12aa', - '1234' # new - ]) - assert_line_around_cursor('', '') - input_keys("\C-r12") - assert_line_around_cursor('1234', '') - input_keys("\C-r") - assert_line_around_cursor('12aa', '') - input_keys("\C-s") - assert_line_around_cursor('12aa', '') - input_keys("\C-s") - assert_line_around_cursor('1234', '') - end - - def test_search_history_to_back_in_the_middle_of_histories - Reline::HISTORY.concat([ - '1235', # old - '12aa', - '1234' # new - ]) - assert_line_around_cursor('', '') - input_keys("\C-p\C-p") - assert_line_around_cursor('12aa', '') - input_keys("\C-r123") - assert_line_around_cursor('1235', '') - end - - def test_search_history_twice - Reline::HISTORY.concat([ - '1235', # old - '12aa', - '1234' # new - ]) - assert_line_around_cursor('', '') - input_keys("\C-r123") - assert_line_around_cursor('1234', '') - input_keys("\C-r") - assert_line_around_cursor('1235', '') - end - - def test_search_history_by_last_determined - Reline::HISTORY.concat([ - '1235', # old - '12aa', - '1234' # new - ]) - assert_line_around_cursor('', '') - input_keys("\C-r123") - assert_line_around_cursor('1234', '') - input_keys("\C-j") - assert_line_around_cursor('', '1234') - input_keys("\C-k") # delete - assert_line_around_cursor('', '') - input_keys("\C-r") - assert_line_around_cursor('', '') - input_keys("\C-r") - assert_line_around_cursor('1235', '') - end - - def test_search_history_with_isearch_terminator - @config.read_lines(<<~LINES.split(/(?<=\n)/)) - set isearch-terminators "XYZ" - LINES - Reline::HISTORY.concat([ - '1235', # old - '12aa', - '1234' # new - ]) - assert_line_around_cursor('', '') - input_keys("\C-r12a") - assert_line_around_cursor('12aa', '') - input_keys('Y') - assert_line_around_cursor('', '12aa') - input_keys('x') - assert_line_around_cursor('x', '12aa') - end - - def test_em_set_mark_and_em_exchange_mark - input_keys('aaa bbb ccc ddd') - assert_line_around_cursor('aaa bbb ccc ddd', '') - input_keys("\C-a\eF\eF") - assert_line_around_cursor('aaa bbb', ' ccc ddd') - assert_equal(nil, @line_editor.instance_variable_get(:@mark_pointer)) - input_keys("\x00") # C-Space - assert_line_around_cursor('aaa bbb', ' ccc ddd') - assert_equal([7, 0], @line_editor.instance_variable_get(:@mark_pointer)) - input_keys("\C-a") - assert_line_around_cursor('', 'aaa bbb ccc ddd') - assert_equal([7, 0], @line_editor.instance_variable_get(:@mark_pointer)) - input_key_by_symbol(:em_exchange_mark) - assert_line_around_cursor('aaa bbb', ' ccc ddd') - assert_equal([0, 0], @line_editor.instance_variable_get(:@mark_pointer)) - end - - def test_em_exchange_mark_without_mark - input_keys('aaa bbb ccc ddd') - assert_line_around_cursor('aaa bbb ccc ddd', '') - input_keys("\C-a\ef") - assert_line_around_cursor('aaa', ' bbb ccc ddd') - assert_equal(nil, @line_editor.instance_variable_get(:@mark_pointer)) - input_key_by_symbol(:em_exchange_mark) - assert_line_around_cursor('aaa', ' bbb ccc ddd') - assert_equal(nil, @line_editor.instance_variable_get(:@mark_pointer)) - end - - def test_modify_lines_with_wrong_rs - verbose, $VERBOSE = $VERBOSE, nil - original_global_slash = $/ - $/ = 'b' - $VERBOSE = verbose - @line_editor.output_modifier_proc = proc { |output| Reline::Unicode.escape_for_print(output) } - input_keys("abcdef\n") - result = @line_editor.__send__(:modify_lines, @line_editor.whole_lines, @line_editor.finished?) - $/ = nil - assert_equal(['abcdef'], result) - ensure - $VERBOSE = nil - $/ = original_global_slash - $VERBOSE = verbose - end - - def test_ed_search_prev_history - Reline::HISTORY.concat([ - '12356', # old - '12aaa', - '12345' # new - ]) - input_keys('123') - # The ed_search_prev_history doesn't have default binding - @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) - assert_line_around_cursor('123', '45') - @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) - assert_line_around_cursor('123', '56') - @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) - assert_line_around_cursor('123', '56') - end - - def test_ed_search_prev_history_with_empty - Reline::HISTORY.concat([ - '12356', # old - '12aaa', - '12345' # new - ]) - # The ed_search_prev_history doesn't have default binding - input_key_by_symbol(:ed_search_prev_history) - assert_line_around_cursor('12345', '') - input_key_by_symbol(:ed_search_prev_history) - assert_line_around_cursor('12aaa', '') - input_key_by_symbol(:ed_search_prev_history) - assert_line_around_cursor('12356', '') - input_key_by_symbol(:ed_search_next_history) - assert_line_around_cursor('12aaa', '') - input_key_by_symbol(:ed_prev_char) - input_key_by_symbol(:ed_next_char) - assert_line_around_cursor('12aaa', '') - input_key_by_symbol(:ed_search_prev_history) - assert_line_around_cursor('12aaa', '') - 3.times { input_key_by_symbol(:ed_prev_char) } - input_key_by_symbol(:ed_search_prev_history) - assert_line_around_cursor('12', '356') - end - - def test_ed_search_prev_history_without_match - Reline::HISTORY.concat([ - '12356', # old - '12aaa', - '12345' # new - ]) - input_keys('ABC') - # The ed_search_prev_history doesn't have default binding - @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) - assert_line_around_cursor('ABC', '') - end - - def test_ed_search_next_history - Reline::HISTORY.concat([ - '12356', # old - '12aaa', - '12345' # new - ]) - input_keys('123') - # The ed_search_prev_history and ed_search_next_history doesn't have default binding - @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) - assert_line_around_cursor('123', '45') - @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) - assert_line_around_cursor('123', '56') - @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) - assert_line_around_cursor('123', '56') - @line_editor.__send__(:ed_search_next_history, "\C-n".ord) - assert_line_around_cursor('123', '45') - @line_editor.__send__(:ed_search_next_history, "\C-n".ord) - assert_line_around_cursor('123', '45') - end - - def test_ed_search_next_history_with_empty - Reline::HISTORY.concat([ - '12356', # old - '12aaa', - '12345' # new - ]) - # The ed_search_prev_history and ed_search_next_history doesn't have default binding - input_key_by_symbol(:ed_search_prev_history) - assert_line_around_cursor('12345', '') - input_key_by_symbol(:ed_search_prev_history) - assert_line_around_cursor('12aaa', '') - input_key_by_symbol(:ed_search_prev_history) - assert_line_around_cursor('12356', '') - input_key_by_symbol(:ed_search_next_history) - assert_line_around_cursor('12aaa', '') - input_key_by_symbol(:ed_search_next_history) - assert_line_around_cursor('12345', '') - input_key_by_symbol(:ed_search_prev_history) - assert_line_around_cursor('12aaa', '') - input_key_by_symbol(:ed_prev_char) - input_key_by_symbol(:ed_next_char) - input_key_by_symbol(:ed_search_next_history) - assert_line_around_cursor('12aaa', '') - 3.times { input_key_by_symbol(:ed_prev_char) } - input_key_by_symbol(:ed_search_next_history) - assert_line_around_cursor('12', '345') - end - - def test_incremental_search_history_cancel_by_symbol_key - # ed_prev_char should move cursor left and cancel incremental search - input_keys("abc\C-r") - input_key_by_symbol(:ed_prev_char, csi: true) - input_keys('d') - assert_line_around_cursor('abd', 'c') - end - - def test_incremental_search_history_saves_and_restores_last_input - Reline::HISTORY.concat(['abc', '123']) - input_keys("abcd") - # \C-j: terminate incremental search - input_keys("\C-r12\C-j") - assert_line_around_cursor('', '123') - input_key_by_symbol(:ed_next_history) - assert_line_around_cursor('abcd', '') - # Most non-printable keys also terminates incremental search - input_keys("\C-r12\C-i") - assert_line_around_cursor('', '123') - input_key_by_symbol(:ed_next_history) - assert_line_around_cursor('abcd', '') - # \C-g: cancel incremental search and restore input, cursor position and history index - input_key_by_symbol(:ed_prev_history) - input_keys("\C-b\C-b") - assert_line_around_cursor('1', '23') - input_keys("\C-rab\C-g") - assert_line_around_cursor('1', '23') - input_key_by_symbol(:ed_next_history) - assert_line_around_cursor('abcd', '') - end - - # Unicode emoji test - def test_ed_insert_for_include_zwj_emoji - omit_unless_utf8 - # U+1F468 U+200D U+1F469 U+200D U+1F467 U+200D U+1F466 is family: man, woman, girl, boy "👨👩👧👦" - input_keys("\u{1F468}") # U+1F468 is man "👨" - assert_line_around_cursor('👨', '') - input_keys("\u200D") # U+200D is ZERO WIDTH JOINER - assert_line_around_cursor('👨', '') - input_keys("\u{1F469}") # U+1F469 is woman "👩" - assert_line_around_cursor('👨👩', '') - input_keys("\u200D") # U+200D is ZERO WIDTH JOINER - assert_line_around_cursor('👨👩', '') - input_keys("\u{1F467}") # U+1F467 is girl "👧" - assert_line_around_cursor('👨👩👧', '') - input_keys("\u200D") # U+200D is ZERO WIDTH JOINER - assert_line_around_cursor('👨👩👧', '') - input_keys("\u{1F466}") # U+1F466 is boy "👦" - assert_line_around_cursor('👨👩👧👦', '') - # U+1F468 U+200D U+1F469 U+200D U+1F467 U+200D U+1F466 is family: man, woman, girl, boy "👨👩👧👦" - input_keys("\u{1F468 200D 1F469 200D 1F467 200D 1F466}") - assert_line_around_cursor('👨👩👧👦👨👩👧👦', '') - end - - def test_ed_insert_for_include_valiation_selector - omit_unless_utf8 - # U+0030 U+FE00 is DIGIT ZERO + VARIATION SELECTOR-1 "0︀" - input_keys("\u0030") # U+0030 is DIGIT ZERO - assert_line_around_cursor('0', '') - input_keys("\uFE00") # U+FE00 is VARIATION SELECTOR-1 - assert_line_around_cursor('0︀', '') - end - - def test_em_yank_pop - input_keys("def hoge\C-w\C-b\C-f\C-w") - assert_line_around_cursor('', '') - input_keys("\C-y") - assert_line_around_cursor('def ', '') - input_keys("\e\C-y") - assert_line_around_cursor('hoge', '') - end - - def test_em_kill_region_with_kill_ring - input_keys("def hoge\C-b\C-b\C-b\C-b") - assert_line_around_cursor('def ', 'hoge') - input_keys("\C-k\C-w") - assert_line_around_cursor('', '') - input_keys("\C-y") - assert_line_around_cursor('def hoge', '') - end - - def test_ed_search_prev_next_history_in_multibyte - Reline::HISTORY.concat([ - "def hoge\n 67890\n 12345\nend", # old - "def aiu\n 0xDEADBEEF\nend", - "def foo\n 12345\nend" # new - ]) - @line_editor.multiline_on - input_keys(' 123') - # The ed_search_prev_history doesn't have default binding - @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) - assert_whole_lines(['def foo', ' 12345', 'end']) - assert_line_index(1) - assert_whole_lines(['def foo', ' 12345', 'end']) - assert_line_around_cursor(' 123', '45') - @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) - assert_line_index(2) - assert_whole_lines(['def hoge', ' 67890', ' 12345', 'end']) - assert_line_around_cursor(' 123', '45') - @line_editor.__send__(:ed_search_prev_history, "\C-p".ord) - assert_line_index(2) - assert_whole_lines(['def hoge', ' 67890', ' 12345', 'end']) - assert_line_around_cursor(' 123', '45') - @line_editor.__send__(:ed_search_next_history, "\C-n".ord) - assert_line_index(1) - assert_whole_lines(['def foo', ' 12345', 'end']) - assert_line_around_cursor(' 123', '45') - @line_editor.__send__(:ed_search_next_history, "\C-n".ord) - assert_line_index(1) - assert_whole_lines(['def foo', ' 12345', 'end']) - assert_line_around_cursor(' 123', '45') - end - - def test_ignore_NUL_by_ed_quoted_insert - input_keys('"') - input_key_by_symbol(:insert_raw_char, char: 0.chr) - input_keys('"') - assert_line_around_cursor('""', '') - end - - def test_ed_argument_digit_by_meta_num - input_keys('abcdef') - assert_line_around_cursor('abcdef', '') - input_keys("\e2") - input_keys("\C-h") - assert_line_around_cursor('abcd', '') - end - - def test_ed_digit_with_ed_argument_digit - input_keys('1' * 30) - assert_line_around_cursor('1' * 30, '') - input_keys("\e2") - input_keys('3') - input_keys("\C-h") - input_keys('4') - assert_line_around_cursor('1' * 7 + '4', '') - end - - def test_halfwidth_kana_width_dakuten - omit_unless_utf8 - input_keys('ガギゲゴ') - assert_line_around_cursor('ガギゲゴ', '') - input_keys("\C-b\C-b") - assert_line_around_cursor('ガギ', 'ゲゴ') - input_keys('グ') - assert_line_around_cursor('ガギグ', 'ゲゴ') - end - - def test_input_unknown_char - omit_unless_utf8 - input_keys('') # U+0378 (unassigned) - assert_line_around_cursor('', '') - end - - def test_unix_line_discard - input_keys("\C-u") - assert_line_around_cursor('', '') - input_keys('abc') - assert_line_around_cursor('abc', '') - input_keys("\C-b\C-u") - assert_line_around_cursor('', 'c') - input_keys("\C-f\C-u") - assert_line_around_cursor('', '') - end - - def test_vi_editing_mode - @line_editor.__send__(:vi_editing_mode, nil) - assert(@config.editing_mode_is?(:vi_insert)) - end - - def test_undo - input_keys("\C-_") - assert_line_around_cursor('', '') - input_keys("aあb\C-h\C-h\C-h") - assert_line_around_cursor('', '') - input_keys("\C-_") - assert_line_around_cursor('a', '') - input_keys("\C-_") - assert_line_around_cursor('aあ', '') - input_keys("\C-_") - assert_line_around_cursor('aあb', '') - input_keys("\C-_") - assert_line_around_cursor('aあ', '') - input_keys("\C-_") - assert_line_around_cursor('a', '') - input_keys("\C-_") - assert_line_around_cursor('', '') - end - - def test_undo_with_cursor_position - input_keys("abc\C-b\C-h") - assert_line_around_cursor('a', 'c') - input_keys("\C-_") - assert_line_around_cursor('ab', 'c') - input_keys("あいう\C-b\C-h") - assert_line_around_cursor('abあ', 'うc') - input_keys("\C-_") - assert_line_around_cursor('abあい', 'うc') - end - - def test_undo_with_multiline - @line_editor.multiline_on - @line_editor.confirm_multiline_termination_proc = proc {} - input_keys("1\n2\n3") - assert_whole_lines(["1", "2", "3"]) - assert_line_index(2) - assert_line_around_cursor('3', '') - input_keys("\C-p\C-h\C-h") - assert_whole_lines(["1", "3"]) - assert_line_index(0) - assert_line_around_cursor('1', '') - input_keys("\C-_") - assert_whole_lines(["1", "", "3"]) - assert_line_index(1) - assert_line_around_cursor('', '') - input_keys("\C-_") - assert_whole_lines(["1", "2", "3"]) - assert_line_index(1) - assert_line_around_cursor('2', '') - input_keys("\C-_") - assert_whole_lines(["1", "2", ""]) - assert_line_index(2) - assert_line_around_cursor('', '') - input_keys("\C-_") - assert_whole_lines(["1", "2"]) - assert_line_index(1) - assert_line_around_cursor('2', '') - end - - def test_undo_with_many_times - str = "a" + "b" * 99 - input_keys(str) - 100.times { input_keys("\C-_") } - assert_line_around_cursor('a', '') - input_keys("\C-_") - assert_line_around_cursor('a', '') - end - - def test_redo - input_keys("aあb") - assert_line_around_cursor('aあb', '') - input_keys("\e\C-_") - assert_line_around_cursor('aあb', '') - input_keys("\C-_") - assert_line_around_cursor('aあ', '') - input_keys("\C-_") - assert_line_around_cursor('a', '') - input_keys("\e\C-_") - assert_line_around_cursor('aあ', '') - input_keys("\e\C-_") - assert_line_around_cursor('aあb', '') - input_keys("\C-_") - assert_line_around_cursor('aあ', '') - input_keys("c") - assert_line_around_cursor('aあc', '') - input_keys("\e\C-_") - assert_line_around_cursor('aあc', '') - end - - def test_redo_with_cursor_position - input_keys("abc\C-b\C-h") - assert_line_around_cursor('a', 'c') - input_keys("\e\C-_") - assert_line_around_cursor('a', 'c') - input_keys("\C-_") - assert_line_around_cursor('ab', 'c') - input_keys("\e\C-_") - assert_line_around_cursor('a', 'c') - end - - def test_redo_with_multiline - @line_editor.multiline_on - @line_editor.confirm_multiline_termination_proc = proc {} - input_keys("1\n2\n3") - assert_whole_lines(["1", "2", "3"]) - assert_line_index(2) - assert_line_around_cursor('3', '') - - input_keys("\C-_") - assert_whole_lines(["1", "2", ""]) - assert_line_index(2) - assert_line_around_cursor('', '') - - input_keys("\C-_") - assert_whole_lines(["1", "2"]) - assert_line_index(1) - assert_line_around_cursor('2', '') - - input_keys("\e\C-_") - assert_whole_lines(["1", "2", ""]) - assert_line_index(2) - assert_line_around_cursor('', '') - - input_keys("\e\C-_") - assert_whole_lines(["1", "2", "3"]) - assert_line_index(2) - assert_line_around_cursor('3', '') - - input_keys("\C-p\C-h\C-h") - assert_whole_lines(["1", "3"]) - assert_line_index(0) - assert_line_around_cursor('1', '') - - input_keys("\C-n") - assert_whole_lines(["1", "3"]) - assert_line_index(1) - assert_line_around_cursor('3', '') - - input_keys("\C-_") - assert_whole_lines(["1", "", "3"]) - assert_line_index(1) - assert_line_around_cursor('', '') - - input_keys("\C-_") - assert_whole_lines(["1", "2", "3"]) - assert_line_index(1) - assert_line_around_cursor('2', '') - - input_keys("\e\C-_") - assert_whole_lines(["1", "", "3"]) - assert_line_index(1) - assert_line_around_cursor('', '') - - input_keys("\e\C-_") - assert_whole_lines(["1", "3"]) - assert_line_index(1) - assert_line_around_cursor('3', '') - end - - def test_undo_redo_restores_indentation - @line_editor.multiline_on - @line_editor.confirm_multiline_termination_proc = proc {} - input_keys(" 1") - assert_whole_lines([' 1']) - input_keys("2") - assert_whole_lines([' 12']) - @line_editor.auto_indent_proc = proc { 2 } - input_keys("\C-_") - assert_whole_lines([' 1']) - input_keys("\e\C-_") - assert_whole_lines([' 12']) - end - - def test_redo_with_many_times - str = "a" + "b" * 98 + "c" - input_keys(str) - 100.times { input_keys("\C-_") } - assert_line_around_cursor('a', '') - input_keys("\C-_") - assert_line_around_cursor('a', '') - 100.times { input_keys("\e\C-_") } - assert_line_around_cursor(str, '') - input_keys("\e\C-_") - assert_line_around_cursor(str, '') - end -end diff --git a/test/reline/test_key_actor_vi.rb b/test/reline/test_key_actor_vi.rb deleted file mode 100644 index 083433f9a8..0000000000 --- a/test/reline/test_key_actor_vi.rb +++ /dev/null @@ -1,967 +0,0 @@ -require_relative 'helper' - -class Reline::ViInsertTest < Reline::TestCase - def setup - Reline.send(:test_mode) - @prompt = '> ' - @config = Reline::Config.new - @config.read_lines(<<~LINES.split(/(?<=\n)/)) - set editing-mode vi - LINES - @encoding = Reline.core.encoding - @line_editor = Reline::LineEditor.new(@config) - @line_editor.reset(@prompt) - end - - def editing_mode_label - @config.instance_variable_get(:@editing_mode_label) - end - - def teardown - Reline.test_reset - end - - def test_vi_command_mode - input_keys("\C-[") - assert_equal(:vi_command, editing_mode_label) - end - - def test_vi_command_mode_with_input - input_keys("abc\C-[") - assert_equal(:vi_command, editing_mode_label) - assert_line_around_cursor('ab', 'c') - end - - def test_vi_insert - assert_equal(:vi_insert, editing_mode_label) - input_keys('i') - assert_line_around_cursor('i', '') - assert_equal(:vi_insert, editing_mode_label) - input_keys("\C-[") - assert_line_around_cursor('', 'i') - assert_equal(:vi_command, editing_mode_label) - input_keys('i') - assert_line_around_cursor('', 'i') - assert_equal(:vi_insert, editing_mode_label) - end - - def test_vi_add - assert_equal(:vi_insert, editing_mode_label) - input_keys('a') - assert_line_around_cursor('a', '') - assert_equal(:vi_insert, editing_mode_label) - input_keys("\C-[") - assert_line_around_cursor('', 'a') - assert_equal(:vi_command, editing_mode_label) - input_keys('a') - assert_line_around_cursor('a', '') - assert_equal(:vi_insert, editing_mode_label) - end - - def test_vi_insert_at_bol - input_keys('I') - assert_line_around_cursor('I', '') - assert_equal(:vi_insert, editing_mode_label) - input_keys("12345\C-[hh") - assert_line_around_cursor('I12', '345') - assert_equal(:vi_command, editing_mode_label) - input_keys('I') - assert_line_around_cursor('', 'I12345') - assert_equal(:vi_insert, editing_mode_label) - end - - def test_vi_add_at_eol - input_keys('A') - assert_line_around_cursor('A', '') - assert_equal(:vi_insert, editing_mode_label) - input_keys("12345\C-[hh") - assert_line_around_cursor('A12', '345') - assert_equal(:vi_command, editing_mode_label) - input_keys('A') - assert_line_around_cursor('A12345', '') - assert_equal(:vi_insert, editing_mode_label) - end - - def test_ed_insert_one - input_keys('a') - assert_line_around_cursor('a', '') - end - - def test_ed_insert_two - input_keys('ab') - assert_line_around_cursor('ab', '') - end - - def test_ed_insert_mbchar_one - input_keys('か') - assert_line_around_cursor('か', '') - end - - def test_ed_insert_mbchar_two - input_keys('かき') - assert_line_around_cursor('かき', '') - end - - def test_ed_insert_for_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("か\u3099") - assert_line_around_cursor("か\u3099", '') - end - - def test_ed_insert_for_plural_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("か\u3099き\u3099") - assert_line_around_cursor("か\u3099き\u3099", '') - end - - def test_ed_insert_ignore_in_vi_command - input_keys("\C-[") - chars_to_be_ignored = "\C-Oあ=".chars - input_keys(chars_to_be_ignored.join) - assert_line_around_cursor('', '') - input_keys(chars_to_be_ignored.map {|c| "5#{c}" }.join) - assert_line_around_cursor('', '') - input_keys('iい') - assert_line_around_cursor("い", '') - end - - def test_ed_next_char - input_keys("abcdef\C-[0") - assert_line_around_cursor('', 'abcdef') - input_keys('l') - assert_line_around_cursor('a', 'bcdef') - input_keys('2l') - assert_line_around_cursor('abc', 'def') - end - - def test_ed_prev_char - input_keys("abcdef\C-[") - assert_line_around_cursor('abcde', 'f') - input_keys('h') - assert_line_around_cursor('abcd', 'ef') - input_keys('2h') - assert_line_around_cursor('ab', 'cdef') - end - - def test_history - Reline::HISTORY.concat(%w{abc 123 AAA}) - input_keys("\C-[") - assert_line_around_cursor('', '') - input_keys('k') - assert_line_around_cursor('', 'AAA') - input_keys('2k') - assert_line_around_cursor('', 'abc') - input_keys('j') - assert_line_around_cursor('', '123') - input_keys('2j') - assert_line_around_cursor('', '') - end - - def test_vi_paste_prev - input_keys("abcde\C-[3h") - assert_line_around_cursor('a', 'bcde') - input_keys('P') - assert_line_around_cursor('a', 'bcde') - input_keys('d$') - assert_line_around_cursor('', 'a') - input_keys('P') - assert_line_around_cursor('bcd', 'ea') - input_keys('2P') - assert_line_around_cursor('bcdbcdbcd', 'eeea') - end - - def test_vi_paste_next - input_keys("abcde\C-[3h") - assert_line_around_cursor('a', 'bcde') - input_keys('p') - assert_line_around_cursor('a', 'bcde') - input_keys('d$') - assert_line_around_cursor('', 'a') - input_keys('p') - assert_line_around_cursor('abcd', 'e') - input_keys('2p') - assert_line_around_cursor('abcdebcdebcd', 'e') - end - - def test_vi_paste_prev_for_mbchar - input_keys("あいうえお\C-[3h") - assert_line_around_cursor('あ', 'いうえお') - input_keys('P') - assert_line_around_cursor('あ', 'いうえお') - input_keys('d$') - assert_line_around_cursor('', 'あ') - input_keys('P') - assert_line_around_cursor('いうえ', 'おあ') - input_keys('2P') - assert_line_around_cursor('いうえいうえいうえ', 'おおおあ') - end - - def test_vi_paste_next_for_mbchar - input_keys("あいうえお\C-[3h") - assert_line_around_cursor('あ', 'いうえお') - input_keys('p') - assert_line_around_cursor('あ', 'いうえお') - input_keys('d$') - assert_line_around_cursor('', 'あ') - input_keys('p') - assert_line_around_cursor('あいうえ', 'お') - input_keys('2p') - assert_line_around_cursor('あいうえおいうえおいうえ', 'お') - end - - def test_vi_paste_prev_for_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("か\u3099き\u3099く\u3099け\u3099こ\u3099\C-[3h") - assert_line_around_cursor("か\u3099", "き\u3099く\u3099け\u3099こ\u3099") - input_keys('P') - assert_line_around_cursor("か\u3099", "き\u3099く\u3099け\u3099こ\u3099") - input_keys('d$') - assert_line_around_cursor('', "か\u3099") - input_keys('P') - assert_line_around_cursor("き\u3099く\u3099け\u3099", "こ\u3099か\u3099") - input_keys('2P') - assert_line_around_cursor("き\u3099く\u3099け\u3099き\u3099く\u3099け\u3099き\u3099く\u3099け\u3099", "こ\u3099こ\u3099こ\u3099か\u3099") - end - - def test_vi_paste_next_for_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("か\u3099き\u3099く\u3099け\u3099こ\u3099\C-[3h") - assert_line_around_cursor("か\u3099", "き\u3099く\u3099け\u3099こ\u3099") - input_keys('p') - assert_line_around_cursor("か\u3099", "き\u3099く\u3099け\u3099こ\u3099") - input_keys('d$') - assert_line_around_cursor('', "か\u3099") - input_keys('p') - assert_line_around_cursor("か\u3099き\u3099く\u3099け\u3099", "こ\u3099") - input_keys('2p') - assert_line_around_cursor("か\u3099き\u3099く\u3099け\u3099こ\u3099き\u3099く\u3099け\u3099こ\u3099き\u3099く\u3099け\u3099", "こ\u3099") - end - - def test_vi_prev_next_word - input_keys("aaa b{b}b ccc\C-[0") - assert_line_around_cursor('', 'aaa b{b}b ccc') - input_keys('w') - assert_line_around_cursor('aaa ', 'b{b}b ccc') - input_keys('w') - assert_line_around_cursor('aaa b', '{b}b ccc') - input_keys('w') - assert_line_around_cursor('aaa b{', 'b}b ccc') - input_keys('w') - assert_line_around_cursor('aaa b{b', '}b ccc') - input_keys('w') - assert_line_around_cursor('aaa b{b}', 'b ccc') - input_keys('w') - assert_line_around_cursor('aaa b{b}b ', 'ccc') - input_keys('w') - assert_line_around_cursor('aaa b{b}b cc', 'c') - input_keys('b') - assert_line_around_cursor('aaa b{b}b ', 'ccc') - input_keys('b') - assert_line_around_cursor('aaa b{b}', 'b ccc') - input_keys('b') - assert_line_around_cursor('aaa b{b', '}b ccc') - input_keys('b') - assert_line_around_cursor('aaa b{', 'b}b ccc') - input_keys('b') - assert_line_around_cursor('aaa b', '{b}b ccc') - input_keys('b') - assert_line_around_cursor('aaa ', 'b{b}b ccc') - input_keys('b') - assert_line_around_cursor('', 'aaa b{b}b ccc') - input_keys('3w') - assert_line_around_cursor('aaa b{', 'b}b ccc') - input_keys('3w') - assert_line_around_cursor('aaa b{b}b ', 'ccc') - input_keys('3w') - assert_line_around_cursor('aaa b{b}b cc', 'c') - input_keys('3b') - assert_line_around_cursor('aaa b{b', '}b ccc') - input_keys('3b') - assert_line_around_cursor('aaa ', 'b{b}b ccc') - input_keys('3b') - assert_line_around_cursor('', 'aaa b{b}b ccc') - end - - def test_vi_end_word - input_keys("aaa b{b}}}b ccc\C-[0") - assert_line_around_cursor('', 'aaa b{b}}}b ccc') - input_keys('e') - assert_line_around_cursor('aa', 'a b{b}}}b ccc') - input_keys('e') - assert_line_around_cursor('aaa ', 'b{b}}}b ccc') - input_keys('e') - assert_line_around_cursor('aaa b', '{b}}}b ccc') - input_keys('e') - assert_line_around_cursor('aaa b{', 'b}}}b ccc') - input_keys('e') - assert_line_around_cursor('aaa b{b}}', '}b ccc') - input_keys('e') - assert_line_around_cursor('aaa b{b}}}', 'b ccc') - input_keys('e') - assert_line_around_cursor('aaa b{b}}}b cc', 'c') - input_keys('e') - assert_line_around_cursor('aaa b{b}}}b cc', 'c') - input_keys('03e') - assert_line_around_cursor('aaa b', '{b}}}b ccc') - input_keys('3e') - assert_line_around_cursor('aaa b{b}}}', 'b ccc') - input_keys('3e') - assert_line_around_cursor('aaa b{b}}}b cc', 'c') - end - - def test_vi_prev_next_big_word - input_keys("aaa b{b}b ccc\C-[0") - assert_line_around_cursor('', 'aaa b{b}b ccc') - input_keys('W') - assert_line_around_cursor('aaa ', 'b{b}b ccc') - input_keys('W') - assert_line_around_cursor('aaa b{b}b ', 'ccc') - input_keys('W') - assert_line_around_cursor('aaa b{b}b cc', 'c') - input_keys('B') - assert_line_around_cursor('aaa b{b}b ', 'ccc') - input_keys('B') - assert_line_around_cursor('aaa ', 'b{b}b ccc') - input_keys('B') - assert_line_around_cursor('', 'aaa b{b}b ccc') - input_keys('2W') - assert_line_around_cursor('aaa b{b}b ', 'ccc') - input_keys('2W') - assert_line_around_cursor('aaa b{b}b cc', 'c') - input_keys('2B') - assert_line_around_cursor('aaa ', 'b{b}b ccc') - input_keys('2B') - assert_line_around_cursor('', 'aaa b{b}b ccc') - end - - def test_vi_end_big_word - input_keys("aaa b{b}}}b ccc\C-[0") - assert_line_around_cursor('', 'aaa b{b}}}b ccc') - input_keys('E') - assert_line_around_cursor('aa', 'a b{b}}}b ccc') - input_keys('E') - assert_line_around_cursor('aaa b{b}}}', 'b ccc') - input_keys('E') - assert_line_around_cursor('aaa b{b}}}b cc', 'c') - input_keys('E') - assert_line_around_cursor('aaa b{b}}}b cc', 'c') - end - - def test_ed_quoted_insert - input_keys('ab') - input_key_by_symbol(:insert_raw_char, char: "\C-a") - assert_line_around_cursor("ab\C-a", '') - end - - def test_ed_quoted_insert_with_vi_arg - input_keys("ab\C-[3") - input_key_by_symbol(:insert_raw_char, char: "\C-a") - input_keys('4') - input_key_by_symbol(:insert_raw_char, char: '1') - assert_line_around_cursor("a\C-a\C-a\C-a1111", 'b') - end - - def test_vi_replace_char - input_keys("abcdef\C-[03l") - assert_line_around_cursor('abc', 'def') - input_keys('rz') - assert_line_around_cursor('abc', 'zef') - input_keys('2rx') - assert_line_around_cursor('abcxx', 'f') - end - - def test_vi_replace_char_with_mbchar - input_keys("あいうえお\C-[0l") - assert_line_around_cursor('あ', 'いうえお') - input_keys('rx') - assert_line_around_cursor('あ', 'xうえお') - input_keys('l2ry') - assert_line_around_cursor('あxyy', 'お') - end - - def test_vi_next_char - input_keys("abcdef\C-[0") - assert_line_around_cursor('', 'abcdef') - input_keys('fz') - assert_line_around_cursor('', 'abcdef') - input_keys('fe') - assert_line_around_cursor('abcd', 'ef') - end - - def test_vi_to_next_char - input_keys("abcdef\C-[0") - assert_line_around_cursor('', 'abcdef') - input_keys('tz') - assert_line_around_cursor('', 'abcdef') - input_keys('te') - assert_line_around_cursor('abc', 'def') - end - - def test_vi_prev_char - input_keys("abcdef\C-[") - assert_line_around_cursor('abcde', 'f') - input_keys('Fz') - assert_line_around_cursor('abcde', 'f') - input_keys('Fa') - assert_line_around_cursor('', 'abcdef') - end - - def test_vi_to_prev_char - input_keys("abcdef\C-[") - assert_line_around_cursor('abcde', 'f') - input_keys('Tz') - assert_line_around_cursor('abcde', 'f') - input_keys('Ta') - assert_line_around_cursor('a', 'bcdef') - end - - def test_vi_delete_next_char - input_keys("abc\C-[h") - assert_line_around_cursor('a', 'bc') - input_keys('x') - assert_line_around_cursor('a', 'c') - input_keys('x') - assert_line_around_cursor('', 'a') - input_keys('x') - assert_line_around_cursor('', '') - input_keys('x') - assert_line_around_cursor('', '') - end - - def test_vi_delete_next_char_for_mbchar - input_keys("あいう\C-[h") - assert_line_around_cursor('あ', 'いう') - input_keys('x') - assert_line_around_cursor('あ', 'う') - input_keys('x') - assert_line_around_cursor('', 'あ') - input_keys('x') - assert_line_around_cursor('', '') - input_keys('x') - assert_line_around_cursor('', '') - end - - def test_vi_delete_next_char_for_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("か\u3099き\u3099く\u3099\C-[h") - assert_line_around_cursor("か\u3099", "き\u3099く\u3099") - input_keys('x') - assert_line_around_cursor("か\u3099", "く\u3099") - input_keys('x') - assert_line_around_cursor('', "か\u3099") - input_keys('x') - assert_line_around_cursor('', '') - input_keys('x') - assert_line_around_cursor('', '') - end - - def test_vi_delete_prev_char - input_keys('ab') - assert_line_around_cursor('ab', '') - input_keys("\C-h") - assert_line_around_cursor('a', '') - end - - def test_vi_delete_prev_char_for_mbchar - input_keys('かき') - assert_line_around_cursor('かき', '') - input_keys("\C-h") - assert_line_around_cursor('か', '') - end - - def test_vi_delete_prev_char_for_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("か\u3099き\u3099") - assert_line_around_cursor("か\u3099き\u3099", '') - input_keys("\C-h") - assert_line_around_cursor("か\u3099", '') - end - - def test_ed_delete_prev_char - input_keys("abcdefg\C-[h") - assert_line_around_cursor('abcde', 'fg') - input_keys('X') - assert_line_around_cursor('abcd', 'fg') - input_keys('3X') - assert_line_around_cursor('a', 'fg') - input_keys('p') - assert_line_around_cursor('afbc', 'dg') - end - - def test_ed_delete_prev_word - input_keys('abc def{bbb}ccc') - assert_line_around_cursor('abc def{bbb}ccc', '') - input_keys("\C-w") - assert_line_around_cursor('abc def{bbb}', '') - input_keys("\C-w") - assert_line_around_cursor('abc def{', '') - input_keys("\C-w") - assert_line_around_cursor('abc ', '') - input_keys("\C-w") - assert_line_around_cursor('', '') - end - - def test_ed_delete_prev_word_for_mbchar - input_keys('あいう かきく{さしす}たちつ') - assert_line_around_cursor('あいう かきく{さしす}たちつ', '') - input_keys("\C-w") - assert_line_around_cursor('あいう かきく{さしす}', '') - input_keys("\C-w") - assert_line_around_cursor('あいう かきく{', '') - input_keys("\C-w") - assert_line_around_cursor('あいう ', '') - input_keys("\C-w") - assert_line_around_cursor('', '') - end - - def test_ed_delete_prev_word_for_mbchar_by_plural_code_points - omit_unless_utf8 - input_keys("あいう か\u3099き\u3099く\u3099{さしす}たちつ") - assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす}たちつ", '') - input_keys("\C-w") - assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす}", '') - input_keys("\C-w") - assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{", '') - input_keys("\C-w") - assert_line_around_cursor('あいう ', '') - input_keys("\C-w") - assert_line_around_cursor('', '') - end - - def test_ed_newline_with_cr - input_keys('ab') - assert_line_around_cursor('ab', '') - refute(@line_editor.finished?) - input_keys("\C-m") - assert_line_around_cursor('ab', '') - assert(@line_editor.finished?) - end - - def test_ed_newline_with_lf - input_keys('ab') - assert_line_around_cursor('ab', '') - refute(@line_editor.finished?) - input_keys("\C-j") - assert_line_around_cursor('ab', '') - assert(@line_editor.finished?) - end - - def test_vi_list_or_eof - input_keys("\C-d") # quit from inputing - assert_nil(@line_editor.line) - assert(@line_editor.finished?) - end - - def test_vi_list_or_eof_with_non_empty_line - input_keys('ab') - assert_line_around_cursor('ab', '') - refute(@line_editor.finished?) - input_keys("\C-d") - assert_line_around_cursor('ab', '') - assert(@line_editor.finished?) - end - - def test_completion_journey - @line_editor.completion_proc = proc { |word| - %w{ - foo_bar - foo_bar_baz - }.map { |i| - i.encode(@encoding) - } - } - input_keys('foo') - assert_line_around_cursor('foo', '') - input_keys("\C-n") - assert_line_around_cursor('foo_bar', '') - input_keys("\C-n") - assert_line_around_cursor('foo_bar_baz', '') - input_keys("\C-n") - assert_line_around_cursor('foo', '') - input_keys("\C-n") - assert_line_around_cursor('foo_bar', '') - input_keys("_\C-n") - assert_line_around_cursor('foo_bar_baz', '') - input_keys("\C-n") - assert_line_around_cursor('foo_bar_', '') - end - - def test_completion_journey_reverse - @line_editor.completion_proc = proc { |word| - %w{ - foo_bar - foo_bar_baz - }.map { |i| - i.encode(@encoding) - } - } - input_keys('foo') - assert_line_around_cursor('foo', '') - input_keys("\C-p") - assert_line_around_cursor('foo_bar_baz', '') - input_keys("\C-p") - assert_line_around_cursor('foo_bar', '') - input_keys("\C-p") - assert_line_around_cursor('foo', '') - input_keys("\C-p") - assert_line_around_cursor('foo_bar_baz', '') - input_keys("\C-h\C-p") - assert_line_around_cursor('foo_bar_baz', '') - input_keys("\C-p") - assert_line_around_cursor('foo_bar_ba', '') - end - - def test_completion_journey_in_middle_of_line - @line_editor.completion_proc = proc { |word| - %w{ - foo_bar - foo_bar_baz - }.map { |i| - i.encode(@encoding) - } - } - input_keys('abcde fo ABCDE') - assert_line_around_cursor('abcde fo ABCDE', '') - input_keys("\C-[" + 'h' * 5 + "i\C-n") - assert_line_around_cursor('abcde foo_bar', ' ABCDE') - input_keys("\C-n") - assert_line_around_cursor('abcde foo_bar_baz', ' ABCDE') - input_keys("\C-n") - assert_line_around_cursor('abcde fo', ' ABCDE') - input_keys("\C-n") - assert_line_around_cursor('abcde foo_bar', ' ABCDE') - input_keys("_\C-n") - assert_line_around_cursor('abcde foo_bar_baz', ' ABCDE') - input_keys("\C-n") - assert_line_around_cursor('abcde foo_bar_', ' ABCDE') - input_keys("\C-n") - assert_line_around_cursor('abcde foo_bar_baz', ' ABCDE') - end - - def test_completion - @line_editor.completion_proc = proc { |word| - %w{ - foo_bar - foo_bar_baz - }.map { |i| - i.encode(@encoding) - } - } - input_keys('foo') - assert_line_around_cursor('foo', '') - input_keys("\C-i") - assert_line_around_cursor('foo_bar', '') - end - - def test_autocompletion_with_upward_navigation - @config.autocompletion = true - @line_editor.completion_proc = proc { |word| - %w{ - Readline - Regexp - RegexpError - }.map { |i| - i.encode(@encoding) - } - } - input_keys('Re') - assert_line_around_cursor('Re', '') - input_keys("\C-i") - assert_line_around_cursor('Readline', '') - input_keys("\C-i") - assert_line_around_cursor('Regexp', '') - input_key_by_symbol(:completion_journey_up) - assert_line_around_cursor('Readline', '') - ensure - @config.autocompletion = false - end - - def test_autocompletion_with_upward_navigation_and_menu_complete_backward - @config.autocompletion = true - @line_editor.completion_proc = proc { |word| - %w{ - Readline - Regexp - RegexpError - }.map { |i| - i.encode(@encoding) - } - } - input_keys('Re') - assert_line_around_cursor('Re', '') - input_keys("\C-i") - assert_line_around_cursor('Readline', '') - input_keys("\C-i") - assert_line_around_cursor('Regexp', '') - input_key_by_symbol(:menu_complete_backward) - assert_line_around_cursor('Readline', '') - ensure - @config.autocompletion = false - end - - def test_completion_with_disable_completion - @config.disable_completion = true - @line_editor.completion_proc = proc { |word| - %w{ - foo_bar - foo_bar_baz - }.map { |i| - i.encode(@encoding) - } - } - input_keys('foo') - assert_line_around_cursor('foo', '') - input_keys("\C-i") - assert_line_around_cursor('foo', '') - end - - def test_vi_first_print - input_keys("abcde\C-[^") - assert_line_around_cursor('', 'abcde') - input_keys("0\C-ki") - input_keys(" abcde\C-[^") - assert_line_around_cursor(' ', 'abcde') - input_keys("0\C-ki") - input_keys(" abcde ABCDE \C-[^") - assert_line_around_cursor(' ', 'abcde ABCDE ') - end - - def test_ed_move_to_beg - input_keys("abcde\C-[0") - assert_line_around_cursor('', 'abcde') - input_keys("0\C-ki") - input_keys(" abcde\C-[0") - assert_line_around_cursor('', ' abcde') - input_keys("0\C-ki") - input_keys(" abcde ABCDE \C-[0") - assert_line_around_cursor('', ' abcde ABCDE ') - end - - def test_vi_to_column - input_keys("a一二三\C-[0") - input_keys('1|') - assert_line_around_cursor('', 'a一二三') - input_keys('2|') - assert_line_around_cursor('a', '一二三') - input_keys('3|') - assert_line_around_cursor('a', '一二三') - input_keys('4|') - assert_line_around_cursor('a一', '二三') - input_keys('9|') - assert_line_around_cursor('a一二', '三') - end - - def test_vi_delete_meta - input_keys("aaa bbb ccc ddd eee\C-[02w") - assert_line_around_cursor('aaa bbb ', 'ccc ddd eee') - input_keys('dw') - assert_line_around_cursor('aaa bbb ', 'ddd eee') - input_keys('db') - assert_line_around_cursor('aaa ', 'ddd eee') - end - - def test_vi_delete_meta_nothing - input_keys("foo\C-[0") - assert_line_around_cursor('', 'foo') - input_keys('dhp') - assert_line_around_cursor('', 'foo') - end - - def test_vi_delete_meta_with_vi_next_word_at_eol - input_keys("foo bar\C-[0w") - assert_line_around_cursor('foo ', 'bar') - input_keys('w') - assert_line_around_cursor('foo ba', 'r') - input_keys('0dw') - assert_line_around_cursor('', 'bar') - input_keys('dw') - assert_line_around_cursor('', '') - end - - def test_vi_delete_meta_with_vi_next_char - input_keys("aaa bbb ccc ___ ddd\C-[02w") - assert_line_around_cursor('aaa bbb ', 'ccc ___ ddd') - input_keys('df_') - assert_line_around_cursor('aaa bbb ', '__ ddd') - end - - def test_vi_delete_meta_with_arg - input_keys("aaa bbb ccc ddd\C-[03w") - assert_line_around_cursor('aaa bbb ccc ', 'ddd') - input_keys('2dl') - assert_line_around_cursor('aaa bbb ccc ', 'd') - input_keys('d2h') - assert_line_around_cursor('aaa bbb cc', 'd') - input_keys('2d3h') - assert_line_around_cursor('aaa ', 'd') - input_keys('dd') - assert_line_around_cursor('', '') - end - - def test_vi_change_meta - input_keys("aaa bbb ccc ddd eee\C-[02w") - assert_line_around_cursor('aaa bbb ', 'ccc ddd eee') - input_keys('cwaiueo') - assert_line_around_cursor('aaa bbb aiueo', ' ddd eee') - input_keys("\C-[") - assert_line_around_cursor('aaa bbb aiue', 'o ddd eee') - input_keys('cb') - assert_line_around_cursor('aaa bbb ', 'o ddd eee') - end - - def test_vi_change_meta_with_vi_next_word - input_keys("foo bar baz\C-[0w") - assert_line_around_cursor('foo ', 'bar baz') - input_keys('cwhoge') - assert_line_around_cursor('foo hoge', ' baz') - input_keys("\C-[") - assert_line_around_cursor('foo hog', 'e baz') - end - - def test_vi_waiting_operator_with_waiting_proc - input_keys("foo foo foo foo foo\C-[0") - input_keys('2d3fo') - assert_line_around_cursor('', ' foo foo') - input_keys('fo') - assert_line_around_cursor(' f', 'oo foo') - end - - def test_waiting_operator_arg_including_zero - input_keys("a111111111111222222222222\C-[0") - input_keys('10df1') - assert_line_around_cursor('', '11222222222222') - input_keys('d10f2') - assert_line_around_cursor('', '22') - end - - def test_vi_waiting_operator_cancel - input_keys("aaa bbb ccc\C-[02w") - assert_line_around_cursor('aaa bbb ', 'ccc') - # dc dy should cancel delete_meta - input_keys('dch') - input_keys('dyh') - # cd cy should cancel change_meta - input_keys('cdh') - input_keys('cyh') - # yd yc should cancel yank_meta - # P should not paste yanked text because yank_meta is canceled - input_keys('ydhP') - input_keys('ychP') - assert_line_around_cursor('aa', 'a bbb ccc') - end - - def test_cancel_waiting_with_symbol_key - input_keys("aaa bbb lll\C-[0") - assert_line_around_cursor('', 'aaa bbb lll') - # ed_next_char should move cursor right and cancel vi_next_char - input_keys('f') - input_key_by_symbol(:ed_next_char, csi: true) - input_keys('l') - assert_line_around_cursor('aa', 'a bbb lll') - # vi_delete_meta + ed_next_char should delete character - input_keys('d') - input_key_by_symbol(:ed_next_char, csi: true) - input_keys('l') - assert_line_around_cursor('aa ', 'bbb lll') - end - - def test_unimplemented_vi_command_should_be_no_op - input_keys("abc\C-[h") - assert_line_around_cursor('a', 'bc') - input_keys('@') - assert_line_around_cursor('a', 'bc') - end - - def test_vi_yank - input_keys("foo bar\C-[2h") - assert_line_around_cursor('foo ', 'bar') - input_keys('y3l') - assert_line_around_cursor('foo ', 'bar') - input_keys('P') - assert_line_around_cursor('foo ba', 'rbar') - input_keys('3h3yhP') - assert_line_around_cursor('foofo', 'o barbar') - input_keys('yyP') - assert_line_around_cursor('foofofoofoo barba', 'ro barbar') - end - - def test_vi_yank_nothing - input_keys("foo\C-[0") - assert_line_around_cursor('', 'foo') - input_keys('yhp') - assert_line_around_cursor('', 'foo') - end - - def test_vi_end_word_with_operator - input_keys("foo bar\C-[0") - assert_line_around_cursor('', 'foo bar') - input_keys('de') - assert_line_around_cursor('', ' bar') - input_keys('de') - assert_line_around_cursor('', '') - input_keys('de') - assert_line_around_cursor('', '') - end - - def test_vi_end_big_word_with_operator - input_keys("aaa b{b}}}b\C-[0") - assert_line_around_cursor('', 'aaa b{b}}}b') - input_keys('dE') - assert_line_around_cursor('', ' b{b}}}b') - input_keys('dE') - assert_line_around_cursor('', '') - input_keys('dE') - assert_line_around_cursor('', '') - end - - def test_vi_next_char_with_operator - input_keys("foo bar\C-[0") - assert_line_around_cursor('', 'foo bar') - input_keys('df ') - assert_line_around_cursor('', 'bar') - end - - def test_ed_delete_next_char_at_eol - input_keys('"あ"') - assert_line_around_cursor('"あ"', '') - input_keys("\C-[") - assert_line_around_cursor('"あ', '"') - input_keys('xa"') - assert_line_around_cursor('"あ"', '') - end - - def test_vi_kill_line_prev - input_keys("\C-u") - assert_line_around_cursor('', '') - input_keys('abc') - assert_line_around_cursor('abc', '') - input_keys("\C-u") - assert_line_around_cursor('', '') - input_keys('abc') - input_keys("\C-[\C-u") - assert_line_around_cursor('', 'c') - input_keys("\C-u") - assert_line_around_cursor('', 'c') - end - - def test_vi_change_to_eol - input_keys("abcdef\C-[2hC") - assert_line_around_cursor('abc', '') - input_keys("\C-[0C") - assert_line_around_cursor('', '') - assert_equal(:vi_insert, editing_mode_label) - end - - def test_vi_motion_operators - assert_equal(:vi_insert, editing_mode_label) - - assert_nothing_raised do - input_keys("test = { foo: bar }\C-[BBBldt}b") - end - end - - def test_emacs_editing_mode - @line_editor.__send__(:emacs_editing_mode, nil) - assert(@config.editing_mode_is?(:emacs)) - end -end diff --git a/test/reline/test_key_stroke.rb b/test/reline/test_key_stroke.rb deleted file mode 100644 index fb2cb1c8b8..0000000000 --- a/test/reline/test_key_stroke.rb +++ /dev/null @@ -1,111 +0,0 @@ -require_relative 'helper' - -class Reline::KeyStroke::Test < Reline::TestCase - def encoding - Reline.core.encoding - end - - def test_match_status - config = Reline::Config.new - { - 'a' => 'xx', - 'ab' => 'y', - 'abc' => 'z', - 'x' => 'rr' - }.each_pair do |key, func| - config.add_default_key_binding(key.bytes, func.bytes) - end - stroke = Reline::KeyStroke.new(config, encoding) - assert_equal(Reline::KeyStroke::MATCHING_MATCHED, stroke.match_status("a".bytes)) - assert_equal(Reline::KeyStroke::MATCHING_MATCHED, stroke.match_status("ab".bytes)) - assert_equal(Reline::KeyStroke::MATCHED, stroke.match_status("abc".bytes)) - assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status("abz".bytes)) - assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status("abcx".bytes)) - assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status("aa".bytes)) - assert_equal(Reline::KeyStroke::MATCHED, stroke.match_status("x".bytes)) - assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status("xa".bytes)) - end - - def test_match_unknown - config = Reline::Config.new - config.add_default_key_binding("\e[9abc".bytes, 'x') - stroke = Reline::KeyStroke.new(config, encoding) - sequences = [ - "\e[9abc", - "\e[9d", - "\e[A", # Up - "\e[1;1R", # Cursor position report - "\e[15~", # F5 - "\eOP", # F1 - "\e\e[A", # Option+Up - "\eX", - "\e\eX" - ] - sequences.each do |seq| - assert_equal(Reline::KeyStroke::MATCHED, stroke.match_status(seq.bytes)) - assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status(seq.bytes + [32])) - (2...seq.size).each do |i| - assert_equal(Reline::KeyStroke::MATCHING, stroke.match_status(seq.bytes.take(i))) - end - end - end - - def test_expand - config = Reline::Config.new - { - 'abc' => 'AB', - 'ab' => "1\C-a" - }.each_pair do |key, func| - config.add_default_key_binding(key.bytes, func.bytes) - end - stroke = Reline::KeyStroke.new(config, encoding) - assert_equal([[Reline::Key.new('A', :ed_insert, false), Reline::Key.new('B', :ed_insert, false)], 'de'.bytes], stroke.expand('abcde'.bytes)) - assert_equal([[Reline::Key.new('1', :ed_digit, false), Reline::Key.new("\C-a", :ed_move_to_beg, false)], 'de'.bytes], stroke.expand('abde'.bytes)) - # CSI sequence - assert_equal([[], 'bc'.bytes], stroke.expand("\e[1;2;3;4;5abc".bytes)) - assert_equal([[], 'BC'.bytes], stroke.expand("\e\e[ABC".bytes)) - # SS3 sequence - assert_equal([[], 'QR'.bytes], stroke.expand("\eOPQR".bytes)) - end - - def test_oneshot_key_bindings - config = Reline::Config.new - { - 'abc'.bytes => '123', - # IRB version <= 1.13.1 wrongly uses Reline::Key with wrong argument. It should be ignored without error. - [Reline::Key.new(nil, 0xE4, true)] => '012', - "\eda".bytes => 'abc', # Alt+d a - [195, 164] => 'def' - }.each_pair do |key, func| - config.add_oneshot_key_binding(key, func.bytes) - end - stroke = Reline::KeyStroke.new(config, encoding) - assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status('zzz'.bytes)) - assert_equal(Reline::KeyStroke::MATCHED, stroke.match_status('abc'.bytes)) - assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status('da'.bytes)) - assert_equal(Reline::KeyStroke::MATCHED, stroke.match_status("\eda".bytes)) - assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status(" \eda".bytes)) - assert_equal(Reline::KeyStroke::MATCHED, stroke.match_status([195, 164])) - end - - def test_multibyte_matching - begin - char = 'あ'.encode(encoding) - rescue Encoding::UndefinedConversionError - omit - end - config = Reline::Config.new - stroke = Reline::KeyStroke.new(config, encoding) - key = Reline::Key.new(char, :ed_insert, false) - bytes = char.bytes - assert_equal(Reline::KeyStroke::MATCHED, stroke.match_status(bytes)) - assert_equal([[key], []], stroke.expand(bytes)) - assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status(bytes * 2)) - assert_equal([[key], bytes], stroke.expand(bytes * 2)) - (1...bytes.size).each do |i| - partial_bytes = bytes.take(i) - assert_equal(Reline::KeyStroke::MATCHING_MATCHED, stroke.match_status(partial_bytes)) - assert_equal([[], []], stroke.expand(partial_bytes)) - end - end -end diff --git a/test/reline/test_kill_ring.rb b/test/reline/test_kill_ring.rb deleted file mode 100644 index 9f6e0c3e74..0000000000 --- a/test/reline/test_kill_ring.rb +++ /dev/null @@ -1,268 +0,0 @@ -require_relative 'helper' - -class Reline::KillRing::Test < Reline::TestCase - def setup - @prompt = '> ' - @kill_ring = Reline::KillRing.new - end - - def test_append_one - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('a') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - assert_equal('a', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal('a', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['a', 'a'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['a', 'a'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - end - - def test_append_two - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('a') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('b') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - assert_equal('b', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal('b', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['a', 'b'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['b', 'a'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - end - - def test_append_three - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('a') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('b') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('c') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - assert_equal('c', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal('c', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['b', 'c'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['a', 'b'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['c', 'a'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - end - - def test_append_three_with_max_two - @kill_ring = Reline::KillRing.new(2) - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('a') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('b') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('c') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - assert_equal('c', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal('c', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['b', 'c'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['c', 'b'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['b', 'c'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - end - - def test_append_four_with_max_two - @kill_ring = Reline::KillRing.new(2) - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('a') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('b') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('c') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('d') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - assert_equal('d', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal('d', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['c', 'd'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['d', 'c'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['c', 'd'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - end - - def test_append_after - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('a') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('b') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - assert_equal('ab', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal('ab', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['ab', 'ab'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['ab', 'ab'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - end - - def test_append_before - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('a') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('b', true) - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - assert_equal('ba', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal('ba', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['ba', 'ba'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['ba', 'ba'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - end - - def test_append_chain_two - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('a') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('b') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('c') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('d') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - assert_equal('cd', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal('cd', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['ab', 'cd'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['cd', 'ab'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - end - - def test_append_complex_chain - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('c') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('d') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('b', true) - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('e') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('a', true) - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::FRESH, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('A') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.append('B') - assert_equal(Reline::KillRing::State::CONTINUED, @kill_ring.instance_variable_get(:@state)) - @kill_ring.process - assert_equal(Reline::KillRing::State::PROCESSED, @kill_ring.instance_variable_get(:@state)) - assert_equal('AB', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal('AB', @kill_ring.yank) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['abcde', 'AB'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - assert_equal(['AB', 'abcde'], @kill_ring.yank_pop) - assert_equal(Reline::KillRing::State::YANK, @kill_ring.instance_variable_get(:@state)) - end - - def test_enumerable - @kill_ring.append('a') - @kill_ring.process - @kill_ring.process - @kill_ring.append('b') - @kill_ring.process - @kill_ring.process - @kill_ring.append('c') - @kill_ring.process - assert_equal(%w{c b a}, @kill_ring.to_a) - end -end diff --git a/test/reline/test_line_editor.rb b/test/reline/test_line_editor.rb deleted file mode 100644 index 28fcbfa6df..0000000000 --- a/test/reline/test_line_editor.rb +++ /dev/null @@ -1,271 +0,0 @@ -require_relative 'helper' -require 'reline/line_editor' -require 'stringio' - -class Reline::LineEditor - - class CompletionBlockTest < Reline::TestCase - def setup - @original_quote_characters = Reline.completer_quote_characters - @original_word_break_characters = Reline.completer_word_break_characters - @line_editor = Reline::LineEditor.new(nil) - end - - def retrieve_completion_block(lines, line_index, byte_pointer) - @line_editor.instance_variable_set(:@buffer_of_lines, lines) - @line_editor.instance_variable_set(:@line_index, line_index) - @line_editor.instance_variable_set(:@byte_pointer, byte_pointer) - @line_editor.retrieve_completion_block - end - - def retrieve_completion_quote(line) - _, _, _, quote = retrieve_completion_block([line], 0, line.bytesize) - quote - end - - def teardown - Reline.completer_quote_characters = @original_quote_characters - Reline.completer_word_break_characters = @original_word_break_characters - end - - def test_retrieve_completion_block - Reline.completer_word_break_characters = ' ([{' - Reline.completer_quote_characters = '' - assert_equal(['', '', 'foo', nil], retrieve_completion_block(['foo'], 0, 0)) - assert_equal(['', 'f', 'oo', nil], retrieve_completion_block(['foo'], 0, 1)) - assert_equal(['foo ', 'ba', 'r baz', nil], retrieve_completion_block(['foo bar baz'], 0, 6)) - assert_equal(['foo([', 'b', 'ar])baz', nil], retrieve_completion_block(['foo([bar])baz'], 0, 6)) - assert_equal(['foo([{', '', '}])baz', nil], retrieve_completion_block(['foo([{}])baz'], 0, 6)) - assert_equal(["abc\nfoo ", 'ba', "r baz\ndef", nil], retrieve_completion_block(['abc', 'foo bar baz', 'def'], 1, 6)) - end - - def test_retrieve_completion_block_with_quote_characters - Reline.completer_word_break_characters = ' ([{' - Reline.completer_quote_characters = '' - assert_equal(['"" ', '"wo', 'rd', nil], retrieve_completion_block(['"" "word'], 0, 6)) - Reline.completer_quote_characters = '"' - assert_equal(['"" "', 'wo', 'rd', nil], retrieve_completion_block(['"" "word'], 0, 6)) - end - - def test_retrieve_completion_quote - Reline.completer_quote_characters = '"\'' - assert_equal('"', retrieve_completion_quote('"\'')) - assert_equal(nil, retrieve_completion_quote('""')) - assert_equal("'", retrieve_completion_quote('""\'"')) - assert_equal(nil, retrieve_completion_quote('""\'\'')) - assert_equal('"', retrieve_completion_quote('"\\"')) - assert_equal(nil, retrieve_completion_quote('"\\""')) - assert_equal(nil, retrieve_completion_quote('"\\\\"')) - end - end - - class CursorPositionTest < Reline::TestCase - def setup - @line_editor = Reline::LineEditor.new(nil) - @line_editor.instance_variable_set(:@config, Reline::Config.new) - end - - def test_cursor_position_with_escaped_input - @line_editor.instance_variable_set(:@screen_size, [4, 16]) - @line_editor.instance_variable_set(:@prompt, "\e[1mprompt\e[0m> ") - @line_editor.instance_variable_set(:@buffer_of_lines, ["\e[1m\0\1\2\3\4\5\6\7abcd"]) - @line_editor.instance_variable_set(:@line_index, 0) - # prompt> ^[[1m^@^ - # A^B^C^D^E^F^Gabc - # d - @line_editor.instance_variable_set(:@byte_pointer, 0) - assert_equal [8, 0], @line_editor.wrapped_cursor_position - @line_editor.instance_variable_set(:@byte_pointer, 5) - assert_equal [15, 0], @line_editor.wrapped_cursor_position - @line_editor.instance_variable_set(:@byte_pointer, 6) - assert_equal [1, 1], @line_editor.wrapped_cursor_position - @line_editor.instance_variable_set(:@byte_pointer, 14) - assert_equal [15, 1], @line_editor.wrapped_cursor_position - @line_editor.instance_variable_set(:@byte_pointer, 15) - assert_equal [0, 2], @line_editor.wrapped_cursor_position - @line_editor.instance_variable_set(:@byte_pointer, 16) - assert_equal [1, 2], @line_editor.wrapped_cursor_position - end - end - - class RenderLineDifferentialTest < Reline::TestCase - class TestIO < Reline::IO - def write(string) - @output << string - end - - def move_cursor_column(col) - @output << "[COL_#{col}]" - end - - def erase_after_cursor - @output << '[ERASE]' - end - end - - def setup - verbose, $VERBOSE = $VERBOSE, nil - @line_editor = Reline::LineEditor.new(nil) - @original_iogate = Reline::IOGate - @output = StringIO.new - @line_editor.instance_variable_set(:@screen_size, [24, 80]) - Reline.send(:remove_const, :IOGate) - Reline.const_set(:IOGate, TestIO.new) - Reline::IOGate.instance_variable_set(:@output, @output) - ensure - $VERBOSE = verbose - end - - def assert_output(expected) - @output.reopen(+'') - yield - actual = @output.string - assert_equal(expected, actual.gsub("\e[0m", '')) - end - - def teardown - Reline.send(:remove_const, :IOGate) - Reline.const_set(:IOGate, @original_iogate) - end - - def test_line_increase_decrease - assert_output '[COL_0]bb' do - @line_editor.render_line_differential([[0, 1, 'a']], [[0, 2, 'bb']]) - end - - assert_output '[COL_0]b[COL_1][ERASE]' do - @line_editor.render_line_differential([[0, 2, 'aa']], [[0, 1, 'b']]) - end - end - - def test_dialog_appear_disappear - assert_output '[COL_3]dialog' do - @line_editor.render_line_differential([[0, 1, 'a']], [[0, 1, 'a'], [3, 6, 'dialog']]) - end - - assert_output '[COL_3]dialog' do - @line_editor.render_line_differential([[0, 10, 'a' * 10]], [[0, 10, 'a' * 10], [3, 6, 'dialog']]) - end - - assert_output '[COL_1][ERASE]' do - @line_editor.render_line_differential([[0, 1, 'a'], [3, 6, 'dialog']], [[0, 1, 'a']]) - end - - assert_output '[COL_3]aaaaaa' do - @line_editor.render_line_differential([[0, 10, 'a' * 10], [3, 6, 'dialog']], [[0, 10, 'a' * 10]]) - end - end - - def test_dialog_change - assert_output '[COL_3]DIALOG' do - @line_editor.render_line_differential([[0, 2, 'a'], [3, 6, 'dialog']], [[0, 2, 'a'], [3, 6, 'DIALOG']]) - end - - assert_output '[COL_3]DIALOG' do - @line_editor.render_line_differential([[0, 10, 'a' * 10], [3, 6, 'dialog']], [[0, 10, 'a' * 10], [3, 6, 'DIALOG']]) - end - end - - def test_update_under_dialog - assert_output '[COL_0]b[COL_1] ' do - @line_editor.render_line_differential([[0, 2, 'aa'], [4, 6, 'dialog']], [[0, 1, 'b'], [4, 6, 'dialog']]) - end - - assert_output '[COL_0]bbb[COL_9]b' do - @line_editor.render_line_differential([[0, 10, 'a' * 10], [3, 6, 'dialog']], [[0, 10, 'b' * 10], [3, 6, 'dialog']]) - end - - assert_output '[COL_0]b[COL_1] [COL_9][ERASE]' do - @line_editor.render_line_differential([[0, 10, 'a' * 10], [3, 6, 'dialog']], [[0, 1, 'b'], [3, 6, 'dialog']]) - end - end - - def test_dialog_move - assert_output '[COL_3]dialog[COL_9][ERASE]' do - @line_editor.render_line_differential([[0, 1, 'a'], [4, 6, 'dialog']], [[0, 1, 'a'], [3, 6, 'dialog']]) - end - - assert_output '[COL_4] [COL_5]dialog' do - @line_editor.render_line_differential([[0, 1, 'a'], [4, 6, 'dialog']], [[0, 1, 'a'], [5, 6, 'dialog']]) - end - - assert_output '[COL_2]dialog[COL_8]a' do - @line_editor.render_line_differential([[0, 10, 'a' * 10], [3, 6, 'dialog']], [[0, 10, 'a' * 10], [2, 6, 'dialog']]) - end - - assert_output '[COL_2]a[COL_3]dialog' do - @line_editor.render_line_differential([[0, 10, 'a' * 10], [2, 6, 'dialog']], [[0, 10, 'a' * 10], [3, 6, 'dialog']]) - end - end - - def test_multibyte - base = [0, 12, '一二三一二三'] - left = [0, 3, 'LLL'] - right = [9, 3, 'RRR'] - front = [3, 6, 'FFFFFF'] - # 一 FFFFFF 三 - # 一二三一二三 - assert_output '[COL_2]二三一二' do - @line_editor.render_line_differential([base, front], [base, nil]) - end - - # LLLFFFFFF 三 - # LLL 三一二三 - assert_output '[COL_3] 三一二' do - @line_editor.render_line_differential([base, left, front], [base, left, nil]) - end - - # 一 FFFFFFRRR - # 一二三一 RRR - assert_output '[COL_2]二三一 ' do - @line_editor.render_line_differential([base, right, front], [base, right, nil]) - end - - # LLLFFFFFFRRR - # LLL 三一 RRR - assert_output '[COL_3] 三一 ' do - @line_editor.render_line_differential([base, left, right, front], [base, left, right, nil]) - end - end - - def test_complicated - state_a = [nil, [19, 7, 'bbbbbbb'], [15, 8, 'cccccccc'], [10, 5, 'ddddd'], [18, 4, 'eeee'], [1, 3, 'fff'], [17, 2, 'gg'], [7, 1, 'h']] - state_b = [[5, 9, 'aaaaaaaaa'], nil, [15, 8, 'cccccccc'], nil, [18, 4, 'EEEE'], [25, 4, 'ffff'], [17, 2, 'gg'], [2, 2, 'hh']] - # state_a: " fff h dddddccggeeecbbb" - # state_b: " hh aaaaaaaaa ccggEEEc ffff" - - assert_output '[COL_1] [COL_2]hh[COL_5]aaaaaaaaa[COL_14] [COL_19]EEE[COL_23] [COL_25]ffff' do - @line_editor.render_line_differential(state_a, state_b) - end - - assert_output '[COL_1]fff[COL_5] [COL_7]h[COL_8] [COL_10]ddddd[COL_19]eee[COL_23]bbb[COL_26][ERASE]' do - @line_editor.render_line_differential(state_b, state_a) - end - end - end - - def test_menu_info_format - list = %w[aa b c d e f g hhh i j k] - col3 = [ - 'aa e i', - 'b f j', - 'c g k', - 'd hhh' - ] - col2 = [ - 'aa g', - 'b hhh', - 'c i', - 'd j', - 'e k', - 'f' - ] - assert_equal(col3, Reline::LineEditor::MenuInfo.new(list).lines(19)) - assert_equal(col3, Reline::LineEditor::MenuInfo.new(list).lines(15)) - assert_equal(col2, Reline::LineEditor::MenuInfo.new(list).lines(14)) - assert_equal(col2, Reline::LineEditor::MenuInfo.new(list).lines(10)) - assert_equal(list, Reline::LineEditor::MenuInfo.new(list).lines(9)) - assert_equal(list, Reline::LineEditor::MenuInfo.new(list).lines(0)) - assert_equal([], Reline::LineEditor::MenuInfo.new([]).lines(10)) - end -end diff --git a/test/reline/test_macro.rb b/test/reline/test_macro.rb deleted file mode 100644 index cacdb76c60..0000000000 --- a/test/reline/test_macro.rb +++ /dev/null @@ -1,40 +0,0 @@ -require_relative 'helper' - -class Reline::MacroTest < Reline::TestCase - def setup - Reline.send(:test_mode) - @config = Reline::Config.new - @encoding = Reline.core.encoding - @line_editor = Reline::LineEditor.new(@config) - @output = Reline::IOGate.output = File.open(IO::NULL, "w") - end - - def teardown - @output.close - Reline.test_reset - end - - def input_key(char, method_symbol = :ed_insert) - @line_editor.input_key(Reline::Key.new(char, method_symbol, false)) - end - - def input(str) - str.each_char {|c| input_key(c)} - end - - def test_simple_input - input('abc') - assert_equal 'abc', @line_editor.line - end - - def test_alias - class << @line_editor - alias delete_char ed_delete_prev_char - end - input('abc') - assert_nothing_raised(ArgumentError) { - input_key('x', :delete_char) - } - assert_equal 'ab', @line_editor.line - end -end diff --git a/test/reline/test_reline.rb b/test/reline/test_reline.rb deleted file mode 100644 index 691ed9ffda..0000000000 --- a/test/reline/test_reline.rb +++ /dev/null @@ -1,487 +0,0 @@ -require_relative 'helper' -require 'reline' -require 'stringio' -begin - require "pty" -rescue LoadError # some platforms don't support PTY -end - -class Reline::Test < Reline::TestCase - class DummyCallbackObject - def call; end - end - - def setup - Reline.send(:test_mode) - Reline.output_modifier_proc = nil - Reline.completion_proc = nil - Reline.prompt_proc = nil - Reline.auto_indent_proc = nil - Reline.pre_input_hook = nil - Reline.dig_perfect_match_proc = nil - end - - def teardown - Reline.test_reset - end - - def test_completion_append_character - completion_append_character = Reline.completion_append_character - - assert_equal(nil, Reline.completion_append_character) - - Reline.completion_append_character = "" - assert_equal(nil, Reline.completion_append_character) - - Reline.completion_append_character = "a".encode(Encoding::ASCII) - assert_equal("a", Reline.completion_append_character) - assert_equal(get_reline_encoding, Reline.completion_append_character.encoding) - - Reline.completion_append_character = "ba".encode(Encoding::ASCII) - assert_equal("b", Reline.completion_append_character) - assert_equal(get_reline_encoding, Reline.completion_append_character.encoding) - - Reline.completion_append_character = "cba".encode(Encoding::ASCII) - assert_equal("c", Reline.completion_append_character) - assert_equal(get_reline_encoding, Reline.completion_append_character.encoding) - - Reline.completion_append_character = nil - assert_equal(nil, Reline.completion_append_character) - ensure - Reline.completion_append_character = completion_append_character - end - - def test_basic_word_break_characters - basic_word_break_characters = Reline.basic_word_break_characters - - assert_equal(" \t\n`><=;|&{(", Reline.basic_word_break_characters) - - Reline.basic_word_break_characters = "[".encode(Encoding::ASCII) - assert_equal("[", Reline.basic_word_break_characters) - assert_equal(get_reline_encoding, Reline.basic_word_break_characters.encoding) - ensure - Reline.basic_word_break_characters = basic_word_break_characters - end - - def test_completer_word_break_characters - completer_word_break_characters = Reline.completer_word_break_characters - - assert_equal(" \t\n`><=;|&{(", Reline.completer_word_break_characters) - - Reline.completer_word_break_characters = "[".encode(Encoding::ASCII) - assert_equal("[", Reline.completer_word_break_characters) - assert_equal(get_reline_encoding, Reline.completer_word_break_characters.encoding) - - assert_nothing_raised { Reline.completer_word_break_characters = '' } - ensure - Reline.completer_word_break_characters = completer_word_break_characters - end - - def test_basic_quote_characters - basic_quote_characters = Reline.basic_quote_characters - - assert_equal('"\'', Reline.basic_quote_characters) - - Reline.basic_quote_characters = "`".encode(Encoding::ASCII) - assert_equal("`", Reline.basic_quote_characters) - assert_equal(get_reline_encoding, Reline.basic_quote_characters.encoding) - ensure - Reline.basic_quote_characters = basic_quote_characters - end - - def test_completer_quote_characters - completer_quote_characters = Reline.completer_quote_characters - - assert_equal('"\'', Reline.completer_quote_characters) - - Reline.completer_quote_characters = "`".encode(Encoding::ASCII) - assert_equal("`", Reline.completer_quote_characters) - assert_equal(get_reline_encoding, Reline.completer_quote_characters.encoding) - - assert_nothing_raised { Reline.completer_quote_characters = '' } - ensure - Reline.completer_quote_characters = completer_quote_characters - end - - def test_filename_quote_characters - filename_quote_characters = Reline.filename_quote_characters - - assert_equal('', Reline.filename_quote_characters) - - Reline.filename_quote_characters = "\'".encode(Encoding::ASCII) - assert_equal("\'", Reline.filename_quote_characters) - assert_equal(get_reline_encoding, Reline.filename_quote_characters.encoding) - ensure - Reline.filename_quote_characters = filename_quote_characters - end - - def test_special_prefixes - special_prefixes = Reline.special_prefixes - - assert_equal('', Reline.special_prefixes) - - Reline.special_prefixes = "\'".encode(Encoding::ASCII) - assert_equal("\'", Reline.special_prefixes) - assert_equal(get_reline_encoding, Reline.special_prefixes.encoding) - ensure - Reline.special_prefixes = special_prefixes - end - - def test_completion_case_fold - completion_case_fold = Reline.completion_case_fold - - assert_equal(nil, Reline.completion_case_fold) - - Reline.completion_case_fold = true - assert_equal(true, Reline.completion_case_fold) - - Reline.completion_case_fold = "hoge".encode(Encoding::ASCII) - assert_equal("hoge", Reline.completion_case_fold) - ensure - Reline.completion_case_fold = completion_case_fold - end - - def test_completion_proc - omit unless Reline.completion_proc == nil - # Another test can set Reline.completion_proc - - # assert_equal(nil, Reline.completion_proc) - - dummy_proc = proc {} - Reline.completion_proc = dummy_proc - assert_equal(dummy_proc, Reline.completion_proc) - - l = lambda {} - Reline.completion_proc = l - assert_equal(l, Reline.completion_proc) - - assert_raise(ArgumentError) { Reline.completion_proc = 42 } - assert_raise(ArgumentError) { Reline.completion_proc = "hoge" } - - dummy = DummyCallbackObject.new - Reline.completion_proc = dummy - assert_equal(dummy, Reline.completion_proc) - end - - def test_output_modifier_proc - assert_equal(nil, Reline.output_modifier_proc) - - dummy_proc = proc {} - Reline.output_modifier_proc = dummy_proc - assert_equal(dummy_proc, Reline.output_modifier_proc) - - l = lambda {} - Reline.output_modifier_proc = l - assert_equal(l, Reline.output_modifier_proc) - - assert_raise(ArgumentError) { Reline.output_modifier_proc = 42 } - assert_raise(ArgumentError) { Reline.output_modifier_proc = "hoge" } - - dummy = DummyCallbackObject.new - Reline.output_modifier_proc = dummy - assert_equal(dummy, Reline.output_modifier_proc) - end - - def test_prompt_proc - assert_equal(nil, Reline.prompt_proc) - - dummy_proc = proc {} - Reline.prompt_proc = dummy_proc - assert_equal(dummy_proc, Reline.prompt_proc) - - l = lambda {} - Reline.prompt_proc = l - assert_equal(l, Reline.prompt_proc) - - assert_raise(ArgumentError) { Reline.prompt_proc = 42 } - assert_raise(ArgumentError) { Reline.prompt_proc = "hoge" } - - dummy = DummyCallbackObject.new - Reline.prompt_proc = dummy - assert_equal(dummy, Reline.prompt_proc) - end - - def test_auto_indent_proc - assert_equal(nil, Reline.auto_indent_proc) - - dummy_proc = proc {} - Reline.auto_indent_proc = dummy_proc - assert_equal(dummy_proc, Reline.auto_indent_proc) - - l = lambda {} - Reline.auto_indent_proc = l - assert_equal(l, Reline.auto_indent_proc) - - assert_raise(ArgumentError) { Reline.auto_indent_proc = 42 } - assert_raise(ArgumentError) { Reline.auto_indent_proc = "hoge" } - - dummy = DummyCallbackObject.new - Reline.auto_indent_proc = dummy - assert_equal(dummy, Reline.auto_indent_proc) - end - - def test_pre_input_hook - assert_equal(nil, Reline.pre_input_hook) - - dummy_proc = proc {} - Reline.pre_input_hook = dummy_proc - assert_equal(dummy_proc, Reline.pre_input_hook) - - l = lambda {} - Reline.pre_input_hook = l - assert_equal(l, Reline.pre_input_hook) - end - - def test_dig_perfect_match_proc - assert_equal(nil, Reline.dig_perfect_match_proc) - - dummy_proc = proc {} - Reline.dig_perfect_match_proc = dummy_proc - assert_equal(dummy_proc, Reline.dig_perfect_match_proc) - - l = lambda {} - Reline.dig_perfect_match_proc = l - assert_equal(l, Reline.dig_perfect_match_proc) - - assert_raise(ArgumentError) { Reline.dig_perfect_match_proc = 42 } - assert_raise(ArgumentError) { Reline.dig_perfect_match_proc = "hoge" } - - dummy = DummyCallbackObject.new - Reline.dig_perfect_match_proc = dummy - assert_equal(dummy, Reline.dig_perfect_match_proc) - end - - def test_insert_text - assert_equal('', Reline.line_buffer) - assert_equal(0, Reline.point) - Reline.insert_text('abc') - assert_equal('abc', Reline.line_buffer) - assert_equal(3, Reline.point) - end - - def test_delete_text - assert_equal('', Reline.line_buffer) - assert_equal(0, Reline.point) - Reline.insert_text('abc') - assert_equal('abc', Reline.line_buffer) - assert_equal(3, Reline.point) - Reline.delete_text() - assert_equal('', Reline.line_buffer) - assert_equal(0, Reline.point) - Reline.insert_text('abc') - Reline.delete_text(1) - assert_equal('a', Reline.line_buffer) - assert_equal(1, Reline.point) - Reline.insert_text('defghi') - Reline.delete_text(2, 2) - assert_equal('adghi', Reline.line_buffer) - assert_equal(5, Reline.point) - end - - def test_set_input_and_output - assert_raise(TypeError) do - Reline.input = "This is not a file." - end - assert_raise(TypeError) do - Reline.output = "This is not a file." - end - - input, to_write = IO.pipe - to_read, output = IO.pipe - unless Reline.__send__(:input=, input) - omit "Setting to input is not effective on #{Reline.core.io_gate}" - end - Reline.output = output - - to_write.write "a\n" - result = Reline.readline - to_write.close - read_text = to_read.read_nonblock(100) - assert_equal('a', result) - refute(read_text.empty?) - ensure - input&.close - output&.close - to_read&.close - end - - def test_vi_editing_mode - Reline.vi_editing_mode - assert_equal(:vi_insert, Reline.core.config.instance_variable_get(:@editing_mode_label)) - end - - def test_emacs_editing_mode - Reline.emacs_editing_mode - assert_equal(:emacs, Reline.core.config.instance_variable_get(:@editing_mode_label)) - end - - def test_add_dialog_proc - dummy_proc = proc {} - Reline.add_dialog_proc(:test_proc, dummy_proc) - d = Reline.dialog_proc(:test_proc) - assert_equal(dummy_proc, d.dialog_proc) - - dummy_proc_2 = proc {} - Reline.add_dialog_proc(:test_proc, dummy_proc_2) - d = Reline.dialog_proc(:test_proc) - assert_equal(dummy_proc_2, d.dialog_proc) - - Reline.add_dialog_proc(:test_proc, nil) - assert_nil(Reline.dialog_proc(:test_proc)) - - l = lambda {} - Reline.add_dialog_proc(:test_lambda, l) - d = Reline.dialog_proc(:test_lambda) - assert_equal(l, d.dialog_proc) - - assert_equal(nil, Reline.dialog_proc(:test_nothing)) - - assert_raise(ArgumentError) { Reline.add_dialog_proc(:error, 42) } - assert_raise(ArgumentError) { Reline.add_dialog_proc(:error, 'hoge') } - assert_raise(ArgumentError) { Reline.add_dialog_proc('error', proc {} ) } - - dummy = DummyCallbackObject.new - Reline.add_dialog_proc(:dummy, dummy) - d = Reline.dialog_proc(:dummy) - assert_equal(dummy, d.dialog_proc) - end - - def test_add_dialog_proc_with_context - dummy_proc = proc {} - array = Array.new - Reline.add_dialog_proc(:test_proc, dummy_proc, array) - d = Reline.dialog_proc(:test_proc) - assert_equal(dummy_proc, d.dialog_proc) - assert_equal(array, d.context) - - Reline.add_dialog_proc(:test_proc, dummy_proc, nil) - d = Reline.dialog_proc(:test_proc) - assert_equal(dummy_proc, d.dialog_proc) - assert_equal(nil, d.context) - end - - def test_readmultiline - # readmultiline is module function - assert_include(Reline.methods, :readmultiline) - assert_include(Reline.private_instance_methods, :readmultiline) - end - - def test_readline - # readline is module function - assert_include(Reline.methods, :readline) - assert_include(Reline.private_instance_methods, :readline) - end - - def test_read_io - # TODO in Reline::Core - end - - def test_dumb_terminal - lib = File.expand_path("../../lib", __dir__) - out = IO.popen([{"TERM"=>"dumb"}, Reline.test_rubybin, "-I#{lib}", "-rreline", "-e", "p Reline.core.io_gate"], &:read) - assert_match(/#<Reline::Dumb/, out.chomp) - end - - def test_print_prompt_before_everything_else - pend if win? - lib = File.expand_path("../../lib", __dir__) - code = "p Reline::IOGate.class; p Reline.readline 'prompt> '" - out = IO.popen([Reline.test_rubybin, "-I#{lib}", "-rreline", "-e", code], "r+") do |io| - io.write "abc\n" - io.close_write - io.read - end - assert_match(/\AReline::ANSI\nprompt> /, out) - end - - def test_read_eof_returns_input - pend if win? - lib = File.expand_path("../../lib", __dir__) - code = "p result: Reline.readline" - out = IO.popen([Reline.test_rubybin, "-I#{lib}", "-rreline", "-e", code], "r+") do |io| - io.write "a\C-a" - io.close_write - io.read - end - assert_include(out, { result: 'a' }.inspect) - end - - def test_read_eof_returns_nil_if_empty - pend if win? - lib = File.expand_path("../../lib", __dir__) - code = "p result: Reline.readline" - out = IO.popen([Reline.test_rubybin, "-I#{lib}", "-rreline", "-e", code], "r+") do |io| - io.write "a\C-h" - io.close_write - io.read - end - assert_include(out, { result: nil }.inspect) - end - - def test_require_reline_should_not_trigger_winsize - pend if win? - lib = File.expand_path("../../lib", __dir__) - code = <<~RUBY - require "io/console" - def STDIN.tty?; true; end - def STDOUT.tty?; true; end - def STDIN.winsize; raise; end - require("reline") && p(Reline.core.io_gate) - RUBY - out = IO.popen([{}, Reline.test_rubybin, "-I#{lib}", "-e", code], &:read) - assert_include(out.chomp, "Reline::ANSI") - end - - def win? - /mswin|mingw/.match?(RUBY_PLATFORM) - end - - def test_tty_amibuous_width - omit unless defined?(PTY) - ruby_file = Tempfile.create('rubyfile') - ruby_file.write(<<~RUBY) - require 'reline' - Thread.new { sleep 2; puts 'timeout'; exit } - p [Reline.ambiguous_width, gets.chomp] - RUBY - ruby_file.close - lib = File.expand_path('../../lib', __dir__) - cmd = [{ 'TERM' => 'xterm' }, Reline.test_rubybin, '-I', lib, ruby_file.to_path] - - # Calculate ambiguous width from cursor position - [1, 2].each do |ambiguous_width| - PTY.spawn(*cmd) do |r, w, pid| - loop { break if r.readpartial(1024).include?("\e[6n") } - w.puts "hello\e[10;#{ambiguous_width + 1}Rworld" - assert_include(r.gets, [ambiguous_width, 'helloworld'].inspect) - ensure - r.close - w.close - Process.waitpid pid - end - end - - # Ambiguous width = 1 when cursor pos timed out - PTY.spawn(*cmd) do |r, w, pid| - loop { break if r.readpartial(1024).include?("\e[6n") } - w.puts "hello\e[10;2Sworld" - assert_include(r.gets, [1, "hello\e[10;2Sworld"].inspect) - ensure - r.close - w.close - Process.waitpid pid - end - ensure - File.delete(ruby_file.path) if ruby_file - end - - def get_reline_encoding - if encoding = Reline.core.encoding - encoding - elsif win? - Encoding::UTF_8 - else - Encoding::default_external - end - end -end diff --git a/test/reline/test_reline_key.rb b/test/reline/test_reline_key.rb deleted file mode 100644 index b6260d57d6..0000000000 --- a/test/reline/test_reline_key.rb +++ /dev/null @@ -1,10 +0,0 @@ -require_relative 'helper' -require "reline" - -class Reline::TestKey < Reline::TestCase - def test_match_symbol - assert(Reline::Key.new('a', :key1, false).match?(:key1)) - refute(Reline::Key.new('a', :key1, false).match?(:key2)) - refute(Reline::Key.new('a', :key1, false).match?(nil)) - end -end diff --git a/test/reline/test_string_processing.rb b/test/reline/test_string_processing.rb deleted file mode 100644 index a105be9aba..0000000000 --- a/test/reline/test_string_processing.rb +++ /dev/null @@ -1,46 +0,0 @@ -require_relative 'helper' - -class Reline::LineEditor::StringProcessingTest < Reline::TestCase - def setup - Reline.send(:test_mode) - @prompt = '> ' - @config = Reline::Config.new - Reline::HISTORY.instance_variable_set(:@config, @config) - @line_editor = Reline::LineEditor.new(@config) - @line_editor.reset(@prompt) - end - - def teardown - Reline.test_reset - end - - def test_calculate_width - width = @line_editor.send(:calculate_width, 'Ruby string') - assert_equal('Ruby string'.size, width) - end - - def test_calculate_width_with_escape_sequence - width = @line_editor.send(:calculate_width, "\1\e[31m\2RubyColor\1\e[34m\2 default string \1\e[m\2>", true) - assert_equal('RubyColor default string >'.size, width) - end - - def test_completion_proc_with_preposing_and_postposing - buf = ['def hoge', ' puts :aaa', 'end'] - - @line_editor.instance_variable_set(:@is_multiline, true) - @line_editor.instance_variable_set(:@buffer_of_lines, buf) - @line_editor.instance_variable_set(:@byte_pointer, 6) - @line_editor.instance_variable_set(:@line_index, 1) - completion_proc_called = false - @line_editor.instance_variable_set(:@completion_proc, proc { |target, pre, post| - assert_equal('puts', target) - assert_equal("def hoge\n ", pre) - assert_equal(" :aaa\nend", post) - completion_proc_called = true - }) - - assert_equal(["def hoge\n ", 'puts', " :aaa\nend", nil], @line_editor.retrieve_completion_block) - @line_editor.__send__(:call_completion_proc, "def hoge\n ", 'puts', " :aaa\nend", nil) - assert(completion_proc_called) - end -end diff --git a/test/reline/test_unicode.rb b/test/reline/test_unicode.rb deleted file mode 100644 index 0778306c32..0000000000 --- a/test/reline/test_unicode.rb +++ /dev/null @@ -1,286 +0,0 @@ -require_relative 'helper' -require "reline/unicode" - -class Reline::Unicode::Test < Reline::TestCase - def setup - Reline.send(:test_mode) - end - - def teardown - Reline.test_reset - end - - def test_get_mbchar_width - assert_equal Reline.ambiguous_width, Reline::Unicode.get_mbchar_width('é') - end - - def test_ambiguous_width - assert_equal 1, Reline::Unicode.calculate_width('√', true) - end - - def test_csi_regexp - csi_sequences = ["\e[m", "\e[1m", "\e[12;34m", "\e[12;34H"] - assert_equal(csi_sequences, "text#{csi_sequences.join('text')}text".scan(Reline::Unicode::CSI_REGEXP)) - end - - def test_osc_regexp - osc_sequences = ["\e]1\a", "\e]0;OSC\a", "\e]1\e\\", "\e]0;OSC\e\\"] - separator = "text\atext" - assert_equal(osc_sequences, "#{separator}#{osc_sequences.join(separator)}#{separator}".scan(Reline::Unicode::OSC_REGEXP)) - end - - def test_split_by_width - # IRB uses this method. - assert_equal [['abc', 'de'], 2], Reline::Unicode.split_by_width('abcde', 3) - end - - def test_split_line_by_width - assert_equal ['abc', 'de'], Reline::Unicode.split_line_by_width('abcde', 3) - assert_equal ['abc', 'def', ''], Reline::Unicode.split_line_by_width('abcdef', 3) - assert_equal ['ab', 'あd', 'ef'], Reline::Unicode.split_line_by_width('abあdef', 3) - assert_equal ['ab[zero]c', 'def', ''], Reline::Unicode.split_line_by_width("ab\1[zero]\2cdef", 3) - assert_equal ["\e[31mabc", "\e[31md\e[42mef", "\e[31m\e[42mg"], Reline::Unicode.split_line_by_width("\e[31mabcd\e[42mefg", 3) - assert_equal ["ab\e]0;1\ac", "\e]0;1\ad"], Reline::Unicode.split_line_by_width("ab\e]0;1\acd", 3) - end - - def test_split_line_by_width_csi_reset_sgr_optimization - assert_equal ["\e[1ma\e[mb\e[2mc", "\e[2md\e[0me\e[3mf", "\e[3mg"], Reline::Unicode.split_line_by_width("\e[1ma\e[mb\e[2mcd\e[0me\e[3mfg", 3) - assert_equal ["\e[1ma\e[mzero\e[0m\e[2mb", "\e[1m\e[2mc"], Reline::Unicode.split_line_by_width("\e[1ma\1\e[mzero\e[0m\2\e[2mbc", 2) - end - - def test_take_range - assert_equal 'cdef', Reline::Unicode.take_range('abcdefghi', 2, 4) - assert_equal 'あde', Reline::Unicode.take_range('abあdef', 2, 4) - assert_equal '[zero]cdef', Reline::Unicode.take_range("ab\1[zero]\2cdef", 2, 4) - assert_equal 'b[zero]cde', Reline::Unicode.take_range("ab\1[zero]\2cdef", 1, 4) - assert_equal "\e[31mcd\e[42mef", Reline::Unicode.take_range("\e[31mabcd\e[42mefg", 2, 4) - assert_equal "\e]0;1\acd", Reline::Unicode.take_range("ab\e]0;1\acd", 2, 3) - assert_equal 'いう', Reline::Unicode.take_range('あいうえお', 2, 4) - end - - def test_nonprinting_start_end - # \1 and \2 should be removed - assert_equal 'ab[zero]cd', Reline::Unicode.take_range("ab\1[zero]\2cdef", 0, 4) - assert_equal ['ab[zero]cd', 'ef'], Reline::Unicode.split_line_by_width("ab\1[zero]\2cdef", 4) - # CSI between \1 and \2 does not need to be applied to the sebsequent line - assert_equal ["\e[31mab\e[32mcd", "\e[31mef"], Reline::Unicode.split_line_by_width("\e[31mab\1\e[32m\2cdef", 4) - end - - def test_strip_non_printing_start_end - assert_equal "ab[zero]cd[ze\1ro]ef[zero]", Reline::Unicode.strip_non_printing_start_end("ab\1[zero]\2cd\1[ze\1ro]\2ef\1[zero]") - end - - def test_calculate_width - assert_equal 9, Reline::Unicode.calculate_width('abcdefghi') - assert_equal 9, Reline::Unicode.calculate_width('abcdefghi', true) - assert_equal 7, Reline::Unicode.calculate_width('abあdef') - assert_equal 7, Reline::Unicode.calculate_width('abあdef', true) - assert_equal 16, Reline::Unicode.calculate_width("ab\1[zero]\2cdef") - assert_equal 6, Reline::Unicode.calculate_width("ab\1[zero]\2cdef", true) - assert_equal 19, Reline::Unicode.calculate_width("\e[31mabcd\e[42mefg") - assert_equal 7, Reline::Unicode.calculate_width("\e[31mabcd\e[42mefg", true) - assert_equal 12, Reline::Unicode.calculate_width("ab\e]0;1\acd") - assert_equal 4, Reline::Unicode.calculate_width("ab\e]0;1\acd", true) - assert_equal 10, Reline::Unicode.calculate_width('あいうえお') - assert_equal 10, Reline::Unicode.calculate_width('あいうえお', true) - end - - def test_take_mbchar_range - assert_equal ['cdef', 2, 4], Reline::Unicode.take_mbchar_range('abcdefghi', 2, 4) - assert_equal ['cdef', 2, 4], Reline::Unicode.take_mbchar_range('abcdefghi', 2, 4, padding: true) - assert_equal ['cdef', 2, 4], Reline::Unicode.take_mbchar_range('abcdefghi', 2, 4, cover_begin: true) - assert_equal ['cdef', 2, 4], Reline::Unicode.take_mbchar_range('abcdefghi', 2, 4, cover_end: true) - assert_equal ['いう', 2, 4], Reline::Unicode.take_mbchar_range('あいうえお', 2, 4) - assert_equal ['いう', 2, 4], Reline::Unicode.take_mbchar_range('あいうえお', 2, 4, padding: true) - assert_equal ['いう', 2, 4], Reline::Unicode.take_mbchar_range('あいうえお', 2, 4, cover_begin: true) - assert_equal ['いう', 2, 4], Reline::Unicode.take_mbchar_range('あいうえお', 2, 4, cover_end: true) - assert_equal ['う', 4, 2], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4) - assert_equal [' う ', 3, 4], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4, padding: true) - assert_equal ['いう', 2, 4], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4, cover_begin: true) - assert_equal ['うえ', 4, 4], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4, cover_end: true) - assert_equal ['いう ', 2, 5], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4, cover_begin: true, padding: true) - assert_equal [' うえ', 3, 5], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4, cover_end: true, padding: true) - assert_equal [' うえお ', 3, 10], Reline::Unicode.take_mbchar_range('あいうえお', 3, 10, padding: true) - assert_equal [" \e[41mうえお\e[0m ", 3, 10], Reline::Unicode.take_mbchar_range("あい\e[41mうえお", 3, 10, padding: true) - assert_equal ["\e[41m \e[42mい\e[43m ", 1, 4], Reline::Unicode.take_mbchar_range("\e[41mあ\e[42mい\e[43mう", 1, 4, padding: true) - assert_equal ["\e[31mc[ABC]d\e[0mef", 2, 4], Reline::Unicode.take_mbchar_range("\e[31mabc\1[ABC]\2d\e[0mefghi", 2, 4) - assert_equal ["\e[41m \e[42mい\e[43m ", 1, 4], Reline::Unicode.take_mbchar_range("\e[41mあ\e[42mい\e[43mう", 1, 4, padding: true) - end - - def test_common_prefix - assert_equal('', Reline::Unicode.common_prefix([])) - assert_equal('abc', Reline::Unicode.common_prefix(['abc'])) - assert_equal('12', Reline::Unicode.common_prefix(['123', '123️⃣'])) - assert_equal('', Reline::Unicode.common_prefix(['abc', 'xyz'])) - assert_equal('ab', Reline::Unicode.common_prefix(['abcd', 'abc', 'abx', 'abcd'])) - assert_equal('A', Reline::Unicode.common_prefix(['AbcD', 'ABC', 'AbX', 'AbCD'])) - assert_equal('Ab', Reline::Unicode.common_prefix(['AbcD', 'ABC', 'AbX', 'AbCD'], ignore_case: true)) - end - - def test_encoding_conversion - texts = [ - String.new("invalid\xFFutf8", encoding: 'utf-8'), - String.new("invalid\xFFsjis", encoding: 'sjis'), - "utf8#{33111.chr('sjis')}convertible", - "utf8#{33222.chr('sjis')}inconvertible", - "sjis->utf8->sjis#{60777.chr('sjis')}irreversible" - ] - utf8_texts = [ - 'invalid�utf8', - 'invalid�sjis', - 'utf8仝convertible', - 'utf8�inconvertible', - 'sjis->utf8->sjis劦irreversible' - ] - sjis_texts = [ - 'invalid?utf8', - 'invalid?sjis', - "utf8#{33111.chr('sjis')}convertible", - 'utf8?inconvertible', - "sjis->utf8->sjis#{60777.chr('sjis')}irreversible" - ] - assert_equal(utf8_texts, texts.map { |s| Reline::Unicode.safe_encode(s, 'utf-8') }) - assert_equal(utf8_texts, texts.map { |s| Reline::Unicode.safe_encode(s, Encoding::UTF_8) }) - assert_equal(sjis_texts, texts.map { |s| Reline::Unicode.safe_encode(s, 'sjis') }) - assert_equal(sjis_texts, texts.map { |s| Reline::Unicode.safe_encode(s, Encoding::Windows_31J) }) - end - - def test_em_forward_word - assert_equal(12, Reline::Unicode.em_forward_word('abc---fooあbar-baz', 3)) - assert_equal(11, Reline::Unicode.em_forward_word('abc---fooあbar-baz'.encode('sjis'), 3)) - assert_equal(3, Reline::Unicode.em_forward_word('abcfoo', 3)) - assert_equal(3, Reline::Unicode.em_forward_word('abc---', 3)) - assert_equal(0, Reline::Unicode.em_forward_word('abc', 3)) - end - - def test_em_forward_word_with_capitalization - assert_equal([12, '---Fooあbar'], Reline::Unicode.em_forward_word_with_capitalization('abc---foOあBar-baz', 3)) - assert_equal([11, '---Fooあbar'.encode('sjis')], Reline::Unicode.em_forward_word_with_capitalization('abc---foOあBar-baz'.encode('sjis'), 3)) - assert_equal([3, 'Foo'], Reline::Unicode.em_forward_word_with_capitalization('abcfOo', 3)) - assert_equal([3, '---'], Reline::Unicode.em_forward_word_with_capitalization('abc---', 3)) - assert_equal([0, ''], Reline::Unicode.em_forward_word_with_capitalization('abc', 3)) - assert_equal([6, 'Ii̇i̇'], Reline::Unicode.em_forward_word_with_capitalization('ıİİ', 0)) - end - - def test_em_backward_word - assert_equal(12, Reline::Unicode.em_backward_word('abc foo-barあbaz--- xyz', 20)) - assert_equal(11, Reline::Unicode.em_backward_word('abc foo-barあbaz--- xyz'.encode('sjis'), 19)) - assert_equal(2, Reline::Unicode.em_backward_word(' ', 2)) - assert_equal(2, Reline::Unicode.em_backward_word('ab', 2)) - assert_equal(0, Reline::Unicode.em_backward_word('ab', 0)) - end - - def test_em_big_backward_word - assert_equal(16, Reline::Unicode.em_big_backward_word('abc foo-barあbaz--- xyz', 20)) - assert_equal(15, Reline::Unicode.em_big_backward_word('abc foo-barあbaz--- xyz'.encode('sjis'), 19)) - assert_equal(2, Reline::Unicode.em_big_backward_word(' ', 2)) - assert_equal(2, Reline::Unicode.em_big_backward_word('ab', 2)) - assert_equal(0, Reline::Unicode.em_big_backward_word('ab', 0)) - end - - def test_ed_transpose_words - # any value that does not trigger transpose - assert_equal([0, 0, 0, 2], Reline::Unicode.ed_transpose_words('aa bb cc ', 1)) - - assert_equal([0, 2, 3, 5], Reline::Unicode.ed_transpose_words('aa bb cc ', 2)) - assert_equal([0, 2, 3, 5], Reline::Unicode.ed_transpose_words('aa bb cc ', 4)) - assert_equal([3, 5, 6, 8], Reline::Unicode.ed_transpose_words('aa bb cc ', 5)) - assert_equal([3, 5, 6, 8], Reline::Unicode.ed_transpose_words('aa bb cc ', 7)) - assert_equal([3, 5, 6, 10], Reline::Unicode.ed_transpose_words('aa bb cc ', 8)) - assert_equal([3, 5, 6, 10], Reline::Unicode.ed_transpose_words('aa bb cc ', 9)) - ['sjis', 'utf-8'].each do |encoding| - texts = ['fooあ', 'barあbaz', 'aaa -', '- -', '- bbb'] - word1, word2, left, middle, right = texts.map { |text| text.encode(encoding) } - expected = [left.bytesize, (left + word1).bytesize, (left + word1 + middle).bytesize, (left + word1 + middle + word2).bytesize] - assert_equal(expected, Reline::Unicode.ed_transpose_words(left + word1 + middle + word2 + right, left.bytesize + word1.bytesize)) - assert_equal(expected, Reline::Unicode.ed_transpose_words(left + word1 + middle + word2 + right, left.bytesize + word1.bytesize + middle.bytesize)) - assert_equal(expected, Reline::Unicode.ed_transpose_words(left + word1 + middle + word2 + right, left.bytesize + word1.bytesize + middle.bytesize + word2.bytesize - 1)) - end - end - - def test_vi_big_forward_word - assert_equal(18, Reline::Unicode.vi_big_forward_word('abc---fooあbar-baz xyz', 3)) - assert_equal(8, Reline::Unicode.vi_big_forward_word('abcfooあ --', 3)) - assert_equal(7, Reline::Unicode.vi_big_forward_word('abcfooあ --'.encode('sjis'), 3)) - assert_equal(6, Reline::Unicode.vi_big_forward_word('abcfooあ', 3)) - assert_equal(3, Reline::Unicode.vi_big_forward_word('abc- ', 3)) - assert_equal(0, Reline::Unicode.vi_big_forward_word('abc', 3)) - end - - def test_vi_big_forward_end_word - assert_equal(4, Reline::Unicode.vi_big_forward_end_word('a bb c', 0)) - assert_equal(4, Reline::Unicode.vi_big_forward_end_word('- bb c', 0)) - assert_equal(1, Reline::Unicode.vi_big_forward_end_word('-a b', 0)) - assert_equal(1, Reline::Unicode.vi_big_forward_end_word('a- b', 0)) - assert_equal(1, Reline::Unicode.vi_big_forward_end_word('aa b', 0)) - assert_equal(3, Reline::Unicode.vi_big_forward_end_word(' aa b', 0)) - assert_equal(15, Reline::Unicode.vi_big_forward_end_word('abc---fooあbar-baz xyz', 3)) - assert_equal(14, Reline::Unicode.vi_big_forward_end_word('abc---fooあbar-baz xyz'.encode('sjis'), 3)) - assert_equal(3, Reline::Unicode.vi_big_forward_end_word('abcfooあ --', 3)) - assert_equal(3, Reline::Unicode.vi_big_forward_end_word('abcfooあ', 3)) - assert_equal(2, Reline::Unicode.vi_big_forward_end_word('abc- ', 3)) - assert_equal(0, Reline::Unicode.vi_big_forward_end_word('abc', 3)) - end - - def test_vi_big_backward_word - assert_equal(16, Reline::Unicode.vi_big_backward_word('abc foo-barあbaz--- xyz', 20)) - assert_equal(15, Reline::Unicode.vi_big_backward_word('abc foo-barあbaz--- xyz'.encode('sjis'), 19)) - assert_equal(2, Reline::Unicode.vi_big_backward_word(' ', 2)) - assert_equal(2, Reline::Unicode.vi_big_backward_word('ab', 2)) - assert_equal(0, Reline::Unicode.vi_big_backward_word('ab', 0)) - end - - def test_vi_forward_word - assert_equal(3, Reline::Unicode.vi_forward_word('abc---fooあbar-baz', 3)) - assert_equal(9, Reline::Unicode.vi_forward_word('abc---fooあbar-baz', 6)) - assert_equal(8, Reline::Unicode.vi_forward_word('abc---fooあbar-baz'.encode('sjis'), 6)) - assert_equal(6, Reline::Unicode.vi_forward_word('abcfooあ', 3)) - assert_equal(3, Reline::Unicode.vi_forward_word('abc---', 3)) - assert_equal(0, Reline::Unicode.vi_forward_word('abc', 3)) - assert_equal(2, Reline::Unicode.vi_forward_word('abc def', 1, true)) - assert_equal(5, Reline::Unicode.vi_forward_word('abc def', 1, false)) - end - - def test_vi_forward_end_word - assert_equal(2, Reline::Unicode.vi_forward_end_word('abc---fooあbar-baz', 3)) - assert_equal(8, Reline::Unicode.vi_forward_end_word('abc---fooあbar-baz', 6)) - assert_equal(7, Reline::Unicode.vi_forward_end_word('abc---fooあbar-baz'.encode('sjis'), 6)) - assert_equal(3, Reline::Unicode.vi_forward_end_word('abcfooあ', 3)) - assert_equal(2, Reline::Unicode.vi_forward_end_word('abc---', 3)) - assert_equal(0, Reline::Unicode.vi_forward_end_word('abc', 3)) - end - - def test_vi_backward_word - assert_equal(3, Reline::Unicode.vi_backward_word('abc foo-barあbaz--- xyz', 20)) - assert_equal(9, Reline::Unicode.vi_backward_word('abc foo-barあbaz--- xyz', 17)) - assert_equal(8, Reline::Unicode.vi_backward_word('abc foo-barあbaz--- xyz'.encode('sjis'), 16)) - assert_equal(2, Reline::Unicode.vi_backward_word(' ', 2)) - assert_equal(2, Reline::Unicode.vi_backward_word('ab', 2)) - assert_equal(0, Reline::Unicode.vi_backward_word('ab', 0)) - end - - def test_vi_first_print - assert_equal(3, Reline::Unicode.vi_first_print(' abcdefg')) - assert_equal(3, Reline::Unicode.vi_first_print(' ')) - assert_equal(0, Reline::Unicode.vi_first_print('abc')) - assert_equal(0, Reline::Unicode.vi_first_print('あ')) - assert_equal(0, Reline::Unicode.vi_first_print('あ'.encode('sjis'))) - assert_equal(0, Reline::Unicode.vi_first_print('')) - end - - def test_character_type - assert(Reline::Unicode.word_character?('a')) - assert(Reline::Unicode.word_character?('あ')) - assert(Reline::Unicode.word_character?('あ'.encode('sjis'))) - refute(Reline::Unicode.word_character?(33345.chr('sjis'))) - refute(Reline::Unicode.word_character?('-')) - refute(Reline::Unicode.word_character?(nil)) - - assert(Reline::Unicode.space_character?(' ')) - refute(Reline::Unicode.space_character?('あ')) - refute(Reline::Unicode.space_character?('あ'.encode('sjis'))) - refute(Reline::Unicode.space_character?(33345.chr('sjis'))) - refute(Reline::Unicode.space_character?('-')) - refute(Reline::Unicode.space_character?(nil)) - end -end diff --git a/test/reline/test_within_pipe.rb b/test/reline/test_within_pipe.rb deleted file mode 100644 index e5d0c12b9c..0000000000 --- a/test/reline/test_within_pipe.rb +++ /dev/null @@ -1,77 +0,0 @@ -require_relative 'helper' - -class Reline::WithinPipeTest < Reline::TestCase - def setup - Reline.send(:test_mode) - @encoding = Reline.core.encoding - @input_reader, @writer = IO.pipe(@encoding) - Reline.input = @input_reader - @reader, @output_writer = IO.pipe(@encoding) - @output = Reline.output = @output_writer - @config = Reline.core.config - @config.keyseq_timeout *= 600 if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? # for --jit-wait CI - @line_editor = Reline.core.line_editor - end - - def teardown - Reline.input = STDIN - Reline.output = STDOUT - Reline.point = 0 - Reline.delete_text - @input_reader.close - @writer.close - @reader.close - @output_writer.close - @config.reset - Reline.test_reset - end - - def test_simple_input - @writer.write("abc\n") - assert_equal 'abc', Reline.readmultiline(&proc{ true }) - end - - def test_unknown_macro - @config.add_default_key_binding('abc'.bytes, :unknown_macro) - @writer.write("abcd\n") - assert_equal 'd', Reline.readmultiline(&proc{ true }) - end - - def test_macro_commands_for_moving - @config.add_default_key_binding("\C-x\C-a".bytes, :beginning_of_line) - @config.add_default_key_binding("\C-x\C-e".bytes, :end_of_line) - @config.add_default_key_binding("\C-x\C-f".bytes, :forward_char) - @config.add_default_key_binding("\C-x\C-b".bytes, :backward_char) - @config.add_default_key_binding("\C-x\ef".bytes, :forward_word) - @config.add_default_key_binding("\C-x\eb".bytes, :backward_word) - @writer.write(" def\C-x\C-aabc\C-x\C-e ghi\C-x\C-a\C-x\C-f\C-x\C-f_\C-x\C-b\C-x\C-b_\C-x\C-f\C-x\C-f\C-x\C-f\C-x\ef_\C-x\eb\n") - assert_equal 'a_b_c def_ ghi', Reline.readmultiline(&proc{ true }) - end - - def test_macro_commands_for_editing - @config.add_default_key_binding("\C-x\C-d".bytes, :delete_char) - @config.add_default_key_binding("\C-x\C-h".bytes, :backward_delete_char) - @config.add_default_key_binding("\C-x\C-v".bytes, :quoted_insert) - #@config.add_default_key_binding("\C-xa".bytes, :self_insert) - @config.add_default_key_binding("\C-x\C-t".bytes, :transpose_chars) - @config.add_default_key_binding("\C-x\et".bytes, :transpose_words) - @config.add_default_key_binding("\C-x\eu".bytes, :upcase_word) - @config.add_default_key_binding("\C-x\el".bytes, :downcase_word) - @config.add_default_key_binding("\C-x\ec".bytes, :capitalize_word) - @writer.write("abcde\C-b\C-b\C-b\C-x\C-d\C-x\C-h\C-x\C-v\C-a\C-f\C-f EF\C-x\C-t gh\C-x\et\C-b\C-b\C-b\C-b\C-b\C-b\C-b\C-b\C-x\eu\C-x\el\C-x\ec\n") - assert_equal "a\C-aDE gh Fe", Reline.readmultiline(&proc{ true }) - end - - def test_delete_text_in_multiline - @writer.write("abc\ndef\nxyz\n") - result = Reline.readmultiline(&proc{ |str| - if str.include?('xyz') - Reline.delete_text - true - else - false - end - }) - assert_equal "abc\ndef", result - end -end diff --git a/test/reline/windows/test_key_event_record.rb b/test/reline/windows/test_key_event_record.rb deleted file mode 100644 index 25c860606a..0000000000 --- a/test/reline/windows/test_key_event_record.rb +++ /dev/null @@ -1,41 +0,0 @@ -require_relative '../helper' -return unless Reline.const_defined?(:Windows) - -class Reline::Windows - class KeyEventRecord::Test < Reline::TestCase - - def setup - # Ctrl+A - @key = Reline::Windows::KeyEventRecord.new(0x41, 1, Reline::Windows::LEFT_CTRL_PRESSED) - end - - def test_matches__with_no_arguments_raises_error - assert_raise(ArgumentError) { @key.match? } - end - - def test_matches_char_code - assert @key.match?(char_code: 0x1) - end - - def test_matches_virtual_key_code - assert @key.match?(virtual_key_code: 0x41) - end - - def test_matches_control_keys - assert @key.match?(control_keys: :CTRL) - end - - def test_doesnt_match_alt - refute @key.match?(control_keys: :ALT) - end - - def test_doesnt_match_empty_control_key - refute @key.match?(control_keys: []) - end - - def test_matches_control_keys_and_virtual_key_code - assert @key.match?(control_keys: :CTRL, virtual_key_code: 0x41) - end - - end -end diff --git a/test/reline/yamatanooroti/multiline_repl b/test/reline/yamatanooroti/multiline_repl deleted file mode 100755 index 8b82be60f4..0000000000 --- a/test/reline/yamatanooroti/multiline_repl +++ /dev/null @@ -1,257 +0,0 @@ -#!/usr/bin/env ruby - - -require 'bundler' -Bundler.require - -require 'reline' -require 'optparse' -require_relative 'termination_checker' - -opt = OptionParser.new -opt.on('--dynamic-prompt') { - Reline.prompt_proc = proc { |lines| - lines.each_with_index.map { |l, i| - "\e[1m[%04d]>\e[m " % i - } - } -} -opt.on('--broken-dynamic-prompt') { - Reline.prompt_proc = proc { |lines| - range = lines.size > 1 ? (0..(lines.size - 2)) : (0..0) - lines[range].each_with_index.map { |l, i| - '[%04d]> ' % i - } - } -} -opt.on('--dynamic-prompt-returns-empty') { - Reline.prompt_proc = proc { |l| [] } -} -opt.on('--dynamic-prompt-with-newline') { - Reline.prompt_proc = proc { |lines| - range = lines.size > 1 ? (0..(lines.size - 2)) : (0..0) - lines[range].each_with_index.map { |l, i| - '[%04d\n]> ' % i - } - } -} -opt.on('--broken-dynamic-prompt-assert-no-escape-sequence') { - Reline.prompt_proc = proc { |lines| - has_escape_sequence = lines.join.include?("\e") - (lines.size + 1).times.map { |i| - has_escape_sequence ? 'error>' : '[%04d]> ' % i - } - } -} -opt.on('--color-bold') { - Reline.output_modifier_proc = ->(output, complete:){ - output.gsub(/./) { |c| "\e[1m#{c}\e[0m" } - } -} -opt.on('--dynamic-prompt-show-line') { - Reline.prompt_proc = proc { |lines| - lines.map { |l| - '[%4.4s]> ' % l - } - } -} - -def assert_auto_indent_params(lines, line_index, byte_pointer, is_newline) - raise 'Wrong lines type' unless lines.all?(String) - - line = lines[line_index] - raise 'Wrong line_index value' unless line - - # The condition `byte_pointer <= line.bytesize` is not satisfied. Maybe bug. - # Instead, loose constraint `byte_pointer <= line.bytesize + 1` seems to be satisfied when is_newline is false. - return if is_newline - - raise 'byte_pointer out of bounds' unless byte_pointer <= line.bytesize + 1 - raise 'Invalid byte_pointer' unless line.byteslice(0, byte_pointer).valid_encoding? -end - -opt.on('--auto-indent') { - Reline.auto_indent_proc = lambda do |lines, line_index, byte_pointer, is_newline| - assert_auto_indent_params(lines, line_index, byte_pointer, is_newline) - AutoIndent.calculate_indent(lines, line_index, byte_pointer, is_newline) - end -} -opt.on('--dialog VAL') { |v| - Reline.add_dialog_proc(:simple_dialog, lambda { - return nil if v.include?('nil') - if v.include?('simple') - contents = <<~RUBY.split("\n") - Ruby is... - A dynamic, open source programming - language with a focus on simplicity - and productivity. It has an elegant - syntax that is natural to read and - easy to write. - RUBY - elsif v.include?('long') - contents = <<~RUBY.split("\n") - Ruby is... - A dynamic, open - source programming - language with a - focus on simplicity - and productivity. - It has an elegant - syntax that is - natural to read - and easy to write. - RUBY - elsif v.include?('fullwidth') - contents = <<~RUBY.split("\n") - Rubyとは... - - オープンソースの動的なプログラミン - グ言語で、シンプルさと高い生産性を - 備えています。エレガントな文法を持 - ち、自然に読み書きができます。 - RUBY - end - if v.include?('scrollkey') - dialog.trap_key = nil - if key and key.match?(dialog.name) - if dialog.pointer.nil? - dialog.pointer = 0 - elsif dialog.pointer >= (contents.size - 1) - dialog.pointer = 0 - else - dialog.pointer += 1 - end - end - dialog.trap_key = [?j.ord] - height = 4 - end - scrollbar = false - if v.include?('scrollbar') - scrollbar = true - end - if v.include?('alt-scrollbar') - scrollbar = true - end - Reline::DialogRenderInfo.new(pos: cursor_pos, contents: contents, height: height, scrollbar: scrollbar, face: :completion_dialog) - }) - if v.include?('alt-scrollbar') - ENV['RELINE_ALT_SCROLLBAR'] = '1' - end -} -opt.on('--complete') { - Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil| - %w{String ScriptError SyntaxError Signal}.select{ |c| c.start_with?(target) } - } -} -opt.on('--complete-menu-with-perfect-match') { - Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil| - %w{abs abs2}.select{ |c| c.start_with?(target) } - } -} -opt.on('--autocomplete') { - Reline.autocompletion = true - Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil| - %w{String Struct Symbol ScriptError SyntaxError Signal}.select{ |c| c.start_with?(target) } - } -} -opt.on('--autocomplete-empty') { - Reline.autocompletion = true - Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil| [] } -} -opt.on('--autocomplete-long') { - Reline.autocompletion = true - Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil| - %w{ - String - Struct - Symbol - StopIteration - SystemCallError - SystemExit - SystemStackError - ScriptError - SyntaxError - Signal - SizedQueue - Set - SecureRandom - Socket - StringIO - StringScanner - Shellwords - Syslog - Singleton - SDBM - }.select{ |c| c.start_with?(target) } - } -} -opt.on('--autocomplete-super-long') { - Reline.autocompletion = true - Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil| - c = +'A' - 2000.times.map{ s = "Str_#{c}"; c.succ!; s }.select{ |c| c.start_with?(target) } - } -} - -opt.on('--autocomplete-width-long') { - Reline.autocompletion = true - Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil| - %w{ - remove_instance_variable - respond_to? - ruby2_keywords - rand - readline - readlines - require - require_relative - raise - respond_to_missing? - redo - rescue - retry - return - }.select{ |c| c.start_with?(target) } - } -} -opt.parse!(ARGV) - -begin - stty_save = `stty -g`.chomp -rescue -end - -begin - prompt = ENV['RELINE_TEST_PROMPT'] || "\e[1mprompt>\e[m " - puts 'Multiline REPL.' - while code = Reline.readmultiline(prompt, true) { |code| TerminationChecker.terminated?(code) } - case code.chomp - when 'exit', 'quit', 'q' - exit 0 - when '' - # NOOP - else - begin - result = eval(code) - puts "=> #{result.inspect}" - rescue ScriptError, StandardError => e - puts "Traceback (most recent call last):" - e.backtrace.reverse_each do |f| - puts " #{f}" - end - puts e.message - end - end - end -rescue Interrupt - puts '^C' - `stty #{stty_save}` if stty_save - exit 0 -ensure - `stty #{stty_save}` if stty_save -end -begin - puts -rescue Errno::EIO - # Maybe the I/O has been closed. -end diff --git a/test/reline/yamatanooroti/termination_checker.rb b/test/reline/yamatanooroti/termination_checker.rb deleted file mode 100644 index b97c798c59..0000000000 --- a/test/reline/yamatanooroti/termination_checker.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'ripper' - -module TerminationChecker - def self.terminated?(code) - Ripper.sexp(code) ? true : false - end -end - -module AutoIndent - def self.calculate_indent(lines, line_index, byte_pointer, is_newline) - if is_newline - 2 * nesting_level(lines[0..line_index - 1]) - else - lines = lines.dup - lines[line_index] = lines[line_index]&.byteslice(0, byte_pointer) - prev_level = nesting_level(lines[0..line_index - 1]) - level = nesting_level(lines[0..line_index]) - 2 * level if level < prev_level - end - end - - def self.nesting_level(lines) - code = lines.join("\n") - code.scan(/if|def|\(|\[|\{/).size - code.scan(/end|\)|\]|\}/).size - end -end diff --git a/test/reline/yamatanooroti/test_rendering.rb b/test/reline/yamatanooroti/test_rendering.rb deleted file mode 100644 index aff5c0462b..0000000000 --- a/test/reline/yamatanooroti/test_rendering.rb +++ /dev/null @@ -1,1915 +0,0 @@ -require 'reline' - -begin - require 'yamatanooroti' - - class Reline::RenderingTest < Yamatanooroti::TestCase - - FACE_CONFIGS = { no_config: "", valid_config: <<~VALID_CONFIG, incomplete_config: <<~INCOMPLETE_CONFIG } - require "reline" - Reline::Face.config(:completion_dialog) do |face| - face.define :default, foreground: :white, background: :blue - face.define :enhanced, foreground: :white, background: :magenta - face.define :scrollbar, foreground: :white, background: :blue - end - VALID_CONFIG - require "reline" - Reline::Face.config(:completion_dialog) do |face| - face.define :default, foreground: :white, background: :black - face.define :scrollbar, foreground: :white, background: :cyan - end - INCOMPLETE_CONFIG - - def iterate_over_face_configs(&block) - FACE_CONFIGS.each do |config_name, face_config| - config_file = Tempfile.create(%w{face_config- .rb}) - config_file.write face_config - block.call(config_name, config_file) - ensure - config_file.close - File.delete(config_file) - end - end - - def setup - @pwd = Dir.pwd - suffix = '%010d' % Random.rand(0..65535) - @tmpdir = File.join(File.expand_path(Dir.tmpdir), "test_reline_config_#{$$}_#{suffix}") - begin - Dir.mkdir(@tmpdir) - rescue Errno::EEXIST - FileUtils.rm_rf(@tmpdir) - Dir.mkdir(@tmpdir) - end - @inputrc_backup = ENV['INPUTRC'] - @inputrc_file = ENV['INPUTRC'] = File.join(@tmpdir, 'temporaty_inputrc') - File.unlink(@inputrc_file) if File.exist?(@inputrc_file) - end - - def teardown - FileUtils.rm_rf(@tmpdir) - ENV['INPUTRC'] = @inputrc_backup - ENV.delete('RELINE_TEST_PROMPT') if ENV['RELINE_TEST_PROMPT'] - end - - def test_history_back - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write(":a\n") - write("\C-p") - assert_screen(<<~EOC) - Multiline REPL. - prompt> :a - => :a - prompt> :a - EOC - close - end - - def test_backspace - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write(":abc\C-h\n") - assert_screen(<<~EOC) - Multiline REPL. - prompt> :ab - => :ab - prompt> - EOC - close - end - - def test_autowrap - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write('01234567890123456789012') - assert_screen(<<~EOC) - Multiline REPL. - prompt> 0123456789012345678901 - 2 - EOC - close - end - - def test_fullwidth - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write(":あ\n") - assert_screen(<<~EOC) - Multiline REPL. - prompt> :あ - => :あ - prompt> - EOC - close - end - - def test_two_fullwidth - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write(":あい\n") - assert_screen(<<~EOC) - Multiline REPL. - prompt> :あい - => :あい - prompt> - EOC - close - end - - def test_finish_autowrapped_line - start_terminal(10, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("[{'user'=>{'email'=>'a@a', 'id'=>'ABC'}, 'version'=>4, 'status'=>'succeeded'}]\n") - expected = [{'user'=>{'email'=>'a@a', 'id'=>'ABC'}, 'version'=>4, 'status'=>'succeeded'}].inspect - assert_screen(<<~EOC) - Multiline REPL. - prompt> [{'user'=>{'email'=>'a@a', 'id'= - >'ABC'}, 'version'=>4, 'status'=>'succee - ded'}] - #{fold_multiline("=> " + expected, 40)} - prompt> - EOC - close - end - - def test_finish_autowrapped_line_in_the_middle_of_lines - start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("[{'user'=>{'email'=>'abcdef@abcdef', 'id'=>'ABC'}, 'version'=>4, 'status'=>'succeeded'}]#{"\C-b"*7}") - write("\n") - expected = [{'user'=>{'email'=>'abcdef@abcdef', 'id'=>'ABC'}, 'version'=>4, 'status'=>'succeeded'}].inspect - assert_screen(<<~EOC) - Multiline REPL. - prompt> [{'user'=>{'email'=>'a - bcdef@abcdef', 'id'=>'ABC'}, ' - version'=>4, 'status'=>'succee - ded'}] - #{fold_multiline("=> " + expected, 30)} - prompt> - EOC - close - end - - def test_finish_autowrapped_line_in_the_middle_of_multilines - omit if RUBY_VERSION < '2.7' - start_terminal(30, 16, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("<<~EOM\n ABCDEFG\nEOM\n") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> <<~EOM - prompt> ABCDEF - G - prompt> EOM - => "ABCDEFG\n" - prompt> - EOC - close - end - - def test_prompt - write_inputrc <<~'LINES' - "abc": "123" - LINES - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("abc\n") - assert_screen(<<~EOC) - Multiline REPL. - prompt> 123 - => 123 - prompt> - EOC - close - end - - def test_mode_string_emacs - write_inputrc <<~LINES - set show-mode-in-prompt on - LINES - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - assert_screen(<<~EOC) - Multiline REPL. - @prompt> - EOC - close - end - - def test_mode_string_vi - write_inputrc <<~LINES - set editing-mode vi - set show-mode-in-prompt on - LINES - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write(":a\n\C-[k") - write("i\n:a") - write("\C-[h") - assert_screen(<<~EOC) - (ins)prompt> :a - => :a - (ins)prompt> :a - => :a - (cmd)prompt> :a - EOC - close - end - - def test_original_mode_string_emacs - write_inputrc <<~LINES - set show-mode-in-prompt on - set emacs-mode-string [emacs] - LINES - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - assert_screen(<<~EOC) - Multiline REPL. - [emacs]prompt> - EOC - close - end - - def test_original_mode_string_with_quote - write_inputrc <<~LINES - set show-mode-in-prompt on - set emacs-mode-string "[emacs]" - LINES - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - assert_screen(<<~EOC) - Multiline REPL. - [emacs]prompt> - EOC - close - end - - def test_original_mode_string_vi - write_inputrc <<~LINES - set editing-mode vi - set show-mode-in-prompt on - set vi-ins-mode-string "{InS}" - set vi-cmd-mode-string "{CmD}" - LINES - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write(":a\n\C-[k") - assert_screen(<<~EOC) - Multiline REPL. - {InS}prompt> :a - => :a - {CmD}prompt> :a - EOC - close - end - - def test_mode_string_vi_changing - write_inputrc <<~LINES - set editing-mode vi - set show-mode-in-prompt on - LINES - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write(":a\C-[ab\C-[ac\C-h\C-h\C-h\C-h:a") - assert_screen(<<~EOC) - Multiline REPL. - (ins)prompt> :a - EOC - close - end - - def test_esc_input - omit if Reline::IOGate.win? - start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def\C-aabc") - write("\e") # single ESC - sleep 1 - write("A") - write("B\eAC") # ESC + A (M-A, no key specified in Reline::KeyActor::Emacs) - assert_screen(<<~EOC) - Multiline REPL. - prompt> abcABCdef - EOC - close - end - - def test_prompt_with_escape_sequence - ENV['RELINE_TEST_PROMPT'] = "\1\e[30m\2prompt> \1\e[m\2" - start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("123\n") - assert_screen(<<~EOC) - Multiline REPL. - prompt> 123 - => 123 - prompt> - EOC - close - end - - def test_prompt_with_escape_sequence_and_autowrap - ENV['RELINE_TEST_PROMPT'] = "\1\e[30m\2prompt> \1\e[m\2" - start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("1234567890123\n") - assert_screen(<<~EOC) - Multiline REPL. - prompt> 123456789012 - 3 - => 1234567890123 - prompt> - EOC - close - end - - def test_readline_with_multiline_input - start_terminal(5, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dynamic-prompt}, startup_message: 'Multiline REPL.') - write("def foo\n bar\nend\n") - write("Reline.readline('prompt> ')\n") - write("\C-p\C-p") - assert_screen(<<~EOC) - => :foo - [0000]> Reline.readline('prompt> ') - prompt> def foo - bar - end - EOC - close - end - - def test_multiline_and_autowrap - start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def aaaaaaaaaa\n 33333333\n end\C-a\C-pputs\C-e\e\C-m888888888888888") - assert_screen(<<~EOC) - Multiline REPL. - prompt> def aaaaaaaa - aa - prompt> puts 333333 - 33 - prompt> 888888888888 - 888 - prompt> e - nd - EOC - close - end - - def test_multiline_add_new_line_and_autowrap - start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def aaaaaaaaaa") - write("\n") - write(" bbbbbbbbbbbb") - write("\n") - assert_screen(<<~EOC) - Multiline REPL. - prompt> def aaaaaaaa - aa - prompt> bbbbbbbbbb - bb - prompt> - EOC - close - end - - def test_clear - start_terminal(10, 15, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("3\C-l") - assert_screen(<<~EOC) - prompt> 3 - EOC - close - end - - def test_clear_multiline_and_autowrap - start_terminal(10, 15, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def aaaaaa\n 3\n\C-lend") - assert_screen(<<~EOC) - prompt> def aaa - aaa - prompt> 3 - prompt> end - EOC - close - end - - def test_nearest_cursor - start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def ああ\n :いい\nend\C-pbb\C-pcc") - assert_screen(<<~EOC) - Multiline REPL. - prompt> def ccああ - prompt> :bbいい - prompt> end - EOC - close - end - - def test_delete_line - start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def a\n\nend\C-p\C-h") - assert_screen(<<~EOC) - Multiline REPL. - prompt> def a - prompt> end - EOC - close - end - - def test_last_line_of_screen - start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("\n\n\n\n\ndef a\nend") - assert_screen(<<~EOC) - prompt> - prompt> - prompt> - prompt> def a - prompt> end - EOC - close - end - - # c17a09b7454352e2aff5a7d8722e80afb73e454b - def test_autowrap_at_last_line_of_screen - start_terminal(5, 15, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def a\nend\n\C-p") - assert_screen(<<~EOC) - prompt> def a - prompt> end - => :a - prompt> def a - prompt> end - EOC - close - end - - # f002483b27cdb325c5edf9e0fe4fa4e1c71c4b0e - def test_insert_line_in_the_middle_of_line - start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("333\C-b\C-b\e\C-m8") - assert_screen(<<~EOC) - Multiline REPL. - prompt> 3 - prompt> 833 - EOC - close - end - - # 9d8978961c5de5064f949d56d7e0286df9e18f43 - def test_insert_line_in_the_middle_of_line_at_last_line_of_screen - start_terminal(3, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("333333333333333\C-a\C-f\e\C-m") - assert_screen(<<~EOC) - prompt> 3 - prompt> 333333333333 - 33 - EOC - close - end - - def test_insert_after_clear - start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def a\n 01234\nend\C-l\C-p5678") - assert_screen(<<~EOC) - prompt> def a - prompt> 056781234 - prompt> end - EOC - close - end - - def test_foced_newline_insertion - start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - #write("def a\nend\C-p\C-e\e\C-m 3") - write("def a\nend\C-p\C-e\e\x0D") - assert_screen(<<~EOC) - Multiline REPL. - prompt> def a - prompt> - prompt> end - EOC - close - end - - def test_multiline_incremental_search - start_terminal(6, 25, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def a\n 8\nend\ndef b\n 3\nend\C-s8") - assert_screen(<<~EOC) - prompt> 8 - prompt> end - => :a - (i-search)`8'def a - (i-search)`8' 8 - (i-search)`8'end - EOC - close - end - - def test_multiline_incremental_search_finish - start_terminal(6, 25, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def a\n 8\nend\ndef b\n 3\nend\C-r8\C-j") - assert_screen(<<~EOC) - prompt> 8 - prompt> end - => :a - prompt> def a - prompt> 8 - prompt> end - EOC - close - end - - def test_binding_for_vi_movement_mode - write_inputrc <<~LINES - set editing-mode vi - "\\C-a": vi-movement-mode - LINES - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write(":1234\C-ahhhi0") - assert_screen(<<~EOC) - Multiline REPL. - prompt> :01234 - EOC - close - end - - def test_broken_prompt_list - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --broken-dynamic-prompt}, startup_message: 'Multiline REPL.') - write("def hoge\n 3\nend") - assert_screen(<<~EOC) - Multiline REPL. - [0000]> def hoge - [0001]> 3 - [0001]> end - EOC - close - end - - def test_no_escape_sequence_passed_to_dynamic_prompt - start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete --color-bold --broken-dynamic-prompt-assert-no-escape-sequence}, startup_message: 'Multiline REPL.') - write("%[ S") - write("\n") - assert_screen(<<~EOC) - Multiline REPL. - [0000]> %[ S - [0001]> - EOC - close - end - - def test_bracketed_paste - omit if Reline.core.io_gate.win? - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("\e[200~def hoge\r\t3\rend\e[201~") - assert_screen(<<~EOC) - Multiline REPL. - prompt> def hoge - prompt> 3 - prompt> end - EOC - write("\e[200~.tap do\r\t4\r\t5\rend\e[201~") - assert_screen(<<~EOC) - prompt> 3 - prompt> end.tap do - prompt> 4 - prompt> 5 - prompt> end - EOC - close - end - - def test_bracketed_paste_with_undo_redo - omit if Reline.core.io_gate.win? - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("abc") - write("\e[200~def hoge\r\t3\rend\e[201~") - write("\C-_") - assert_screen(<<~EOC) - Multiline REPL. - prompt> abc - EOC - write("\e\C-_") - assert_screen(<<~EOC) - Multiline REPL. - prompt> abcdef hoge - prompt> 3 - prompt> end - EOC - close - end - - def test_backspace_until_returns_to_initial - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("ABC") - write("\C-h\C-h\C-h") - assert_screen(<<~EOC) - Multiline REPL. - prompt> - EOC - close - end - - def test_longer_than_screen_height - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write(<<~EOC.chomp) - def each_top_level_statement - initialize_input - catch(:TERM_INPUT) do - loop do - begin - prompt - unless l = lex - throw :TERM_INPUT if @line == '' - else - @line_no += l.count("\n") - next if l == "\n" - @line.concat l - if @code_block_open or @ltype or @continue or @indent > 0 - next - end - end - if @line != "\n" - @line.force_encoding(@io.encoding) - yield @line, @exp_line_no - end - break if @io.eof? - @line = '' - @exp_line_no = @line_no - # - @indent = 0 - rescue TerminateLineInput - initialize_input - prompt - end - end - end - end - EOC - assert_screen(<<~EOC) - prompt> prompt - prompt> end - prompt> end - prompt> end - prompt> end - EOC - write("\C-p" * 6) - assert_screen(<<~EOC) - prompt> rescue Terminate - LineInput - prompt> initialize_inp - ut - prompt> prompt - EOC - write("\C-n" * 4) - assert_screen(<<~EOC) - prompt> initialize_inp - ut - prompt> prompt - prompt> end - prompt> end - EOC - close - end - - def test_longer_than_screen_height_nearest_cursor_with_scroll_back - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write(<<~EOC.chomp) - if 1 - if 2 - if 3 - if 4 - puts - end - end - end - end - EOC - write("\C-p" * 4 + "\C-e" + "\C-p" * 4) - write("2") - assert_screen(<<~EOC) - prompt> if 12 - prompt> if 2 - prompt> if 3 - prompt> if 4 - prompt> puts - EOC - close - end - - def test_update_cursor_correctly_when_just_cursor_moving - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def hoge\n 01234678") - write("\C-p") - write("\C-b") - write("\C-n") - write('5') - write("\C-e") - write('9') - assert_screen(<<~EOC) - Multiline REPL. - prompt> def hoge - prompt> 0123456789 - EOC - close - end - - def test_auto_indent - start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.') - "def hoge\nputs(\n1,\n2\n)\nend".lines do |line| - write line - end - assert_screen(<<~EOC) - Multiline REPL. - prompt> def hoge - prompt> puts( - prompt> 1, - prompt> 2 - prompt> ) - prompt> end - EOC - close - end - - def test_auto_indent_when_inserting_line - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.') - write 'aa(bb(cc(dd(ee(' - write "\C-b" * 5 + "\n" - assert_screen(<<~EOC) - Multiline REPL. - prompt> aa(bb(cc(d - prompt> d(ee( - EOC - close - end - - def test_auto_indent_multibyte_insert_line - start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.') - write "if true\n" - write "あいうえお\n" - 4.times { write "\C-b\C-b\C-b\C-b\e\r" } - assert_screen(<<~EOC) - Multiline REPL. - prompt> if true - prompt> あ - prompt> い - prompt> う - prompt> え - prompt> お - prompt> - EOC - close - end - - def test_newline_after_wrong_indent - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.') - write "if 1\n aa" - write "\n" - assert_screen(<<~EOC) - Multiline REPL. - prompt> if 1 - prompt> aa - prompt> - EOC - close - end - - def test_suppress_auto_indent_just_after_pasted - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.') - write("def hoge\n [[\n 3]]\ned") - write("\C-bn") - assert_screen(<<~EOC) - Multiline REPL. - prompt> def hoge - prompt> [[ - prompt> 3]] - prompt> end - EOC - close - end - - def test_suppress_auto_indent_for_adding_newlines_in_pasting - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.') - write("<<~Q\n") - write("{\n #\n}") - write("#") - assert_screen(<<~EOC) - Multiline REPL. - prompt> <<~Q - prompt> { - prompt> # - prompt> }# - EOC - close - end - - def test_auto_indent_with_various_spaces - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.') - write "(\n\C-v" - write "\C-k\n\C-v" - write "\C-k)" - assert_screen(<<~EOC) - Multiline REPL. - prompt> ( - prompt> ^K - prompt> ) - EOC - close - end - - def test_autowrap_in_the_middle_of_a_line - start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def abcdefg; end\C-b\C-b\C-b\C-b\C-b") - %w{h i}.each do |c| - write(c) - end - assert_screen(<<~EOC) - Multiline REPL. - prompt> def abcdefgh - i; end - EOC - close - end - - def test_newline_in_the_middle_of_lines - start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def hoge\n 1\n 2\n 3\n 4\nend\n") - write("\C-p\C-p\C-p\C-e\n") - assert_screen(<<~EOC) - prompt> def hoge - prompt> 1 - prompt> 2 - prompt> 3 - prompt> - EOC - close - end - - def test_ed_force_submit_in_the_middle_of_lines - write_inputrc <<~LINES - "\\C-a": ed_force_submit - LINES - start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def hoge\nend") - write("\C-p\C-a") - assert_screen(<<~EOC) - Multiline REPL. - prompt> def hoge - prompt> end - => :hoge - prompt> - EOC - close - end - - def test_dynamic_prompt_returns_empty - start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dynamic-prompt-returns-empty}, startup_message: 'Multiline REPL.') - write("def hoge\nend\n") - assert_screen(<<~EOC) - Multiline REPL. - prompt> def hoge - prompt> end - => :hoge - prompt> - EOC - close - end - - def test_reset_rest_height_when_clear_screen - start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("\n\n\n\C-l3\n") - assert_screen(<<~EOC) - prompt> 3 - => 3 - prompt> - EOC - close - end - - def test_meta_key - start_terminal(30, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def ge\ebho") - assert_screen(<<~EOC) - Multiline REPL. - prompt> def hoge - EOC - close - end - - def test_not_meta_key - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("おだんご") # "だ" in UTF-8 contains "\xA0" - assert_screen(<<~EOC) - Multiline REPL. - prompt> おだんご - EOC - close - end - - def test_force_enter - start_terminal(30, 120, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def hoge\nend\C-p\C-e") - write("\e\x0D") - assert_screen(<<~EOC) - Multiline REPL. - prompt> def hoge - prompt> - prompt> end - EOC - close - end - - def test_nontty - omit if Reline.core.io_gate.win? - cmd = %Q{ruby -e 'puts(%Q{ello\C-ah\C-e})' | ruby -I#{@pwd}/lib -rreline -e 'p Reline.readline(%{> })' | ruby -e 'print STDIN.read'} - start_terminal(40, 50, ['bash', '-c', cmd]) - assert_screen(<<~'EOC') - > hello - "hello" - EOC - close - end - - def test_eof_with_newline - omit if Reline.core.io_gate.win? - cmd = %Q{ruby -e 'print(%Q{abc def \\e\\r})' | ruby -I#{@pwd}/lib -rreline -e 'p Reline.readline(%{> })'} - start_terminal(40, 50, ['bash', '-c', cmd]) - assert_screen(<<~'EOC') - > abc def - "abc def " - EOC - close - end - - def test_eof_without_newline - omit if Reline.core.io_gate.win? - cmd = %Q{ruby -e 'print(%{hello})' | ruby -I#{@pwd}/lib -rreline -e 'p Reline.readline(%{> })'} - start_terminal(40, 50, ['bash', '-c', cmd]) - assert_screen(<<~'EOC') - > hello - "hello" - EOC - close - end - - def test_em_set_mark_and_em_exchange_mark - start_terminal(10, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("aaa bbb ccc ddd\eb\eb\e\x20\eb\C-x\C-xX\C-x\C-xY") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> aaa Ybbb Xccc ddd - EOC - close - end - - def test_multiline_completion - start_terminal(10, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --complete}, startup_message: 'Multiline REPL.') - write("def hoge\n St\n St\C-p\t") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> def hoge - prompt> String - prompt> St - EOC - close - end - - def test_completion_journey_2nd_line - write_inputrc <<~LINES - set editing-mode vi - LINES - start_terminal(10, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --complete}, startup_message: 'Multiline REPL.') - write("def hoge\n S\C-n") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> def hoge - prompt> String - EOC - close - end - - def test_completion_journey_with_empty_line - write_inputrc <<~LINES - set editing-mode vi - LINES - start_terminal(10, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --complete}, startup_message: 'Multiline REPL.') - write("\C-n\C-p") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> - EOC - close - end - - def test_completion_menu_is_displayed_horizontally - start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --complete}, startup_message: 'Multiline REPL.') - write("S\t\t") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> S - ScriptError String - Signal SyntaxError - EOC - close - end - - def test_show_all_if_ambiguous_on - write_inputrc <<~LINES - set show-all-if-ambiguous on - LINES - start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --complete}, startup_message: 'Multiline REPL.') - write("S\t") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> S - ScriptError String - Signal SyntaxError - EOC - close - end - - def test_show_all_if_ambiguous_on_and_menu_with_perfect_match - write_inputrc <<~LINES - set show-all-if-ambiguous on - LINES - start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --complete-menu-with-perfect-match}, startup_message: 'Multiline REPL.') - write("a\t") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> abs - abs abs2 - EOC - close - end - - def test_simple_dialog - iterate_over_face_configs do |config_name, config_file| - start_terminal(20, 50, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.') - write('a') - write('b') - write('c') - write("\C-h") - close - assert_screen(<<~'EOC', "Failed with `#{config_name}` in Face") - Multiline REPL. - prompt> ab - Ruby is... - A dynamic, open source programming - language with a focus on simplicity - and productivity. It has an elegant - syntax that is natural to read and - easy to write. - EOC - end - end - - def test_simple_dialog_at_right_edge - iterate_over_face_configs do |config_name, config_file| - start_terminal(20, 40, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.') - write('a') - write('b') - write('c') - write("\C-h") - close - assert_screen(<<~'EOC') - Multiline REPL. - prompt> ab - Ruby is... - A dynamic, open source programming - language with a focus on simplicity - and productivity. It has an elegant - syntax that is natural to read and - easy to write. - EOC - end - end - - def test_dialog_scroll_pushup_condition - iterate_over_face_configs do |config_name, config_file| - start_terminal(10, 50, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write("\n" * 10) - write("if 1\n sSts\nend") - write("\C-p\C-h\C-e\C-h") - assert_screen(<<~'EOC') - prompt> - prompt> - prompt> - prompt> - prompt> - prompt> - prompt> if 1 - prompt> St - prompt> enString - Struct - EOC - close - end - end - - def test_simple_dialog_with_scroll_screen - iterate_over_face_configs do |config_name, config_file| - start_terminal(5, 50, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: /prompt>/) - write("if 1\n 2\n 3\n 4\n 5\n 6") - write("\C-p\C-n\C-p\C-p\C-p#") - close - assert_screen(<<~'EOC') - prompt> 2 - prompt> 3# - prompt> 4 - prompt> 5 Ruby is... - prompt> 6 A dynamic, open source programming - EOC - end - end - - def test_autocomplete_at_bottom - start_terminal(15, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write('def hoge' + "\C-m" * 10 + "end\C-p ") - write('S') - assert_screen(<<~'EOC') - Multiline REPL. - prompt> def hoge - prompt> - prompt> - prompt> String - prompt> Struct - prompt> Symbol - prompt> ScriptError - prompt> SyntaxError - prompt> Signal - prompt> S - prompt> end - EOC - close - end - - def test_autocomplete_return_to_original - start_terminal(20, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write('S') - write('t') - write('r') - 3.times{ write("\C-i") } - assert_screen(<<~'EOC') - Multiline REPL. - prompt> Str - String - Struct - EOC - close - end - - def test_autocomplete_target_is_wrapped - start_terminal(20, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write(' ') - write('S') - write('t') - write('r') - assert_screen(<<~'EOC') - Multiline REPL. - prompt> St - r - String - Struct - EOC - close - end - - def test_autocomplete_target_at_end_of_line - start_terminal(20, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write(' ') - write('Str') - write("\C-i") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> Str - ing String - Struct - EOC - close - end - - def test_autocomplete_completed_input_is_wrapped - start_terminal(20, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write(' ') - write('Str') - write("\C-i") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> Stri - ng String - Struct - EOC - close - end - - def test_force_insert_before_autocomplete - start_terminal(20, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write('Sy') - write(";St\t\t") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> Sy;Struct - String - Struct - EOC - close - end - - def test_simple_dialog_with_scroll_key - start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog long,scrollkey}, startup_message: 'Multiline REPL.') - write('a') - 5.times{ write('j') } - assert_screen(<<~'EOC') - Multiline REPL. - prompt> a - A dynamic, open - source programming - language with a - focus on simplicity - EOC - close - end - - def test_simple_dialog_scrollbar_with_moving_to_right - start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog long,scrollkey,scrollbar}, startup_message: 'Multiline REPL.') - 6.times{ write('j') } - write('a') - assert_screen(<<~'EOC') - Multiline REPL. - prompt> a - source programming ▄ - language with a █ - focus on simplicity - and productivity. - EOC - close - end - - def test_simple_dialog_scrollbar_with_moving_to_left - start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog long,scrollkey,scrollbar}, startup_message: 'Multiline REPL.') - write('a') - 6.times{ write('j') } - write("\C-h") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> - source programming ▄ - language with a █ - focus on simplicity - and productivity. - EOC - close - end - - def test_dialog_with_fullwidth_chars - ENV['RELINE_TEST_PROMPT'] = '> ' - start_terminal(20, 5, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog fullwidth,scrollkey,scrollbar}, startup_message: 'Multiline REPL.') - 6.times{ write('j') } - assert_screen(<<~'EOC') - Multi - line - REPL. - > - オー - グ言▄ - 備え█ - ち、█ - EOC - close - end - - def test_dialog_with_fullwidth_chars_split - ENV['RELINE_TEST_PROMPT'] = '> ' - start_terminal(20, 6, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog fullwidth,scrollkey,scrollbar}, startup_message: 'Multiline REPL.') - 6.times{ write('j') } - assert_screen(<<~'EOC') - Multil - ine RE - PL. - > - オー - グ言 ▄ - 備え █ - ち、 █ - EOC - close - end - - def test_autocomplete_empty - start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write('Street') - assert_screen(<<~'EOC') - Multiline REPL. - prompt> Street - EOC - close - end - - def test_autocomplete - start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write('Str') - assert_screen(<<~'EOC') - Multiline REPL. - prompt> Str - String - Struct - EOC - close - end - - def test_autocomplete_empty_string - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write("\C-i") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> String - String █ - Struct ▀ - Symbol - EOC - close - end - - def test_paste_code_with_tab_indent_does_not_fail - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete-empty}, startup_message: 'Multiline REPL.') - write("2.times do\n\tputs\n\tputs\nend") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> 2.times do - prompt> puts - prompt> puts - prompt> end - EOC - close - end - - def test_autocomplete_after_2nd_line - start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write("def hoge\n Str") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> def hoge - prompt> Str - String - Struct - EOC - close - end - - def test_autocomplete_rerender_under_dialog - start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write("def hoge\n\n 123456\n 456789\nend\C-p\C-p\C-p a = Str") - write('i') - assert_screen(<<~'EOC') - Multiline REPL. - prompt> def hoge - prompt> a = Stri - prompt> 1234String - prompt> 456789 - prompt> end - EOC - close - end - - def test_rerender_multiple_dialog - start_terminal(20, 60, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete --dialog simple}, startup_message: 'Multiline REPL.') - write("if\n abcdef\n 123456\n 456789\nend\C-p\C-p\C-p\C-p Str") - write("\t") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> if String - prompt> aStringRuby is... - prompt> 1StructA dynamic, open source programming - prompt> 456789 language with a focus on simplicity - prompt> end and productivity. It has an elegant - syntax that is natural to read and - easy to write. - EOC - close - end - - def test_autocomplete_long_with_scrollbar - start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete-long}, startup_message: 'Multiline REPL.') - write('S') - assert_screen(<<~'EOC') - Multiline REPL. - prompt> S - String █ - Struct █ - Symbol █ - StopIteration █ - SystemCallError █ - SystemExit █ - SystemStackError█ - ScriptError █ - SyntaxError █ - Signal █ - SizedQueue █ - Set - SecureRandom - Socket - StringIO - EOC - write("\C-i" * 16) - assert_screen(<<~'EOC') - Multiline REPL. - prompt> StringScanner - Struct ▄ - Symbol █ - StopIteration █ - SystemCallError █ - SystemExit █ - SystemStackError█ - ScriptError █ - SyntaxError █ - Signal █ - SizedQueue █ - Set █ - SecureRandom ▀ - Socket - StringIO - StringScanner - EOC - close - end - - def test_autocomplete_super_long_scroll_to_bottom - start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete-super-long}, startup_message: 'Multiline REPL.') - shift_tab = [27, 91, 90] - write('S' + shift_tab.map(&:chr).join) - assert_screen(<<~'EOC') - Multiline REPL. - prompt> Str_BXX - Str_BXJ - Str_BXK - Str_BXL - Str_BXM - Str_BXN - Str_BXO - Str_BXP - Str_BXQ - Str_BXR - Str_BXS - Str_BXT - Str_BXU - Str_BXV - Str_BXW - Str_BXX▄ - EOC - close - end - - def test_autocomplete_super_long_and_backspace - start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete-super-long}, startup_message: 'Multiline REPL.') - shift_tab = [27, 91, 90] - write('S' + shift_tab.map(&:chr).join) - write("\C-h") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> Str_BX - Str_BX █ - Str_BXA█ - Str_BXB█ - Str_BXC█ - Str_BXD█ - Str_BXE█ - Str_BXF█ - Str_BXG█ - Str_BXH█ - Str_BXI - Str_BXJ - Str_BXK - Str_BXL - Str_BXM - Str_BXN - EOC - close - end - - def test_dialog_callback_returns_nil - start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog nil}, startup_message: 'Multiline REPL.') - write('a') - assert_screen(<<~'EOC') - Multiline REPL. - prompt> a - EOC - close - end - - def test_dialog_narrower_than_screen - start_terminal(20, 11, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.') - assert_screen(<<~'EOC') - Multiline R - EPL. - prompt> - Ruby is... - A dynamic, - language wi - and product - syntax that - easy to wri - EOC - close - end - - def test_dialog_narrower_than_screen_with_scrollbar - start_terminal(20, 11, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete-long}, startup_message: 'Multiline REPL.') - write('S' + "\C-i" * 3) - assert_screen(<<~'EOC') - Multiline R - EPL. - prompt> Sym - String █ - Struct █ - Symbol █ - StopIterat█ - SystemCall█ - SystemExit█ - SystemStac█ - ScriptErro█ - SyntaxErro█ - Signal █ - SizedQueue█ - Set - SecureRand - Socket - StringIO - EOC - close - end - - def test_dialog_with_fullwidth_scrollbar - start_terminal(20, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple,scrollkey,alt-scrollbar}, startup_message: 'Multiline REPL.') - assert_screen(<<~'EOC') - Multiline REPL. - prompt> - Ruby is... :: - A dynamic, open source programming :: - language with a focus on simplicity'' - and productivity. It has an elegant - EOC - close - end - - def test_rerender_argument_prompt_after_pasting - start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write('abcdef') - write("\e3\C-h") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> abc - EOC - close - end - - def test_autocomplete_old_dialog_width_greater_than_dialog_width - start_terminal(40, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete-width-long}, startup_message: 'Multiline REPL.') - write("0+ \n12345678901234") - write("\C-p") - write("r") - write("a") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> 0+ ra - prompt> 123rand 901234 - raise - EOC - close - end - - def test_scroll_at_bottom_for_dialog - start_terminal(10, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write("\n\n\n\n\n\n\n\n\n\n\n") - write("def hoge\n\nend\C-p\C-e") - write(" S") - assert_screen(<<~'EOC') - prompt> - prompt> - prompt> - prompt> - prompt> - prompt> def hoge - prompt> S - prompt> enString █ - Struct ▀ - Symbol - EOC - close - end - - def test_clear_dialog_in_pasting - start_terminal(10, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write("S") - write("tring ") - assert_screen(<<~'EOC') - Multiline REPL. - prompt> String - EOC - close - end - - def test_prompt_with_newline - ENV['RELINE_TEST_PROMPT'] = "::\n> " - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("def hoge\n 3\nend") - assert_screen(<<~'EOC') - Multiline REPL. - ::\n> def hoge - ::\n> 3 - ::\n> end - EOC - close - end - - def test_dynamic_prompt_with_newline - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dynamic-prompt-with-newline}, startup_message: 'Multiline REPL.') - write("def hoge\n 3\nend") - assert_screen(<<~'EOC') - Multiline REPL. - [0000\n]> def hoge - [0001\n]> 3 - [0001\n]> end - EOC - close - end - - def test_lines_passed_to_dynamic_prompt - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dynamic-prompt-show-line}, startup_message: 'Multiline REPL.') - write("if true") - write("\n") - assert_screen(<<~EOC) - Multiline REPL. - [if t]> if true - [ ]> - EOC - close - end - - def test_clear_dialog_when_just_move_cursor_at_last_line - start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write("class A\n 3\nend\n\n\n") - write("\C-p\C-p\C-e; S") - assert_screen(/String/) - write("\C-n") - write(";") - assert_screen(<<~'EOC') - prompt> 3 - prompt> end - => 3 - prompt> - prompt> - prompt> class A - prompt> 3; S - prompt> end; - EOC - close - end - - def test_clear_dialog_when_adding_new_line_to_end_of_buffer - start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write("class A\n def a\n 3\n 3\n end\nend") - write("\n") - write("class S") - write("\n") - write(" 3") - assert_screen(<<~'EOC') - prompt> def a - prompt> 3 - prompt> 3 - prompt> end - prompt> end - => :a - prompt> class S - prompt> 3 - EOC - close - end - - def test_insert_newline_in_the_middle_of_buffer_just_after_dialog - start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write("class A\n def a\n 3\n end\nend") - write("\n") - write("\C-p\C-p\C-p\C-p\C-p\C-e\C-hS") - write("\e\x0D") - write(" 3") - assert_screen(<<~'EOC') - prompt> 3 - prompt> end - prompt> end - => :a - prompt> class S - prompt> 3 - prompt> def a - prompt> 3 - prompt> end - prompt> end - EOC - close - end - - def test_incremental_search_on_not_last_line - start_terminal(10, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write("def abc\nend\n") - write("def def\nend\n") - write("\C-p\C-p\C-e") - write("\C-r") - write("a") - write("\n\n") - assert_screen(<<~'EOC') - prompt> def abc - prompt> end - => :abc - prompt> def def - prompt> end - => :def - prompt> def abc - prompt> end - => :abc - prompt> - EOC - close - end - - def test_bracket_newline_indent - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.') - write("[\n") - write("1") - assert_screen(<<~EOC) - Multiline REPL. - prompt> [ - prompt> 1 - EOC - close - end - - def test_repeated_input_delete - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write("a\C-h" * 4000) - assert_screen(<<~'EOC') - Multiline REPL. - prompt> - EOC - close - end - - def test_exit_with_ctrl_d - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.') - begin - write("\C-d") - close - rescue EOFError - # EOFError is raised when process terminated. - end - assert_screen(<<~EOC) - Multiline REPL. - prompt> - EOC - close - end - - def test_quoted_insert_intr_keys - omit if Reline.core.io_gate.win? - start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.') - write '"' - write "\C-v" - write "\C-c" - write "\C-v" - write "\C-z" - write "\C-v" - write "\C-\\" - write "\".bytes\n" - assert_screen(<<~EOC) - Multiline REPL. - prompt> "^C^Z^\\\".bytes - => [3, 26, 28] - prompt> - EOC - close - end - - def test_print_before_readline - code = <<~RUBY - puts 'Multiline REPL.' - 2.times do - print 'a' * 10 - Reline.readline '>' - end - RUBY - start_terminal(6, 30, ['ruby', "-I#{@pwd}/lib", '-rreline', '-e', code], startup_message: 'Multiline REPL.') - write "x\n" - assert_screen(<<~EOC) - Multiline REPL. - >x - > - EOC - close - end - - def test_pre_input_hook_with_redisplay - code = <<~'RUBY' - puts 'Multiline REPL.' - Reline.pre_input_hook = -> do - Reline.insert_text 'abc' - Reline.redisplay # Reline doesn't need this but Readline requires calling redisplay - end - Reline.readline('prompt> ') - RUBY - start_terminal(6, 30, ['ruby', "-I#{@pwd}/lib", '-rreline', '-e', code], startup_message: 'Multiline REPL.') - assert_screen(<<~EOC) - Multiline REPL. - prompt> abc - EOC - close - end - - def test_pre_input_hook_with_multiline_text_insert - # Frequently used pattern of pre_input_hook - code = <<~'RUBY' - puts 'Multiline REPL.' - Reline.pre_input_hook = -> do - Reline.insert_text "abc\nef" - end - Reline.readline('>') - RUBY - start_terminal(6, 30, ['ruby', "-I#{@pwd}/lib", '-rreline', '-e', code], startup_message: 'Multiline REPL.') - write("\C-ad") - assert_screen(<<~EOC) - Multiline REPL. - >abc - def - EOC - close - end - - def test_thread_safe - start_terminal(6, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.') - write("[Thread.new{Reline.readline'>'},Thread.new{Reline.readmultiline('>'){true}}].map(&:join).size\n") - write("exit\n") - write("exit\n") - write("42\n") - assert_screen(<<~EOC) - >exit - >exit - => 2 - prompt> 42 - => 42 - prompt> - EOC - close - end - - def test_user_defined_winch - omit if Reline.core.io_gate.win? - pidfile = Tempfile.create('pidfile') - rubyfile = Tempfile.create('rubyfile') - rubyfile.write <<~RUBY - File.write(#{pidfile.path.inspect}, Process.pid) - winch_called = false - Signal.trap(:WINCH, ->(_arg){ winch_called = true }) - p Reline.readline('>') - puts "winch: \#{winch_called}" - RUBY - rubyfile.close - - start_terminal(10, 50, %W{ruby -I#{@pwd}/lib -rreline #{rubyfile.path}}) - assert_screen(/^>/) - write 'a' - assert_screen(/^>a/) - pid = pidfile.tap(&:rewind).read.to_i - Process.kill(:WINCH, pid) unless pid.zero? - write "b\n" - assert_screen(/"ab"\nwinch: true/) - close - ensure - File.delete(rubyfile.path) if rubyfile - pidfile.close if pidfile - File.delete(pidfile.path) if pidfile - end - - def test_stop_continue - omit if Reline.core.io_gate.win? - pidfile = Tempfile.create('pidfile') - rubyfile = Tempfile.create('rubyfile') - rubyfile.write <<~RUBY - File.write(#{pidfile.path.inspect}, Process.pid) - cont_called = false - Signal.trap(:CONT, ->(_arg){ cont_called = true }) - Reline.readmultiline('>'){|input| input.match?(/ghi/) } - puts "cont: \#{cont_called}" - RUBY - rubyfile.close - start_terminal(10, 50, ['bash']) - write "ruby -I#{@pwd}/lib -rreline #{rubyfile.path}\n" - assert_screen(/^>/) - write "abc\ndef\nhi" - pid = pidfile.tap(&:rewind).read.to_i - Process.kill(:STOP, pid) unless pid.zero? - write "fg\n" - assert_screen(/fg\n.*>/m) - write "\ebg" - assert_screen(/>abc\n>def\n>ghi\n/) - write "\n" - assert_screen(/cont: true/) - close - ensure - File.delete(rubyfile.path) if rubyfile - pidfile.close if pidfile - File.delete(pidfile.path) if pidfile - end - - def write_inputrc(content) - File.open(@inputrc_file, 'w') do |f| - f.write content - end - end - - def fold_multiline(str, width) - str.scan(/.{1,#{width}}/).each(&:rstrip!).join("\n") - end - end -rescue LoadError, NameError - # On Ruby repository, this test suit doesn't run because Ruby repo doesn't - # have the yamatanooroti gem. -end |
