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/test_reline.rb
aycabta cafa7904e7
Backport lib/reline, and lib/irb for 3.0.1 4th (#4349)
* [ruby/irb] Update help message for next context-mode of 4

While here, fixing tab/space issues in help message, and sync
rdoc for IRB class to match the help message.

ef8e3901cc

* [ruby/irb] Do not continue line if last expression is an endless range

Fixes [Bug #14824]

63414f8465

* [ruby/irb] Add a test for not continuing when endless range at eol

1020ac9c65

* [ruby/irb] Make save-history extension safe for concurrent use

This makes the save-history extension check for modifications to
the history file before saving it.  If the history file was modified
after the history was loaded and before it was saved, append only
the new history lines to the history file.

This can result in more lines in the history file than SAVE_HISTORY
allows.  However, that will be fixed the next time irb is run and
the history is saved.

Fixes [Bug #13654]

041ef53845

* Fix errors when XDG_CONFIG_HOME points to non-writable directory

`$HOME/.config` is not writable on CI
because I think tests should not corrupt user's data.

And GitHub Actions CI sets `XDG_CONFIG_HOME`
since `Version: 20210309.1`.

2130811016 (step):16:301
```
Errno::EACCES: Permission denied @ dir_s_mkdir - /home/runner/.config/irb
```

* Try to fix errors in TestIRB::TestHistory too

2137935523 (step):9:562
```
  1) Error:
TestIRB::TestHistory#test_history_concurrent_use:
Errno::EACCES: Permission denied @ dir_s_mkdir - /home/runner/.config/irb
    /home/runner/work/actions/actions/ruby/lib/fileutils.rb:253:in `mkdir'
    /home/runner/work/actions/actions/ruby/lib/fileutils.rb:253:in `fu_mkdir'
    /home/runner/work/actions/actions/ruby/lib/fileutils.rb:231:in `block (2 levels) in mkdir_p'
    /home/runner/work/actions/actions/ruby/lib/fileutils.rb:229:in `reverse_each'
    /home/runner/work/actions/actions/ruby/lib/fileutils.rb:229:in `block in mkdir_p'
    /home/runner/work/actions/actions/ruby/lib/fileutils.rb:211:in `each'
    /home/runner/work/actions/actions/ruby/lib/fileutils.rb:211:in `mkdir_p'
    /home/runner/work/actions/actions/ruby/lib/irb/init.rb:355:in `rc_file_generators'
    /home/runner/work/actions/actions/ruby/lib/irb/init.rb:330:in `rc_file'
    /home/runner/work/actions/actions/ruby/test/irb/test_history.rb:170:in `block in assert_history'
    /home/runner/work/actions/actions/ruby/lib/tmpdir.rb:96:in `mktmpdir'
    /home/runner/work/actions/actions/ruby/test/irb/test_history.rb:168:in `assert_history'
    /home/runner/work/actions/actions/ruby/test/irb/test_history.rb:133:in `test_history_concurrent_use'
```

* [ruby/irb] Define "measure" command without forced override

9587ba13b5

* [ruby/irb] Add all lib files automatically

ecc82336b7

* [ruby/irb] Don't call Ruby 2.4+'s String#pretty_print

89bcf107be

* [ruby/irb] Implement ls command

19b6c20604

* [ruby/irb] Add whereami command

bc822e4aac

* [ruby/irb] Fix column overflow on ls output

6115754623

* [ruby/irb] Fix step's argument

cols.size was calling Integer#size, which returns 8.

Fixing a bug of https://github.com/ruby/irb/pull/209

c93ae4be71

* [ruby/irb] Deal with different screen sizes

e.g. 20210321T063003Z.fail.html.gz

ddb3472ba2

* [ruby/irb] Have some right padding

instead of filling out an entire line

6ac8f45f5f

* Suppress verbose messages

Get rid of warnings in the parallel test.

```
unknown command: "Switch to inspect mode."
```

* [ruby/irb] Change ripper_lex_without_warning to a class method

d9f8abc17e

* [ruby/irb] Complete require and require_relative

1c61178b4c

* [ruby/reline] Add Reline.ungetc to control buffer

43ac03c624

* [ruby/reline] Reline.delete_text removes the current line in multiline

da90c094a1

* [ruby/reline] Support preposing and postposing for Reline.completion_proc

1f469de90c

* [ruby/reline] Suppress crashing when completer_{quote,word_break}_characters is empty

c6f1164942

* [ruby/irb] fix completion test when out-of-place build

* [ruby/irb] Cache completion files to require

612ebcb311

* [ruby/irb] Always add input method when calling Irb.new in tests

When passes input method as nil to Context.new through Irb.new,
ReidlineInputMethod.new is executed and the global internal state of Reline is
rewritten, therefore other tests are failed in the Ruby repository. This
commit changes to use TestInputMethod.

010dce9210

* [ruby/irb] Prevent the completion from crashing if rdoc is missing

There are cases where ruby is installed without rdoc and e.g.
lib/irb/cmd/help.rb also handles the LoadError

Here is how to replicate the issue:

```
$ docker run -it alpine:3.13.3 sh

/ # apk add ruby ruby-irb ruby-io-console

/ # irb

irb(main):001:0> Class[TAB][TAB]
```

And you end up with something like:

```
irb(main):001:0> ClassTraceback (most recent call last):
        34: from /usr/bin/irb:23:in `<main>'
        33: from /usr/bin/irb:23:in `load'
        32: from /usr/lib/ruby/gems/2.7.0/gems/irb-1.2.6/exe/irb:11:in `<top (required)>'
        31: from /usr/lib/ruby/2.7.0/irb.rb:400:in `start'
        30: from /usr/lib/ruby/2.7.0/irb.rb:471:in `run'
        29: from /usr/lib/ruby/2.7.0/irb.rb:471:in `catch'
        28: from /usr/lib/ruby/2.7.0/irb.rb:472:in `block in run'
        27: from /usr/lib/ruby/2.7.0/irb.rb:537:in `eval_input'
        26: from /usr/lib/ruby/2.7.0/irb/ruby-lex.rb:150:in `each_top_level_statement'
        25: from /usr/lib/ruby/2.7.0/irb/ruby-lex.rb:150:in `catch'
        24: from /usr/lib/ruby/2.7.0/irb/ruby-lex.rb:151:in `block in each_top_level_statement'
        23: from /usr/lib/ruby/2.7.0/irb/ruby-lex.rb:151:in `loop'
        22: from /usr/lib/ruby/2.7.0/irb/ruby-lex.rb:154:in `block (2 levels) in each_top_level_statement'
        21: from /usr/lib/ruby/2.7.0/irb/ruby-lex.rb:182:in `lex'
        20: from /usr/lib/ruby/2.7.0/irb.rb:518:in `block in eval_input'
        19: from /usr/lib/ruby/2.7.0/irb.rb:704:in `signal_status'
        18: from /usr/lib/ruby/2.7.0/irb.rb:519:in `block (2 levels) in eval_input'
        17: from /usr/lib/ruby/2.7.0/irb/input-method.rb:294:in `gets'
        16: from /usr/lib/ruby/2.7.0/forwardable.rb:235:in `readmultiline'
        15: from /usr/lib/ruby/2.7.0/forwardable.rb:235:in `readmultiline'
        14: from /usr/lib/ruby/2.7.0/reline.rb:175:in `readmultiline'
        13: from /usr/lib/ruby/2.7.0/reline.rb:238:in `inner_readline'
        12: from /usr/lib/ruby/2.7.0/reline.rb:238:in `loop'
        11: from /usr/lib/ruby/2.7.0/reline.rb:239:in `block in inner_readline'
        10: from /usr/lib/ruby/2.7.0/reline.rb:270:in `read_io'
         9: from /usr/lib/ruby/2.7.0/reline.rb:270:in `loop'
         8: from /usr/lib/ruby/2.7.0/reline.rb:311:in `block in read_io'
         7: from /usr/lib/ruby/2.7.0/reline.rb:240:in `block (2 levels) in inner_readline'
         6: from /usr/lib/ruby/2.7.0/reline.rb:240:in `each'
         5: from /usr/lib/ruby/2.7.0/reline.rb:241:in `block (3 levels) in inner_readline'
         4: from /usr/lib/ruby/2.7.0/reline/line_editor.rb:820:in `input_key'
         3: from /usr/lib/ruby/2.7.0/reline/line_editor.rb:608:in `complete'
         2: from /usr/lib/ruby/2.7.0/irb/completion.rb:269:in `block in <module:InputCompletor>'
         1: from /usr/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'
/usr/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require': cannot load such file -- rdoc (LoadError)
```

a2d299c2ac

* [ruby/irb] Suppress verbose messages in the parallel test

`:VERBOSE` flag needs to be set prior to `IRB::Irb.new`.

78604682d9

* [ruby/irb] SIGINT should raise Interrupt after IRB session

5832cfe75b

* [ruby/irb] Colorize `__END__` as keyword

9b84018311

* [ruby/irb] Add show_source command

108cb04352

* [ruby/reline] Reset @rest_height when clear screen

3a7019b0d5

* [ruby/irb] process multi-line pastes as a single entity

this allows pasting leading-dot chained methods correctly:

```ruby
class A
  def a; self; end
  def b; true; end
end

a = A.new

a
 .a
 .b
```

will properly return `true` instead of erroring on the `.a` line:

```
irb(main):001:1*     class A
irb(main):002:1*       def a; self; end
irb(main):003:0>     end
irb(main):004:0*
irb(main):005:0>     a = A.new
irb(main):006:0*
irb(main):007:0>     a
irb(main):008:0>      .a
irb(main):009:0>      .a
=> #<A:0x00007f984211fbe8>
```

45aeb52575

* [ruby/irb] Add yamatanooroti test example

279155fcee

* [ruby/irb] Add test for multiline paste

e93c9cb54d

* [ruby/irb] Evaluate each toplevel statement

bc1b1d8bc3

* [ruby/irb] Version 1.3.5

22e2ddf715

* [ruby/reline] Version 0.2.5

22ce5651e5

Co-authored-by: Jeremy Evans <code@jeremyevans.net>
Co-authored-by: Kazuhiro NISHIYAMA <zn@mbf.nifty.com>
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
Co-authored-by: Aleksandar Ivanov <aivanov92@gmail.com>
Co-authored-by: Koichi Sasada <ko1@atdot.net>
Co-authored-by: Cody Cutrer <cody@instructure.com>
2021-04-03 18:26:46 +09:00

319 lines
9 KiB
Ruby

require_relative 'helper'
require "reline"
class Reline::Test < Reline::TestCase
class DummyCallbackObject
def call; end
end
def setup
Reline.output_modifier_proc = nil
Reline.completion_proc = nil
Reline.prompt_proc = nil
Reline.auto_indent_proc = nil
Reline.pre_input_hook = nil
Reline.dig_perfect_match_proc = nil
end
def teardown
Reline.test_reset
end
def test_completion_append_character
completion_append_character = Reline.completion_append_character
assert_equal(nil, Reline.completion_append_character)
Reline.completion_append_character = ""
assert_equal(nil, Reline.completion_append_character)
Reline.completion_append_character = "a".encode(Encoding::ASCII)
assert_equal("a", Reline.completion_append_character)
assert_equal(get_reline_encoding, Reline.completion_append_character.encoding)
Reline.completion_append_character = "ba".encode(Encoding::ASCII)
assert_equal("b", Reline.completion_append_character)
assert_equal(get_reline_encoding, Reline.completion_append_character.encoding)
Reline.completion_append_character = "cba".encode(Encoding::ASCII)
assert_equal("c", Reline.completion_append_character)
assert_equal(get_reline_encoding, Reline.completion_append_character.encoding)
Reline.completion_append_character = nil
assert_equal(nil, Reline.completion_append_character)
ensure
Reline.completion_append_character = completion_append_character
end
def test_basic_word_break_characters
basic_word_break_characters = Reline.basic_word_break_characters
assert_equal(" \t\n`><=;|&{(", Reline.basic_word_break_characters)
Reline.basic_word_break_characters = "[".encode(Encoding::ASCII)
assert_equal("[", Reline.basic_word_break_characters)
assert_equal(get_reline_encoding, Reline.basic_word_break_characters.encoding)
ensure
Reline.basic_word_break_characters = basic_word_break_characters
end
def test_completer_word_break_characters
completer_word_break_characters = Reline.completer_word_break_characters
assert_equal(" \t\n`><=;|&{(", Reline.completer_word_break_characters)
Reline.completer_word_break_characters = "[".encode(Encoding::ASCII)
assert_equal("[", Reline.completer_word_break_characters)
assert_equal(get_reline_encoding, Reline.completer_word_break_characters.encoding)
assert_nothing_raised { Reline.completer_word_break_characters = '' }
ensure
Reline.completer_word_break_characters = completer_word_break_characters
end
def test_basic_quote_characters
basic_quote_characters = Reline.basic_quote_characters
assert_equal('"\'', Reline.basic_quote_characters)
Reline.basic_quote_characters = "`".encode(Encoding::ASCII)
assert_equal("`", Reline.basic_quote_characters)
assert_equal(get_reline_encoding, Reline.basic_quote_characters.encoding)
ensure
Reline.basic_quote_characters = basic_quote_characters
end
def test_completer_quote_characters
completer_quote_characters = Reline.completer_quote_characters
assert_equal('"\'', Reline.completer_quote_characters)
Reline.completer_quote_characters = "`".encode(Encoding::ASCII)
assert_equal("`", Reline.completer_quote_characters)
assert_equal(get_reline_encoding, Reline.completer_quote_characters.encoding)
assert_nothing_raised { Reline.completer_quote_characters = '' }
ensure
Reline.completer_quote_characters = completer_quote_characters
end
def test_filename_quote_characters
filename_quote_characters = Reline.filename_quote_characters
assert_equal('', Reline.filename_quote_characters)
Reline.filename_quote_characters = "\'".encode(Encoding::ASCII)
assert_equal("\'", Reline.filename_quote_characters)
assert_equal(get_reline_encoding, Reline.filename_quote_characters.encoding)
ensure
Reline.filename_quote_characters = filename_quote_characters
end
def test_special_prefixes
special_prefixes = Reline.special_prefixes
assert_equal('', Reline.special_prefixes)
Reline.special_prefixes = "\'".encode(Encoding::ASCII)
assert_equal("\'", Reline.special_prefixes)
assert_equal(get_reline_encoding, Reline.special_prefixes.encoding)
ensure
Reline.special_prefixes = special_prefixes
end
def test_completion_case_fold
completion_case_fold = Reline.completion_case_fold
assert_equal(nil, Reline.completion_case_fold)
Reline.completion_case_fold = true
assert_equal(true, Reline.completion_case_fold)
Reline.completion_case_fold = "hoge".encode(Encoding::ASCII)
assert_equal("hoge", Reline.completion_case_fold)
ensure
Reline.completion_case_fold = completion_case_fold
end
def test_completion_proc
skip unless Reline.completion_proc == nil
# Another test can set Reline.completion_proc
# assert_equal(nil, Reline.completion_proc)
p = proc {}
Reline.completion_proc = p
assert_equal(p, Reline.completion_proc)
l = lambda {}
Reline.completion_proc = l
assert_equal(l, Reline.completion_proc)
assert_raise(ArgumentError) { Reline.completion_proc = 42 }
assert_raise(ArgumentError) { Reline.completion_proc = "hoge" }
dummy = DummyCallbackObject.new
Reline.completion_proc = dummy
assert_equal(dummy, Reline.completion_proc)
end
def test_output_modifier_proc
assert_equal(nil, Reline.output_modifier_proc)
p = proc {}
Reline.output_modifier_proc = p
assert_equal(p, Reline.output_modifier_proc)
l = lambda {}
Reline.output_modifier_proc = l
assert_equal(l, Reline.output_modifier_proc)
assert_raise(ArgumentError) { Reline.output_modifier_proc = 42 }
assert_raise(ArgumentError) { Reline.output_modifier_proc = "hoge" }
dummy = DummyCallbackObject.new
Reline.output_modifier_proc = dummy
assert_equal(dummy, Reline.output_modifier_proc)
end
def test_prompt_proc
assert_equal(nil, Reline.prompt_proc)
p = proc {}
Reline.prompt_proc = p
assert_equal(p, Reline.prompt_proc)
l = lambda {}
Reline.prompt_proc = l
assert_equal(l, Reline.prompt_proc)
assert_raise(ArgumentError) { Reline.prompt_proc = 42 }
assert_raise(ArgumentError) { Reline.prompt_proc = "hoge" }
dummy = DummyCallbackObject.new
Reline.prompt_proc = dummy
assert_equal(dummy, Reline.prompt_proc)
end
def test_auto_indent_proc
assert_equal(nil, Reline.auto_indent_proc)
p = proc {}
Reline.auto_indent_proc = p
assert_equal(p, Reline.auto_indent_proc)
l = lambda {}
Reline.auto_indent_proc = l
assert_equal(l, Reline.auto_indent_proc)
assert_raise(ArgumentError) { Reline.auto_indent_proc = 42 }
assert_raise(ArgumentError) { Reline.auto_indent_proc = "hoge" }
dummy = DummyCallbackObject.new
Reline.auto_indent_proc = dummy
assert_equal(dummy, Reline.auto_indent_proc)
end
def test_pre_input_hook
assert_equal(nil, Reline.pre_input_hook)
p = proc {}
Reline.pre_input_hook = p
assert_equal(p, Reline.pre_input_hook)
l = lambda {}
Reline.pre_input_hook = l
assert_equal(l, Reline.pre_input_hook)
end
def test_dig_perfect_match_proc
assert_equal(nil, Reline.dig_perfect_match_proc)
p = proc {}
Reline.dig_perfect_match_proc = p
assert_equal(p, Reline.dig_perfect_match_proc)
l = lambda {}
Reline.dig_perfect_match_proc = l
assert_equal(l, Reline.dig_perfect_match_proc)
assert_raise(ArgumentError) { Reline.dig_perfect_match_proc = 42 }
assert_raise(ArgumentError) { Reline.dig_perfect_match_proc = "hoge" }
dummy = DummyCallbackObject.new
Reline.dig_perfect_match_proc = dummy
assert_equal(dummy, Reline.dig_perfect_match_proc)
end
def test_insert_text
# TODO
end
def test_line_buffer
# TODO
end
def test_point
# TODO
end
def test_input=
# TODO
assert_raise(TypeError) do
Reline.input = "This is not a file."
end
end
def test_output=
# TODO
assert_raise(TypeError) do
Reline.output = "This is not a file."
end
end
def test_vi_editing_mode
Reline.vi_editing_mode
assert_equal(Reline::KeyActor::ViInsert, Reline.send(:core).config.editing_mode.class)
end
def test_emacs_editing_mode
Reline.emacs_editing_mode
assert_equal(Reline::KeyActor::Emacs, Reline.send(:core).config.editing_mode.class)
end
def test_editing_mode
# TODO
end
def test_readmultiline
# readmultiline is module function
assert_include(Reline.methods, :readmultiline)
assert_include(Reline.private_instance_methods, :readmultiline)
end
def test_readline
# readline is module function
assert_include(Reline.methods, :readline)
assert_include(Reline.private_instance_methods, :readline)
end
def test_inner_readline
# TODO in Reline::Core
end
def test_read_io
# TODO in Reline::Core
end
def test_read_escaped_key
# TODO in Reline::Core
end
def test_may_req_ambiguous_char_width
# TODO in Reline::Core
end
def get_reline_encoding
RUBY_PLATFORM =~ /mswin|mingw/ ? Encoding::UTF_8 : Encoding::default_external
end
end