summaryrefslogtreecommitdiff
path: root/test/reline/yamatanooroti/test_rendering.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/reline/yamatanooroti/test_rendering.rb')
-rw-r--r--test/reline/yamatanooroti/test_rendering.rb649
1 files changed, 592 insertions, 57 deletions
diff --git a/test/reline/yamatanooroti/test_rendering.rb b/test/reline/yamatanooroti/test_rendering.rb
index f68b614327..09d064934a 100644
--- a/test/reline/yamatanooroti/test_rendering.rb
+++ b/test/reline/yamatanooroti/test_rendering.rb
@@ -3,7 +3,34 @@ require 'reline'
begin
require 'yamatanooroti'
- class Reline::TestRendering < Yamatanooroti::TestCase
+ class Reline::RenderingTest < Yamatanooroti::TestCase
+
+ FACE_CONFIGS = { no_config: "", valid_config: <<~VALID_CONFIG, incomplete_config: <<~INCOMPLETE_CONFIG }
+ require "reline"
+ Reline::Face.config(:completion_dialog) do |face|
+ face.define :default, foreground: :white, background: :blue
+ face.define :enhanced, foreground: :white, background: :magenta
+ face.define :scrollbar, foreground: :white, background: :blue
+ end
+ VALID_CONFIG
+ require "reline"
+ Reline::Face.config(:completion_dialog) do |face|
+ face.define :default, foreground: :white, background: :black
+ face.define :scrollbar, foreground: :white, background: :cyan
+ end
+ INCOMPLETE_CONFIG
+
+ def iterate_over_face_configs(&block)
+ FACE_CONFIGS.each do |config_name, face_config|
+ config_file = Tempfile.create(%w{face_config- .rb})
+ config_file.write face_config
+ block.call(config_name, config_file)
+ config_file.close
+ ensure
+ File.delete(config_file)
+ end
+ end
+
def setup
@pwd = Dir.pwd
suffix = '%010d' % Random.rand(0..65535)
@@ -121,6 +148,7 @@ begin
end
def test_finish_autowrapped_line_in_the_middle_of_multilines
+ omit if RUBY_VERSION < '2.7'
start_terminal(30, 16, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("<<~EOM\n ABCDEFG\nEOM\n")
close
@@ -169,9 +197,12 @@ begin
LINES
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write(":a\n\C-[k")
+ write("i\n:a")
+ write("\C-[h")
close
assert_screen(<<~EOC)
- Multiline REPL.
+ (ins)prompt> :a
+ => :a
(ins)prompt> :a
=> :a
(cmd)prompt> :a
@@ -236,6 +267,21 @@ begin
EOC
end
+ def test_esc_input
+ omit if Reline::IOGate.win?
+ start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
+ write("def\C-aabc")
+ write("\e") # single ESC
+ sleep 1
+ write("A")
+ write("B\eAC") # ESC + A (M-A, specified ed_unassigned in Reline::KeyActor::Emacs)
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> abcABCdef
+ EOC
+ end
+
def test_prompt_with_escape_sequence
ENV['RELINE_TEST_PROMPT'] = "\1\e[30m\2prompt> \1\e[m\2"
start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
@@ -263,6 +309,21 @@ begin
EOC
end
+ def test_readline_with_multiline_input
+ start_terminal(5, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dynamic-prompt}, startup_message: 'Multiline REPL.')
+ write("def foo\n bar\nend\n")
+ write("Reline.readline('prompt> ')\n")
+ write("\C-p\C-p")
+ close
+ assert_screen(<<~EOC)
+ => :foo
+ [0000]> Reline.readline('prompt> ')
+ prompt> def foo
+ bar
+ end
+ EOC
+ end
+
def test_multiline_and_autowrap
start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def aaaaaaaaaa\n 33333333\n end\C-a\C-pputs\C-e\e\C-m888888888888888")
@@ -280,6 +341,23 @@ begin
EOC
end
+ def test_multiline_add_new_line_and_autowrap
+ start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
+ write("def aaaaaaaaaa")
+ write("\n")
+ write(" bbbbbbbbbbbb")
+ write("\n")
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> def aaaaaaaa
+ aa
+ prompt> bbbbbbbbbb
+ bb
+ prompt>
+ EOC
+ end
+
def test_clear
start_terminal(10, 15, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("3\C-l")
@@ -404,6 +482,9 @@ begin
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
@@ -415,6 +496,9 @@ begin
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
@@ -435,32 +519,32 @@ begin
EOC
end
- def test_prompt_list_caching
- start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --prompt-list-cache-timeout 10 --dynamic-prompt}, startup_message: 'Multiline REPL.')
+ def test_broken_prompt_list
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --broken-dynamic-prompt}, startup_message: 'Multiline REPL.')
write("def hoge\n 3\nend")
close
assert_screen(<<~EOC)
Multiline REPL.
[0000]> def hoge
[0001]> 3
- [0002]> end
+ [0001]> end
EOC
end
- def test_broken_prompt_list
- start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --broken-dynamic-prompt}, startup_message: 'Multiline REPL.')
- write("def hoge\n 3\nend")
+ def test_no_escape_sequence_passed_to_dynamic_prompt
+ start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete --color-bold --broken-dynamic-prompt-assert-no-escape-sequence}, startup_message: 'Multiline REPL.')
+ write("%[ S")
+ write("\n")
close
assert_screen(<<~EOC)
Multiline REPL.
- [0000]> def hoge
- [0001]> 3
- [0001]> end
+ [0000]> %[ S
+ [0001]>
EOC
end
def test_enable_bracketed_paste
- omit if Reline::IOGate.win?
+ omit if Reline.core.io_gate.win?
write_inputrc <<~LINES
set enable-bracketed-paste on
LINES
@@ -631,6 +715,31 @@ begin
EOC
end
+ def test_longer_than_screen_height_nearest_cursor_with_scroll_back
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
+ write(<<~EOC.chomp)
+ if 1
+ if 2
+ if 3
+ if 4
+ puts
+ end
+ end
+ end
+ end
+ EOC
+ write("\C-p" * 4 + "\C-e" + "\C-p" * 4)
+ write("2")
+ close
+ assert_screen(<<~EOC)
+ prompt> if 12
+ prompt> if 2
+ prompt> if 3
+ prompt> if 4
+ prompt> puts
+ EOC
+ end
+
def test_update_cursor_correctly_when_just_cursor_moving
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def hoge\n 01234678")
@@ -648,6 +757,66 @@ begin
EOC
end
+ def test_auto_indent
+ start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
+ "def hoge\nputs(\n1,\n2\n)\nend".lines do |line|
+ write line
+ end
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> def hoge
+ prompt> puts(
+ prompt> 1,
+ prompt> 2
+ prompt> )
+ prompt> end
+ EOC
+ end
+
+ def test_auto_indent_when_inserting_line
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
+ write 'aa(bb(cc(dd(ee('
+ write "\C-b" * 5 + "\n"
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> aa(bb(cc(d
+ prompt> d(ee(
+ EOC
+ end
+
+ def test_auto_indent_multibyte_insert_line
+ start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
+ write "if true\n"
+ write "あいうえお\n"
+ 4.times { write "\C-b\C-b\C-b\C-b\e\r" }
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> if true
+ prompt> あ
+ prompt> い
+ prompt> う
+ prompt> え
+ prompt> お
+ prompt>
+ EOC
+ end
+
+ def test_newline_after_wrong_indent
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
+ write "if 1\n aa"
+ write "\n"
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> if 1
+ prompt> aa
+ prompt>
+ EOC
+ end
+
def test_suppress_auto_indent_just_after_pasted
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
write("def hoge\n [[\n 3]]\ned")
@@ -677,6 +846,20 @@ begin
EOC
end
+ def test_auto_indent_with_various_spaces
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
+ write "(\n\C-v"
+ write "\C-k\n\C-v"
+ write "\C-k)"
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> (
+ prompt> ^K
+ prompt> )
+ EOC
+ end
+
def test_autowrap_in_the_middle_of_a_line
start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def abcdefg; end\C-b\C-b\C-b\C-b\C-b")
@@ -739,6 +922,16 @@ begin
EOC
end
+ def test_not_meta_key
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
+ write("おだんご") # "だ" in UTF-8 contains "\xA0"
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> おだんご
+ EOC
+ end
+
def test_force_enter
start_terminal(30, 120, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def hoge\nend\C-p\C-e")
@@ -753,9 +946,10 @@ begin
end
def test_with_newline
- omit if Reline::IOGate.win?
+ omit if Reline.core.io_gate.win?
cmd = %Q{ruby -e 'print(%Q{abc def \\e\\r})' | ruby -I#{@pwd}/lib -rreline -e 'p Reline.readline(%{> })'}
start_terminal(40, 50, ['bash', '-c', cmd])
+ sleep 1
close
assert_screen(<<~'EOC')
> abc def
@@ -773,6 +967,18 @@ begin
EOC
end
+ def test_multiline_completion
+ start_terminal(10, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --complete}, startup_message: 'Multiline REPL.')
+ write("def hoge\n St\n St\C-p\t")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> def hoge
+ prompt> String
+ prompt> St
+ EOC
+ end
+
def test_completion_journey_2nd_line
write_inputrc <<~LINES
set editing-mode vi
@@ -801,41 +1007,83 @@ begin
end
def test_simple_dialog
- start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.')
- write('a')
- write('b')
- write('c')
- write("\C-h")
- close
- assert_screen(<<~'EOC')
- Multiline REPL.
- prompt> ab
- Ruby is...
- A dynamic, open source programming
- language with a focus on simplicity
- and productivity. It has an elegant
- syntax that is natural to read and
- easy to write.
- EOC
+ iterate_over_face_configs do |config_name, config_file|
+ start_terminal(20, 50, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.')
+ write('a')
+ write('b')
+ write('c')
+ write("\C-h")
+ close
+ assert_screen(<<~'EOC', "Failed with `#{config_name}` in Face")
+ Multiline REPL.
+ prompt> ab
+ Ruby is...
+ A dynamic, open source programming
+ language with a focus on simplicity
+ and productivity. It has an elegant
+ syntax that is natural to read and
+ easy to write.
+ EOC
+ end
end
def test_simple_dialog_at_right_edge
- start_terminal(20, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.')
- write('a')
- write('b')
- write('c')
- write("\C-h")
- close
- assert_screen(<<~'EOC')
- Multiline REPL.
- prompt> ab
- Ruby is...
- A dynamic, open source programming
- language with a focus on simplicity
- and productivity. It has an elegant
- syntax that is natural to read and
- easy to write.
- EOC
+ iterate_over_face_configs do |config_name, config_file|
+ start_terminal(20, 40, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.')
+ write('a')
+ write('b')
+ write('c')
+ write("\C-h")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> ab
+ Ruby is...
+ A dynamic, open source programming
+ language with a focus on simplicity
+ and productivity. It has an elegant
+ syntax that is natural to read and
+ easy to write.
+ EOC
+ end
+ end
+
+ 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 sSts\nend")
+ write("\C-p\C-h\C-e\C-h")
+ close
+ assert_screen(<<~'EOC')
+ prompt>
+ prompt>
+ prompt>
+ prompt>
+ prompt>
+ prompt>
+ prompt> if 1
+ prompt> St
+ prompt> enString
+ Struct
+ EOC
+ end
+ end
+
+ def test_simple_dialog_with_scroll_screen
+ iterate_over_face_configs do |config_name, config_file|
+ start_terminal(5, 50, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.')
+ write("if 1\n 2\n 3\n 4\n 5\n 6")
+ write("\C-p\C-n\C-p\C-p\C-p#")
+ close
+ assert_screen(<<~'EOC')
+ prompt> 2
+ prompt> 3#
+ prompt> 4
+ prompt> 5 Ruby is...
+ prompt> 6 A dynamic, open source programming
+ EOC
+ end
end
def test_autocomplete_at_bottom
@@ -889,6 +1137,19 @@ begin
EOC
end
+ def test_force_insert_before_autocomplete
+ start_terminal(20, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write('Sy')
+ write(";St\t\t")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> Sy;Struct
+ String
+ Struct
+ EOC
+ end
+
def test_simple_dialog_with_scroll_key
start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog long,scrollkey}, startup_message: 'Multiline REPL.')
write('a')
@@ -937,7 +1198,7 @@ begin
def test_dialog_with_fullwidth_chars
ENV['RELINE_TEST_PROMPT'] = '> '
- start_terminal(30, 5, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog fullwidth,scrollkey,scrollbar}, startup_message: 'Multiline REPL.')
+ start_terminal(20, 5, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog fullwidth,scrollkey,scrollbar}, startup_message: 'Multiline REPL.')
6.times{ write('j') }
close
assert_screen(<<~'EOC')
@@ -954,7 +1215,7 @@ begin
def test_dialog_with_fullwidth_chars_split
ENV['RELINE_TEST_PROMPT'] = '> '
- start_terminal(30, 6, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog fullwidth,scrollkey,scrollbar}, startup_message: 'Multiline REPL.')
+ start_terminal(20, 6, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog fullwidth,scrollkey,scrollbar}, startup_message: 'Multiline REPL.')
6.times{ write('j') }
close
assert_screen(<<~'EOC')
@@ -991,6 +1252,32 @@ begin
EOC
end
+ def test_autocomplete_empty_string
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write("\C-i")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> String
+ String █
+ Struct ▀
+ Symbol
+ EOC
+ end
+
+ def test_paste_code_with_tab_indent_does_not_fail
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete-empty}, startup_message: 'Multiline REPL.')
+ write("2.times do\n\tputs\n\tputs\nend")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> 2.times do
+ prompt> puts
+ prompt> puts
+ prompt> end
+ EOC
+ end
+
def test_autocomplete_after_2nd_line
start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
write("def hoge\n Str")
@@ -1019,6 +1306,23 @@ begin
EOC
end
+ def test_rerender_multiple_dialog
+ start_terminal(20, 60, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete --dialog simple}, startup_message: 'Multiline REPL.')
+ write("if\n abcdef\n 123456\n 456789\nend\C-p\C-p\C-p\C-p Str")
+ write("\t")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> if String
+ prompt> aStringRuby is...
+ prompt> 1StructA dynamic, open source programming
+ prompt> 456789 language with a focus on simplicity
+ prompt> end and productivity. It has an elegant
+ syntax that is natural to read and
+ easy to write.
+ EOC
+ end
+
def test_autocomplete_long_with_scrollbar
start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete-long}, startup_message: 'Multiline REPL.')
write('S')
@@ -1069,6 +1373,32 @@ begin
EOC
end
+ def test_autocomplete_super_long_scroll_to_bottom
+ start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete-super-long}, startup_message: 'Multiline REPL.')
+ shift_tab = [27, 91, 90]
+ write('S' + shift_tab.map(&:chr).join)
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> Str_BXX
+ Str_BXJ
+ Str_BXK
+ Str_BXL
+ Str_BXM
+ Str_BXN
+ Str_BXO
+ Str_BXP
+ Str_BXQ
+ Str_BXR
+ Str_BXS
+ Str_BXT
+ Str_BXU
+ Str_BXV
+ Str_BXW
+ Str_BXX▄
+ EOC
+ end
+
def test_autocomplete_super_long_and_backspace
start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete-super-long}, startup_message: 'Multiline REPL.')
shift_tab = [27, 91, 90]
@@ -1078,15 +1408,15 @@ begin
assert_screen(<<~'EOC')
Multiline REPL.
prompt> Str_BX
- Str_BX
- Str_BXA
- Str_BXB
- Str_BXC
- Str_BXD
- Str_BXE
- Str_BXF
- Str_BXG
- Str_BXH
+ Str_BX █
+ Str_BXA█
+ Str_BXB█
+ Str_BXC█
+ Str_BXD█
+ Str_BXE█
+ Str_BXF█
+ Str_BXG█
+ Str_BXH█
Str_BXI
Str_BXJ
Str_BXK
@@ -1130,7 +1460,7 @@ begin
Multiline R
EPL.
prompt> Sym
- String
+ String █
Struct █
Symbol █
StopIterat█
@@ -1187,6 +1517,211 @@ begin
EOC
end
+ def test_scroll_at_bottom_for_dialog
+ start_terminal(10, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write("\n\n\n\n\n\n\n\n\n\n\n")
+ write("def hoge\n\nend\C-p\C-e")
+ write(" S")
+ close
+ assert_screen(<<~'EOC')
+ prompt>
+ prompt>
+ prompt>
+ prompt>
+ prompt>
+ prompt> def hoge
+ prompt> S
+ prompt> enString █
+ Struct ▀
+ Symbol
+ EOC
+ end
+
+ def test_clear_dialog_in_pasting
+ start_terminal(10, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write("S")
+ write("tring ")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> String
+ EOC
+ end
+
+ def test_prompt_with_newline
+ ENV['RELINE_TEST_PROMPT'] = "::\n> "
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
+ write("def hoge\n 3\nend")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ ::\n> def hoge
+ ::\n> 3
+ ::\n> end
+ EOC
+ end
+
+ def test_dynamic_prompt_with_newline
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dynamic-prompt-with-newline}, startup_message: 'Multiline REPL.')
+ write("def hoge\n 3\nend")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ [0000\n]> def hoge
+ [0001\n]> 3
+ [0001\n]> end
+ EOC
+ end
+
+ def test_lines_passed_to_dynamic_prompt
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dynamic-prompt-show-line}, startup_message: 'Multiline REPL.')
+ write("if true")
+ write("\n")
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ [if t]> if true
+ [ ]>
+ EOC
+ end
+
+ def test_clear_dialog_when_just_move_cursor_at_last_line
+ start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write("class A\n 3\nend\n\n\n")
+ write("\C-p\C-p\C-e; S")
+ write("\C-n")
+ write(";")
+ close
+ assert_screen(<<~'EOC')
+ prompt> 3
+ prompt> end
+ => 3
+ prompt>
+ prompt>
+ prompt> class A
+ prompt> 3; S
+ prompt> end;
+ EOC
+ end
+
+ def test_clear_dialog_when_adding_new_line_to_end_of_buffer
+ start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write("class A\n def a\n 3\n 3\n end\nend")
+ write("\n")
+ write("class S")
+ write("\n")
+ write(" 3")
+ close
+ assert_screen(<<~'EOC')
+ prompt> def a
+ prompt> 3
+ prompt> 3
+ prompt> end
+ prompt> end
+ => :a
+ prompt> class S
+ prompt> 3
+ EOC
+ end
+
+ def test_insert_newline_in_the_middle_of_buffer_just_after_dialog
+ start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write("class A\n def a\n 3\n end\nend")
+ write("\n")
+ write("\C-p\C-p\C-p\C-p\C-p\C-e\C-hS")
+ write("\M-\x0D")
+ write(" 3")
+ close
+ assert_screen(<<~'EOC')
+ prompt> 3
+ prompt> end
+ prompt> end
+ => :a
+ prompt> class S
+ prompt> 3
+ prompt> def a
+ prompt> 3
+ prompt> end
+ prompt> end
+ EOC
+ end
+
+ def test_incremental_search_on_not_last_line
+ start_terminal(10, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write("def abc\nend\n")
+ write("def def\nend\n")
+ write("\C-p\C-p\C-e")
+ write("\C-r")
+ write("a")
+ write("\n\n")
+ close
+ assert_screen(<<~'EOC')
+ prompt> def abc
+ prompt> end
+ => :abc
+ prompt> def def
+ prompt> end
+ => :def
+ prompt> def abc
+ prompt> end
+ => :abc
+ prompt>
+ EOC
+ end
+
+ def test_bracket_newline_indent
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
+ write("[\n")
+ write("1")
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> [
+ prompt> 1
+ EOC
+ end
+
+ def test_repeated_input_delete
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
+ write("a\C-h" * 4000)
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt>
+ EOC
+ end
+
+ def test_exit_with_ctrl_d
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
+ begin
+ write("\C-d")
+ close
+ rescue EOFError
+ # EOFError is raised when process terminated.
+ end
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt>
+ EOC
+ end
+
+ def test_thread_safe
+ start_terminal(6, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
+ write("[Thread.new{Reline.readline'>'},Thread.new{Reline.readmultiline('>'){true}}].map(&:join).size\n")
+ write("exit\n")
+ write("exit\n")
+ write("42\n")
+ close
+ assert_screen(<<~EOC)
+ >exit
+ >exit
+ => 2
+ prompt> 42
+ => 42
+ prompt>
+ EOC
+ end
+
def write_inputrc(content)
File.open(@inputrc_file, 'w') do |f|
f.write content