diff --git a/lib/irb/completion.rb b/lib/irb/completion.rb index 9121174a5..bfe6c7e7a 100644 --- a/lib/irb/completion.rb +++ b/lib/irb/completion.rb @@ -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 + end + end.compact.sort end def self.retrieve_files_to_require_from_load_path diff --git a/test/irb/test_completion.rb b/test/irb/test_completion.rb index 3aa99d74d..4bc3fc778 100644 --- a/test/irb/test_completion.rb +++ b/test/irb/test_completion.rb @@ -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" @@ -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 ", "")