2019-04-27 08:53:09 +03:00
|
|
|
require_relative 'helper'
|
|
|
|
|
|
|
|
class Reline::Config::Test < Reline::TestCase
|
|
|
|
def setup
|
|
|
|
@pwd = Dir.pwd
|
|
|
|
@tmpdir = File.join(Dir.tmpdir, "test_reline_config_#{$$}")
|
|
|
|
begin
|
|
|
|
Dir.mkdir(@tmpdir)
|
|
|
|
rescue Errno::EEXIST
|
|
|
|
FileUtils.rm_rf(@tmpdir)
|
|
|
|
Dir.mkdir(@tmpdir)
|
|
|
|
end
|
|
|
|
Dir.chdir(@tmpdir)
|
|
|
|
@config = Reline::Config.new
|
|
|
|
end
|
|
|
|
|
|
|
|
def teardown
|
|
|
|
Dir.chdir(@pwd)
|
|
|
|
FileUtils.rm_rf(@tmpdir)
|
2019-06-01 10:47:59 +03:00
|
|
|
@config.reset
|
2019-04-27 08:53:09 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_read_lines
|
2019-06-03 04:32:32 +03:00
|
|
|
@config.read_lines(<<~LINES.lines)
|
2019-04-27 08:53:09 +03:00
|
|
|
set bell-style on
|
|
|
|
LINES
|
|
|
|
|
|
|
|
assert_equal :audible, @config.instance_variable_get(:@bell_style)
|
|
|
|
end
|
|
|
|
|
2019-12-04 16:26:40 +03:00
|
|
|
def test_read_lines_with_variable
|
|
|
|
@config.read_lines(<<~LINES.lines)
|
|
|
|
set disable-completion on
|
|
|
|
LINES
|
|
|
|
|
|
|
|
assert_equal true, @config.instance_variable_get(:@disable_completion)
|
|
|
|
end
|
|
|
|
|
2020-07-20 14:52:07 +03:00
|
|
|
def test_string_value
|
|
|
|
@config.read_lines(<<~LINES.lines)
|
|
|
|
set show-mode-in-prompt on
|
|
|
|
set emacs-mode-string Emacs
|
|
|
|
LINES
|
|
|
|
|
|
|
|
assert_equal 'Emacs', @config.instance_variable_get(:@emacs_mode_string)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_string_value_with_brackets
|
|
|
|
@config.read_lines(<<~LINES.lines)
|
|
|
|
set show-mode-in-prompt on
|
|
|
|
set emacs-mode-string [Emacs]
|
|
|
|
LINES
|
|
|
|
|
|
|
|
assert_equal '[Emacs]', @config.instance_variable_get(:@emacs_mode_string)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_string_value_with_brackets_and_quotes
|
|
|
|
@config.read_lines(<<~LINES.lines)
|
|
|
|
set show-mode-in-prompt on
|
|
|
|
set emacs-mode-string "[Emacs]"
|
|
|
|
LINES
|
|
|
|
|
|
|
|
assert_equal '[Emacs]', @config.instance_variable_get(:@emacs_mode_string)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_string_value_with_parens
|
|
|
|
@config.read_lines(<<~LINES.lines)
|
|
|
|
set show-mode-in-prompt on
|
|
|
|
set emacs-mode-string (Emacs)
|
|
|
|
LINES
|
|
|
|
|
|
|
|
assert_equal '(Emacs)', @config.instance_variable_get(:@emacs_mode_string)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_string_value_with_parens_and_quotes
|
|
|
|
@config.read_lines(<<~LINES.lines)
|
|
|
|
set show-mode-in-prompt on
|
|
|
|
set emacs-mode-string "(Emacs)"
|
|
|
|
LINES
|
|
|
|
|
|
|
|
assert_equal '(Emacs)', @config.instance_variable_get(:@emacs_mode_string)
|
|
|
|
end
|
|
|
|
|
2019-07-04 12:46:34 +03:00
|
|
|
def test_comment_line
|
|
|
|
@config.read_lines([" #a: error\n"])
|
|
|
|
assert_not_include @config.key_bindings, nil
|
|
|
|
end
|
|
|
|
|
2019-07-04 12:54:50 +03:00
|
|
|
def test_invalid_keystroke
|
|
|
|
@config.read_lines(["a: error\n"])
|
|
|
|
assert_not_include @config.key_bindings, nil
|
|
|
|
end
|
|
|
|
|
2019-04-27 08:53:09 +03:00
|
|
|
def test_bind_key
|
2019-06-01 03:05:58 +03:00
|
|
|
assert_equal ['input'.bytes, 'abcde'.bytes], @config.bind_key('"input"', '"abcde"')
|
2019-04-27 08:53:09 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_bind_key_with_macro
|
|
|
|
|
2019-06-01 03:05:58 +03:00
|
|
|
assert_equal ['input'.bytes, :abcde], @config.bind_key('"input"', 'abcde')
|
2019-04-27 08:53:09 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_bind_key_with_escaped_chars
|
2019-06-01 03:05:58 +03:00
|
|
|
assert_equal ['input'.bytes, "\e \\ \" ' \a \b \d \f \n \r \t \v".bytes], @config.bind_key('"input"', '"\\e \\\\ \\" \\\' \\a \\b \\d \\f \\n \\r \\t \\v"')
|
2019-04-27 08:53:09 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_bind_key_with_ctrl_chars
|
2019-06-01 03:05:58 +03:00
|
|
|
assert_equal ['input'.bytes, "\C-h\C-h".bytes], @config.bind_key('"input"', '"\C-h\C-H"')
|
2019-07-04 14:58:11 +03:00
|
|
|
assert_equal ['input'.bytes, "\C-h\C-h".bytes], @config.bind_key('"input"', '"\Control-h\Control-H"')
|
2019-04-27 08:53:09 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_bind_key_with_meta_chars
|
2019-06-01 03:05:58 +03:00
|
|
|
assert_equal ['input'.bytes, "\M-h\M-H".bytes], @config.bind_key('"input"', '"\M-h\M-H"')
|
2019-07-04 14:58:11 +03:00
|
|
|
assert_equal ['input'.bytes, "\M-h\M-H".bytes], @config.bind_key('"input"', '"\Meta-h\Meta-H"')
|
2019-04-27 08:53:09 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_bind_key_with_octal_number
|
2019-06-01 03:05:58 +03:00
|
|
|
input = %w{i n p u t}.map(&:ord)
|
|
|
|
assert_equal [input, "\1".bytes], @config.bind_key('"input"', '"\1"')
|
|
|
|
assert_equal [input, "\12".bytes], @config.bind_key('"input"', '"\12"')
|
|
|
|
assert_equal [input, "\123".bytes], @config.bind_key('"input"', '"\123"')
|
|
|
|
assert_equal [input, "\123".bytes + '4'.bytes], @config.bind_key('"input"', '"\1234"')
|
2019-04-27 08:53:09 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_bind_key_with_hexadecimal_number
|
2019-06-01 03:05:58 +03:00
|
|
|
input = %w{i n p u t}.map(&:ord)
|
|
|
|
assert_equal [input, "\x4".bytes], @config.bind_key('"input"', '"\x4"')
|
|
|
|
assert_equal [input, "\x45".bytes], @config.bind_key('"input"', '"\x45"')
|
|
|
|
assert_equal [input, "\x45".bytes + '6'.bytes], @config.bind_key('"input"', '"\x456"')
|
2019-04-27 08:53:09 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_include
|
|
|
|
File.open('included_partial', 'wt') do |f|
|
|
|
|
f.write(<<~PARTIAL_LINES)
|
|
|
|
set bell-style on
|
|
|
|
PARTIAL_LINES
|
|
|
|
end
|
2019-06-03 04:32:32 +03:00
|
|
|
@config.read_lines(<<~LINES.lines)
|
2019-04-27 08:53:09 +03:00
|
|
|
$include included_partial
|
|
|
|
LINES
|
|
|
|
|
|
|
|
assert_equal :audible, @config.instance_variable_get(:@bell_style)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_if
|
2019-06-03 04:32:32 +03:00
|
|
|
@config.read_lines(<<~LINES.lines)
|
2019-04-27 08:53:09 +03:00
|
|
|
$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
|
2019-06-03 04:32:32 +03:00
|
|
|
@config.read_lines(<<~LINES.lines)
|
2019-04-27 08:53:09 +03:00
|
|
|
$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
|
2019-06-02 06:21:09 +03:00
|
|
|
%w[Ruby Reline].each do |cond|
|
2019-06-03 04:32:32 +03:00
|
|
|
@config.read_lines(<<~LINES.lines)
|
2019-06-02 06:21:09 +03:00
|
|
|
set bell-style none
|
|
|
|
$if #{cond}
|
|
|
|
set bell-style audible
|
|
|
|
$else
|
|
|
|
set bell-style visible
|
|
|
|
$endif
|
|
|
|
LINES
|
|
|
|
|
|
|
|
assert_equal :audible, @config.instance_variable_get(:@bell_style)
|
|
|
|
end
|
2019-04-27 08:53:09 +03:00
|
|
|
end
|
2019-06-01 03:05:58 +03:00
|
|
|
|
2019-06-02 06:14:29 +03:00
|
|
|
def test_unclosed_if
|
|
|
|
e = assert_raise(Reline::Config::InvalidInputrc) do
|
2019-06-03 04:32:32 +03:00
|
|
|
@config.read_lines(<<~LINES.lines, "INPUTRC")
|
2019-06-02 06:14:29 +03:00
|
|
|
$if Ruby
|
|
|
|
LINES
|
|
|
|
end
|
|
|
|
assert_equal "INPUTRC:1: unclosed if", e.message
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_unmatched_else
|
|
|
|
e = assert_raise(Reline::Config::InvalidInputrc) do
|
2019-06-03 04:32:32 +03:00
|
|
|
@config.read_lines(<<~LINES.lines, "INPUTRC")
|
2019-06-02 06:14:29 +03:00
|
|
|
$else
|
|
|
|
LINES
|
|
|
|
end
|
|
|
|
assert_equal "INPUTRC:1: unmatched else", e.message
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_unmatched_endif
|
|
|
|
e = assert_raise(Reline::Config::InvalidInputrc) do
|
2019-06-03 04:32:32 +03:00
|
|
|
@config.read_lines(<<~LINES.lines, "INPUTRC")
|
2019-06-02 06:14:29 +03:00
|
|
|
$endif
|
|
|
|
LINES
|
|
|
|
end
|
|
|
|
assert_equal "INPUTRC:1: unmatched endif", e.message
|
|
|
|
end
|
|
|
|
|
2019-06-01 03:05:58 +03:00
|
|
|
def test_default_key_bindings
|
|
|
|
@config.add_default_key_binding('abcd'.bytes, 'EFGH'.bytes)
|
2019-06-03 04:32:32 +03:00
|
|
|
@config.read_lines(<<~'LINES'.lines)
|
2019-06-01 03:05:58 +03:00
|
|
|
"abcd": "ABCD"
|
|
|
|
"ijkl": "IJKL"
|
|
|
|
LINES
|
|
|
|
|
|
|
|
expected = { 'abcd'.bytes => 'ABCD'.bytes, 'ijkl'.bytes => 'IJKL'.bytes }
|
|
|
|
assert_equal expected, @config.key_bindings
|
|
|
|
end
|
2019-07-04 13:29:07 +03:00
|
|
|
|
|
|
|
def test_additional_key_bindings
|
|
|
|
@config.read_lines(<<~'LINES'.lines)
|
|
|
|
"ef": "EF"
|
|
|
|
"gh": "GH"
|
|
|
|
LINES
|
|
|
|
|
|
|
|
expected = { 'ef'.bytes => 'EF'.bytes, 'gh'.bytes => 'GH'.bytes }
|
|
|
|
assert_equal expected, @config.key_bindings
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_additional_key_bindings_with_nesting_and_comment_out
|
|
|
|
@config.read_lines(<<~'LINES'.lines)
|
|
|
|
#"ab": "AB"
|
|
|
|
#"cd": "cd"
|
|
|
|
"ef": "EF"
|
|
|
|
"gh": "GH"
|
|
|
|
LINES
|
|
|
|
|
|
|
|
expected = { 'ef'.bytes => 'EF'.bytes, 'gh'.bytes => 'GH'.bytes }
|
|
|
|
assert_equal expected, @config.key_bindings
|
|
|
|
end
|
2020-01-06 15:50:48 +03:00
|
|
|
|
|
|
|
def test_history_size
|
|
|
|
@config.read_lines(<<~LINES.lines)
|
|
|
|
set history-size 5000
|
|
|
|
LINES
|
|
|
|
|
|
|
|
assert_equal 5000, @config.instance_variable_get(:@history_size)
|
|
|
|
history = Reline::History.new(@config)
|
|
|
|
history << "a\n"
|
|
|
|
assert_equal 1, history.size
|
|
|
|
end
|
2020-03-21 12:13:50 +03:00
|
|
|
|
|
|
|
def test_empty_inputrc_env
|
|
|
|
inputrc_backup = ENV['INPUTRC']
|
|
|
|
ENV['INPUTRC'] = ''
|
|
|
|
assert_nothing_raised do
|
|
|
|
@config.read
|
|
|
|
end
|
2020-04-24 11:54:54 +03:00
|
|
|
ensure
|
2020-03-21 12:13:50 +03:00
|
|
|
ENV['INPUTRC'] = inputrc_backup
|
|
|
|
end
|
2020-04-21 12:17:27 +03:00
|
|
|
|
|
|
|
def test_inputrc
|
|
|
|
inputrc_backup = ENV['INPUTRC']
|
|
|
|
expected = "#{@tmpdir}/abcde"
|
|
|
|
ENV['INPUTRC'] = expected
|
|
|
|
assert_equal expected, @config.inputrc_path
|
2020-04-24 11:54:54 +03:00
|
|
|
ensure
|
2020-04-21 12:17:27 +03:00
|
|
|
ENV['INPUTRC'] = inputrc_backup
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_xdg_config_home
|
|
|
|
home_backup = ENV['HOME']
|
|
|
|
xdg_config_home_backup = ENV['XDG_CONFIG_HOME']
|
|
|
|
xdg_config_home = File.expand_path("#{@tmpdir}/.config/example_dir")
|
|
|
|
expected = File.expand_path("#{xdg_config_home}/readline/inputrc")
|
|
|
|
FileUtils.mkdir_p(File.dirname(expected))
|
|
|
|
FileUtils.touch(expected)
|
2020-04-23 21:10:41 +03:00
|
|
|
ENV['HOME'] = @tmpdir
|
2020-04-21 12:17:27 +03:00
|
|
|
ENV['XDG_CONFIG_HOME'] = xdg_config_home
|
|
|
|
assert_equal expected, @config.inputrc_path
|
2020-04-24 11:54:54 +03:00
|
|
|
ensure
|
2020-04-21 12:17:27 +03:00
|
|
|
FileUtils.rm(expected)
|
|
|
|
ENV['XDG_CONFIG_HOME'] = xdg_config_home_backup
|
|
|
|
ENV['HOME'] = home_backup
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_empty_xdg_config_home
|
|
|
|
home_backup = ENV['HOME']
|
|
|
|
xdg_config_home_backup = ENV['XDG_CONFIG_HOME']
|
|
|
|
ENV['HOME'] = @tmpdir
|
|
|
|
ENV['XDG_CONFIG_HOME'] = ''
|
|
|
|
expected = File.expand_path('~/.config/readline/inputrc')
|
|
|
|
FileUtils.mkdir_p(File.dirname(expected))
|
|
|
|
FileUtils.touch(expected)
|
|
|
|
assert_equal expected, @config.inputrc_path
|
2020-04-24 11:54:54 +03:00
|
|
|
ensure
|
|
|
|
FileUtils.rm(expected)
|
|
|
|
ENV['XDG_CONFIG_HOME'] = xdg_config_home_backup
|
|
|
|
ENV['HOME'] = home_backup
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_relative_xdg_config_home
|
|
|
|
home_backup = ENV['HOME']
|
|
|
|
xdg_config_home_backup = ENV['XDG_CONFIG_HOME']
|
|
|
|
ENV['HOME'] = @tmpdir
|
|
|
|
expected = File.expand_path('~/.config/readline/inputrc')
|
|
|
|
FileUtils.mkdir_p(File.dirname(expected))
|
|
|
|
FileUtils.touch(expected)
|
|
|
|
result = Dir.chdir(@tmpdir) do
|
|
|
|
xdg_config_home = ".config/example_dir"
|
|
|
|
ENV['XDG_CONFIG_HOME'] = xdg_config_home
|
|
|
|
inputrc = "#{xdg_config_home}/readline/inputrc"
|
|
|
|
FileUtils.mkdir_p(File.dirname(inputrc))
|
|
|
|
FileUtils.touch(inputrc)
|
|
|
|
@config.inputrc_path
|
|
|
|
end
|
|
|
|
assert_equal expected, result
|
2020-04-21 12:17:27 +03:00
|
|
|
FileUtils.rm(expected)
|
|
|
|
ENV['XDG_CONFIG_HOME'] = xdg_config_home_backup
|
|
|
|
ENV['HOME'] = home_backup
|
|
|
|
end
|
2019-04-27 08:53:09 +03:00
|
|
|
end
|