Skip to content

Commit

Permalink
[ruby/irb] Cache RDoc::RI::Driver.new
Browse files Browse the repository at this point in the history
(ruby/irb#911)

* Cache RDoc::RI::Driver.new to improve performance and to avoid flaky test

* Insert sleep to fix flaky rendering test that renders document dialog

ruby/irb@da84e6cb56
  • Loading branch information
tompng authored and matzbot committed Mar 25, 2024
1 parent 5f334b6 commit f53209f
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 17 deletions.
28 changes: 18 additions & 10 deletions lib/irb/input-method.rb
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,20 @@ def retrieve_doc_namespace(matched)
@completor.doc_namespace(preposing, matched, postposing, bind: bind)
end

def rdoc_ri_driver
return @rdoc_ri_driver if defined?(@rdoc_ri_driver)

begin
require 'rdoc'
rescue LoadError
@rdoc_ri_driver = nil
else
options = {}
options[:extra_doc_dirs] = IRB.conf[:EXTRA_DOC_DIRS] unless IRB.conf[:EXTRA_DOC_DIRS].empty?
@rdoc_ri_driver = RDoc::RI::Driver.new(options)
end
end

def show_doc_dialog_proc
input_method = self # self is changed in the lambda below.
->() {
Expand All @@ -331,9 +345,7 @@ def show_doc_dialog_proc

show_easter_egg = name&.match?(/\ARubyVM/) && !ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER']

options = {}
options[:extra_doc_dirs] = IRB.conf[:EXTRA_DOC_DIRS] unless IRB.conf[:EXTRA_DOC_DIRS].empty?
driver = RDoc::RI::Driver.new(options)
driver = input_method.rdoc_ri_driver

if key.match?(dialog.name)
if show_easter_egg
Expand Down Expand Up @@ -421,12 +433,9 @@ def show_doc_dialog_proc
}
end

def display_document(matched, driver: nil)
begin
require 'rdoc'
rescue LoadError
return
end
def display_document(matched)
driver = rdoc_ri_driver
return unless driver

if matched =~ /\A(?:::)?RubyVM/ and not ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER']
IRB.__send__(:easter_egg)
Expand All @@ -436,7 +445,6 @@ def display_document(matched, driver: nil)
namespace = retrieve_doc_namespace(matched)
return unless namespace

driver ||= RDoc::RI::Driver.new
if namespace.is_a?(Array)
out = RDoc::Markup::Document.new
namespace.each do |m|
Expand Down
13 changes: 7 additions & 6 deletions test/irb/test_input_method.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,18 @@ def setup
@driver = RDoc::RI::Driver.new(use_stdout: true)
end

def display_document(target, bind)
def display_document(target, bind, driver = nil)
input_method = IRB::RelineInputMethod.new(IRB::RegexpCompletor.new)
input_method.instance_variable_set(:@rdoc_ri_driver, driver) if driver
input_method.instance_variable_set(:@completion_params, ['', target, '', bind])
input_method.display_document(target, driver: @driver)
input_method.display_document(target)
end

def test_perfectly_matched_namespace_triggers_document_display
omit unless has_rdoc_content?

out, err = capture_output do
display_document("String", binding)
display_document("String", binding, @driver)
end

assert_empty(err)
Expand All @@ -109,7 +110,7 @@ def test_perfectly_matched_namespace_triggers_document_display
def test_perfectly_matched_multiple_namespaces_triggers_document_display
result = nil
out, err = capture_output do
result = display_document("{}.nil?", binding)
result = display_document("{}.nil?", binding, @driver)
end

assert_empty(err)
Expand All @@ -131,7 +132,7 @@ def test_perfectly_matched_multiple_namespaces_triggers_document_display
def test_not_matched_namespace_triggers_nothing
result = nil
out, err = capture_output do
result = display_document("Stri", binding)
result = display_document("Stri", binding, @driver)
end

assert_empty(err)
Expand All @@ -156,7 +157,7 @@ def test_perfect_matching_stops_without_rdoc
def test_perfect_matching_handles_nil_namespace
out, err = capture_output do
# symbol literal has `nil` doc namespace so it's a good test subject
assert_nil(display_document(":aiueo", binding))
assert_nil(display_document(":aiueo", binding, @driver))
end

assert_empty(err)
Expand Down
4 changes: 3 additions & 1 deletion test/irb/yamatanooroti/test_rendering.rb
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,9 @@ def test_autocomplete_with_multiple_doc_namespaces
start_terminal(3, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
write("{}.__id_")
write("\C-i")
sleep 0.2
close
screen = result.join("\n").sub(/\n*\z/, "\n")
# This assertion passes whether showdoc dialog completed or not.
assert_match(/start\ IRB\nirb\(main\):001> {}\.__id__\n }\.__id__(?:Press )?/, screen)
end

Expand All @@ -278,6 +278,7 @@ def test_autocomplete_with_showdoc_in_gaps_on_narrow_screen_right
start_terminal(4, 19, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
write("IR")
write("\C-i")
sleep 0.2
close

# This is because on macOS we display different shortcut for displaying the full doc
Expand Down Expand Up @@ -315,6 +316,7 @@ def test_autocomplete_with_showdoc_in_gaps_on_narrow_screen_left
start_terminal(4, 12, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
write("IR")
write("\C-i")
sleep 0.2
close
assert_screen(<<~EOC)
start IRB
Expand Down

0 comments on commit f53209f

Please sign in to comment.