55require 'reline'
66require 'test/unit'
77
8+ begin
9+ require 'rbconfig'
10+ rescue LoadError
11+ end
12+
13+ begin
14+ # This should exist and available in load path when this file is mirrored to ruby/ruby and running at there
15+ if File . exist? ( File . expand_path ( '../../tool/lib/envutil.rb' , __dir__ ) )
16+ require 'envutil'
17+ end
18+ rescue LoadError
19+ end
20+
821module Reline
922 class <<self
10- def test_mode
11- remove_const ( 'IOGate' ) if const_defined? ( 'IOGate' )
12- const_set ( 'IOGate' , Reline ::GeneralIO )
13- if ENV [ 'RELINE_TEST_ENCODING' ]
14- encoding = Encoding . find ( ENV [ 'RELINE_TEST_ENCODING' ] )
15- else
16- encoding = Encoding ::UTF_8
23+ def test_mode ( ansi : false )
24+ @original_iogate = IOGate
25+
26+ if ENV [ 'RELINE_TEST_ENCODING' ]
27+ encoding = Encoding . find ( ENV [ 'RELINE_TEST_ENCODING' ] )
28+ else
29+ encoding = Encoding ::UTF_8
30+ end
31+
32+ if ansi
33+ new_io_gate = ANSI . new
34+ # Setting ANSI gate's screen size through set_screen_size will also change the tester's stdin's screen size
35+ # Let's avoid that side-effect by stubbing the get_screen_size method
36+ new_io_gate . define_singleton_method ( :get_screen_size ) do
37+ [ 24 , 80 ]
1738 end
18- Reline ::GeneralIO . reset ( encoding : encoding )
19- send ( :core ) . config . instance_variable_set ( :@test_mode , true )
20- send ( :core ) . config . reset
39+ new_io_gate . define_singleton_method ( :encoding ) do
40+ encoding
41+ end
42+ else
43+ new_io_gate = Dumb . new ( encoding : encoding )
44+ end
45+
46+ remove_const ( 'IOGate' )
47+ const_set ( 'IOGate' , new_io_gate )
48+ core . config . instance_variable_set ( :@test_mode , true )
49+ core . config . reset
2150 end
2251
2352 def test_reset
53+ remove_const ( 'IOGate' )
54+ const_set ( 'IOGate' , @original_iogate )
2455 Reline . instance_variable_set ( :@core , nil )
2556 end
26- end
27- end
2857
29- def start_pasting
30- Reline ::GeneralIO . start_pasting
31- end
58+ # Return a executable name to spawn Ruby process. In certain build configuration,
59+ # "ruby" may not be available.
60+ def test_rubybin
61+ # When this test suite is running in ruby/ruby, prefer EnvUtil result over original implementation
62+ if const_defined? ( :EnvUtil )
63+ return EnvUtil . rubybin
64+ end
3265
33- def finish_pasting
34- Reline ::GeneralIO . finish_pasting
66+ # The following is a simplified port of EnvUtil.rubybin in ruby/ruby
67+ if ruby = ENV [ "RUBY" ]
68+ return ruby
69+ end
70+ ruby = "ruby"
71+ exeext = RbConfig ::CONFIG [ "EXEEXT" ]
72+ rubyexe = ( ruby + exeext if exeext and !exeext . empty? )
73+ if File . exist? ruby and File . executable? ruby and !File . directory? ruby
74+ return File . expand_path ( ruby )
75+ end
76+ if rubyexe and File . exist? rubyexe and File . executable? rubyexe
77+ return File . expand_path ( rubyexe )
78+ end
79+ if defined? ( RbConfig . ruby )
80+ RbConfig . ruby
81+ else
82+ "ruby"
83+ end
84+ end
85+ end
3586end
3687
3788class Reline ::TestCase < Test ::Unit ::TestCase
@@ -41,11 +92,11 @@ class Reline::TestCase < Test::Unit::TestCase
4192 if Reline ::Unicode ::EscapedChars . include? ( c . ord )
4293 c
4394 else
44- c . encode ( @line_editor . instance_variable_get ( :@ encoding) , Encoding ::UTF_8 , **options )
95+ c . encode ( @line_editor . encoding , Encoding ::UTF_8 , **options )
4596 end
4697 } . join
4798 rescue Encoding ::UndefinedConversionError , Encoding ::InvalidByteSequenceError
48- input . unicode_normalize! ( :nfc )
99+ input = input . unicode_normalize ( :nfc )
49100 if normalized
50101 options [ :undef ] = :replace
51102 options [ :replace ] = '?'
@@ -70,23 +121,33 @@ def input_keys(input, convert = true)
70121 @line_editor . input_key ( Reline ::Key . new ( byte , byte , false ) )
71122 end
72123 else
73- c . bytes . each do |b |
74- @line_editor . input_key ( Reline ::Key . new ( b , b , false ) )
75- end
124+ @line_editor . input_key ( Reline ::Key . new ( c . ord , c . ord , false ) )
76125 end
77126 end
78127 end
79128
80129 def input_raw_keys ( input , convert = true )
81130 input = convert_str ( input ) if convert
82- input . bytes . each do |b |
83- @line_editor . input_key ( Reline ::Key . new ( b , b , false ) )
131+ input . chars . each do |c |
132+ @line_editor . input_key ( Reline ::Key . new ( c . ord , c . ord , false ) )
84133 end
85134 end
86135
87- def assert_line ( expected )
88- expected = convert_str ( expected )
89- assert_equal ( expected , @line_editor . line )
136+ def set_line_around_cursor ( before , after )
137+ input_keys ( "\C -a\C -k" )
138+ input_keys ( after )
139+ input_keys ( "\C -a" )
140+ input_keys ( before )
141+ end
142+
143+ def assert_line_around_cursor ( before , after )
144+ before = convert_str ( before )
145+ after = convert_str ( after )
146+ line = @line_editor . current_line
147+ byte_pointer = @line_editor . instance_variable_get ( :@byte_pointer )
148+ actual_before = line . byteslice ( 0 , byte_pointer )
149+ actual_after = line . byteslice ( byte_pointer ..)
150+ assert_equal ( [ before , after ] , [ actual_before , actual_after ] )
90151 end
91152
92153 def assert_byte_pointer_size ( expected )
@@ -97,29 +158,22 @@ def assert_byte_pointer_size(expected)
97158 expected . bytesize , byte_pointer ,
98159 <<~EOM )
99160 <#{ expected . inspect } (#{ expected . encoding . inspect } )> expected but was
100- <#{ chunk . inspect } (#{ chunk . encoding . inspect } )> in <Terminal #{ Reline ::GeneralIO . encoding . inspect } >
161+ <#{ chunk . inspect } (#{ chunk . encoding . inspect } )> in <Terminal #{ Reline ::Dumb . new . encoding . inspect } >
101162 EOM
102163 end
103164
104- def assert_cursor ( expected )
105- assert_equal ( expected , @line_editor . instance_variable_get ( :@cursor ) )
106- end
107-
108- def assert_cursor_max ( expected )
109- assert_equal ( expected , @line_editor . instance_variable_get ( :@cursor_max ) )
110- end
111-
112165 def assert_line_index ( expected )
113166 assert_equal ( expected , @line_editor . instance_variable_get ( :@line_index ) )
114167 end
115168
116169 def assert_whole_lines ( expected )
117- previous_line_index = @line_editor . instance_variable_get ( :@previous_line_index )
118- if previous_line_index
119- lines = @line_editor . whole_lines ( index : previous_line_index )
120- else
121- lines = @line_editor . whole_lines
170+ assert_equal ( expected , @line_editor . whole_lines )
171+ end
172+
173+ def assert_key_binding ( input , method_symbol , editing_modes = [ :emacs , :vi_insert , :vi_command ] )
174+ editing_modes . each do |editing_mode |
175+ @config . editing_mode = editing_mode
176+ assert_equal ( method_symbol , @config . editing_mode . get ( input . bytes ) )
122177 end
123- assert_equal ( expected , lines )
124178 end
125179end
0 commit comments