ruby/test/rubygems/test_gem.rb

711 строки
19 KiB
Ruby

require_relative 'gemutilities'
require 'rubygems'
require 'rubygems/gem_openssl'
require 'rubygems/installer'
require 'pathname'
require 'tmpdir'
class TestGem < RubyGemTestCase
def setup
super
@additional = %w[a b].map { |d| File.join @tempdir, d }
@default_dir_re = if RUBY_VERSION > '1.9' then
%r|/.*?[Rr]uby.*?/[Gg]ems/[0-9.]+|
else
%r|/[Rr]uby/[Gg]ems/[0-9.]+|
end
util_remove_interrupt_command
end
def test_self_all_load_paths
util_make_gems
expected = [
File.join(@gemhome, *%W[gems #{@a1.full_name} lib]),
File.join(@gemhome, *%W[gems #{@a2.full_name} lib]),
File.join(@gemhome, *%W[gems #{@a3a.full_name} lib]),
File.join(@gemhome, *%W[gems #{@a_evil9.full_name} lib]),
File.join(@gemhome, *%W[gems #{@b2.full_name} lib]),
File.join(@gemhome, *%W[gems #{@c1_2.full_name} lib]),
File.join(@gemhome, *%W[gems #{@pl1.full_name} lib]),
]
assert_equal expected, Gem.all_load_paths.sort
end
def test_self_available?
util_make_gems
assert(Gem.available?("a"))
assert(Gem.available?("a", "1"))
assert(Gem.available?("a", ">1"))
assert(!Gem.available?("monkeys"))
end
def test_self_bin_path_bin_name
util_exec_gem
assert_equal @abin_path, Gem.bin_path('a', 'abin')
end
def test_self_bin_path_bin_name_version
util_exec_gem
assert_equal @abin_path, Gem.bin_path('a', 'abin', '4')
end
def test_self_bin_path_name
util_exec_gem
assert_equal @exec_path, Gem.bin_path('a')
end
def test_self_bin_path_name_version
util_exec_gem
assert_equal @exec_path, Gem.bin_path('a', nil, '4')
end
def test_self_bin_path_no_default_bin
quick_gem 'a', '2' do |s|
s.executables = ['exec']
end
assert_raises(Gem::Exception) do
Gem.bin_path('a', '2')
end
end
def test_self_bin_path_no_bin_file
quick_gem 'a', '1'
assert_raises(Gem::Exception) do
Gem.bin_path('a', '1')
end
end
def test_self_bin_path_not_found
assert_raises(Gem::GemNotFoundException) do
Gem.bin_path('non-existent')
end
end
def test_self_bindir
assert_equal File.join(@gemhome, 'bin'), Gem.bindir
assert_equal File.join(@gemhome, 'bin'), Gem.bindir(Gem.dir)
assert_equal File.join(@gemhome, 'bin'), Gem.bindir(Pathname.new(Gem.dir))
end
def test_self_bindir_default_dir
default = Gem.default_dir
bindir = if defined?(RUBY_FRAMEWORK_VERSION) then
'/usr/bin'
else
RbConfig::CONFIG['bindir']
end
assert_equal bindir, Gem.bindir(default)
assert_equal bindir, Gem.bindir(Pathname.new(default))
end
def test_self_clear_paths
Gem.dir
Gem.path
searcher = Gem.searcher
source_index = Gem.source_index
Gem.clear_paths
assert_equal nil, Gem.instance_variable_get(:@gem_home)
assert_equal nil, Gem.instance_variable_get(:@gem_path)
refute_equal searcher, Gem.searcher
refute_equal source_index.object_id, Gem.source_index.object_id
end
def test_self_configuration
expected = Gem::ConfigFile.new []
Gem.configuration = nil
assert_equal expected, Gem.configuration
end
def test_self_datadir
foo = nil
Dir.chdir @tempdir do
FileUtils.mkdir_p 'data'
File.open File.join('data', 'foo.txt'), 'w' do |fp|
fp.puts 'blah'
end
foo = quick_gem 'foo' do |s| s.files = %w[data/foo.txt] end
install_gem foo
end
Gem.source_index = nil
gem 'foo'
expected = File.join @gemhome, 'gems', foo.full_name, 'data', 'foo'
assert_equal expected, Gem.datadir('foo')
end
def test_self_datadir_nonexistent_package
assert_nil Gem.datadir('xyzzy')
end
def test_self_default_dir
assert_match @default_dir_re, Gem.default_dir
end
def test_self_default_exec_format
orig_RUBY_INSTALL_NAME = Gem::ConfigMap[:ruby_install_name]
Gem::ConfigMap[:ruby_install_name] = 'ruby'
assert_equal '%s', Gem.default_exec_format
ensure
Gem::ConfigMap[:ruby_install_name] = orig_RUBY_INSTALL_NAME
end
def test_self_default_exec_format_18
orig_RUBY_INSTALL_NAME = Gem::ConfigMap[:ruby_install_name]
Gem::ConfigMap[:ruby_install_name] = 'ruby18'
assert_equal '%s18', Gem.default_exec_format
ensure
Gem::ConfigMap[:ruby_install_name] = orig_RUBY_INSTALL_NAME
end
def test_self_default_exec_format_jruby
orig_RUBY_INSTALL_NAME = Gem::ConfigMap[:ruby_install_name]
Gem::ConfigMap[:ruby_install_name] = 'jruby'
assert_equal 'j%s', Gem.default_exec_format
ensure
Gem::ConfigMap[:ruby_install_name] = orig_RUBY_INSTALL_NAME
end
def test_self_default_sources
assert_equal %w[http://rubygems.org/], Gem.default_sources
end
def test_self_dir
assert_equal @gemhome, Gem.dir
end
def test_self_ensure_gem_directories
FileUtils.rm_r @gemhome
Gem.use_paths @gemhome
Gem.ensure_gem_subdirectories @gemhome
assert File.directory?(File.join(@gemhome, "cache"))
end
def test_self_ensure_gem_directories_missing_parents
gemdir = File.join @tempdir, 'a/b/c/gemdir'
FileUtils.rm_rf File.join(@tempdir, 'a') rescue nil
refute File.exist?(File.join(@tempdir, 'a')),
"manually remove #{File.join @tempdir, 'a'}, tests are broken"
Gem.use_paths gemdir
Gem.ensure_gem_subdirectories gemdir
assert File.directory?("#{gemdir}/cache")
end
unless win_platform? then # only for FS that support write protection
def test_self_ensure_gem_directories_write_protected
gemdir = File.join @tempdir, "egd"
FileUtils.rm_r gemdir rescue nil
refute File.exist?(gemdir), "manually remove #{gemdir}, tests are broken"
FileUtils.mkdir_p gemdir
FileUtils.chmod 0400, gemdir
Gem.use_paths gemdir
Gem.ensure_gem_subdirectories gemdir
refute File.exist?("#{gemdir}/cache")
ensure
FileUtils.chmod 0600, gemdir
end
def test_self_ensure_gem_directories_write_protected_parents
parent = File.join(@tempdir, "egd")
gemdir = "#{parent}/a/b/c"
FileUtils.rm_r parent rescue nil
refute File.exist?(parent), "manually remove #{parent}, tests are broken"
FileUtils.mkdir_p parent
FileUtils.chmod 0400, parent
Gem.use_paths(gemdir)
Gem.ensure_gem_subdirectories gemdir
refute File.exist?("#{gemdir}/cache")
ensure
FileUtils.chmod 0600, parent
end
end
def test_ensure_ssl_available
orig_Gem_ssl_available = Gem.ssl_available?
Gem.ssl_available = true
Gem.ensure_ssl_available
Gem.ssl_available = false
e = assert_raises Gem::Exception do Gem.ensure_ssl_available end
assert_equal 'SSL is not installed on this system', e.message
ensure
Gem.ssl_available = orig_Gem_ssl_available
end
def test_self_find_files
discover_path = File.join 'lib', 'foo', 'discover.rb'
cwd = File.expand_path '..', __FILE__
$LOAD_PATH.unshift cwd.dup
foo1 = quick_gem 'foo', '1' do |s|
s.files << discover_path
end
foo2 = quick_gem 'foo', '2' do |s|
s.files << discover_path
end
path = File.join 'gems', foo1.full_name, discover_path
write_file(path) { |fp| fp.puts "# #{path}" }
path = File.join 'gems', foo2.full_name, discover_path
write_file(path) { |fp| fp.puts "# #{path}" }
@fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher
Gem.source_index = util_setup_spec_fetcher foo1, foo2
Gem.searcher = nil
expected = [
File.expand_path('../foo/discover.rb', __FILE__),
File.join(foo2.full_gem_path, discover_path),
File.join(foo1.full_gem_path, discover_path),
]
assert_equal expected, Gem.find_files('foo/discover')
bug3701 = '[ruby-core:31730]'
assert_equal expected, Gem.find_files('foo/**.rb'), bug3701
ensure
assert_equal cwd, $LOAD_PATH.shift
end
def test_self_latest_load_paths
util_make_gems
expected = [
File.join(@gemhome, *%W[gems #{@a3a.full_name} lib]),
File.join(@gemhome, *%W[gems #{@a_evil9.full_name} lib]),
File.join(@gemhome, *%W[gems #{@b2.full_name} lib]),
File.join(@gemhome, *%W[gems #{@c1_2.full_name} lib]),
File.join(@gemhome, *%W[gems #{@pl1.full_name} lib]),
]
assert_equal expected, Gem.latest_load_paths.sort
end
def test_self_loaded_specs
foo = quick_gem 'foo'
install_gem foo
Gem.source_index = nil
Gem.activate 'foo'
assert_equal true, Gem.loaded_specs.keys.include?('foo')
end
def test_self_path
assert_equal [Gem.dir], Gem.path
end
def test_self_path_default
if defined? APPLE_GEM_HOME
orig_APPLE_GEM_HOME = APPLE_GEM_HOME
Object.send :remove_const, :APPLE_GEM_HOME
end
Gem.instance_variable_set :@gem_path, nil
assert_equal [Gem.default_path, Gem.dir].flatten, Gem.path
ensure
Object.const_set :APPLE_GEM_HOME, orig_APPLE_GEM_HOME
end
unless win_platform?
def test_self_path_APPLE_GEM_HOME
Gem.clear_paths
apple_gem_home = File.join @tempdir, 'apple_gem_home'
Gem.const_set :APPLE_GEM_HOME, apple_gem_home
assert_includes Gem.path, apple_gem_home
ensure
Gem.send :remove_const, :APPLE_GEM_HOME
end
def test_self_path_APPLE_GEM_HOME_GEM_PATH
Gem.clear_paths
ENV['GEM_PATH'] = @gemhome
apple_gem_home = File.join @tempdir, 'apple_gem_home'
Gem.const_set :APPLE_GEM_HOME, apple_gem_home
refute Gem.path.include?(apple_gem_home)
ensure
Gem.send :remove_const, :APPLE_GEM_HOME
end
end
def test_self_path_ENV_PATH
Gem.send :set_paths, nil
path_count = Gem.path.size
Gem.clear_paths
ENV['GEM_PATH'] = @additional.join(File::PATH_SEPARATOR)
assert_equal @additional, Gem.path[0,2]
assert_equal path_count + @additional.size, Gem.path.size,
"extra path components: #{Gem.path[2..-1].inspect}"
assert_equal Gem.dir, Gem.path.last
end
def test_self_path_duplicate
Gem.clear_paths
util_ensure_gem_dirs
dirs = @additional + [@gemhome] + [File.join(@tempdir, 'a')]
ENV['GEM_HOME'] = @gemhome
ENV['GEM_PATH'] = dirs.join File::PATH_SEPARATOR
assert_equal @gemhome, Gem.dir
paths = [Gem.dir]
assert_equal @additional + paths, Gem.path
end
def test_self_path_overlap
Gem.clear_paths
util_ensure_gem_dirs
ENV['GEM_HOME'] = @gemhome
ENV['GEM_PATH'] = @additional.join(File::PATH_SEPARATOR)
assert_equal @gemhome, Gem.dir
paths = [Gem.dir]
assert_equal @additional + paths, Gem.path
end
def test_self_platforms
assert_equal [Gem::Platform::RUBY, Gem::Platform.local], Gem.platforms
end
def test_self_prefix
file_name = File.expand_path __FILE__
prefix = File.dirname File.dirname(file_name)
prefix = File.dirname prefix if File.basename(prefix) == 'test'
assert_equal prefix, Gem.prefix
end
def test_self_prefix_libdir
orig_libdir = Gem::ConfigMap[:libdir]
file_name = File.expand_path __FILE__
prefix = File.dirname File.dirname(file_name)
prefix = File.dirname prefix if File.basename(prefix) == 'test'
Gem::ConfigMap[:libdir] = prefix
assert_nil Gem.prefix
ensure
Gem::ConfigMap[:libdir] = orig_libdir
end
def test_self_prefix_sitelibdir
orig_sitelibdir = Gem::ConfigMap[:sitelibdir]
file_name = File.expand_path __FILE__
prefix = File.dirname File.dirname(file_name)
prefix = File.dirname prefix if File.basename(prefix) == 'test'
Gem::ConfigMap[:sitelibdir] = prefix
assert_nil Gem.prefix
ensure
Gem::ConfigMap[:sitelibdir] = orig_sitelibdir
end
def test_self_refresh
util_make_gems
a1_spec = File.join @gemhome, "specifications", @a1.spec_name
FileUtils.mv a1_spec, @tempdir
refute Gem.source_index.gems.include?(@a1.full_name)
FileUtils.mv File.join(@tempdir, @a1.spec_name), a1_spec
Gem.refresh
assert_includes Gem.source_index.gems, @a1.full_name
assert_equal nil, Gem.instance_variable_get(:@searcher)
end
def test_self_required_location
util_make_gems
assert_equal File.join(@tempdir, *%w[gemhome gems c-1.2 lib code.rb]),
Gem.required_location("c", "code.rb")
assert_equal File.join(@tempdir, *%w[gemhome gems a-1 lib code.rb]),
Gem.required_location("a", "code.rb", "< 2")
assert_equal File.join(@tempdir, *%w[gemhome gems a-2 lib code.rb]),
Gem.required_location("a", "code.rb", "= 2")
end
def test_self_ruby_escaping_spaces_in_path
orig_ruby = Gem.ruby
orig_bindir = Gem::ConfigMap[:bindir]
orig_ruby_install_name = Gem::ConfigMap[:ruby_install_name]
orig_exe_ext = Gem::ConfigMap[:EXEEXT]
Gem::ConfigMap[:bindir] = "C:/Ruby 1.8/bin"
Gem::ConfigMap[:ruby_install_name] = "ruby"
Gem::ConfigMap[:EXEEXT] = ".exe"
Gem.instance_variable_set("@ruby", nil)
assert_equal "\"C:/Ruby 1.8/bin/ruby.exe\"", Gem.ruby
ensure
Gem.instance_variable_set("@ruby", orig_ruby)
Gem::ConfigMap[:bindir] = orig_bindir
Gem::ConfigMap[:ruby_install_name] = orig_ruby_install_name
Gem::ConfigMap[:EXEEXT] = orig_exe_ext
end
def test_self_ruby_path_without_spaces
orig_ruby = Gem.ruby
orig_bindir = Gem::ConfigMap[:bindir]
orig_ruby_install_name = Gem::ConfigMap[:ruby_install_name]
orig_exe_ext = Gem::ConfigMap[:EXEEXT]
Gem::ConfigMap[:bindir] = "C:/Ruby18/bin"
Gem::ConfigMap[:ruby_install_name] = "ruby"
Gem::ConfigMap[:EXEEXT] = ".exe"
Gem.instance_variable_set("@ruby", nil)
assert_equal "C:/Ruby18/bin/ruby.exe", Gem.ruby
ensure
Gem.instance_variable_set("@ruby", orig_ruby)
Gem::ConfigMap[:bindir] = orig_bindir
Gem::ConfigMap[:ruby_install_name] = orig_ruby_install_name
Gem::ConfigMap[:EXEEXT] = orig_exe_ext
end
def test_self_ruby_version_1_8_5
util_set_RUBY_VERSION '1.8.5'
assert_equal Gem::Version.new('1.8.5'), Gem.ruby_version
ensure
util_restore_RUBY_VERSION
end
def test_self_ruby_version_1_8_6p287
util_set_RUBY_VERSION '1.8.6', 287
assert_equal Gem::Version.new('1.8.6.287'), Gem.ruby_version
ensure
util_restore_RUBY_VERSION
end
def test_self_ruby_version_1_9_2dev_r23493
util_set_RUBY_VERSION '1.9.2', -1, 23493
assert_equal Gem::Version.new('1.9.2.dev.23493'), Gem.ruby_version
ensure
util_restore_RUBY_VERSION
end
def test_self_searcher
assert_kind_of Gem::GemPathSearcher, Gem.searcher
end
def test_self_set_paths
other = File.join @tempdir, 'other'
path = [@userhome, other].join File::PATH_SEPARATOR
Gem.send :set_paths, path
assert_equal [@userhome, other, @gemhome], Gem.path
end
def test_self_set_paths_nonexistent_home
ENV['GEM_HOME'] = @gemhome
Gem.clear_paths
other = File.join @tempdir, 'other'
ENV['HOME'] = other
Gem.send :set_paths, other
assert_equal [other, @gemhome], Gem.path
end
def test_self_source_index
assert_kind_of Gem::SourceIndex, Gem.source_index
end
def test_self_sources
assert_equal %w[http://gems.example.com/], Gem.sources
end
def test_ssl_available_eh
orig_Gem_ssl_available = Gem.ssl_available?
Gem.ssl_available = true
assert_equal true, Gem.ssl_available?
Gem.ssl_available = false
assert_equal false, Gem.ssl_available?
ensure
Gem.ssl_available = orig_Gem_ssl_available
end
def test_self_use_paths
util_ensure_gem_dirs
Gem.use_paths @gemhome, @additional
assert_equal @gemhome, Gem.dir
assert_equal @additional + [Gem.dir], Gem.path
end
def test_self_user_dir
assert_equal File.join(@userhome, '.gem', Gem.ruby_engine,
Gem::ConfigMap[:ruby_version]), Gem.user_dir
end
def test_self_user_home
if ENV['HOME'] then
assert_equal ENV['HOME'], Gem.user_home
else
assert true, 'count this test'
end
end
def test_self_user_home_user_drive_and_path
Gem.clear_paths
# safe-keep env variables
orig_home, orig_user_profile = ENV['HOME'], ENV['USERPROFILE']
orig_user_drive, orig_user_path = ENV['HOMEDRIVE'], ENV['HOMEPATH']
# prepare the environment
ENV.delete('HOME')
ENV.delete('USERPROFILE')
ENV['HOMEDRIVE'] = 'Z:'
ENV['HOMEPATH'] = '\\Users\\RubyUser'
assert_equal "Z:\\Users\\RubyUser", Gem.user_home
ensure
ENV['HOME'] = orig_home
ENV['USERPROFILE'] = orig_user_profile
ENV['USERDRIVE'] = orig_user_drive
ENV['USERPATH'] = orig_user_path
end if '1.9' > RUBY_VERSION
def test_load_plugins
with_plugin('load') { Gem.load_plugins }
assert_equal :loaded, TEST_PLUGIN_LOAD
util_remove_interrupt_command
# Should attempt to cause a StandardError
with_plugin('standarderror') { Gem.load_plugins }
assert_equal :loaded, TEST_PLUGIN_STANDARDERROR
util_remove_interrupt_command
# Should attempt to cause an Exception
with_plugin('exception') { Gem.load_plugins }
assert_equal :loaded, TEST_PLUGIN_EXCEPTION
end
def with_plugin(path)
test_plugin_path = File.expand_path "../plugin/#{path}", __FILE__
# A single test plugin should get loaded once only, in order to preserve
# sane test semantics.
refute_includes $LOAD_PATH, test_plugin_path
$LOAD_PATH.unshift test_plugin_path
capture_io do
yield
end
ensure
$LOAD_PATH.delete test_plugin_path
end
def util_ensure_gem_dirs
Gem.ensure_gem_subdirectories @gemhome
@additional.each do |dir|
Gem.ensure_gem_subdirectories @gemhome
end
end
def util_exec_gem
spec, _ = quick_gem 'a', '4' do |s|
s.default_executable = 'exec'
s.executables = ['exec', 'abin']
end
@exec_path = File.join spec.full_gem_path, spec.bindir, 'exec'
@abin_path = File.join spec.full_gem_path, spec.bindir, 'abin'
end
def util_set_RUBY_VERSION(version, patchlevel = nil, revision = nil)
if Gem.instance_variables.include? :@ruby_version or
Gem.instance_variables.include? '@ruby_version' then
Gem.send :remove_instance_variable, :@ruby_version
end
@RUBY_VERSION = RUBY_VERSION
@RUBY_PATCHLEVEL = RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
@RUBY_REVISION = RUBY_REVISION if defined?(RUBY_REVISION)
Object.send :remove_const, :RUBY_VERSION
Object.send :remove_const, :RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
Object.const_set :RUBY_VERSION, version
Object.const_set :RUBY_PATCHLEVEL, patchlevel if patchlevel
Object.const_set :RUBY_REVISION, revision if revision
end
def util_restore_RUBY_VERSION
Object.send :remove_const, :RUBY_VERSION
Object.send :remove_const, :RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
Object.const_set :RUBY_VERSION, @RUBY_VERSION
Object.const_set :RUBY_PATCHLEVEL, @RUBY_PATCHLEVEL if
defined?(@RUBY_PATCHLEVEL)
Object.const_set :RUBY_REVISION, @RUBY_REVISION if
defined?(@RUBY_REVISION)
end
def util_remove_interrupt_command
Gem::Commands.send :remove_const, :InterruptCommand if
Gem::Commands.const_defined? :InterruptCommand
end
end