Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle non-String $LOAD_PATH values more carefully #400

Merged
merged 1 commit into from
Sep 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion lib/irb/completion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,14 @@ def self.retrieve_gem_and_system_load_path
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
peterzhu2118 marked this conversation as resolved.
Show resolved Hide resolved
end
end.compact.sort
end

def self.retrieve_files_to_require_from_load_path
Expand Down
42 changes: 42 additions & 0 deletions test/irb/test_completion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

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"
Expand Down Expand Up @@ -84,6 +89,43 @@ def test_complete_require
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 ", "")
Expand Down