From c754e979d3eeca51f1b13778f19f347df3da656e Mon Sep 17 00:00:00 2001 From: aycabta Date: Tue, 14 May 2019 07:00:03 +0900 Subject: [PATCH] Test ext/readline and lib/reline by test/readline --- test/readline/helper.rb | 16 ++ test/readline/test_readline.rb | 224 ++++++++++++++----------- test/readline/test_readline_history.rb | 183 ++++++++++---------- 3 files changed, 225 insertions(+), 198 deletions(-) create mode 100644 test/readline/helper.rb diff --git a/test/readline/helper.rb b/test/readline/helper.rb new file mode 100644 index 00000000000000..29b44996f1747a --- /dev/null +++ b/test/readline/helper.rb @@ -0,0 +1,16 @@ +begin + require "readline.so" + ReadlineSo = Readline +rescue LoadError +end +require "reline" + +def use_ext_readline # Use ext/readline as Readline + Object.send(:remove_const, :Readline) if Object.const_defined?(:Readline) + Object.const_set(:Readline, ReadlineSo) +end + +def use_lib_reline # Use lib/reline as Readline + Object.send(:remove_const, :Readline) if Object.const_defined?(:Readline) + Object.const_set(:Readline, Reline) +end diff --git a/test/readline/test_readline.rb b/test/readline/test_readline.rb index 8628e9d6701a6f..e8e5a5aec2c4e2 100644 --- a/test/readline/test_readline.rb +++ b/test/readline/test_readline.rb @@ -1,14 +1,10 @@ # frozen_string_literal: false -begin - require "readline" -rescue LoadError -else - require "test/unit" - require "tempfile" - require "timeout" -end +require_relative "helper" +require "test/unit" +require "tempfile" +require "timeout" -class TestReadline < Test::Unit::TestCase +module BasetestReadline INPUTRC = "INPUTRC" SAVED_ENV = %w[COLUMNS LINES] @@ -30,90 +26,91 @@ def teardown SAVED_ENV.each_with_index {|k, i| ENV[k] = @saved_env[i] } end - if !/EditLine/n.match(Readline::VERSION) - def test_readline - with_temp_stdio do |stdin, stdout| - stdin.write("hello\n") - stdin.close - stdout.flush - line = replace_stdio(stdin.path, stdout.path) { - Readline.readline("> ", true) - } - assert_equal("hello", line) - assert_equal(true, line.tainted?) - stdout.rewind - assert_equal("> ", stdout.read(2)) - assert_equal(1, Readline::HISTORY.length) - assert_equal("hello", Readline::HISTORY[0]) - Thread.start { - $SAFE = 1 - assert_raise(SecurityError) do - replace_stdio(stdin.path, stdout.path) do - Readline.readline("> ".taint) - end + def test_readline + skip "Skip Editline" if /EditLine/n.match(Readline::VERSION) + with_temp_stdio do |stdin, stdout| + stdin.write("hello\n") + stdin.close + stdout.flush + line = replace_stdio(stdin.path, stdout.path) { + Readline.readline("> ", true) + } + assert_equal("hello", line) + assert_equal(true, line.tainted?) + stdout.rewind + assert_equal("> ", stdout.read(2)) + assert_equal(1, Readline::HISTORY.length) + assert_equal("hello", Readline::HISTORY[0]) + Thread.start { + $SAFE = 1 + assert_raise(SecurityError) do + replace_stdio(stdin.path, stdout.path) do + Readline.readline("> ".taint) end - }.join - ensure - $SAFE = 0 - end + end + }.join + ensure + $SAFE = 0 end + end - # line_buffer - # point - def test_line_buffer__point - begin - Readline.line_buffer - Readline.point - rescue NotImplementedError - return - end + # line_buffer + # point + def test_line_buffer__point + skip "Skip Editline" if /EditLine/n.match(Readline::VERSION) + skip "GNU Readline has special behaviors" if defined?(Reline) and Readline == Reline + begin + Readline.line_buffer + Readline.point + rescue NotImplementedError + return + end - with_temp_stdio do |stdin, stdout| - actual_text = nil - actual_line_buffer = nil - actual_point = nil - Readline.completion_proc = ->(text) { - actual_text = text - actual_point = Readline.point - actual_line_buffer = Readline.line_buffer - stdin.write(" finish\n") - stdin.flush - stdout.flush - return ["complete"] - } - - stdin.write("first second\t") - stdin.flush - Readline.completion_append_character = " " - replace_stdio(stdin.path, stdout.path) { - Readline.readline("> ", false) - } - assert_equal("second", actual_text) - assert_equal("first second", actual_line_buffer) - assert_equal(12, actual_point) - assert_equal("first complete finish", Readline.line_buffer) - assert_equal(Encoding.find("locale"), Readline.line_buffer.encoding) - assert_equal(true, Readline.line_buffer.tainted?) - assert_equal(22, Readline.point) - - stdin.rewind - stdout.rewind - - stdin.write("first second\t") + with_temp_stdio do |stdin, stdout| + actual_text = nil + actual_line_buffer = nil + actual_point = nil + Readline.completion_proc = ->(text) { + actual_text = text + actual_point = Readline.point + actual_line_buffer = Readline.line_buffer + stdin.write(" finish\n") stdin.flush - Readline.completion_append_character = nil - replace_stdio(stdin.path, stdout.path) { - Readline.readline("> ", false) - } - assert_equal("second", actual_text) - assert_equal("first second", actual_line_buffer) - assert_equal(12, actual_point) - assert_equal("first complete finish", Readline.line_buffer) - assert_equal(Encoding.find("locale"), Readline.line_buffer.encoding) - assert_equal(true, Readline.line_buffer.tainted?) - assert_equal(21, Readline.point) - end - end if !defined?(Reline) or Readline != Reline + stdout.flush + return ["complete"] + } + + stdin.write("first second\t") + stdin.flush + Readline.completion_append_character = " " + replace_stdio(stdin.path, stdout.path) { + Readline.readline("> ", false) + } + assert_equal("second", actual_text) + assert_equal("first second", actual_line_buffer) + assert_equal(12, actual_point) + assert_equal("first complete finish", Readline.line_buffer) + assert_equal(Encoding.find("locale"), Readline.line_buffer.encoding) + assert_equal(true, Readline.line_buffer.tainted?) + assert_equal(22, Readline.point) + + stdin.rewind + stdout.rewind + + stdin.write("first second\t") + stdin.flush + Readline.completion_append_character = nil + replace_stdio(stdin.path, stdout.path) { + Readline.readline("> ", false) + } + assert_equal("second", actual_text) + assert_equal("first second", actual_line_buffer) + assert_equal(12, actual_point) + assert_equal("first complete finish", Readline.line_buffer) + assert_equal(Encoding.find("locale"), Readline.line_buffer.encoding) + assert_equal(true, Readline.line_buffer.tainted?) + assert_equal(21, Readline.point) + end end def test_input= @@ -147,6 +144,7 @@ def test_completion_case_fold end def test_completion_proc_empty_result + skip "Skip Editline" if /EditLine/n.match(Readline::VERSION) with_temp_stdio do |stdin, stdout| stdin.write("first\t") stdin.flush @@ -165,7 +163,7 @@ def test_completion_proc_empty_result rescue NotimplementedError end end - end if !/EditLine/n.match(Readline::VERSION) + end def test_get_screen_size begin @@ -225,6 +223,7 @@ def test_completion_append_character end def test_completion_encoding + skip "Skip Editline" if /EditLine/n.match(Readline::VERSION) bug5941 = '[Bug #5941]' append_character = Readline.completion_append_character Readline.completion_append_character = "" @@ -264,9 +263,10 @@ def test_completion_encoding with_pipe {|r, w| w << "\t"} end ensure + return if /EditLine/n.match(Readline::VERSION) Readline.completion_case_fold = completion_case_fold Readline.completion_append_character = append_character - end if !/EditLine/n.match(Readline::VERSION) + end # basic_word_break_characters # completer_word_break_characters @@ -325,6 +325,7 @@ def test_pre_input_hook end def test_point + skip "Skip Editline" if /EditLine/n.match(Readline::VERSION) assert_equal(0, Readline.point) Readline.insert_text('12345') assert_equal(5, Readline.point) @@ -336,9 +337,10 @@ def test_point assert_equal('1234abc5', Readline.line_buffer) rescue NotImplementedError - end if !/EditLine/n.match(Readline::VERSION) + end def test_insert_text + skip "Skip Editline" if /EditLine/n.match(Readline::VERSION) str = "test_insert_text" assert_equal(0, Readline.point) assert_equal(Readline, Readline.insert_text(str)) @@ -366,9 +368,10 @@ def test_insert_text Readline.delete_text assert_equal("", Readline.line_buffer) rescue NotImplementedError - end if !/EditLine/n.match(Readline::VERSION) + end def test_delete_text + skip "Skip Editline" if /EditLine/n.match(Readline::VERSION) str = "test_insert_text" assert_equal(0, Readline.point) assert_equal(Readline, Readline.insert_text(str)) @@ -385,9 +388,10 @@ def test_delete_text assert_equal("", Readline.line_buffer) end rescue NotImplementedError - end if !/EditLine/n.match(Readline::VERSION) + end def test_modify_text_in_pre_input_hook + skip "Skip Editline" if /EditLine/n.match(Readline::VERSION) with_temp_stdio {|stdin, stdout| begin stdin.write("world\n") @@ -413,9 +417,10 @@ def test_modify_text_in_pre_input_hook end end } - end if !/EditLine|\A4\.3\z/n.match(Readline::VERSION) + end def test_input_metachar + skip "Skip Editline" if /EditLine/n.match(Readline::VERSION) skip("Won't pass on mingw w/readline 7.0.005 [ruby-core:45682]") if mingw? bug6601 = '[ruby-core:45682]' Readline::HISTORY << "hello" @@ -427,11 +432,13 @@ def test_input_metachar assert_equal("hello", line, bug6601) ensure wo&.close + return if /EditLine/n.match(Readline::VERSION) Readline.delete_text Readline::HISTORY.clear - end if !/EditLine/n.match(Readline::VERSION) + end def test_input_metachar_multibyte + skip "Skip Editline" if /EditLine/n.match(Readline::VERSION) unless Encoding.find("locale") == Encoding::UTF_8 return if assert_under_utf8 skip 'this test needs UTF-8 locale' @@ -455,11 +462,13 @@ def test_input_metachar_multibyte end end ensure + return if /EditLine/n.match(Readline::VERSION) Readline.delete_text Readline::HISTORY.clear - end if !/EditLine/n.match(Readline::VERSION) + end def test_refresh_line + skip "Only when refresh_line exists" unless Readline.respond_to?(:refresh_line) bug6232 = '[ruby-core:43957] [Bug #6232] refresh_line after set_screen_size' with_temp_stdio do |stdin, stdout| replace_stdio(stdin.path, stdout.path) do @@ -469,7 +478,7 @@ def test_refresh_line end; end end - end if Readline.respond_to?(:refresh_line) + end def test_setting_quoting_detection_proc return unless Readline.respond_to?(:quoting_detection_proc=) @@ -692,5 +701,22 @@ def assert_under_utf8 SRC return true end -end if defined?(::Readline) && !(/mswin|mingw/ =~ RUBY_PLATFORM && defined?(Reline) && Readline == Reline) -# skip on Windows now when using reline because it causes hang of whole tests +end + +class TestReadline < Test::Unit::TestCase + include BasetestReadline + + def setup + use_ext_readline + super + end +end if defined?(ReadlineSo) + +class TestRelineAsReadline < Test::Unit::TestCase + include BasetestReadline + + def setup + use_lib_reline + super + end +end diff --git a/test/readline/test_readline_history.rb b/test/readline/test_readline_history.rb index a9a324fb9e7871..30c0c7f6bcf4a6 100644 --- a/test/readline/test_readline_history.rb +++ b/test/readline/test_readline_history.rb @@ -1,61 +1,28 @@ # frozen_string_literal: false -begin - require "readline" -=begin - class << Readline::HISTORY - def []=(index, str) - raise NotImplementedError - end - - def pop - raise NotImplementedError - end - - def shift - raise NotImplementedError - end - - def delete_at(index) - raise NotImplementedError - end - end -=end - -=begin - class << Readline::HISTORY - def clear - raise NotImplementedError - end - end -=end -rescue LoadError -else - require "test/unit" -end - -class Readline::TestHistory < Test::Unit::TestCase - include Readline +require_relative "helper" +require "test/unit" +module Readline::BasetestHistory def setup - HISTORY.clear + Readline::HISTORY.clear end def test_to_s expected = "HISTORY" - assert_equal(expected, HISTORY.to_s) + assert_equal(expected, Readline::HISTORY.to_s) end def test_get lines = push_history(5) lines.each_with_index do |s, i| - assert_external_string_equal(s, HISTORY[i]) + assert_external_string_equal(s, Readline::HISTORY[i]) end end def test_get__negative lines = push_history(5) (1..5).each do |i| - assert_equal(lines[-i], HISTORY[-i]) + assert_equal(lines[-i], Readline::HISTORY[-i]) end end @@ -64,7 +31,7 @@ def test_get__out_of_range invalid_indexes = [5, 6, 100, -6, -7, -100] invalid_indexes.each do |i| assert_raise(IndexError, "i=<#{i}>") do - HISTORY[i] + Readline::HISTORY[i] end end @@ -72,7 +39,7 @@ def test_get__out_of_range -100_000_000_000_000_000_000] invalid_indexes.each do |i| assert_raise(RangeError, "i=<#{i}>") do - HISTORY[i] + Readline::HISTORY[i] end end end @@ -82,8 +49,8 @@ def test_set push_history(5) 5.times do |i| expected = "set: #{i}" - HISTORY[i] = expected - assert_external_string_equal(expected, HISTORY[i]) + Readline::HISTORY[i] = expected + assert_external_string_equal(expected, Readline::HISTORY[i]) end rescue NotImplementedError end @@ -91,14 +58,14 @@ def test_set def test_set__out_of_range assert_raise(IndexError, NotImplementedError, "index=<0>") do - HISTORY[0] = "set: 0" + Readline::HISTORY[0] = "set: 0" end push_history(5) invalid_indexes = [5, 6, 100, -6, -7, -100] invalid_indexes.each do |i| assert_raise(IndexError, NotImplementedError, "index=<#{i}>") do - HISTORY[i] = "set: #{i}" + Readline::HISTORY[i] = "set: #{i}" end end @@ -106,7 +73,7 @@ def test_set__out_of_range -100_000_000_000_000_000_000] invalid_indexes.each do |i| assert_raise(RangeError, NotImplementedError, "index=<#{i}>") do - HISTORY[i] = "set: #{i}" + Readline::HISTORY[i] = "set: #{i}" end end end @@ -114,102 +81,102 @@ def test_set__out_of_range def test_push 5.times do |i| s = i.to_s - assert_equal(HISTORY, HISTORY.push(s)) - assert_external_string_equal(s, HISTORY[i]) + assert_equal(Readline::HISTORY, Readline::HISTORY.push(s)) + assert_external_string_equal(s, Readline::HISTORY[i]) end - assert_equal(5, HISTORY.length) + assert_equal(5, Readline::HISTORY.length) end def test_push__operator 5.times do |i| s = i.to_s - assert_equal(HISTORY, HISTORY << s) - assert_external_string_equal(s, HISTORY[i]) + assert_equal(Readline::HISTORY, Readline::HISTORY << s) + assert_external_string_equal(s, Readline::HISTORY[i]) end - assert_equal(5, HISTORY.length) + assert_equal(5, Readline::HISTORY.length) end def test_push__plural - assert_equal(HISTORY, HISTORY.push("0", "1", "2", "3", "4")) + assert_equal(Readline::HISTORY, Readline::HISTORY.push("0", "1", "2", "3", "4")) (0..4).each do |i| - assert_external_string_equal(i.to_s, HISTORY[i]) + assert_external_string_equal(i.to_s, Readline::HISTORY[i]) end - assert_equal(5, HISTORY.length) + assert_equal(5, Readline::HISTORY.length) - assert_equal(HISTORY, HISTORY.push("5", "6", "7", "8", "9")) + assert_equal(Readline::HISTORY, Readline::HISTORY.push("5", "6", "7", "8", "9")) (5..9).each do |i| - assert_external_string_equal(i.to_s, HISTORY[i]) + assert_external_string_equal(i.to_s, Readline::HISTORY[i]) end - assert_equal(10, HISTORY.length) + assert_equal(10, Readline::HISTORY.length) end def test_pop begin - assert_equal(nil, HISTORY.pop) + assert_equal(nil, Readline::HISTORY.pop) lines = push_history(5) (1..5).each do |i| - assert_external_string_equal(lines[-i], HISTORY.pop) - assert_equal(lines.length - i, HISTORY.length) + assert_external_string_equal(lines[-i], Readline::HISTORY.pop) + assert_equal(lines.length - i, Readline::HISTORY.length) end - assert_equal(nil, HISTORY.pop) + assert_equal(nil, Readline::HISTORY.pop) rescue NotImplementedError end end def test_shift begin - assert_equal(nil, HISTORY.shift) + assert_equal(nil, Readline::HISTORY.shift) lines = push_history(5) (0..4).each do |i| - assert_external_string_equal(lines[i], HISTORY.shift) - assert_equal(lines.length - (i + 1), HISTORY.length) + assert_external_string_equal(lines[i], Readline::HISTORY.shift) + assert_equal(lines.length - (i + 1), Readline::HISTORY.length) end - assert_equal(nil, HISTORY.shift) + assert_equal(nil, Readline::HISTORY.shift) rescue NotImplementedError end end def test_each - e = HISTORY.each do |s| + e = Readline::HISTORY.each do |s| assert(false) # not reachable end - assert_equal(HISTORY, e) + assert_equal(Readline::HISTORY, e) lines = push_history(5) i = 0 - e = HISTORY.each do |s| - assert_external_string_equal(HISTORY[i], s) + e = Readline::HISTORY.each do |s| + assert_external_string_equal(Readline::HISTORY[i], s) assert_external_string_equal(lines[i], s) i += 1 end - assert_equal(HISTORY, e) + assert_equal(Readline::HISTORY, e) end def test_each__enumerator - e = HISTORY.each + e = Readline::HISTORY.each assert_instance_of(Enumerator, e) end def test_length - assert_equal(0, HISTORY.length) + assert_equal(0, Readline::HISTORY.length) push_history(1) - assert_equal(1, HISTORY.length) + assert_equal(1, Readline::HISTORY.length) push_history(4) - assert_equal(5, HISTORY.length) - HISTORY.clear - assert_equal(0, HISTORY.length) + assert_equal(5, Readline::HISTORY.length) + Readline::HISTORY.clear + assert_equal(0, Readline::HISTORY.length) end def test_empty_p 2.times do - assert(HISTORY.empty?) - HISTORY.push("s") - assert_equal(false, HISTORY.empty?) - HISTORY.clear - assert(HISTORY.empty?) + assert(Readline::HISTORY.empty?) + Readline::HISTORY.push("s") + assert_equal(false, Readline::HISTORY.empty?) + Readline::HISTORY.clear + assert(Readline::HISTORY.empty?) end end @@ -217,37 +184,37 @@ def test_delete_at begin lines = push_history(5) (0..4).each do |i| - assert_external_string_equal(lines[i], HISTORY.delete_at(0)) + assert_external_string_equal(lines[i], Readline::HISTORY.delete_at(0)) end - assert(HISTORY.empty?) + assert(Readline::HISTORY.empty?) lines = push_history(5) (1..5).each do |i| - assert_external_string_equal(lines[lines.length - i], HISTORY.delete_at(-1)) + assert_external_string_equal(lines[lines.length - i], Readline::HISTORY.delete_at(-1)) end - assert(HISTORY.empty?) + assert(Readline::HISTORY.empty?) lines = push_history(5) - assert_external_string_equal(lines[0], HISTORY.delete_at(0)) - assert_external_string_equal(lines[4], HISTORY.delete_at(3)) - assert_external_string_equal(lines[1], HISTORY.delete_at(0)) - assert_external_string_equal(lines[3], HISTORY.delete_at(1)) - assert_external_string_equal(lines[2], HISTORY.delete_at(0)) - assert(HISTORY.empty?) + assert_external_string_equal(lines[0], Readline::HISTORY.delete_at(0)) + assert_external_string_equal(lines[4], Readline::HISTORY.delete_at(3)) + assert_external_string_equal(lines[1], Readline::HISTORY.delete_at(0)) + assert_external_string_equal(lines[3], Readline::HISTORY.delete_at(1)) + assert_external_string_equal(lines[2], Readline::HISTORY.delete_at(0)) + assert(Readline::HISTORY.empty?) rescue NotImplementedError end end def test_delete_at__out_of_range assert_raise(IndexError, NotImplementedError, "index=<0>") do - HISTORY.delete_at(0) + Readline::HISTORY.delete_at(0) end push_history(5) invalid_indexes = [5, 6, 100, -6, -7, -100] invalid_indexes.each do |i| assert_raise(IndexError, NotImplementedError, "index=<#{i}>") do - HISTORY.delete_at(i) + Readline::HISTORY.delete_at(i) end end @@ -255,7 +222,7 @@ def test_delete_at__out_of_range -100_000_000_000_000_000_000] invalid_indexes.each do |i| assert_raise(RangeError, NotImplementedError, "index=<#{i}>") do - HISTORY.delete_at(i) + Readline::HISTORY.delete_at(i) end end end @@ -271,7 +238,7 @@ def push_history(num) end lines.push("#{i + 1}:#{s}") end - HISTORY.push(*lines) + Readline::HISTORY.push(*lines) return lines end @@ -283,11 +250,29 @@ def assert_external_string_equal(expected, actual) def get_default_internal_encoding return Encoding.default_internal || Encoding.find("locale") end -end if defined?(::Readline) && defined?(::Readline::HISTORY) && +end + +class Readline::TestHistory < Test::Unit::TestCase + include Readline::BasetestHistory + + def setup + use_ext_readline + super + end +end if defined?(::ReadlineSo) && defined?(::ReadlineSo::HISTORY) && ( begin - Readline::HISTORY.clear + ReadlineSo::HISTORY.clear rescue NotImplementedError false end ) + +class Reline::TestHistory < Test::Unit::TestCase + include Readline::BasetestHistory + + def setup + use_lib_reline + super + end +end