From 5f6a691f315c7e78026376fa63fd00ad26601c66 Mon Sep 17 00:00:00 2001 From: tompng Date: Mon, 25 Mar 2024 19:32:00 +0900 Subject: [PATCH 1/2] Cache RDoc::RI::Driver.new to improve performance and to avoid flaky test --- lib/irb/input-method.rb | 28 ++++++++++++++++++---------- test/irb/test_input_method.rb | 13 +++++++------ 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/lib/irb/input-method.rb b/lib/irb/input-method.rb index c19983092..e5adb350e 100644 --- a/lib/irb/input-method.rb +++ b/lib/irb/input-method.rb @@ -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. ->() { @@ -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 @@ -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) @@ -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| diff --git a/test/irb/test_input_method.rb b/test/irb/test_input_method.rb index 7644d3176..ce317b4b3 100644 --- a/test/irb/test_input_method.rb +++ b/test/irb/test_input_method.rb @@ -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) @@ -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) @@ -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) @@ -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) From d584651cc604b7f96bae79e5fce3ac6a4f94f3d4 Mon Sep 17 00:00:00 2001 From: tompng Date: Mon, 25 Mar 2024 19:54:00 +0900 Subject: [PATCH 2/2] Insert sleep to fix flaky rendering test that renders document dialog --- test/irb/yamatanooroti/test_rendering.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/irb/yamatanooroti/test_rendering.rb b/test/irb/yamatanooroti/test_rendering.rb index df4ec01a5..44e07a3a1 100644 --- a/test/irb/yamatanooroti/test_rendering.rb +++ b/test/irb/yamatanooroti/test_rendering.rb @@ -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 @@ -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 @@ -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