1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/test/reline/helper.rb
Yusuke Endoh 424800f707 [ruby/reline] Fix test input_keys to handle "hankaku" characters correctly on Windows
The method "input_keys" in test/reline/helper.rb handles a single-byte
and 8-bit charater as an input with the meta key.
However, "test_halfwidth_kana_width_dakuten" in test/reline/test_key_actor_emacs.rb
uses a string that contains "hankaku" characters.
A "hankaku" character is not with the meta key, but it is a single-byte
and 8-bit character on Windows-31J encoding, which confused "input_keys"
method. This caused the following error.

https://ci.appveyor.com/project/ruby/ruby/builds/41997092/job/ejm77qxgvnlpdwvg
```
  1) Failure:
Reline::KeyActor::Emacs::Test#test_halfwidth_kana_width_dakuten [C:/projects/ruby/test/reline/test_key_actor_emacs.rb:2311]:
<"\xB6\xDE\xB7\xDE\xB9\xDE\xBA\xDE" (#<Encoding:Windows-31J>)> expected but was
<"\e^\e^\e^\e:\e^" (#<Encoding:Windows-31J>)> in <Terminal #<Encoding:Windows-31J>>
.
<8> expected but was
<10>.
Finished tests in 1045.472722s, 19.3922 tests/s, 2609.4320 assertions/s.
```

This change introduces "input_raw_keys" that does not convert a
single-byte and 8-bit character to "with the meta key", and use it in
the test in question.

https://github.com/ruby/reline/commit/f6ae0e5d19
2021-12-24 15:01:17 +09:00

125 lines
3.4 KiB
Ruby

$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
ENV['TERM'] = 'xterm' # for some CI environments
require 'reline'
require 'test/unit'
module Reline
class <<self
def test_mode
remove_const('IOGate') if const_defined?('IOGate')
const_set('IOGate', Reline::GeneralIO)
if ENV['RELINE_TEST_ENCODING']
encoding = Encoding.find(ENV['RELINE_TEST_ENCODING'])
else
encoding = Encoding::UTF_8
end
Reline::GeneralIO.reset(encoding: encoding)
send(:core).config.instance_variable_set(:@test_mode, true)
send(:core).config.reset
end
def test_reset
Reline.instance_variable_set(:@core, nil)
end
end
end
def start_pasting
Reline::GeneralIO.start_pasting
end
def finish_pasting
Reline::GeneralIO.finish_pasting
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_key_by_symbol(input)
@line_editor.input_key(Reline::Key.new(input, input, false))
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(Reline::Key.new(byte ^ eighth_bit, byte, true))
else
@line_editor.input_key(Reline::Key.new(byte, byte, false))
end
else
c.bytes.each do |b|
@line_editor.input_key(Reline::Key.new(b, b, false))
end
end
end
end
def input_raw_keys(input, convert = true)
input = convert_str(input) if convert
input.bytes.each do |b|
@line_editor.input_key(Reline::Key.new(b, b, false))
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)
chunk = @line_editor.line.byteslice(0, byte_pointer)
assert_equal(
expected.bytesize, byte_pointer,
<<~EOM)
<#{expected.inspect} (#{expected.encoding.inspect})> expected but was
<#{chunk.inspect} (#{chunk.encoding.inspect})> in <Terminal #{Reline::GeneralIO.encoding.inspect}>
EOM
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
def assert_line_index(expected)
assert_equal(expected, @line_editor.instance_variable_get(:@line_index))
end
def assert_whole_lines(expected)
previous_line_index = @line_editor.instance_variable_get(:@previous_line_index)
if previous_line_index
lines = @line_editor.whole_lines(index: previous_line_index)
else
lines = @line_editor.whole_lines
end
assert_equal(expected, lines)
end
end