summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2024-09-06 09:55:34 +0900
committerGitHub <noreply@github.com>2024-09-05 17:55:34 -0700
commitc3f7041ab19fbf0e937126dc1b7397b97f768b9a (patch)
tree741575c32037cd78586588ced0dd7cbaaa0f8cad /test
parent4eb51dfc9e67683a1a03fdf302d5ddd95cad716a (diff)
Merge reline-0.5.10 (#11558)
* Merge reline-0.5.8 * Merge reline-0.5.9 * Merge reline-0.5.10
Diffstat (limited to 'test')
-rw-r--r--test/reline/helper.rb33
-rw-r--r--test/reline/test_ansi_with_terminfo.rb4
-rw-r--r--test/reline/test_ansi_without_terminfo.rb4
-rw-r--r--test/reline/test_config.rb159
-rw-r--r--test/reline/test_key_actor_emacs.rb163
-rw-r--r--test/reline/test_key_actor_vi.rb56
-rw-r--r--test/reline/test_key_stroke.rb56
-rw-r--r--test/reline/test_line_editor.rb10
-rw-r--r--test/reline/test_reline.rb44
-rw-r--r--test/reline/test_reline_key.rb51
-rw-r--r--test/reline/yamatanooroti/test_rendering.rb99
11 files changed, 478 insertions, 201 deletions
diff --git a/test/reline/helper.rb b/test/reline/helper.rb
index 26fe834482..3d7dc7d812 100644
--- a/test/reline/helper.rb
+++ b/test/reline/helper.rb
@@ -22,29 +22,36 @@ module Reline
class <<self
def test_mode(ansi: false)
@original_iogate = IOGate
- remove_const('IOGate')
- const_set('IOGate', ansi ? Reline::ANSI : Reline::GeneralIO)
+
if ENV['RELINE_TEST_ENCODING']
encoding = Encoding.find(ENV['RELINE_TEST_ENCODING'])
else
encoding = Encoding::UTF_8
end
- @original_get_screen_size = IOGate.method(:get_screen_size)
- IOGate.singleton_class.remove_method(:get_screen_size)
- def IOGate.get_screen_size
- [24, 80]
+
+ 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
- Reline::GeneralIO.reset(encoding: encoding) unless ansi
+
+ remove_const('IOGate')
+ const_set('IOGate', new_io_gate)
core.config.instance_variable_set(:@test_mode, true)
core.config.reset
end
def test_reset
- IOGate.singleton_class.remove_method(:get_screen_size)
- IOGate.define_singleton_method(:get_screen_size, @original_get_screen_size)
remove_const('IOGate')
const_set('IOGate', @original_iogate)
- Reline::GeneralIO.reset
Reline.instance_variable_set(:@core, nil)
end
@@ -89,7 +96,7 @@ class Reline::TestCase < Test::Unit::TestCase
end
}.join
rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError
- input.unicode_normalize!(:nfc)
+ input = input.unicode_normalize(:nfc)
if normalized
options[:undef] = :replace
options[:replace] = '?'
@@ -146,7 +153,7 @@ class Reline::TestCase < Test::Unit::TestCase
expected.bytesize, byte_pointer,
<<~EOM)
<#{expected.inspect} (#{expected.encoding.inspect})> expected but was
- <#{chunk.inspect} (#{chunk.encoding.inspect})> in <Terminal #{Reline::GeneralIO.encoding.inspect}>
+ <#{chunk.inspect} (#{chunk.encoding.inspect})> in <Terminal #{Reline::Dumb.new.encoding.inspect}>
EOM
end
@@ -161,7 +168,7 @@ class Reline::TestCase < Test::Unit::TestCase
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.default_key_bindings[input.bytes])
+ assert_equal(method_symbol, @config.editing_mode.get(input.bytes))
end
end
end
diff --git a/test/reline/test_ansi_with_terminfo.rb b/test/reline/test_ansi_with_terminfo.rb
index e1c56b9ee1..3adda10716 100644
--- a/test/reline/test_ansi_with_terminfo.rb
+++ b/test/reline/test_ansi_with_terminfo.rb
@@ -1,7 +1,7 @@
require_relative 'helper'
-require 'reline/ansi'
+require 'reline'
-class Reline::ANSI::TestWithTerminfo < Reline::TestCase
+class Reline::ANSI::WithTerminfoTest < Reline::TestCase
def setup
Reline.send(:test_mode, ansi: true)
@config = Reline::Config.new
diff --git a/test/reline/test_ansi_without_terminfo.rb b/test/reline/test_ansi_without_terminfo.rb
index 3d153514f3..2db14cf0a0 100644
--- a/test/reline/test_ansi_without_terminfo.rb
+++ b/test/reline/test_ansi_without_terminfo.rb
@@ -1,7 +1,7 @@
require_relative 'helper'
-require 'reline/ansi'
+require 'reline'
-class Reline::ANSI::TestWithoutTerminfo < Reline::TestCase
+class Reline::ANSI::WithoutTerminfoTest < Reline::TestCase
def setup
Reline.send(:test_mode, ansi: true)
@config = Reline::Config.new
diff --git a/test/reline/test_config.rb b/test/reline/test_config.rb
index 6068292847..68a102a599 100644
--- a/test/reline/test_config.rb
+++ b/test/reline/test_config.rb
@@ -13,6 +13,7 @@ class Reline::Config::Test < Reline::TestCase
Dir.chdir(@tmpdir)
Reline.test_mode
@config = Reline::Config.new
+ @inputrc_backup = ENV['INPUTRC']
end
def teardown
@@ -20,14 +21,28 @@ class Reline::Config::Test < Reline::TestCase
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 bell-style on
+ set show-mode-in-prompt on
LINES
- assert_equal :audible, @config.instance_variable_get(:@bell_style)
+ assert_equal true, get_config_variable(:@show_mode_in_prompt)
end
def test_read_lines_with_variable
@@ -35,7 +50,7 @@ class Reline::Config::Test < Reline::TestCase
set disable-completion on
LINES
- assert_equal true, @config.instance_variable_get(:@disable_completion)
+ assert_equal true, get_config_variable(:@disable_completion)
end
def test_string_value
@@ -44,7 +59,7 @@ class Reline::Config::Test < Reline::TestCase
set emacs-mode-string Emacs
LINES
- assert_equal 'Emacs', @config.instance_variable_get(:@emacs_mode_string)
+ assert_equal 'Emacs', get_config_variable(:@emacs_mode_string)
end
def test_string_value_with_brackets
@@ -53,7 +68,7 @@ class Reline::Config::Test < Reline::TestCase
set emacs-mode-string [Emacs]
LINES
- assert_equal '[Emacs]', @config.instance_variable_get(:@emacs_mode_string)
+ assert_equal '[Emacs]', get_config_variable(:@emacs_mode_string)
end
def test_string_value_with_brackets_and_quotes
@@ -62,7 +77,7 @@ class Reline::Config::Test < Reline::TestCase
set emacs-mode-string "[Emacs]"
LINES
- assert_equal '[Emacs]', @config.instance_variable_get(:@emacs_mode_string)
+ assert_equal '[Emacs]', get_config_variable(:@emacs_mode_string)
end
def test_string_value_with_parens
@@ -71,7 +86,7 @@ class Reline::Config::Test < Reline::TestCase
set emacs-mode-string (Emacs)
LINES
- assert_equal '(Emacs)', @config.instance_variable_get(:@emacs_mode_string)
+ assert_equal '(Emacs)', get_config_variable(:@emacs_mode_string)
end
def test_string_value_with_parens_and_quotes
@@ -80,33 +95,34 @@ class Reline::Config::Test < Reline::TestCase
set emacs-mode-string "(Emacs)"
LINES
- assert_equal '(Emacs)', @config.instance_variable_get(:@emacs_mode_string)
+ assert_equal '(Emacs)', get_config_variable(:@emacs_mode_string)
end
def test_encoding_is_ascii
@config.reset
- Reline.core.io_gate.reset(encoding: Encoding::US_ASCII)
+ 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.reset
- Reline.core.io_gate.reset(encoding: Encoding::UTF_8)
@config = Reline::Config.new
- assert_equal nil, @config.convert_meta
- end
-
- def test_comment_line
- @config.read_lines([" #a: error\n"])
- assert_not_include @config.key_bindings, nil
+ assert_equal false, @config.convert_meta
end
def test_invalid_keystroke
- @config.read_lines(["a: error\n"])
- assert_not_include @config.key_bindings, nil
+ @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
@@ -150,21 +166,21 @@ class Reline::Config::Test < Reline::TestCase
def test_include
File.open('included_partial', 'wt') do |f|
f.write(<<~PARTIAL_LINES)
- set bell-style on
+ set show-mode-in-prompt on
PARTIAL_LINES
end
@config.read_lines(<<~LINES.lines)
$include included_partial
LINES
- assert_equal :audible, @config.instance_variable_get(:@bell_style)
+ 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 bell-style on
+ set show-mode-in-prompt on
PARTIAL_LINES
end
ENV['HOME'] = Dir.pwd
@@ -172,7 +188,7 @@ class Reline::Config::Test < Reline::TestCase
$include ~/included_partial
LINES
- assert_equal :audible, @config.instance_variable_get(:@bell_style)
+ assert_equal true, get_config_variable(:@show_mode_in_prompt)
ensure
ENV['HOME'] = home_backup
end
@@ -180,39 +196,39 @@ class Reline::Config::Test < Reline::TestCase
def test_if
@config.read_lines(<<~LINES.lines)
$if Ruby
- set bell-style audible
+ set vi-cmd-mode-string (cmd)
$else
- set bell-style visible
+ set vi-cmd-mode-string [cmd]
$endif
LINES
- assert_equal :audible, @config.instance_variable_get(:@bell_style)
+ assert_equal '(cmd)', get_config_variable(:@vi_cmd_mode_string)
end
def test_if_with_false
@config.read_lines(<<~LINES.lines)
$if Python
- set bell-style audible
+ set vi-cmd-mode-string (cmd)
$else
- set bell-style visible
+ set vi-cmd-mode-string [cmd]
$endif
LINES
- assert_equal :visible, @config.instance_variable_get(:@bell_style)
+ 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 bell-style none
+ set vi-cmd-mode-string {cmd}
$if #{cond}
- set bell-style audible
+ set vi-cmd-mode-string (cmd)
$else
- set bell-style visible
+ set vi-cmd-mode-string [cmd]
$endif
LINES
- assert_equal :audible, @config.instance_variable_get(:@bell_style)
+ assert_equal '(cmd)', get_config_variable(:@vi_cmd_mode_string)
end
end
@@ -244,8 +260,8 @@ class Reline::Config::Test < Reline::TestCase
"\xC": "O"
LINES
keys = [0x1, 0x3, 0x4, 0x6, 0x7, 0xC]
- key_bindings = keys.to_h { |k| [[k.ord], ['O'.ord]] }
- assert_equal(key_bindings, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
+ key_bindings = keys.to_h { |k| [[k], ['O'.ord]] }
+ assert_equal(key_bindings, additional_key_bindings(:emacs))
end
def test_unclosed_if
@@ -284,9 +300,9 @@ class Reline::Config::Test < Reline::TestCase
$endif
LINES
- assert_equal({[5] => :history_search_backward}, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command])
+ 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
@@ -298,9 +314,9 @@ class Reline::Config::Test < Reline::TestCase
$endif
LINES
- assert_equal({[6] => :history_search_forward}, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command])
+ 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
@@ -312,9 +328,9 @@ class Reline::Config::Test < Reline::TestCase
$endif
LINES
- assert_equal({[6] => :history_search_forward}, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command])
+ 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
@@ -329,9 +345,9 @@ class Reline::Config::Test < Reline::TestCase
"\C-e": history-search-backward
$endif
LINES
- assert_equal({[5] => :history_search_backward}, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command])
+ 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
@@ -342,9 +358,9 @@ class Reline::Config::Test < Reline::TestCase
$endif
LINES
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
- assert_equal({[5] => :history_search_backward}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert])
- assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command])
+ 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
@@ -355,7 +371,7 @@ class Reline::Config::Test < Reline::TestCase
LINES
expected = { 'abcd'.bytes => 'ABCD'.bytes, 'ijkl'.bytes => 'IJKL'.bytes }
- assert_equal expected, @config.key_bindings
+ assert_equal expected, registered_key_bindings(expected.keys)
end
def test_additional_key_bindings
@@ -365,7 +381,7 @@ class Reline::Config::Test < Reline::TestCase
LINES
expected = { 'ef'.bytes => 'EF'.bytes, 'gh'.bytes => 'GH'.bytes }
- assert_equal expected, @config.key_bindings
+ assert_equal expected, registered_key_bindings(expected.keys)
end
def test_additional_key_bindings_with_nesting_and_comment_out
@@ -377,7 +393,7 @@ class Reline::Config::Test < Reline::TestCase
LINES
expected = { 'ef'.bytes => 'EF'.bytes, 'gh'.bytes => 'GH'.bytes }
- assert_equal expected, @config.key_bindings
+ assert_equal expected, registered_key_bindings(expected.keys)
end
def test_additional_key_bindings_for_other_keymap
@@ -392,7 +408,7 @@ class Reline::Config::Test < Reline::TestCase
LINES
expected = { 'cd'.bytes => 'CD'.bytes }
- assert_equal expected, @config.key_bindings
+ assert_equal expected, registered_key_bindings(expected.keys)
end
def test_additional_key_bindings_for_auxiliary_emacs_keymaps
@@ -414,7 +430,7 @@ class Reline::Config::Test < Reline::TestCase
"\C-xef".bytes => 'EF'.bytes,
"\egh".bytes => 'GH'.bytes,
}
- assert_equal expected, @config.key_bindings
+ assert_equal expected, registered_key_bindings(expected.keys)
end
def test_key_bindings_with_reset
@@ -426,7 +442,7 @@ class Reline::Config::Test < Reline::TestCase
LINES
@config.reset
expected = { 'default'.bytes => 'DEFAULT'.bytes, 'additional'.bytes => 'ADDITIONAL'.bytes }
- assert_equal expected, @config.key_bindings
+ assert_equal expected, registered_key_bindings(expected.keys)
end
def test_history_size
@@ -434,7 +450,7 @@ class Reline::Config::Test < Reline::TestCase
set history-size 5000
LINES
- assert_equal 5000, @config.instance_variable_get(:@history_size)
+ assert_equal 5000, get_config_variable(:@history_size)
history = Reline::History.new(@config)
history << "a\n"
assert_equal 1, history.size
@@ -459,6 +475,17 @@ class Reline::Config::Test < Reline::TestCase
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)
@@ -541,5 +568,21 @@ class Reline::Config::Test < Reline::TestCase
ENV['XDG_CONFIG_HOME'] = xdg_config_home_backup
ENV['HOME'] = home_backup
end
-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_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb
index 013ca2f7b3..4dddf9c890 100644
--- a/test/reline/test_key_actor_emacs.rb
+++ b/test/reline/test_key_actor_emacs.rb
@@ -1,6 +1,6 @@
require_relative 'helper'
-class Reline::KeyActor::Emacs::Test < Reline::TestCase
+class Reline::KeyActor::EmacsTest < Reline::TestCase
def setup
Reline.send(:test_mode)
@prompt = '> '
@@ -1242,14 +1242,22 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12345' # new
])
# The ed_search_prev_history doesn't have default binding
- @line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_line_around_cursor('', '12345')
- @line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_line_around_cursor('', '12aaa')
- @line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_line_around_cursor('', '12356')
- @line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_line_around_cursor('', '12356')
+ 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
@@ -1291,18 +1299,25 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12345' # new
])
# 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('', '12345')
- @line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_line_around_cursor('', '12aaa')
- @line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_line_around_cursor('', '12356')
- @line_editor.__send__(:ed_search_next_history, "\C-n".ord)
- assert_line_around_cursor('', '12aaa')
- @line_editor.__send__(:ed_search_next_history, "\C-n".ord)
- assert_line_around_cursor('', '12345')
- @line_editor.__send__(:ed_search_next_history, "\C-n".ord)
- assert_line_around_cursor('', '')
+ 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
@@ -1498,11 +1513,115 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
end
def test_undo_with_many_times
- str = "a" + "b" * 100
+ str = "a" + "b" * 99
+ input_keys(str, false)
+ 100.times { input_keys("\C-_", false) }
+ assert_line_around_cursor('a', '')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('a', '')
+ end
+
+ def test_redo
+ input_keys("aあb", false)
+ assert_line_around_cursor('aあb', '')
+ input_keys("\M-\C-_", false)
+ assert_line_around_cursor('aあb', '')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('aあ', '')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('a', '')
+ input_keys("\M-\C-_", false)
+ assert_line_around_cursor('aあ', '')
+ input_keys("\M-\C-_", false)
+ assert_line_around_cursor('aあb', '')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('aあ', '')
+ input_keys("c", false)
+ assert_line_around_cursor('aあc', '')
+ input_keys("\M-\C-_", false)
+ assert_line_around_cursor('aあc', '')
+ end
+
+ def test_redo_with_cursor_position
+ input_keys("abc\C-b\C-h", false)
+ assert_line_around_cursor('a', 'c')
+ input_keys("\M-\C-_", false)
+ assert_line_around_cursor('a', 'c')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('ab', 'c')
+ input_keys("\M-\C-_", false)
+ 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", false)
+ assert_whole_lines(["1", "2", "3"])
+ assert_line_index(2)
+ assert_line_around_cursor('3', '')
+
+ input_keys("\C-_", false)
+ assert_whole_lines(["1", "2", ""])
+ assert_line_index(2)
+ assert_line_around_cursor('', '')
+
+ input_keys("\C-_", false)
+ assert_whole_lines(["1", "2"])
+ assert_line_index(1)
+ assert_line_around_cursor('2', '')
+
+ input_keys("\M-\C-_", false)
+ assert_whole_lines(["1", "2", ""])
+ assert_line_index(2)
+ assert_line_around_cursor('', '')
+
+ input_keys("\M-\C-_", false)
+ assert_whole_lines(["1", "2", "3"])
+ assert_line_index(2)
+ assert_line_around_cursor('3', '')
+
+ input_keys("\C-p\C-h\C-h", false)
+ assert_whole_lines(["1", "3"])
+ assert_line_index(0)
+ assert_line_around_cursor('1', '')
+
+ input_keys("\C-n", false)
+ assert_whole_lines(["1", "3"])
+ assert_line_index(1)
+ assert_line_around_cursor('3', '')
+
+ input_keys("\C-_", false)
+ assert_whole_lines(["1", "", "3"])
+ assert_line_index(1)
+ assert_line_around_cursor('', '')
+
+ input_keys("\C-_", false)
+ assert_whole_lines(["1", "2", "3"])
+ assert_line_index(1)
+ assert_line_around_cursor('2', '')
+
+ input_keys("\M-\C-_", false)
+ assert_whole_lines(["1", "", "3"])
+ assert_line_index(1)
+ assert_line_around_cursor('', '')
+
+ input_keys("\M-\C-_", false)
+ assert_whole_lines(["1", "3"])
+ assert_line_index(1)
+ assert_line_around_cursor('3', '')
+ end
+
+ def test_redo_with_many_times
+ str = "a" + "b" * 98 + "c"
input_keys(str, false)
100.times { input_keys("\C-_", false) }
assert_line_around_cursor('a', '')
input_keys("\C-_", false)
assert_line_around_cursor('a', '')
+ 100.times { input_keys("\M-\C-_", false) }
+ assert_line_around_cursor(str, '')
+ input_keys("\M-\C-_", false)
+ 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
index 4deae2dd83..07ca873ce3 100644
--- a/test/reline/test_key_actor_vi.rb
+++ b/test/reline/test_key_actor_vi.rb
@@ -1,6 +1,6 @@
require_relative 'helper'
-class Reline::KeyActor::ViInsert::Test < Reline::TestCase
+class Reline::ViInsertTest < Reline::TestCase
def setup
Reline.send(:test_mode)
@prompt = '> '
@@ -13,69 +13,73 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
@line_editor.reset(@prompt, encoding: @encoding)
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_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
+ assert_equal(:vi_command, editing_mode_label)
end
def test_vi_command_mode_with_input
input_keys("abc\C-[")
- assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
+ assert_equal(:vi_command, editing_mode_label)
assert_line_around_cursor('ab', 'c')
end
def test_vi_insert
- assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
+ assert_equal(:vi_insert, editing_mode_label)
input_keys('i')
assert_line_around_cursor('i', '')
- assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
+ assert_equal(:vi_insert, editing_mode_label)
input_keys("\C-[")
assert_line_around_cursor('', 'i')
- assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
+ assert_equal(:vi_command, editing_mode_label)
input_keys('i')
assert_line_around_cursor('', 'i')
- assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
+ assert_equal(:vi_insert, editing_mode_label)
end
def test_vi_add
- assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
+ assert_equal(:vi_insert, editing_mode_label)
input_keys('a')
assert_line_around_cursor('a', '')
- assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
+ assert_equal(:vi_insert, editing_mode_label)
input_keys("\C-[")
assert_line_around_cursor('', 'a')
- assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
+ assert_equal(:vi_command, editing_mode_label)
input_keys('a')
assert_line_around_cursor('a', '')
- assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
+ assert_equal(:vi_insert, editing_mode_label)
end
def test_vi_insert_at_bol
input_keys('I')
assert_line_around_cursor('I', '')
- assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
+ assert_equal(:vi_insert, editing_mode_label)
input_keys("12345\C-[hh")
assert_line_around_cursor('I12', '345')
- assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
+ assert_equal(:vi_command, editing_mode_label)
input_keys('I')
assert_line_around_cursor('', 'I12345')
- assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
+ assert_equal(:vi_insert, editing_mode_label)
end
def test_vi_add_at_eol
input_keys('A')
assert_line_around_cursor('A', '')
- assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
+ assert_equal(:vi_insert, editing_mode_label)
input_keys("12345\C-[hh")
assert_line_around_cursor('A12', '345')
- assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
+ assert_equal(:vi_command, editing_mode_label)
input_keys('A')
assert_line_around_cursor('A12345', '')
- assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
+ assert_equal(:vi_insert, editing_mode_label)
end
def test_ed_insert_one
@@ -734,6 +738,13 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
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')
@@ -844,6 +855,13 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
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')
@@ -901,11 +919,11 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
assert_line_around_cursor('abc', '')
input_keys("\C-[0C")
assert_line_around_cursor('', '')
- assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
+ assert_equal(:vi_insert, editing_mode_label)
end
def test_vi_motion_operators
- assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
+ assert_equal(:vi_insert, editing_mode_label)
assert_nothing_raised do
input_keys("test = { foo: bar }\C-[BBBldt}b")
diff --git a/test/reline/test_key_stroke.rb b/test/reline/test_key_stroke.rb
index cd205c7d9e..ec70a05957 100644
--- a/test/reline/test_key_stroke.rb
+++ b/test/reline/test_key_stroke.rb
@@ -24,16 +24,14 @@ class Reline::KeyStroke::Test < Reline::TestCase
config.add_default_key_binding(key.bytes, func.bytes)
end
stroke = Reline::KeyStroke.new(config)
- assert_equal(:matching, stroke.match_status("a".bytes))
- assert_equal(:matching, stroke.match_status("ab".bytes))
- assert_equal(:matched, stroke.match_status("abc".bytes))
- assert_equal(:matched, stroke.match_status("abz".bytes))
- assert_equal(:matched, stroke.match_status("abx".bytes))
- assert_equal(:matched, stroke.match_status("ac".bytes))
- assert_equal(:matched, stroke.match_status("aa".bytes))
- assert_equal(:matched, stroke.match_status("x".bytes))
- assert_equal(:unmatched, stroke.match_status("m".bytes))
- assert_equal(:matched, stroke.match_status("abzwabk".bytes))
+ 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
@@ -47,12 +45,15 @@ class Reline::KeyStroke::Test < Reline::TestCase
"\e[1;1R", # Cursor position report
"\e[15~", # F5
"\eOP", # F1
- "\e\e[A" # Option+Up
+ "\e\e[A", # Option+Up
+ "\eX",
+ "\e\eX"
]
sequences.each do |seq|
- assert_equal(:matched, stroke.match_status(seq.bytes))
- (1...seq.size).each do |i|
- assert_equal(:matching, stroke.match_status(seq.bytes.take(i)))
+ 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
@@ -61,16 +62,18 @@ class Reline::KeyStroke::Test < Reline::TestCase
config = Reline::Config.new
{
'abc' => '123',
+ 'ab' => '456'
}.each_pair do |key, func|
config.add_default_key_binding(key.bytes, func.bytes)
end
stroke = Reline::KeyStroke.new(config)
- assert_equal('123'.bytes, stroke.expand('abc'.bytes))
+ assert_equal(['123'.bytes.map { |c| Reline::Key.new(c, c, false) }, 'de'.bytes], stroke.expand('abcde'.bytes))
+ assert_equal(['456'.bytes.map { |c| Reline::Key.new(c, c, false) }, 'de'.bytes], stroke.expand('abde'.bytes))
# CSI sequence
- assert_equal([:ed_unassigned] + 'bc'.bytes, stroke.expand("\e[1;2;3;4;5abc".bytes))
- assert_equal([:ed_unassigned] + 'BC'.bytes, stroke.expand("\e\e[ABC".bytes))
+ 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([:ed_unassigned] + 'QR'.bytes, stroke.expand("\eOPQR".bytes))
+ assert_equal([[], 'QR'.bytes], stroke.expand("\eOPQR".bytes))
end
def test_oneshot_key_bindings
@@ -81,25 +84,22 @@ class Reline::KeyStroke::Test < Reline::TestCase
config.add_default_key_binding(key.bytes, func.bytes)
end
stroke = Reline::KeyStroke.new(config)
- assert_equal(:unmatched, stroke.match_status('zzz'.bytes))
- assert_equal(:matched, stroke.match_status('abc'.bytes))
+ assert_equal(Reline::KeyStroke::UNMATCHED, stroke.match_status('zzz'.bytes))
+ assert_equal(Reline::KeyStroke::MATCHED, stroke.match_status('abc'.bytes))
end
def test_with_reline_key
config = Reline::Config.new
{
- [
- Reline::Key.new(100, 228, true), # Alt+d
- Reline::Key.new(97, 97, false) # a
- ] => 'abc',
+ "\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)
- assert_equal(:unmatched, stroke.match_status('da'.bytes))
- assert_equal(:matched, stroke.match_status("\M-da".bytes))
- assert_equal(:unmatched, stroke.match_status([32, 195, 164]))
- assert_equal(:matched, stroke.match_status([195, 164]))
+ 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([32, 195, 164]))
+ assert_equal(Reline::KeyStroke::MATCHED, stroke.match_status([195, 164]))
end
end
diff --git a/test/reline/test_line_editor.rb b/test/reline/test_line_editor.rb
index 7a38ecd596..1859da8199 100644
--- a/test/reline/test_line_editor.rb
+++ b/test/reline/test_line_editor.rb
@@ -4,14 +4,12 @@ require 'stringio'
class Reline::LineEditor
class RenderLineDifferentialTest < Reline::TestCase
- module TestIO
- RESET_COLOR = "\e[0m"
-
- def self.move_cursor_column(col)
+ class TestIO < Reline::IO
+ def move_cursor_column(col)
@output << "[COL_#{col}]"
end
- def self.erase_after_cursor
+ def erase_after_cursor
@output << '[ERASE]'
end
end
@@ -24,7 +22,7 @@ class Reline::LineEditor
@line_editor.instance_variable_set(:@screen_size, [24, 80])
@line_editor.instance_variable_set(:@output, @output)
Reline.send(:remove_const, :IOGate)
- Reline.const_set(:IOGate, TestIO)
+ Reline.const_set(:IOGate, TestIO.new)
Reline::IOGate.instance_variable_set(:@output, @output)
ensure
$VERBOSE = verbose
diff --git a/test/reline/test_reline.rb b/test/reline/test_reline.rb
index a20a5c9f44..515805467d 100644
--- a/test/reline/test_reline.rb
+++ b/test/reline/test_reline.rb
@@ -303,12 +303,12 @@ class Reline::Test < Reline::TestCase
def test_vi_editing_mode
Reline.vi_editing_mode
- assert_equal(Reline::KeyActor::ViInsert, Reline.core.config.editing_mode.class)
+ 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(Reline::KeyActor::Emacs, Reline.core.config.editing_mode.class)
+ assert_equal(:emacs, Reline.core.config.instance_variable_get(:@editing_mode_label))
end
def test_add_dialog_proc
@@ -375,7 +375,43 @@ class Reline::Test < Reline::TestCase
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_equal("Reline::GeneralIO", out.chomp)
+ 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
@@ -389,7 +425,7 @@ class Reline::Test < Reline::TestCase
require("reline") && p(Reline.core.io_gate)
RUBY
out = IO.popen([{}, Reline.test_rubybin, "-I#{lib}", "-e", code], &:read)
- assert_equal("Reline::ANSI", out.chomp)
+ assert_include(out.chomp, "Reline::ANSI")
end
def win?
diff --git a/test/reline/test_reline_key.rb b/test/reline/test_reline_key.rb
index 7f9a11394a..1e6b9fcb6c 100644
--- a/test/reline/test_reline_key.rb
+++ b/test/reline/test_reline_key.rb
@@ -2,53 +2,10 @@ require_relative 'helper'
require "reline"
class Reline::TestKey < Reline::TestCase
- def setup
- Reline.test_mode
- end
-
- def teardown
- Reline.test_reset
- end
-
- def test_match_key
- assert(Reline::Key.new(1, 2, false).match?(Reline::Key.new(1, 2, false)))
- assert(Reline::Key.new(1, 2, false).match?(Reline::Key.new(nil, 2, false)))
- assert(Reline::Key.new(1, 2, false).match?(Reline::Key.new(1, 2, nil)))
-
- assert(Reline::Key.new(nil, 2, false).match?(Reline::Key.new(nil, 2, false)))
- assert(Reline::Key.new(1, nil, false).match?(Reline::Key.new(1, nil, false)))
- assert(Reline::Key.new(1, 2, nil).match?(Reline::Key.new(1, 2, nil)))
-
- assert(Reline::Key.new(nil, 2, false).match?(Reline::Key.new(nil, 2, false)))
- assert(Reline::Key.new(1, nil, false).match?(Reline::Key.new(1, nil, false)))
- assert(Reline::Key.new(1, 2, nil).match?(Reline::Key.new(1, 2, nil)))
-
- assert(!Reline::Key.new(1, 2, false).match?(Reline::Key.new(3, 1, false)))
- assert(!Reline::Key.new(1, 2, false).match?(Reline::Key.new(1, 3, false)))
- assert(!Reline::Key.new(1, 2, false).match?(Reline::Key.new(1, 3, true)))
- end
-
- def test_match_integer
- assert(Reline::Key.new(1, 2, false).match?(2))
- assert(Reline::Key.new(nil, 2, false).match?(2))
- assert(Reline::Key.new(1, nil, false).match?(1))
-
- assert(!Reline::Key.new(1, 2, false).match?(1))
- assert(!Reline::Key.new(1, nil, false).match?(2))
- assert(!Reline::Key.new(nil, nil, false).match?(1))
- end
-
def test_match_symbol
- assert(Reline::Key.new(:key1, :key2, false).match?(:key2))
- assert(Reline::Key.new(:key1, nil, false).match?(:key1))
-
- assert(!Reline::Key.new(:key1, :key2, false).match?(:key1))
- assert(!Reline::Key.new(:key1, nil, false).match?(:key2))
- assert(!Reline::Key.new(nil, nil, false).match?(:key1))
- end
-
- def test_match_other
- assert(!Reline::Key.new(:key1, 2, false).match?("key1"))
- assert(!Reline::Key.new(nil, nil, false).match?(nil))
+ assert(Reline::Key.new(:key1, :key1, false).match?(:key1))
+ refute(Reline::Key.new(:key1, :key1, false).match?(:key2))
+ refute(Reline::Key.new(:key1, :key1, false).match?(nil))
+ refute(Reline::Key.new(1, 1, false).match?(:key1))
end
end
diff --git a/test/reline/yamatanooroti/test_rendering.rb b/test/reline/yamatanooroti/test_rendering.rb
index 37a1c1a193..c90d3d6a7f 100644
--- a/test/reline/yamatanooroti/test_rendering.rb
+++ b/test/reline/yamatanooroti/test_rendering.rb
@@ -569,6 +569,22 @@ begin
EOC
end
+ def test_bracketed_paste_with_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-_")
+ write("\M-\C-_")
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> abcdef hoge
+ prompt> 3
+ prompt> end
+ EOC
+ 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")
@@ -953,6 +969,18 @@ begin
EOC
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])
+ sleep 1
+ close rescue nil
+ assert_screen(<<~'EOC')
+ > hello
+ "hello"
+ EOC
+ 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(%{> })'}
@@ -1795,6 +1823,58 @@ begin
EOC
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"
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ >x
+ >
+ EOC
+ 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
+ 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
+ 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")
@@ -1812,6 +1892,25 @@ begin
EOC
end
+ def test_stop_continue
+ pidfile = Tempfile.create('pidfile')
+ rubyfile = Tempfile.create('rubyfile')
+ rubyfile.write <<~RUBY
+ File.write(#{pidfile.path.inspect}, Process.pid)
+ p Reline.readmultiline('>'){false}
+ RUBY
+ rubyfile.close
+ start_terminal(40, 50, ['bash'])
+ write "ruby -I#{@pwd}/lib -rreline #{rubyfile.path}\n"
+ write "abc\ndef\nhi"
+ pid = pidfile.tap(&:rewind).read.to_i
+ Process.kill(:STOP, pid) unless pid.zero?
+ write "fg\n"
+ write "\ebg"
+ close
+ assert_include result.join("\n"), ">abc\n>def\n>ghi\n"
+ end
+
def write_inputrc(content)
File.open(@inputrc_file, 'w') do |f|
f.write content