diff --git a/lib/reline/general_io.rb b/lib/reline/general_io.rb index eaae63f925..b830eb39a0 100644 --- a/lib/reline/general_io.rb +++ b/lib/reline/general_io.rb @@ -57,7 +57,7 @@ def self.ungetc(c) end def self.get_screen_size - [1, 1] + [24, 80] end def self.cursor_pos diff --git a/test/reline/helper.rb b/test/reline/helper.rb index fb2262e7f5..2180fdf596 100644 --- a/test/reline/helper.rb +++ b/test/reline/helper.rb @@ -29,12 +29,19 @@ def test_mode(ansi: false) 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] + end Reline::GeneralIO.reset(encoding: encoding) unless ansi 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 @@ -147,11 +154,22 @@ def assert_byte_pointer_size(expected) end def assert_cursor(expected) - assert_equal(expected, @line_editor.instance_variable_get(:@cursor)) + # This test satisfies nothing because there is no `@cursor` anymore + # Test editor_cursor_position instead + cursor_x = @line_editor.instance_eval do + line_before_cursor = whole_lines[@line_index].byteslice(0, @byte_pointer) + Reline::Unicode.calculate_width(line_before_cursor) + end + assert_equal(expected, cursor_x) end def assert_cursor_max(expected) - assert_equal(expected, @line_editor.instance_variable_get(:@cursor_max)) + # This test satisfies nothing because there is no `@cursor_max` anymore + cursor_max = @line_editor.instance_eval do + line = whole_lines[@line_index] + Reline::Unicode.calculate_width(line) + end + assert_equal(expected, cursor_max) end def assert_line_index(expected) diff --git a/test/reline/test_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb index 4575e51eb2..d5ddd40f85 100644 --- a/test/reline/test_key_actor_emacs.rb +++ b/test/reline/test_key_actor_emacs.rb @@ -1737,19 +1737,19 @@ def test_search_history_to_back assert_cursor_max(0) input_keys("\C-r123") assert_line('1234') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) # doesn't determine yet + assert_byte_pointer_size('1234') + assert_cursor(4) + assert_cursor_max(4) input_keys("\C-ha") assert_line('12aa') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) + assert_byte_pointer_size('12aa') + assert_cursor(4) + assert_cursor_max(4) input_keys("\C-h3") assert_line('1235') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) + assert_byte_pointer_size('1235') + assert_cursor(4) + assert_cursor_max(4) end def test_search_history_to_front @@ -1764,19 +1764,19 @@ def test_search_history_to_front assert_cursor_max(0) input_keys("\C-s123") assert_line('1235') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) # doesn't determine yet + assert_byte_pointer_size('1235') + assert_cursor(4) + assert_cursor_max(4) input_keys("\C-ha") assert_line('12aa') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) + assert_byte_pointer_size('12aa') + assert_cursor(4) + assert_cursor_max(4) input_keys("\C-h3") assert_line('1234') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) + assert_byte_pointer_size('1234') + assert_cursor(4) + assert_cursor_max(4) end def test_search_history_front_and_back @@ -1791,24 +1791,24 @@ def test_search_history_front_and_back assert_cursor_max(0) input_keys("\C-s12") assert_line('1235') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) # doesn't determine yet + assert_byte_pointer_size('1235') + assert_cursor(4) + assert_cursor_max(4) input_keys("\C-s") assert_line('12aa') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) + assert_byte_pointer_size('12aa') + assert_cursor(4) + assert_cursor_max(4) input_keys("\C-r") assert_line('12aa') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) + assert_byte_pointer_size('12aa') + assert_cursor(4) + assert_cursor_max(4) input_keys("\C-r") assert_line('1235') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) + assert_byte_pointer_size('1235') + assert_cursor(4) + assert_cursor_max(4) end def test_search_history_back_and_front @@ -1823,24 +1823,24 @@ def test_search_history_back_and_front assert_cursor_max(0) input_keys("\C-r12") assert_line('1234') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) # doesn't determine yet + assert_byte_pointer_size('1234') + assert_cursor(4) + assert_cursor_max(4) input_keys("\C-r") assert_line('12aa') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) + assert_byte_pointer_size('12aa') + assert_cursor(4) + assert_cursor_max(4) input_keys("\C-s") assert_line('12aa') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) + assert_byte_pointer_size('12aa') + assert_cursor(4) + assert_cursor_max(4) input_keys("\C-s") assert_line('1234') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) + assert_byte_pointer_size('1234') + assert_cursor(4) + assert_cursor_max(4) end def test_search_history_to_back_in_the_middle_of_histories @@ -1877,14 +1877,14 @@ def test_search_history_twice assert_cursor_max(0) input_keys("\C-r123") assert_line('1234') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) # doesn't determine yet + assert_byte_pointer_size('1234') + assert_cursor(4) + assert_cursor_max(4) input_keys("\C-r") assert_line('1235') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) + assert_byte_pointer_size('1235') + assert_cursor(4) + assert_cursor_max(4) end def test_search_history_by_last_determined @@ -1899,9 +1899,9 @@ def test_search_history_by_last_determined assert_cursor_max(0) input_keys("\C-r123") assert_line('1234') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) # doesn't determine yet + assert_byte_pointer_size('1234') + assert_cursor(4) + assert_cursor_max(4) input_keys("\C-j") assert_line('1234') assert_byte_pointer_size('') @@ -1919,9 +1919,9 @@ def test_search_history_by_last_determined assert_cursor_max(0) input_keys("\C-r") assert_line('1235') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) + assert_byte_pointer_size('1235') + assert_cursor(4) + assert_cursor_max(4) end def test_search_history_with_isearch_terminator @@ -1939,9 +1939,9 @@ def test_search_history_with_isearch_terminator assert_cursor_max(0) input_keys("\C-r12a") assert_line('12aa') - assert_byte_pointer_size('') - assert_cursor(0) - assert_cursor_max(0) # doesn't determine yet + assert_byte_pointer_size('12aa') + assert_cursor(4) + assert_cursor_max(4) input_keys('Y') assert_line('12aa') assert_byte_pointer_size('') @@ -2013,7 +2013,7 @@ def test_modify_lines_with_wrong_rs $VERBOSE = verbose @line_editor.output_modifier_proc = proc { |output| Reline::Unicode.escape_for_print(output) } input_keys("abcdef\n") - result = @line_editor.__send__(:modify_lines, @line_editor.whole_lines) + result = @line_editor.__send__(:modify_lines, @line_editor.whole_lines, @line_editor.finished?) $/ = nil assert_equal(['abcdef'], result) ensure diff --git a/test/reline/test_line_editor.rb b/test/reline/test_line_editor.rb index 8399e76e92..a5fcc3e2a1 100644 --- a/test/reline/test_line_editor.rb +++ b/test/reline/test_line_editor.rb @@ -1,13 +1,124 @@ require_relative 'helper' require 'reline/line_editor' +require 'stringio' -class Reline::LineEditor::Test < Reline::TestCase - def test_range_subtract - dummy_config = nil - editor = Reline::LineEditor.new(dummy_config, 'ascii-8bit') - base_ranges = [3...5, 4...10, 6...8, 12...15, 15...20] - subtract_ranges = [5...7, 8...9, 11...13, 17...18, 18...19] - expected_result = [3...5, 7...8, 9...10, 13...17, 19...20] - assert_equal expected_result, editor.send(:range_subtract, base_ranges, subtract_ranges) +class Reline::LineEditor + class RenderLineDifferentialTest < Reline::TestCase + def setup + verbose, $VERBOSE = $VERBOSE, nil + @line_editor = Reline::LineEditor.new(nil, Encoding::UTF_8) + @original_iogate = Reline::IOGate + @output = StringIO.new + @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, Object.new) + Reline::IOGate.instance_variable_set(:@output, @output) + def (Reline::IOGate).move_cursor_column(col) + @output << "[COL_#{col}]" + end + def (Reline::IOGate).erase_after_cursor + @output << '[ERASE]' + end + ensure + $VERBOSE = verbose + end + + def assert_output(expected) + @output.reopen('') + yield + actual = @output.string + assert_equal(expected, actual.gsub("\e[0m", '')) + end + + def teardown + Reline.send(:remove_const, :IOGate) + Reline.const_set(:IOGate, @original_iogate) + end + + def test_line_increase_decrease + assert_output '[COL_0]bb' do + @line_editor.render_line_differential([[0, 1, 'a']], [[0, 2, 'bb']]) + end + + assert_output '[COL_0]b[COL_1][ERASE]' do + @line_editor.render_line_differential([[0, 2, 'aa']], [[0, 1, 'b']]) + end + end + + def test_dialog_apear_disappear + assert_output '[COL_3]dialog' do + @line_editor.render_line_differential([[0, 1, 'a']], [[0, 1, 'a'], [3, 6, 'dialog']]) + end + + assert_output '[COL_3]dialog' do + @line_editor.render_line_differential([[0, 10, 'a' * 10]], [[0, 10, 'a' * 10], [3, 6, 'dialog']]) + end + + assert_output '[COL_1][ERASE]' do + @line_editor.render_line_differential([[0, 1, 'a'], [3, 6, 'dialog']], [[0, 1, 'a']]) + end + + assert_output '[COL_3]aaaaaa' do + @line_editor.render_line_differential([[0, 10, 'a' * 10], [3, 6, 'dialog']], [[0, 10, 'a' * 10]]) + end + end + + def test_dialog_change + assert_output '[COL_3]DIALOG' do + @line_editor.render_line_differential([[0, 2, 'a'], [3, 6, 'dialog']], [[0, 2, 'a'], [3, 6, 'DIALOG']]) + end + + assert_output '[COL_3]DIALOG' do + @line_editor.render_line_differential([[0, 10, 'a' * 10], [3, 6, 'dialog']], [[0, 10, 'a' * 10], [3, 6, 'DIALOG']]) + end + end + + def test_update_under_dialog + assert_output '[COL_0]b[COL_1] ' do + @line_editor.render_line_differential([[0, 2, 'aa'], [4, 6, 'dialog']], [[0, 1, 'b'], [4, 6, 'dialog']]) + end + + assert_output '[COL_0]bbb[COL_9]b' do + @line_editor.render_line_differential([[0, 10, 'a' * 10], [3, 6, 'dialog']], [[0, 10, 'b' * 10], [3, 6, 'dialog']]) + end + + assert_output '[COL_0]b[COL_1] [COL_9][ERASE]' do + @line_editor.render_line_differential([[0, 10, 'a' * 10], [3, 6, 'dialog']], [[0, 1, 'b'], [3, 6, 'dialog']]) + end + end + + def test_dialog_move + assert_output '[COL_3]dialog[COL_9][ERASE]' do + @line_editor.render_line_differential([[0, 1, 'a'], [4, 6, 'dialog']], [[0, 1, 'a'], [3, 6, 'dialog']]) + end + + assert_output '[COL_4] [COL_5]dialog' do + @line_editor.render_line_differential([[0, 1, 'a'], [4, 6, 'dialog']], [[0, 1, 'a'], [5, 6, 'dialog']]) + end + + assert_output '[COL_2]dialog[COL_8]a' do + @line_editor.render_line_differential([[0, 10, 'a' * 10], [3, 6, 'dialog']], [[0, 10, 'a' * 10], [2, 6, 'dialog']]) + end + + assert_output '[COL_2]a[COL_3]dialog' do + @line_editor.render_line_differential([[0, 10, 'a' * 10], [2, 6, 'dialog']], [[0, 10, 'a' * 10], [3, 6, 'dialog']]) + end + end + + def test_complex + state_a = [nil, [19, 7, 'bbbbbbb'], [15, 8, 'cccccccc'], [10, 5, 'ddddd'], [18, 4, 'eeee'], [1, 3, 'fff'], [17, 2, 'gg'], [7, 1, 'h']] + state_b = [[5, 9, 'aaaaaaaaa'], nil, [15, 8, 'cccccccc'], nil, [18, 4, 'EEEE'], [25, 4, 'ffff'], [17, 2, 'gg'], [2, 2, 'hh']] + # state_a: " fff h dddddccggeeecbbb" + # state_b: " hh aaaaaaaaa ccggEEEc ffff" + + assert_output '[COL_1] [COL_2]hh[COL_5]aaaaaaaaa[COL_14] [COL_19]EEE[COL_23] [COL_25]ffff' do + @line_editor.render_line_differential(state_a, state_b) + end + + assert_output '[COL_1]fff[COL_5] [COL_7]h[COL_8] [COL_10]ddddd[COL_19]eee[COL_23]bbb[COL_26][ERASE]' do + @line_editor.render_line_differential(state_b, state_a) + end + end end end diff --git a/test/reline/test_macro.rb b/test/reline/test_macro.rb index 3096930830..04aa6474b4 100644 --- a/test/reline/test_macro.rb +++ b/test/reline/test_macro.rb @@ -6,7 +6,6 @@ def setup @config = Reline::Config.new @encoding = Reline.core.encoding @line_editor = Reline::LineEditor.new(@config, @encoding) - @line_editor.instance_variable_set(:@screen_size, [24, 80]) @output = @line_editor.output = File.open(IO::NULL, "w") end diff --git a/test/reline/yamatanooroti/test_rendering.rb b/test/reline/yamatanooroti/test_rendering.rb index b61c84527d..3b1f63adff 100644 --- a/test/reline/yamatanooroti/test_rendering.rb +++ b/test/reline/yamatanooroti/test_rendering.rb @@ -464,6 +464,9 @@ def test_multiline_incremental_search write("def a\n 8\nend\ndef b\n 3\nend\C-s8") close assert_screen(<<~EOC) + prompt> 8 + prompt> end + => :a (i-search)`8'def a (i-search)`8' 8 (i-search)`8'end @@ -475,6 +478,9 @@ def test_multiline_incremental_search_finish write("def a\n 8\nend\ndef b\n 3\nend\C-r8\C-j") close assert_screen(<<~EOC) + prompt> 8 + prompt> end + => :a prompt> def a prompt> 8 prompt> end @@ -1026,8 +1032,8 @@ def test_dialog_scroll_pushup_condition iterate_over_face_configs do |config_name, config_file| start_terminal(10, 50, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') write("\n" * 10) - write("if 1\n sSt\nend") - write("\C-p\C-h\C-e") + write("if 1\n sSts\nend") + write("\C-p\C-h\C-e\C-h") close assert_screen(<<~'EOC') prompt> @@ -1054,8 +1060,8 @@ def test_simple_dialog_with_scroll_screen prompt> 2 prompt> 3# prompt> 4 - prompt> 5 - prompt> 6 Ruby is... + prompt> 5 Ruby is... + prompt> 6 A dynamic, open source programming EOC end end