summaryrefslogtreecommitdiff
path: root/test/reline
diff options
context:
space:
mode:
Diffstat (limited to 'test/reline')
-rw-r--r--test/reline/config_test.rb113
-rw-r--r--test/reline/helper.rb71
-rw-r--r--test/reline/key_actor_emacs_test.rb1166
-rw-r--r--test/reline/key_actor_vi_test.rb1026
-rw-r--r--test/reline/key_stroke_test.rb51
-rw-r--r--test/reline/kill_ring_test.rb256
6 files changed, 2683 insertions, 0 deletions
diff --git a/test/reline/config_test.rb b/test/reline/config_test.rb
new file mode 100644
index 0000000000..34ee407498
--- /dev/null
+++ b/test/reline/config_test.rb
@@ -0,0 +1,113 @@
+require_relative 'helper'
+
+class Reline::Config::Test < Reline::TestCase
+ def setup
+ @pwd = Dir.pwd
+ @tmpdir = File.join(Dir.tmpdir, "test_reline_config_#{$$}")
+ Dir.mkdir(@tmpdir)
+ Dir.chdir(@tmpdir)
+ @config = Reline::Config.new
+ end
+
+ def teardown
+ Dir.chdir(@pwd)
+ FileUtils.rm_rf(@tmpdir)
+ end
+
+ def test_read_lines
+ @config.read_lines(<<~LINES.split(/(?<=\n)/))
+ set bell-style on
+ LINES
+
+ assert_equal :audible, @config.instance_variable_get(:@bell_style)
+ end
+
+ def test_bind_key
+ key, func = @config.bind_key('"input"', '"abcde"')
+
+ assert_equal 'input', key
+ assert_equal 'abcde', func
+ end
+
+ def test_bind_key_with_macro
+ key, func = @config.bind_key('"input"', 'abcde')
+
+ assert_equal 'input', key
+ assert_equal :abcde, func
+ end
+
+ def test_bind_key_with_escaped_chars
+ assert_equal ['input', "\e \\ \" ' \a \b \d \f \n \r \t \v"], @config.bind_key('"input"', '"\\e \\\\ \\" \\\' \\a \\b \\d \\f \\n \\r \\t \\v"')
+ end
+
+ def test_bind_key_with_ctrl_chars
+ assert_equal ['input', "\C-h\C-h"], @config.bind_key('"input"', '"\C-h\C-H"')
+ end
+
+ def test_bind_key_with_meta_chars
+ assert_equal ['input', "\M-h\M-H".force_encoding('ASCII-8BIT')], @config.bind_key('"input"', '"\M-h\M-H"')
+ end
+
+ def test_bind_key_with_octal_number
+ assert_equal ['input', "\1"], @config.bind_key('"input"', '"\1"')
+ assert_equal ['input', "\12"], @config.bind_key('"input"', '"\12"')
+ assert_equal ['input', "\123"], @config.bind_key('"input"', '"\123"')
+ assert_equal ['input', ["\123", '4'].join], @config.bind_key('"input"', '"\1234"')
+ end
+
+ def test_bind_key_with_hexadecimal_number
+ assert_equal ['input', "\x4"], @config.bind_key('"input"', '"\x4"')
+ assert_equal ['input', "\x45"], @config.bind_key('"input"', '"\x45"')
+ assert_equal ['input', ["\x45", '6'].join], @config.bind_key('"input"', '"\x456"')
+ end
+
+ def test_include
+ File.open('included_partial', 'wt') do |f|
+ f.write(<<~PARTIAL_LINES)
+ set bell-style on
+ PARTIAL_LINES
+ end
+ @config.read_lines(<<~LINES.split(/(?<=\n)/))
+ $include included_partial
+ LINES
+
+ assert_equal :audible, @config.instance_variable_get(:@bell_style)
+ end
+
+ def test_if
+ @config.read_lines(<<~LINES.split(/(?<=\n)/))
+ $if Ruby
+ set bell-style audible
+ $else
+ set bell-style visible
+ $endif
+ LINES
+
+ assert_equal :audible, @config.instance_variable_get(:@bell_style)
+ end
+
+ def test_if_with_false
+ @config.read_lines(<<~LINES.split(/(?<=\n)/))
+ $if Python
+ set bell-style audible
+ $else
+ set bell-style visible
+ $endif
+ LINES
+
+ assert_equal :visible, @config.instance_variable_get(:@bell_style)
+ end
+
+ def test_if_with_indent
+ @config.read_lines(<<~LINES.split(/(?<=\n)/))
+ set bell-style none
+ $if Ruby
+ set bell-style audible
+ $else
+ set bell-style visible
+ $endif
+ LINES
+
+ assert_equal :audible, @config.instance_variable_get(:@bell_style)
+ end
+end
diff --git a/test/reline/helper.rb b/test/reline/helper.rb
new file mode 100644
index 0000000000..b73b5d974e
--- /dev/null
+++ b/test/reline/helper.rb
@@ -0,0 +1,71 @@
+$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
+require 'reline'
+require 'test/unit'
+
+RELINE_TEST_ENCODING =
+ if ENV['RELINE_TEST_ENCODING']
+ Encoding.find(ENV['RELINE_TEST_ENCODING'])
+ else
+ Encoding.default_external
+ end
+
+class Reline::TestCase < Test::Unit::TestCase
+ private def convert_str(input, options = {}, normalized = nil)
+ return nil if input.nil?
+ input.chars.map { |c|
+ if Reline::Unicode::EscapedChars.include?(c.ord)
+ c
+ else
+ c.encode(@line_editor.instance_variable_get(:@encoding), Encoding::UTF_8, options)
+ end
+ }.join
+ rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError
+ input.unicode_normalize!(:nfc)
+ if normalized
+ options[:undef] = :replace
+ options[:replace] = '?'
+ end
+ normalized = true
+ retry
+ end
+
+ def input_keys(input, convert = true)
+ input = convert_str(input) if convert
+ input.chars.each do |c|
+ if c.bytesize == 1
+ eighth_bit = 0b10000000
+ byte = c.bytes.first
+ if byte.allbits?(eighth_bit)
+ @line_editor.input_key("\e".ord)
+ byte ^= eighth_bit
+ end
+ @line_editor.input_key(byte)
+ else
+ c.bytes.each do |b|
+ @line_editor.input_key(b)
+ end
+ end
+ end
+ end
+
+ def assert_line(expected)
+ expected = convert_str(expected)
+ assert_equal(expected, @line_editor.line)
+ end
+
+ def assert_byte_pointer_size(expected)
+ expected = convert_str(expected)
+ byte_pointer = @line_editor.instance_variable_get(:@byte_pointer)
+ assert_equal(
+ expected.bytesize, byte_pointer,
+ "<#{expected.inspect}> expected but was\n<#{@line_editor.line.byteslice(0, byte_pointer).inspect}>")
+ end
+
+ def assert_cursor(expected)
+ assert_equal(expected, @line_editor.instance_variable_get(:@cursor))
+ end
+
+ def assert_cursor_max(expected)
+ assert_equal(expected, @line_editor.instance_variable_get(:@cursor_max))
+ end
+end
diff --git a/test/reline/key_actor_emacs_test.rb b/test/reline/key_actor_emacs_test.rb
new file mode 100644
index 0000000000..f4dfb952f5
--- /dev/null
+++ b/test/reline/key_actor_emacs_test.rb
@@ -0,0 +1,1166 @@
+require_relative 'helper'
+
+class Reline::KeyActor::Emacs::Test < Reline::TestCase
+ def setup
+ @prompt = '> '
+ @config = Reline::Config.new # Emacs mode is default
+ @line_editor = Reline::LineEditor.new(
+ @config, @prompt,
+ (RELINE_TEST_ENCODING rescue Encoding.default_external))
+ @line_editor.retrieve_completion_block = Reline.method(:retrieve_completion_block)
+ end
+
+ def test_ed_insert_one
+ input_keys('a')
+ assert_line('a')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(1)
+ end
+
+ def test_ed_insert_two
+ input_keys('ab')
+ assert_line('ab')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ end
+
+ def test_ed_insert_mbchar_one
+ input_keys('か')
+ assert_line('か')
+ assert_byte_pointer_size('か')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ end
+
+ def test_ed_insert_mbchar_two
+ input_keys('かき')
+ assert_line('かき')
+ assert_byte_pointer_size('かき')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ end
+
+ def test_ed_insert_for_mbchar_by_plural_code_points
+ input_keys("か\u3099")
+ assert_line("か\u3099")
+ assert_byte_pointer_size("か\u3099")
+ assert_cursor(2)
+ assert_cursor_max(2)
+ end
+
+ def test_ed_insert_for_plural_mbchar_by_plural_code_points
+ input_keys("か\u3099き\u3099")
+ assert_line("か\u3099き\u3099")
+ assert_byte_pointer_size("か\u3099き\u3099")
+ assert_cursor(4)
+ assert_cursor_max(4)
+ end
+
+ def test_move_next_and_prev
+ input_keys('abd')
+ assert_byte_pointer_size('abd')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(3)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(3)
+ input_keys("\C-f", false)
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(3)
+ input_keys('c')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(4)
+ assert_line('abcd')
+ end
+
+ def test_move_next_and_prev_for_mbchar
+ input_keys('かきけ')
+ assert_byte_pointer_size('かきけ')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size('かき')
+ assert_cursor(4)
+ assert_cursor_max(6)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size('か')
+ assert_cursor(2)
+ assert_cursor_max(6)
+ input_keys("\C-f", false)
+ assert_byte_pointer_size('かき')
+ assert_cursor(4)
+ assert_cursor_max(6)
+ input_keys('く')
+ assert_byte_pointer_size('かきく')
+ assert_cursor(6)
+ assert_cursor_max(8)
+ assert_line('かきくけ')
+ end
+
+ def test_move_next_and_prev_for_mbchar_by_plural_code_points
+ input_keys("か\u3099き\u3099け\u3099")
+ assert_byte_pointer_size("か\u3099き\u3099け\u3099")
+ assert_cursor(6)
+ assert_cursor_max(6)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size("か\u3099き\u3099")
+ assert_cursor(4)
+ assert_cursor_max(6)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size("か\u3099")
+ assert_cursor(2)
+ assert_cursor_max(6)
+ input_keys("\C-f", false)
+ assert_byte_pointer_size("か\u3099き\u3099")
+ assert_cursor(4)
+ assert_cursor_max(6)
+ input_keys("く\u3099")
+ assert_byte_pointer_size("か\u3099き\u3099く\u3099")
+ assert_cursor(6)
+ assert_cursor_max(8)
+ assert_line("か\u3099き\u3099く\u3099け\u3099")
+ end
+
+ def test_move_to_beg_end
+ input_keys('bcd')
+ assert_byte_pointer_size('bcd')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ input_keys("\C-a", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
+ input_keys('a')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(4)
+ input_keys("\C-e", false)
+ assert_byte_pointer_size('abcd')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ input_keys('e')
+ assert_byte_pointer_size('abcde')
+ assert_cursor(5)
+ assert_cursor_max(5)
+ assert_line('abcde')
+ end
+
+ def test_ed_newline_with_cr
+ input_keys('ab')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ refute(@line_editor.finished?)
+ input_keys("\C-m", false)
+ assert_line('ab')
+ assert(@line_editor.finished?)
+ end
+
+ def test_ed_newline_with_lf
+ input_keys('ab')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ refute(@line_editor.finished?)
+ input_keys("\C-j", false)
+ assert_line('ab')
+ assert(@line_editor.finished?)
+ end
+
+ def test_em_delete_prev_char
+ input_keys('ab')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ input_keys("\C-h", false)
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(1)
+ assert_line('a')
+ end
+
+ def test_em_delete_prev_char_for_mbchar
+ input_keys('かき')
+ assert_byte_pointer_size('かき')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ input_keys("\C-h", false)
+ assert_byte_pointer_size('か')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ assert_line('か')
+ end
+
+ def test_em_delete_prev_char_for_mbchar_by_plural_code_points
+ input_keys("か\u3099き\u3099")
+ assert_byte_pointer_size("か\u3099き\u3099")
+ assert_cursor(4)
+ assert_cursor_max(4)
+ input_keys("\C-h", false)
+ assert_byte_pointer_size("か\u3099")
+ assert_cursor(2)
+ assert_cursor_max(2)
+ assert_line("か\u3099")
+ end
+
+ def test_ed_kill_line
+ input_keys("\C-k", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ input_keys('abc')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ input_keys("\C-k", false)
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('abc')
+ input_keys("\C-b\C-k", false)
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ assert_line('ab')
+ end
+
+ def test_em_kill_line
+ input_keys("\C-u", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ input_keys('abc')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ input_keys("\C-u", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ input_keys('abc')
+ input_keys("\C-b\C-u", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(1)
+ assert_line('c')
+ input_keys("\C-u", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(1)
+ assert_line('c')
+ end
+
+ def test_ed_move_to_beg
+ input_keys('abd')
+ assert_byte_pointer_size('abd')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(3)
+ input_keys('c')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(4)
+ input_keys("\C-a", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(4)
+ input_keys('012')
+ assert_byte_pointer_size('012')
+ assert_cursor(3)
+ assert_cursor_max(7)
+ assert_line('012abcd')
+ input_keys("\C-a", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(7)
+ input_keys('ABC')
+ assert_byte_pointer_size('ABC')
+ assert_cursor(3)
+ assert_cursor_max(10)
+ assert_line('ABC012abcd')
+ input_keys("\C-f" * 10 + "\C-a", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(10)
+ input_keys('a')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(11)
+ assert_line('aABC012abcd')
+ end
+
+ def test_ed_move_to_end
+ input_keys('abd')
+ assert_byte_pointer_size('abd')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(3)
+ input_keys('c')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(4)
+ input_keys("\C-e", false)
+ assert_byte_pointer_size('abcd')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ input_keys('012')
+ assert_byte_pointer_size('abcd012')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('abcd012')
+ input_keys("\C-e", false)
+ assert_byte_pointer_size('abcd012')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ input_keys('ABC')
+ assert_byte_pointer_size('abcd012ABC')
+ assert_cursor(10)
+ assert_cursor_max(10)
+ assert_line('abcd012ABC')
+ input_keys("\C-b" * 10 + "\C-e", false)
+ assert_byte_pointer_size('abcd012ABC')
+ assert_cursor(10)
+ assert_cursor_max(10)
+ input_keys('a')
+ assert_byte_pointer_size('abcd012ABCa')
+ assert_cursor(11)
+ assert_cursor_max(11)
+ assert_line('abcd012ABCa')
+ end
+
+ def test_em_delete_or_list
+ input_keys('ab')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ input_keys("\C-a", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
+ input_keys("\C-d", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(1)
+ assert_line('b')
+ end
+
+ def test_em_delete_or_list_for_mbchar
+ input_keys('かき')
+ assert_byte_pointer_size('かき')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ input_keys("\C-a", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(4)
+ input_keys("\C-d", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
+ assert_line('き')
+ end
+
+ def test_em_delete_or_list_for_mbchar_by_plural_code_points
+ input_keys("か\u3099き\u3099")
+ assert_byte_pointer_size("か\u3099き\u3099")
+ assert_cursor(4)
+ assert_cursor_max(4)
+ input_keys("\C-a", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(4)
+ input_keys("\C-d", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
+ assert_line("き\u3099")
+ end
+
+ def test_ed_clear_screen
+ refute(@line_editor.instance_variable_get(:@cleared))
+ input_keys("\C-l", false)
+ assert(@line_editor.instance_variable_get(:@cleared))
+ end
+
+ def test_ed_clear_screen_with_inputed
+ input_keys('abc')
+ input_keys("\C-b", false)
+ refute(@line_editor.instance_variable_get(:@cleared))
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(3)
+ input_keys("\C-l", false)
+ assert(@line_editor.instance_variable_get(:@cleared))
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(3)
+ assert_line('abc')
+ end
+
+ def test_em_next_word
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ input_keys('abc def{bbb}ccc')
+ input_keys("\C-a\M-F", false)
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ input_keys("\M-F", false)
+ assert_byte_pointer_size('abc def')
+ assert_cursor(7)
+ input_keys("\M-F", false)
+ assert_byte_pointer_size('abc def{bbb')
+ assert_cursor(11)
+ input_keys("\M-F", false)
+ assert_byte_pointer_size('abc def{bbb}ccc')
+ assert_cursor(15)
+ input_keys("\M-F", false)
+ assert_byte_pointer_size('abc def{bbb}ccc')
+ assert_cursor(15)
+ end
+
+ def test_em_next_word_for_mbchar
+ assert_cursor(0)
+ input_keys('あいう かきく{さしす}たちつ')
+ input_keys("\C-a\M-F", false)
+ assert_byte_pointer_size('あいう')
+ assert_cursor(6)
+ input_keys("\M-F", false)
+ assert_byte_pointer_size('あいう かきく')
+ assert_cursor(13)
+ input_keys("\M-F", false)
+ assert_byte_pointer_size('あいう かきく{さしす')
+ assert_cursor(20)
+ input_keys("\M-F", false)
+ assert_byte_pointer_size('あいう かきく{さしす}たちつ')
+ assert_cursor(27)
+ input_keys("\M-F", false)
+ assert_byte_pointer_size('あいう かきく{さしす}たちつ')
+ assert_cursor(27)
+ end
+
+ def test_em_next_word_for_mbchar_by_plural_code_points
+ assert_cursor(0)
+ input_keys("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
+ input_keys("\C-a\M-F", false)
+ assert_byte_pointer_size("あいう")
+ assert_cursor(6)
+ input_keys("\M-F", false)
+ assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099")
+ assert_cursor(13)
+ input_keys("\M-F", false)
+ assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす")
+ assert_cursor(20)
+ input_keys("\M-F", false)
+ assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
+ assert_cursor(27)
+ input_keys("\M-F", false)
+ assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
+ assert_cursor(27)
+ end
+
+ def test_em_prev_word
+ input_keys('abc def{bbb}ccc')
+ assert_byte_pointer_size('abc def{bbb}ccc')
+ assert_cursor(15)
+ input_keys("\M-B", false)
+ assert_byte_pointer_size('abc def{bbb}')
+ assert_cursor(12)
+ input_keys("\M-B", false)
+ assert_byte_pointer_size('abc def{')
+ assert_cursor(8)
+ input_keys("\M-B", false)
+ assert_byte_pointer_size('abc ')
+ assert_cursor(4)
+ input_keys("\M-B", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ input_keys("\M-B", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ end
+
+ def test_em_prev_word_for_mbchar
+ input_keys('あいう かきく{さしす}たちつ')
+ assert_byte_pointer_size('あいう かきく{さしす}たちつ')
+ assert_cursor(27)
+ input_keys("\M-B", false)
+ assert_byte_pointer_size('あいう かきく{さしす}')
+ assert_cursor(21)
+ input_keys("\M-B", false)
+ assert_byte_pointer_size('あいう かきく{')
+ assert_cursor(14)
+ input_keys("\M-B", false)
+ assert_byte_pointer_size('あいう ')
+ assert_cursor(7)
+ input_keys("\M-B", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ input_keys("\M-B", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ end
+
+ def test_em_prev_word_for_mbchar_by_plural_code_points
+ input_keys("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
+ assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
+ assert_cursor(27)
+ input_keys("\M-B", false)
+ assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}")
+ assert_cursor(21)
+ input_keys("\M-B", false)
+ assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{")
+ assert_cursor(14)
+ input_keys("\M-B", false)
+ assert_byte_pointer_size('あいう ')
+ assert_cursor(7)
+ input_keys("\M-B", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ input_keys("\M-B", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ end
+
+ def test_em_delete_next_word
+ input_keys('abc def{bbb}ccc')
+ input_keys("\C-a", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(15)
+ input_keys("\M-d", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(12)
+ assert_line(' def{bbb}ccc')
+ input_keys("\M-d", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(8)
+ assert_line('{bbb}ccc')
+ input_keys("\M-d", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(4)
+ assert_line('}ccc')
+ input_keys("\M-d", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ end
+
+ def test_em_delete_next_word_for_mbchar
+ input_keys('あいう かきく{さしす}たちつ')
+ input_keys("\C-a", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(27)
+ input_keys("\M-d", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(21)
+ assert_line(' かきく{さしす}たちつ')
+ input_keys("\M-d", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(14)
+ assert_line('{さしす}たちつ')
+ input_keys("\M-d", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(7)
+ assert_line('}たちつ')
+ input_keys("\M-d", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ end
+
+ def test_em_delete_next_word_for_mbchar_by_plural_code_points
+ input_keys("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
+ input_keys("\C-a", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(27)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(27)
+ input_keys("\M-d", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(21)
+ assert_line(" か\u3099き\u3099く\u3099{さしす}たちつ")
+ input_keys("\M-d", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(14)
+ assert_line('{さしす}たちつ')
+ input_keys("\M-d", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(7)
+ assert_line('}たちつ')
+ input_keys("\M-d", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ end
+
+ def test_ed_delete_prev_word
+ input_keys('abc def{bbb}ccc')
+ assert_byte_pointer_size('abc def{bbb}ccc')
+ assert_cursor(15)
+ assert_cursor_max(15)
+ input_keys("\M-\C-H", false)
+ assert_byte_pointer_size('abc def{bbb}')
+ assert_cursor(12)
+ assert_cursor_max(12)
+ assert_line('abc def{bbb}')
+ input_keys("\M-\C-H", false)
+ assert_byte_pointer_size('abc def{')
+ assert_cursor(8)
+ assert_cursor_max(8)
+ assert_line('abc def{')
+ input_keys("\M-\C-H", false)
+ assert_byte_pointer_size('abc ')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('abc ')
+ input_keys("\M-\C-H", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ end
+
+ def test_ed_delete_prev_word_for_mbchar
+ input_keys('あいう かきく{さしす}たちつ')
+ assert_byte_pointer_size('あいう かきく{さしす}たちつ')
+ assert_cursor(27)
+ assert_cursor_max(27)
+ input_keys("\M-\C-H", false)
+ assert_byte_pointer_size('あいう かきく{さしす}')
+ assert_cursor(21)
+ assert_cursor_max(21)
+ assert_line('あいう かきく{さしす}')
+ input_keys("\M-\C-H", false)
+ assert_byte_pointer_size('あいう かきく{')
+ assert_cursor(14)
+ assert_cursor_max(14)
+ assert_line('あいう かきく{')
+ input_keys("\M-\C-H", false)
+ assert_byte_pointer_size('あいう ')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('あいう ')
+ input_keys("\M-\C-H", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ end
+
+ def test_ed_delete_prev_word_for_mbchar_by_plural_code_points
+ input_keys("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
+ assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
+ assert_cursor(27)
+ assert_cursor_max(27)
+ input_keys("\M-\C-H", false)
+ assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}")
+ assert_cursor(21)
+ assert_cursor_max(21)
+ assert_line("あいう か\u3099き\u3099く\u3099{さしす}")
+ input_keys("\M-\C-H", false)
+ assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{")
+ assert_cursor(14)
+ assert_cursor_max(14)
+ assert_line("あいう か\u3099き\u3099く\u3099{")
+ input_keys("\M-\C-H", false)
+ assert_byte_pointer_size("あいう ")
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('あいう ')
+ input_keys("\M-\C-H", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ end
+
+ def test_ed_transpose_chars
+ input_keys('abc')
+ input_keys("\C-a", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
+ input_keys("\C-t", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
+ assert_line('abc')
+ input_keys("\C-f\C-t", false)
+ assert_byte_pointer_size('ba')
+ assert_cursor(2)
+ assert_cursor_max(3)
+ assert_line('bac')
+ input_keys("\C-t", false)
+ assert_byte_pointer_size('bca')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('bca')
+ input_keys("\C-t", false)
+ assert_byte_pointer_size('bac')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('bac')
+ end
+
+ def test_ed_transpose_chars_for_mbchar
+ input_keys('あかさ')
+ input_keys("\C-a", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
+ input_keys("\C-t", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
+ assert_line('あかさ')
+ input_keys("\C-f\C-t", false)
+ assert_byte_pointer_size('かあ')
+ assert_cursor(4)
+ assert_cursor_max(6)
+ assert_line('かあさ')
+ input_keys("\C-t", false)
+ assert_byte_pointer_size('かさあ')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line('かさあ')
+ input_keys("\C-t", false)
+ assert_byte_pointer_size('かあさ')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line('かあさ')
+ end
+
+ def test_ed_transpose_chars_for_mbchar_by_plural_code_points
+ input_keys("あか\u3099さ")
+ input_keys("\C-a", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
+ input_keys("\C-t", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
+ assert_line("あか\u3099さ")
+ input_keys("\C-f\C-t", false)
+ assert_byte_pointer_size("か\u3099あ")
+ assert_cursor(4)
+ assert_cursor_max(6)
+ assert_line("か\u3099あさ")
+ input_keys("\C-t", false)
+ assert_byte_pointer_size("か\u3099さあ")
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line("か\u3099さあ")
+ input_keys("\C-t", false)
+ assert_byte_pointer_size("か\u3099あさ")
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line("か\u3099あさ")
+ end
+
+ def test_ed_digit
+ input_keys('0123')
+ assert_byte_pointer_size('0123')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('0123')
+ end
+
+ def test_ed_next_and_prev_char
+ input_keys('abc')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(3)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(3)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
+ input_keys("\C-f", false)
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(3)
+ input_keys("\C-f", false)
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(3)
+ input_keys("\C-f", false)
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ input_keys("\C-f", false)
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ end
+
+ def test_ed_next_and_prev_char_for_mbchar
+ input_keys('あいう')
+ assert_byte_pointer_size('あいう')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size('あい')
+ assert_cursor(4)
+ assert_cursor_max(6)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size('あ')
+ assert_cursor(2)
+ assert_cursor_max(6)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
+ input_keys("\C-f", false)
+ assert_byte_pointer_size('あ')
+ assert_cursor(2)
+ assert_cursor_max(6)
+ input_keys("\C-f", false)
+ assert_byte_pointer_size('あい')
+ assert_cursor(4)
+ assert_cursor_max(6)
+ input_keys("\C-f", false)
+ assert_byte_pointer_size('あいう')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ input_keys("\C-f", false)
+ assert_byte_pointer_size('あいう')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ end
+
+ def test_ed_next_and_prev_char_for_mbchar_by_plural_code_points
+ input_keys("か\u3099き\u3099く\u3099")
+ assert_byte_pointer_size("か\u3099き\u3099く\u3099")
+ assert_cursor(6)
+ assert_cursor_max(6)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size("か\u3099き\u3099")
+ assert_cursor(4)
+ assert_cursor_max(6)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size("か\u3099")
+ assert_cursor(2)
+ assert_cursor_max(6)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
+ input_keys("\C-b", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
+ input_keys("\C-f", false)
+ assert_byte_pointer_size("か\u3099")
+ assert_cursor(2)
+ assert_cursor_max(6)
+ input_keys("\C-f", false)
+ assert_byte_pointer_size("か\u3099き\u3099")
+ assert_cursor(4)
+ assert_cursor_max(6)
+ input_keys("\C-f", false)
+ assert_byte_pointer_size("か\u3099き\u3099く\u3099")
+ assert_cursor(6)
+ assert_cursor_max(6)
+ input_keys("\C-f", false)
+ assert_byte_pointer_size("か\u3099き\u3099く\u3099")
+ assert_cursor(6)
+ assert_cursor_max(6)
+ end
+
+ def test_em_capitol_case
+ input_keys('abc def{bbb}ccc')
+ input_keys("\C-a\M-c", false)
+ assert_byte_pointer_size('Abc')
+ assert_cursor(3)
+ assert_cursor_max(15)
+ assert_line('Abc def{bbb}ccc')
+ input_keys("\M-c", false)
+ assert_byte_pointer_size('Abc Def')
+ assert_cursor(7)
+ assert_cursor_max(15)
+ assert_line('Abc Def{bbb}ccc')
+ input_keys("\M-c", false)
+ assert_byte_pointer_size('Abc Def{Bbb')
+ assert_cursor(11)
+ assert_cursor_max(15)
+ assert_line('Abc Def{Bbb}ccc')
+ input_keys("\M-c", false)
+ assert_byte_pointer_size('Abc Def{Bbb}Ccc')
+ assert_cursor(15)
+ assert_cursor_max(15)
+ assert_line('Abc Def{Bbb}Ccc')
+ end
+
+ def test_em_capitol_case_with_complex_example
+ input_keys('{}#* AaA!!!cCc ')
+ input_keys("\C-a\M-c", false)
+ assert_byte_pointer_size('{}#* Aaa')
+ assert_cursor(11)
+ assert_cursor_max(20)
+ assert_line('{}#* Aaa!!!cCc ')
+ input_keys("\M-c", false)
+ assert_byte_pointer_size('{}#* Aaa!!!Ccc')
+ assert_cursor(17)
+ assert_cursor_max(20)
+ assert_line('{}#* Aaa!!!Ccc ')
+ input_keys("\M-c", false)
+ assert_byte_pointer_size('{}#* Aaa!!!Ccc ')
+ assert_cursor(20)
+ assert_cursor_max(20)
+ assert_line('{}#* Aaa!!!Ccc ')
+ end
+
+ def test_em_lower_case
+ input_keys('AbC def{bBb}CCC')
+ input_keys("\C-a\M-l", false)
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(15)
+ assert_line('abc def{bBb}CCC')
+ input_keys("\M-l", false)
+ assert_byte_pointer_size('abc def')
+ assert_cursor(7)
+ assert_cursor_max(15)
+ assert_line('abc def{bBb}CCC')
+ input_keys("\M-l", false)
+ assert_byte_pointer_size('abc def{bbb')
+ assert_cursor(11)
+ assert_cursor_max(15)
+ assert_line('abc def{bbb}CCC')
+ input_keys("\M-l", false)
+ assert_byte_pointer_size('abc def{bbb}ccc')
+ assert_cursor(15)
+ assert_cursor_max(15)
+ assert_line('abc def{bbb}ccc')
+ end
+
+ def test_em_lower_case_with_complex_example
+ input_keys('{}#* AaA!!!cCc ')
+ input_keys("\C-a\M-l", false)
+ assert_byte_pointer_size('{}#* aaa')
+ assert_cursor(11)
+ assert_cursor_max(20)
+ assert_line('{}#* aaa!!!cCc ')
+ input_keys("\M-l", false)
+ assert_byte_pointer_size('{}#* aaa!!!ccc')
+ assert_cursor(17)
+ assert_cursor_max(20)
+ assert_line('{}#* aaa!!!ccc ')
+ input_keys("\M-l", false)
+ assert_byte_pointer_size('{}#* aaa!!!ccc ')
+ assert_cursor(20)
+ assert_cursor_max(20)
+ assert_line('{}#* aaa!!!ccc ')
+ end
+
+ def test_em_upper_case
+ input_keys('AbC def{bBb}CCC')
+ input_keys("\C-a\M-u", false)
+ assert_byte_pointer_size('ABC')
+ assert_cursor(3)
+ assert_cursor_max(15)
+ assert_line('ABC def{bBb}CCC')
+ input_keys("\M-u", false)
+ assert_byte_pointer_size('ABC DEF')
+ assert_cursor(7)
+ assert_cursor_max(15)
+ assert_line('ABC DEF{bBb}CCC')
+ input_keys("\M-u", false)
+ assert_byte_pointer_size('ABC DEF{BBB')
+ assert_cursor(11)
+ assert_cursor_max(15)
+ assert_line('ABC DEF{BBB}CCC')
+ input_keys("\M-u", false)
+ assert_byte_pointer_size('ABC DEF{BBB}CCC')
+ assert_cursor(15)
+ assert_cursor_max(15)
+ assert_line('ABC DEF{BBB}CCC')
+ end
+
+ def test_em_upper_case_with_complex_example
+ input_keys('{}#* AaA!!!cCc ')
+ input_keys("\C-a\M-u", false)
+ assert_byte_pointer_size('{}#* AAA')
+ assert_cursor(11)
+ assert_cursor_max(20)
+ assert_line('{}#* AAA!!!cCc ')
+ input_keys("\M-u", false)
+ assert_byte_pointer_size('{}#* AAA!!!CCC')
+ assert_cursor(17)
+ assert_cursor_max(20)
+ assert_line('{}#* AAA!!!CCC ')
+ input_keys("\M-u", false)
+ assert_byte_pointer_size('{}#* AAA!!!CCC ')
+ assert_cursor(20)
+ assert_cursor_max(20)
+ assert_line('{}#* AAA!!!CCC ')
+ end
+
+ def test_completion
+ @line_editor.completion_proc = proc { |word|
+ %w{
+ foo_foo
+ foo_bar
+ foo_baz
+ qux
+ }
+ }
+ input_keys('fo')
+ assert_byte_pointer_size('fo')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ assert_line('fo')
+ assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
+ input_keys("\C-i", false)
+ assert_byte_pointer_size('foo_')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('foo_')
+ assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
+ input_keys("\C-i", false)
+ assert_byte_pointer_size('foo_')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('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", false)
+ assert_byte_pointer_size('foo_a')
+ assert_cursor(5)
+ assert_cursor_max(5)
+ assert_line('foo_a')
+ input_keys("\C-h", false)
+ input_keys('b')
+ input_keys("\C-i", false)
+ assert_byte_pointer_size('foo_ba')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line('foo_ba')
+ end
+
+ def test_completion_in_middle_of_line
+ @line_editor.completion_proc = proc { |word|
+ %w{
+ foo_foo
+ foo_bar
+ foo_baz
+ qux
+ }
+ }
+ input_keys('abcde fo ABCDE')
+ assert_line('abcde fo ABCDE')
+ input_keys("\C-b" * 6 + "\C-i", false)
+ assert_byte_pointer_size('abcde foo_')
+ assert_cursor(10)
+ assert_cursor_max(16)
+ assert_line('abcde foo_ ABCDE')
+ input_keys("\C-b" * 2 + "\C-i", false)
+ assert_byte_pointer_size('abcde foo_')
+ assert_cursor(10)
+ assert_cursor_max(18)
+ assert_line('abcde foo_o_ ABCDE')
+ end
+
+ def test_em_kill_region
+ input_keys('abc def{bbb}ccc ddd ')
+ assert_byte_pointer_size('abc def{bbb}ccc ddd ')
+ assert_cursor(26)
+ assert_cursor_max(26)
+ assert_line('abc def{bbb}ccc ddd ')
+ input_keys("\C-w", false)
+ assert_byte_pointer_size('abc def{bbb}ccc ')
+ assert_cursor(20)
+ assert_cursor_max(20)
+ assert_line('abc def{bbb}ccc ')
+ input_keys("\C-w", false)
+ assert_byte_pointer_size('abc ')
+ assert_cursor(6)
+ assert_cursor_max(6)
+ assert_line('abc ')
+ input_keys("\C-w", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ input_keys("\C-w", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ end
+
+ def test_em_kill_region_mbchar
+ input_keys('あ い う{う}う ')
+ assert_byte_pointer_size('あ い う{う}う ')
+ assert_cursor(21)
+ assert_cursor_max(21)
+ assert_line('あ い う{う}う ')
+ input_keys("\C-w", false)
+ assert_byte_pointer_size('あ い ')
+ assert_cursor(10)
+ assert_cursor_max(10)
+ assert_line('あ い ')
+ input_keys("\C-w", false)
+ assert_byte_pointer_size('あ ')
+ assert_cursor(5)
+ assert_cursor_max(5)
+ assert_line('あ ')
+ input_keys("\C-w", false)
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ end
+end
diff --git a/test/reline/key_actor_vi_test.rb b/test/reline/key_actor_vi_test.rb
new file mode 100644
index 0000000000..63618d5fb3
--- /dev/null
+++ b/test/reline/key_actor_vi_test.rb
@@ -0,0 +1,1026 @@
+require_relative 'helper'
+
+class Reline::KeyActor::ViInsert::Test < Reline::TestCase
+ def setup
+ @prompt = '> '
+ @config = Reline::Config.new
+ @config.read_lines(<<~LINES.split(/(?<=\n)/))
+ set editing-mode vi
+ LINES
+ @line_editor = Reline::LineEditor.new(
+ @config, @prompt,
+ (RELINE_TEST_ENCODING rescue Encoding.default_external))
+ @line_editor.retrieve_completion_block = Reline.method(:retrieve_completion_block)
+ end
+
+ def test_vi_command_mode
+ input_keys("\C-[")
+ assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
+ end
+
+ def test_vi_command_mode_with_input
+ input_keys("abc\C-[")
+ assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
+ assert_line('abc')
+ end
+
+ def test_ed_insert_one
+ input_keys('a')
+ assert_line('a')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(1)
+ end
+
+ def test_ed_insert_two
+ input_keys('ab')
+ assert_line('ab')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ end
+
+ def test_ed_insert_mbchar_one
+ input_keys('か')
+ assert_line('か')
+ assert_byte_pointer_size('か')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ end
+
+ def test_ed_insert_mbchar_two
+ input_keys('かき')
+ assert_line('かき')
+ assert_byte_pointer_size('かき')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ end
+
+ def test_ed_insert_for_mbchar_by_plural_code_points
+ input_keys("か\u3099")
+ assert_line("か\u3099")
+ assert_byte_pointer_size("か\u3099")
+ assert_cursor(2)
+ assert_cursor_max(2)
+ end
+
+ def test_ed_insert_for_plural_mbchar_by_plural_code_points
+ input_keys("か\u3099き\u3099")
+ assert_line("か\u3099き\u3099")
+ assert_byte_pointer_size("か\u3099き\u3099")
+ assert_cursor(4)
+ assert_cursor_max(4)
+ end
+
+ def test_ed_next_char
+ input_keys("abcdef\C-[0")
+ assert_line('abcdef')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
+ input_keys('l')
+ assert_line('abcdef')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(6)
+ input_keys('2l')
+ assert_line('abcdef')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(6)
+ end
+
+ def test_ed_prev_char
+ input_keys("abcdef\C-[")
+ assert_line('abcdef')
+ assert_byte_pointer_size('abcde')
+ assert_cursor(5)
+ assert_cursor_max(6)
+ input_keys('h')
+ assert_line('abcdef')
+ assert_byte_pointer_size('abcd')
+ assert_cursor(4)
+ assert_cursor_max(6)
+ input_keys('2h')
+ assert_line('abcdef')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(6)
+ end
+
+ def test_history
+ Reline::HISTORY.concat(%w{abc 123 AAA})
+ input_keys("\C-[")
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ input_keys('k')
+ assert_line('AAA')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
+ input_keys('2k')
+ assert_line('abc')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
+ input_keys('j')
+ assert_line('123')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(3)
+ input_keys('2j')
+ assert_line('')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ end
+
+ def test_vi_paste_prev
+ input_keys("abcde\C-[3h")
+ assert_line('abcde')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(5)
+ input_keys('P')
+ assert_line('abcde')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(5)
+ input_keys('d$')
+ assert_line('a')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(1)
+ input_keys('P')
+ assert_line('bcdea')
+ assert_byte_pointer_size('bcd')
+ assert_cursor(3)
+ assert_cursor_max(5)
+ input_keys('2P')
+ assert_line('bcdbcdbcdeeea')
+ assert_byte_pointer_size('bcdbcdbcd')
+ assert_cursor(9)
+ assert_cursor_max(13)
+ end
+
+ def test_vi_paste_next
+ input_keys("abcde\C-[3h")
+ assert_line('abcde')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(5)
+ input_keys('p')
+ assert_line('abcde')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(5)
+ input_keys('d$')
+ assert_line('a')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(1)
+ input_keys('p')
+ assert_line('abcde')
+ assert_byte_pointer_size('abcd')
+ assert_cursor(4)
+ assert_cursor_max(5)
+ input_keys('2p')
+ assert_line('abcdebcdebcde')
+ assert_byte_pointer_size('abcdebcdebcd')
+ assert_cursor(12)
+ assert_cursor_max(13)
+ end
+
+ def test_vi_paste_prev_for_mbchar
+ input_keys("あいうえお\C-[3h")
+ assert_line('あいうえお')
+ assert_byte_pointer_size('あ')
+ assert_cursor(2)
+ assert_cursor_max(10)
+ input_keys('P')
+ assert_line('あいうえお')
+ assert_byte_pointer_size('あ')
+ assert_cursor(2)
+ assert_cursor_max(10)
+ input_keys('d$')
+ assert_line('あ')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
+ input_keys('P')
+ assert_line('いうえおあ')
+ assert_byte_pointer_size('いうえ')
+ assert_cursor(6)
+ assert_cursor_max(10)
+ input_keys('2P')
+ assert_line('いうえいうえいうえおおおあ')
+ assert_byte_pointer_size('いうえいうえいうえ')
+ assert_cursor(18)
+ assert_cursor_max(26)
+ end
+
+ def test_vi_paste_next_for_mbchar
+ input_keys("あいうえお\C-[3h")
+ assert_line('あいうえお')
+ assert_byte_pointer_size('あ')
+ assert_cursor(2)
+ assert_cursor_max(10)
+ input_keys('p')
+ assert_line('あいうえお')
+ assert_byte_pointer_size('あ')
+ assert_cursor(2)
+ assert_cursor_max(10)
+ input_keys('d$')
+ assert_line('あ')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
+ input_keys('p')
+ assert_line('あいうえお')
+ assert_byte_pointer_size('あいうえ')
+ assert_cursor(8)
+ assert_cursor_max(10)
+ input_keys('2p')
+ assert_line('あいうえおいうえおいうえお')
+ assert_byte_pointer_size('あいうえおいうえおいうえ')
+ assert_cursor(24)
+ assert_cursor_max(26)
+ end
+
+ def test_vi_paste_prev_for_mbchar_by_plural_code_points
+ input_keys("か\u3099き\u3099く\u3099け\u3099こ\u3099\C-[3h")
+ assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099")
+ assert_byte_pointer_size("か\u3099")
+ assert_cursor(2)
+ assert_cursor_max(10)
+ input_keys('P')
+ assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099")
+ assert_byte_pointer_size("か\u3099")
+ assert_cursor(2)
+ assert_cursor_max(10)
+ input_keys('d$')
+ assert_line("か\u3099")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
+ input_keys('P')
+ assert_line("き\u3099く\u3099け\u3099こ\u3099か\u3099")
+ assert_byte_pointer_size("き\u3099く\u3099け\u3099")
+ assert_cursor(6)
+ assert_cursor_max(10)
+ input_keys('2P')
+ assert_line("き\u3099く\u3099け\u3099き\u3099く\u3099け\u3099き\u3099く\u3099け\u3099こ\u3099こ\u3099こ\u3099か\u3099")
+ assert_byte_pointer_size("き\u3099く\u3099け\u3099き\u3099く\u3099け\u3099き\u3099く\u3099け\u3099")
+ assert_cursor(18)
+ assert_cursor_max(26)
+ end
+
+ def test_vi_paste_next_for_mbchar_by_plural_code_points
+ input_keys("か\u3099き\u3099く\u3099け\u3099こ\u3099\C-[3h")
+ assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099")
+ assert_byte_pointer_size("か\u3099")
+ assert_cursor(2)
+ assert_cursor_max(10)
+ input_keys('p')
+ assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099")
+ assert_byte_pointer_size("か\u3099")
+ assert_cursor(2)
+ assert_cursor_max(10)
+ input_keys('d$')
+ assert_line("か\u3099")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
+ input_keys('p')
+ assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099")
+ assert_byte_pointer_size("か\u3099き\u3099く\u3099け\u3099")
+ assert_cursor(8)
+ assert_cursor_max(10)
+ input_keys('2p')
+ assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099き\u3099く\u3099け\u3099こ\u3099き\u3099く\u3099け\u3099こ\u3099")
+ assert_byte_pointer_size("か\u3099き\u3099く\u3099け\u3099こ\u3099き\u3099く\u3099け\u3099こ\u3099き\u3099く\u3099け\u3099")
+ assert_cursor(24)
+ assert_cursor_max(26)
+ end
+
+ def test_vi_prev_next_word
+ input_keys("aaa b{b}b ccc\C-[0")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(13)
+ input_keys('w')
+ assert_byte_pointer_size('aaa ')
+ assert_cursor(4)
+ assert_cursor_max(13)
+ input_keys('w')
+ assert_byte_pointer_size('aaa b')
+ assert_cursor(5)
+ assert_cursor_max(13)
+ input_keys('w')
+ assert_byte_pointer_size('aaa b{')
+ assert_cursor(6)
+ assert_cursor_max(13)
+ input_keys('w')
+ assert_byte_pointer_size('aaa b{b')
+ assert_cursor(7)
+ assert_cursor_max(13)
+ input_keys('w')
+ assert_byte_pointer_size('aaa b{b}')
+ assert_cursor(8)
+ assert_cursor_max(13)
+ input_keys('w')
+ assert_byte_pointer_size('aaa b{b}b ')
+ assert_cursor(10)
+ assert_cursor_max(13)
+ input_keys('w')
+ assert_byte_pointer_size('aaa b{b}b cc')
+ assert_cursor(12)
+ assert_cursor_max(13)
+ input_keys('b')
+ assert_byte_pointer_size('aaa b{b}b ')
+ assert_cursor(10)
+ assert_cursor_max(13)
+ input_keys('b')
+ assert_byte_pointer_size('aaa b{b}')
+ assert_cursor(8)
+ assert_cursor_max(13)
+ input_keys('b')
+ assert_byte_pointer_size('aaa b{b')
+ assert_cursor(7)
+ assert_cursor_max(13)
+ input_keys('b')
+ assert_byte_pointer_size('aaa b{')
+ assert_cursor(6)
+ assert_cursor_max(13)
+ input_keys('b')
+ assert_byte_pointer_size('aaa b')
+ assert_cursor(5)
+ assert_cursor_max(13)
+ input_keys('b')
+ assert_byte_pointer_size('aaa ')
+ assert_cursor(4)
+ assert_cursor_max(13)
+ input_keys('b')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(13)
+ input_keys('3w')
+ assert_byte_pointer_size('aaa b{')
+ assert_cursor(6)
+ assert_cursor_max(13)
+ input_keys('3w')
+ assert_byte_pointer_size('aaa b{b}b ')
+ assert_cursor(10)
+ assert_cursor_max(13)
+ input_keys('3w')
+ assert_byte_pointer_size('aaa b{b}b cc')
+ assert_cursor(12)
+ assert_cursor_max(13)
+ input_keys('3b')
+ assert_byte_pointer_size('aaa b{b')
+ assert_cursor(7)
+ assert_cursor_max(13)
+ input_keys('3b')
+ assert_byte_pointer_size('aaa ')
+ assert_cursor(4)
+ assert_cursor_max(13)
+ input_keys('3b')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(13)
+ end
+
+ def test_vi_end_word
+ input_keys("aaa b{b}}}b ccc\C-[0")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(19)
+ input_keys('e')
+ assert_byte_pointer_size('aa')
+ assert_cursor(2)
+ assert_cursor_max(19)
+ input_keys('e')
+ assert_byte_pointer_size('aaa ')
+ assert_cursor(6)
+ assert_cursor_max(19)
+ input_keys('e')
+ assert_byte_pointer_size('aaa b')
+ assert_cursor(7)
+ assert_cursor_max(19)
+ input_keys('e')
+ assert_byte_pointer_size('aaa b{')
+ assert_cursor(8)
+ assert_cursor_max(19)
+ input_keys('e')
+ assert_byte_pointer_size('aaa b{b}}')
+ assert_cursor(11)
+ assert_cursor_max(19)
+ input_keys('e')
+ assert_byte_pointer_size('aaa b{b}}}')
+ assert_cursor(12)
+ assert_cursor_max(19)
+ input_keys('e')
+ assert_byte_pointer_size('aaa b{b}}}b cc')
+ assert_cursor(18)
+ assert_cursor_max(19)
+ input_keys('e')
+ assert_byte_pointer_size('aaa b{b}}}b cc')
+ assert_cursor(18)
+ assert_cursor_max(19)
+ input_keys('03e')
+ assert_byte_pointer_size('aaa b')
+ assert_cursor(7)
+ assert_cursor_max(19)
+ input_keys('3e')
+ assert_byte_pointer_size('aaa b{b}}}')
+ assert_cursor(12)
+ assert_cursor_max(19)
+ input_keys('3e')
+ assert_byte_pointer_size('aaa b{b}}}b cc')
+ assert_cursor(18)
+ assert_cursor_max(19)
+ end
+
+ def test_vi_prev_next_big_word
+ input_keys("aaa b{b}b ccc\C-[0")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(13)
+ input_keys('W')
+ assert_byte_pointer_size('aaa ')
+ assert_cursor(4)
+ assert_cursor_max(13)
+ input_keys('W')
+ assert_byte_pointer_size('aaa b{b}b ')
+ assert_cursor(10)
+ assert_cursor_max(13)
+ input_keys('W')
+ assert_byte_pointer_size('aaa b{b}b cc')
+ assert_cursor(12)
+ assert_cursor_max(13)
+ input_keys('B')
+ assert_byte_pointer_size('aaa b{b}b ')
+ assert_cursor(10)
+ assert_cursor_max(13)
+ input_keys('B')
+ assert_byte_pointer_size('aaa ')
+ assert_cursor(4)
+ assert_cursor_max(13)
+ input_keys('B')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(13)
+ input_keys('2W')
+ assert_byte_pointer_size('aaa b{b}b ')
+ assert_cursor(10)
+ assert_cursor_max(13)
+ input_keys('2W')
+ assert_byte_pointer_size('aaa b{b}b cc')
+ assert_cursor(12)
+ assert_cursor_max(13)
+ input_keys('2B')
+ assert_byte_pointer_size('aaa ')
+ assert_cursor(4)
+ assert_cursor_max(13)
+ input_keys('2B')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(13)
+ end
+
+ def test_vi_end_big_word
+ input_keys("aaa b{b}}}b ccc\C-[0")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(19)
+ input_keys('E')
+ assert_byte_pointer_size('aa')
+ assert_cursor(2)
+ assert_cursor_max(19)
+ input_keys('E')
+ assert_byte_pointer_size('aaa b{b}}}')
+ assert_cursor(12)
+ assert_cursor_max(19)
+ input_keys('E')
+ assert_byte_pointer_size('aaa b{b}}}b cc')
+ assert_cursor(18)
+ assert_cursor_max(19)
+ input_keys('E')
+ assert_byte_pointer_size('aaa b{b}}}b cc')
+ assert_cursor(18)
+ assert_cursor_max(19)
+ end
+
+ def test_ed_quoted_insert
+ input_keys("ab\C-v\C-acd")
+ assert_line("ab\C-acd")
+ assert_byte_pointer_size("ab\C-acd")
+ assert_cursor(6)
+ assert_cursor_max(6)
+ end
+
+ def test_ed_quoted_insert_with_vi_arg
+ input_keys("ab\C-[3\C-v\C-aacd")
+ assert_line("a\C-a\C-a\C-abcd")
+ assert_byte_pointer_size("a\C-a\C-a\C-abcd")
+ assert_cursor(10)
+ assert_cursor_max(10)
+ end
+
+ def test_vi_replace_char
+ input_keys("abcdef\C-[03l")
+ assert_line('abcdef')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(6)
+ input_keys('rz')
+ assert_line('abczef')
+ assert_byte_pointer_size('abc')
+ assert_cursor(3)
+ assert_cursor_max(6)
+ input_keys('2rx')
+ assert_line('abcxxf')
+ assert_byte_pointer_size('abcxx')
+ assert_cursor(5)
+ assert_cursor_max(6)
+ end
+
+ def test_vi_next_char
+ input_keys("abcdef\C-[0")
+ assert_line('abcdef')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
+ input_keys('fz')
+ assert_line('abcdef')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(6)
+ input_keys('fe')
+ assert_line('abcdef')
+ assert_byte_pointer_size('abcd')
+ assert_cursor(4)
+ assert_cursor_max(6)
+ end
+
+ def test_vi_delete_next_char
+ input_keys("abc\C-[h")
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(3)
+ assert_line('abc')
+ input_keys('x')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(2)
+ assert_line('ac')
+ input_keys('x')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(1)
+ assert_line('a')
+ input_keys('x')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ input_keys('x')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ end
+
+ def test_vi_delete_next_char_for_mbchar
+ input_keys("あいう\C-[h")
+ assert_byte_pointer_size('あ')
+ assert_cursor(2)
+ assert_cursor_max(6)
+ assert_line('あいう')
+ input_keys('x')
+ assert_byte_pointer_size('あ')
+ assert_cursor(2)
+ assert_cursor_max(4)
+ assert_line('あう')
+ input_keys('x')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
+ assert_line('あ')
+ input_keys('x')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ input_keys('x')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ end
+
+ def test_vi_delete_next_char_for_mbchar_by_plural_code_points
+ input_keys("か\u3099き\u3099く\u3099\C-[h")
+ assert_byte_pointer_size("か\u3099")
+ assert_cursor(2)
+ assert_cursor_max(6)
+ assert_line("か\u3099き\u3099く\u3099")
+ input_keys('x')
+ assert_byte_pointer_size("か\u3099")
+ assert_cursor(2)
+ assert_cursor_max(4)
+ assert_line("か\u3099く\u3099")
+ input_keys('x')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(2)
+ assert_line("か\u3099")
+ input_keys('x')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ input_keys('x')
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ end
+
+ def test_vi_delete_prev_char
+ input_keys('ab')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ input_keys("\C-h")
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(1)
+ assert_line('a')
+ end
+
+ def test_vi_delete_prev_char_for_mbchar
+ input_keys('かき')
+ assert_byte_pointer_size('かき')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ input_keys("\C-h")
+ assert_byte_pointer_size('か')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ assert_line('か')
+ end
+
+ def test_vi_delete_prev_char_for_mbchar_by_plural_code_points
+ input_keys("か\u3099き\u3099")
+ assert_byte_pointer_size("か\u3099き\u3099")
+ assert_cursor(4)
+ assert_cursor_max(4)
+ input_keys("\C-h")
+ assert_byte_pointer_size("か\u3099")
+ assert_cursor(2)
+ assert_cursor_max(2)
+ assert_line("か\u3099")
+ end
+
+ def test_ed_delete_prev_char
+ input_keys("abcdefg\C-[h")
+ assert_byte_pointer_size('abcde')
+ assert_cursor(5)
+ assert_cursor_max(7)
+ assert_line('abcdefg')
+ input_keys('X')
+ assert_byte_pointer_size('abcd')
+ assert_cursor(4)
+ assert_cursor_max(6)
+ assert_line('abcdfg')
+ input_keys('3X')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(3)
+ assert_line('afg')
+ input_keys('p')
+ assert_byte_pointer_size('abcd')
+ assert_cursor(4)
+ assert_cursor_max(6)
+ assert_line('afbcdg')
+ end
+
+ def test_ed_delete_prev_word
+ input_keys('abc def{bbb}ccc')
+ assert_byte_pointer_size('abc def{bbb}ccc')
+ assert_cursor(15)
+ assert_cursor_max(15)
+ input_keys("\C-w")
+ assert_byte_pointer_size('abc def{bbb}')
+ assert_cursor(12)
+ assert_cursor_max(12)
+ assert_line('abc def{bbb}')
+ input_keys("\C-w")
+ assert_byte_pointer_size('abc def{')
+ assert_cursor(8)
+ assert_cursor_max(8)
+ assert_line('abc def{')
+ input_keys("\C-w")
+ assert_byte_pointer_size('abc ')
+ assert_cursor(4)
+ assert_cursor_max(4)
+ assert_line('abc ')
+ input_keys("\C-w")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ end
+
+ def test_ed_delete_prev_word_for_mbchar
+ input_keys('あいう かきく{さしす}たちつ')
+ assert_byte_pointer_size('あいう かきく{さしす}たちつ')
+ assert_cursor(27)
+ assert_cursor_max(27)
+ input_keys("\C-w")
+ assert_byte_pointer_size('あいう かきく{さしす}')
+ assert_cursor(21)
+ assert_cursor_max(21)
+ assert_line('あいう かきく{さしす}')
+ input_keys("\C-w")
+ assert_byte_pointer_size('あいう かきく{')
+ assert_cursor(14)
+ assert_cursor_max(14)
+ assert_line('あいう かきく{')
+ input_keys("\C-w")
+ assert_byte_pointer_size('あいう ')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('あいう ')
+ input_keys("\C-w")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ end
+
+ def test_ed_delete_prev_word_for_mbchar_by_plural_code_points
+ input_keys("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
+ assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
+ assert_cursor(27)
+ assert_cursor_max(27)
+ input_keys("\C-w")
+ assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}")
+ assert_cursor(21)
+ assert_cursor_max(21)
+ assert_line("あいう か\u3099き\u3099く\u3099{さしす}")
+ input_keys("\C-w")
+ assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{")
+ assert_cursor(14)
+ assert_cursor_max(14)
+ assert_line("あいう か\u3099き\u3099く\u3099{")
+ input_keys("\C-w")
+ assert_byte_pointer_size('あいう ')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('あいう ')
+ input_keys("\C-w")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(0)
+ assert_line('')
+ end
+
+ def test_ed_newline_with_cr
+ input_keys('ab')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ refute(@line_editor.finished?)
+ input_keys("\C-m")
+ assert_line('ab')
+ assert(@line_editor.finished?)
+ end
+
+ def test_ed_newline_with_lf
+ input_keys('ab')
+ assert_byte_pointer_size('ab')
+ assert_cursor(2)
+ assert_cursor_max(2)
+ refute(@line_editor.finished?)
+ input_keys("\C-j")
+ assert_line('ab')
+ assert(@line_editor.finished?)
+ end
+
+ def test_vi_list_or_eof
+ input_keys('a')
+ assert_byte_pointer_size('a')
+ assert_cursor(1)
+ assert_cursor_max(1)
+ refute(@line_editor.finished?)
+ input_keys("\C-d")
+ assert_line('a')
+ refute(@line_editor.finished?)
+ input_keys("\C-h\C-d")
+ assert_line(nil)
+ assert(@line_editor.finished?)
+ end
+
+ def test_completion_journey
+ @line_editor.completion_proc = proc { |word|
+ %w{
+ foo_bar
+ foo_bar_baz
+ }
+ }
+ input_keys('foo')
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('foo')
+ input_keys("\C-n")
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('foo')
+ input_keys("\C-n")
+ assert_byte_pointer_size('foo_bar')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('foo_bar')
+ input_keys("\C-n")
+ assert_byte_pointer_size('foo_bar_baz')
+ assert_cursor(11)
+ assert_cursor_max(11)
+ assert_line('foo_bar_baz')
+ input_keys("\C-n")
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('foo')
+ input_keys("\C-n")
+ assert_byte_pointer_size('foo_bar')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('foo_bar')
+ input_keys("_\C-n")
+ assert_byte_pointer_size('foo_bar_')
+ assert_cursor(8)
+ assert_cursor_max(8)
+ assert_line('foo_bar_')
+ input_keys("\C-n")
+ assert_byte_pointer_size('foo_bar_baz')
+ assert_cursor(11)
+ assert_cursor_max(11)
+ assert_line('foo_bar_baz')
+ input_keys("\C-n")
+ assert_byte_pointer_size('foo_bar_')
+ assert_cursor(8)
+ assert_cursor_max(8)
+ assert_line('foo_bar_')
+ end
+
+ def test_completion_journey_reverse
+ @line_editor.completion_proc = proc { |word|
+ %w{
+ foo_bar
+ foo_bar_baz
+ }
+ }
+ input_keys('foo')
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('foo')
+ input_keys("\C-p")
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('foo')
+ input_keys("\C-p")
+ assert_byte_pointer_size('foo_bar_baz')
+ assert_cursor(11)
+ assert_cursor_max(11)
+ assert_line('foo_bar_baz')
+ input_keys("\C-p")
+ assert_byte_pointer_size('foo_bar')
+ assert_cursor(7)
+ assert_cursor_max(7)
+ assert_line('foo_bar')
+ input_keys("\C-p")
+ assert_byte_pointer_size('foo')
+ assert_cursor(3)
+ assert_cursor_max(3)
+ assert_line('foo')
+ input_keys("\C-p")
+ assert_byte_pointer_size('foo_bar_baz')
+ assert_cursor(11)
+ assert_cursor_max(11)
+ assert_line('foo_bar_baz')
+ input_keys("\C-h\C-p")
+ assert_byte_pointer_size('foo_bar_ba')
+ assert_cursor(10)
+ assert_cursor_max(10)
+ assert_line('foo_bar_ba')
+ input_keys("\C-p")
+ assert_byte_pointer_size('foo_bar_baz')
+ assert_cursor(11)
+ assert_cursor_max(11)
+ assert_line('foo_bar_baz')
+ input_keys("\C-p")
+ assert_byte_pointer_size('foo_bar_ba')
+ assert_cursor(10)
+ assert_cursor_max(10)
+ assert_line('foo_bar_ba')
+ end
+
+ def test_completion_journey_in_middle_of_line
+ @line_editor.completion_proc = proc { |word|
+ %w{
+ foo_bar
+ foo_bar_baz
+ }
+ }
+ input_keys('abcde fo ABCDE')
+ assert_line('abcde fo ABCDE')
+ input_keys("\C-[" + 'h' * 5 + "i\C-n")
+ assert_byte_pointer_size('abcde fo')
+ assert_cursor(8)
+ assert_cursor_max(14)
+ assert_line('abcde fo ABCDE')
+ input_keys("\C-n")
+ assert_byte_pointer_size('abcde foo_bar')
+ assert_cursor(13)
+ assert_cursor_max(19)
+ assert_line('abcde foo_bar ABCDE')
+ input_keys("\C-n")
+ assert_byte_pointer_size('abcde foo_bar_baz')
+ assert_cursor(17)
+ assert_cursor_max(23)
+ assert_line('abcde foo_bar_baz ABCDE')
+ input_keys("\C-n")
+ assert_byte_pointer_size('abcde fo')
+ assert_cursor(8)
+ assert_cursor_max(14)
+ assert_line('abcde fo ABCDE')
+ input_keys("\C-n")
+ assert_byte_pointer_size('abcde foo_bar')
+ assert_cursor(13)
+ assert_cursor_max(19)
+ assert_line('abcde foo_bar ABCDE')
+ input_keys("_\C-n")
+ assert_byte_pointer_size('abcde foo_bar_')
+ assert_cursor(14)
+ assert_cursor_max(20)
+ assert_line('abcde foo_bar_ ABCDE')
+ input_keys("\C-n")
+ assert_byte_pointer_size('abcde foo_bar_baz')
+ assert_cursor(17)
+ assert_cursor_max(23)
+ assert_line('abcde foo_bar_baz ABCDE')
+ input_keys("\C-n")
+ assert_byte_pointer_size('abcde foo_bar_')
+ assert_cursor(14)
+ assert_cursor_max(20)
+ assert_line('abcde foo_bar_ ABCDE')
+ input_keys("\C-n")
+ assert_byte_pointer_size('abcde foo_bar_baz')
+ assert_cursor(17)
+ assert_cursor_max(23)
+ assert_line('abcde foo_bar_baz ABCDE')
+ end
+
+ def test_ed_move_to_beg
+ input_keys("abcde\C-[^")
+ assert_byte_pointer_size('')
+ assert_cursor(0)
+ assert_cursor_max(5)
+ input_keys("0\C-ki")
+ input_keys(" abcde\C-[^")
+ assert_byte_pointer_size(' ')
+ assert_cursor(1)
+ assert_cursor_max(6)
+ input_keys("0\C-ki")
+ input_keys(" abcde ABCDE \C-[^")
+ assert_byte_pointer_size(' ')
+ assert_cursor(3)
+ assert_cursor_max(17)
+ end
+
+ def test_vi_delete_meta
+ input_keys("aaa bbb ccc ddd eee\C-[02w")
+ assert_byte_pointer_size('aaa bbb ')
+ assert_cursor(8)
+ assert_cursor_max(19)
+ assert_line('aaa bbb ccc ddd eee')
+ input_keys('dw')
+ assert_byte_pointer_size('aaa bbb ')
+ assert_cursor(8)
+ assert_cursor_max(15)
+ assert_line('aaa bbb ddd eee')
+ input_keys('db')
+ assert_byte_pointer_size('aaa ')
+ assert_cursor(4)
+ assert_cursor_max(11)
+ assert_line('aaa ddd eee')
+ end
+end
diff --git a/test/reline/key_stroke_test.rb b/test/reline/key_stroke_test.rb
new file mode 100644
index 0000000000..b6d5ce4150
--- /dev/null
+++ b/test/reline/key_stroke_test.rb
@@ -0,0 +1,51 @@
+require_relative 'helper'
+
+class Reline::KeyStroke::Test < Reline::TestCase
+ using Module.new {
+ refine Array do
+ def as_s
+ map(&:chr).join
+ end
+ end
+ }
+
+ def test_input_to!
+ config = {
+ key_mapping: {
+ "a" => "xx",
+ "ab" => "y",
+ "abc" => "z",
+ "x" => "rr"
+ }
+ }
+ stroke = Reline::KeyStroke.new(config)
+ result = ("abzwabk".bytes).map { |char|
+ stroke.input_to!(char)&.then { |result|
+ "#{result.as_s}"
+ }
+ }
+ assert_equal(result, [nil, nil, "yz", "w", nil, nil, "yk"])
+ end
+
+ def test_input_to
+ config = {
+ key_mapping: {
+ "a" => "xx",
+ "ab" => "y",
+ "abc" => "z",
+ "x" => "rr"
+ }
+ }
+ stroke = Reline::KeyStroke.new(config)
+ assert_equal(stroke.input_to("a".bytes)&.as_s, nil)
+ assert_equal(stroke.input_to("ab".bytes)&.as_s, nil)
+ assert_equal(stroke.input_to("abc".bytes)&.as_s, "z")
+ assert_equal(stroke.input_to("abz".bytes)&.as_s, "yz")
+ assert_equal(stroke.input_to("abx".bytes)&.as_s, "yrr")
+ assert_equal(stroke.input_to("ac".bytes)&.as_s, "rrrrc")
+ assert_equal(stroke.input_to("aa".bytes)&.as_s, "rrrrrrrr")
+ assert_equal(stroke.input_to("x".bytes)&.as_s, "rr")
+ assert_equal(stroke.input_to("m".bytes)&.as_s, "m")
+ assert_equal(stroke.input_to("abzwabk".bytes)&.as_s, "yzwabk")
+ end
+end
diff --git a/test/reline/kill_ring_test.rb b/test/reline/kill_ring_test.rb
new file mode 100644
index 0000000000..8bebfe2177
--- /dev/null
+++ b/test/reline/kill_ring_test.rb
@@ -0,0 +1,256 @@
+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
+end