1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

[ruby/irb] Handle non-String $LOAD_PATH values more carefully

In addition to String values, $LOAD_PATH can also take objects that
respond_to the `to_path` method, like Pathname objects. So `irb` should
be able to handle those objects too.

And if $LOAD_PATH contains objects that can't be converted into String,
`irb` should simply ignore it.

b2f562176b
This commit is contained in:
st0012 2022-09-19 16:14:03 +01:00 committed by git
parent 1a2ee4cfab
commit 6325fc8854
2 changed files with 50 additions and 1 deletions

View file

@ -60,7 +60,14 @@ module IRB
end
}
}.flatten if defined?(Gem::Specification)
(gem_paths.to_a | $LOAD_PATH).sort
candidates = (gem_paths.to_a | $LOAD_PATH)
candidates.map do |p|
if p.respond_to?(:to_path)
p.to_path
else
String(p) rescue nil
end
end.compact.sort
end
def self.retrieve_files_to_require_from_load_path

View file

@ -4,6 +4,11 @@ require "irb"
module TestIRB
class TestCompletion < Test::Unit::TestCase
def setup
# make sure require completion candidates are not cached
IRB::InputCompletor.class_variable_set(:@@files_from_load_path, nil)
end
def test_nonstring_module_name
begin
require "irb/completion"
@ -84,6 +89,43 @@ module TestIRB
end
end
def test_complete_require_with_pathname_in_load_path
temp_dir = Dir.mktmpdir
File.write(File.join(temp_dir, "foo.rb"), "test")
test_path = Pathname.new(temp_dir)
$LOAD_PATH << test_path
candidates = IRB::InputCompletor::CompletionProc.("'foo", "require ", "")
assert_equal ["'foo"], candidates
ensure
$LOAD_PATH.pop if test_path
FileUtils.remove_entry(temp_dir) if temp_dir
end
def test_complete_require_with_string_convertable_in_load_path
temp_dir = Dir.mktmpdir
File.write(File.join(temp_dir, "foo.rb"), "test")
object = Object.new
object.define_singleton_method(:to_s) { temp_dir }
$LOAD_PATH << object
candidates = IRB::InputCompletor::CompletionProc.("'foo", "require ", "")
assert_equal ["'foo"], candidates
ensure
$LOAD_PATH.pop if object
FileUtils.remove_entry(temp_dir) if temp_dir
end
def test_complete_require_with_malformed_object_in_load_path
object = Object.new
def object.to_s; raise; end
$LOAD_PATH << object
assert_empty IRB::InputCompletor::CompletionProc.("'foo", "require ", "")
ensure
$LOAD_PATH.pop if object
end
def test_complete_require_library_name_first
pend 'Need to use virtual library paths'
candidates = IRB::InputCompletor::CompletionProc.("'csv", "require ", "")