diff options
Diffstat (limited to 'test')
62 files changed, 3133 insertions, 387 deletions
diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index e33742049c..0da28bb9fb 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb @@ -75,6 +75,21 @@ class TestGem < Gem::TestCase end end + def test_self_install + spec_fetcher do |f| + f.gem 'a', 1 + f.spec 'a', 2 + end + + gemhome2 = "#{@gemhome}2" + + installed = Gem.install 'a', '= 1', :install_dir => gemhome2 + + assert_equal %w[a-1], installed.map { |spec| spec.full_name } + + assert_path_exists File.join(gemhome2, 'gems', 'a-1') + end + def test_require_missing save_loaded_features do assert_raises ::LoadError do @@ -216,6 +231,58 @@ class TestGem < Gem::TestCase end end + def test_default_path + orig_vendordir = RbConfig::CONFIG['vendordir'] + RbConfig::CONFIG['vendordir'] = File.join @tempdir, 'vendor' + + FileUtils.rm_rf Gem.user_home + + expected = [Gem.default_dir] + + assert_equal expected, Gem.default_path + ensure + RbConfig::CONFIG['vendordir'] = orig_vendordir + end + + def test_default_path_missing_vendor + orig_vendordir = RbConfig::CONFIG['vendordir'] + RbConfig::CONFIG.delete 'vendordir' + + FileUtils.rm_rf Gem.user_home + + expected = [Gem.default_dir] + + assert_equal expected, Gem.default_path + ensure + RbConfig::CONFIG['vendordir'] = orig_vendordir + end + + def test_default_path_user_home + orig_vendordir = RbConfig::CONFIG['vendordir'] + RbConfig::CONFIG['vendordir'] = File.join @tempdir, 'vendor' + + expected = [Gem.user_dir, Gem.default_dir] + + assert_equal expected, Gem.default_path + ensure + RbConfig::CONFIG['vendordir'] = orig_vendordir + end + + def test_default_path_vendor_dir + orig_vendordir = RbConfig::CONFIG['vendordir'] + RbConfig::CONFIG['vendordir'] = File.join @tempdir, 'vendor' + + FileUtils.mkdir_p Gem.vendor_dir + + FileUtils.rm_rf Gem.user_home + + expected = [Gem.default_dir, Gem.vendor_dir] + + assert_equal expected, Gem.default_path + ensure + RbConfig::CONFIG['vendordir'] = orig_vendordir + end + def test_self_default_sources assert_equal %w[https://rubygems.org/], Gem.default_sources end @@ -816,6 +883,23 @@ class TestGem < Gem::TestCase assert_match %r%Could not find 'b' %, e.message end + def test_self_try_activate_missing_extensions + util_spec 'ext', '1' do |s| + s.extensions = %w[ext/extconf.rb] + s.mark_version + s.installed_by_version = v('2.2') + end + + _, err = capture_io do + refute Gem.try_activate 'nonexistent' + end + + expected = "Ignoring ext-1 because its extensions are not built. " + + "Try: gem pristine ext-1\n" + + assert_equal expected, err + end + def test_self_use_paths util_ensure_gem_dirs @@ -951,6 +1035,30 @@ class TestGem < Gem::TestCase end end + def test_self_vendor_dir + expected = + File.join RbConfig::CONFIG['vendordir'], 'gems', + RbConfig::CONFIG['ruby_version'] + + assert_equal expected, Gem.vendor_dir + end + + def test_self_vendor_dir_ENV_GEM_VENDOR + ENV['GEM_VENDOR'] = File.join @tempdir, 'vendor', 'gems' + + assert_equal ENV['GEM_VENDOR'], Gem.vendor_dir + refute Gem.vendor_dir.frozen? + end + + def test_self_vendor_dir_missing + orig_vendordir = RbConfig::CONFIG['vendordir'] + RbConfig::CONFIG.delete 'vendordir' + + assert_nil Gem.vendor_dir + ensure + RbConfig::CONFIG['vendordir'] = orig_vendordir + end + def test_load_plugins skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7" plugin_path = File.join "lib", "rubygems_plugin.rb" @@ -1251,13 +1359,28 @@ class TestGem < Gem::TestCase end def test_use_gemdeps + gem_deps_file = 'gem.deps.rb'.untaint + spec = util_spec 'a', 1 + + refute spec.activated? + + open gem_deps_file, 'w' do |io| + io.write 'gem "a"' + end + + Gem.use_gemdeps gem_deps_file + + assert spec.activated? + end + + def test_use_gemdeps_ENV rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], nil spec = util_spec 'a', 1 refute spec.activated? - open 'Gemfile', 'w' do |io| + open 'gem.deps.rb', 'w' do |io| io.write 'gem "a"' end @@ -1268,6 +1391,29 @@ class TestGem < Gem::TestCase ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps end + def test_use_gemdeps_argument_missing + e = assert_raises ArgumentError do + Gem.use_gemdeps 'gem.deps.rb' + end + + assert_equal 'Unable to find gem dependencies file at gem.deps.rb', + e.message + end + + def test_use_gemdeps_argument_missing_match_ENV + rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = + ENV['RUBYGEMS_GEMDEPS'], 'gem.deps.rb' + + e = assert_raises ArgumentError do + Gem.use_gemdeps 'gem.deps.rb' + end + + assert_equal 'Unable to find gem dependencies file at gem.deps.rb', + e.message + ensure + ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps + end + def test_use_gemdeps_automatic skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7" rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], '-' @@ -1287,6 +1433,17 @@ class TestGem < Gem::TestCase ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps end + def test_use_gemdeps_automatic_missing + skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7" + rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], '-' + + Gem.use_gemdeps + + assert true # count + ensure + ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps + end + def test_use_gemdeps_disabled rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], '' @@ -1294,7 +1451,7 @@ class TestGem < Gem::TestCase refute spec.activated? - open 'Gemfile', 'w' do |io| + open 'gem.deps.rb', 'w' do |io| io.write 'gem "a"' end @@ -1305,6 +1462,27 @@ class TestGem < Gem::TestCase ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps end + def test_use_gemdeps_missing_gem + skip 'Insecure operation - read' if RUBY_VERSION <= "1.8.7" + rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], 'x' + + open 'x', 'w' do |io| + io.write 'gem "a"' + end + + expected = <<-EXPECTED +Unable to resolve dependency: user requested 'a (>= 0)' +You may need to `gem install -g` to install missing gems + + EXPECTED + + assert_output nil, expected do + Gem.use_gemdeps + end + ensure + ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps + end + def test_use_gemdeps_specific skip 'Insecure operation - read' if RUBY_VERSION <= "1.8.7" rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], 'x' diff --git a/test/rubygems/test_gem_available_set.rb b/test/rubygems/test_gem_available_set.rb index 9c204d046b..2b515447a3 100644 --- a/test/rubygems/test_gem_available_set.rb +++ b/test/rubygems/test_gem_available_set.rb @@ -3,6 +3,7 @@ require 'rubygems/available_set' require 'rubygems/security' class TestGemAvailableSet < Gem::TestCase + def setup super @@ -23,22 +24,24 @@ class TestGemAvailableSet < Gem::TestCase end def test_find_all - a1, a1_gem = util_gem 'a', 1 + a1, a1_gem = util_gem 'a', 1 + a1a, a1a_gem = util_gem 'a', '1.a' - source = Gem::Source::SpecificFile.new a1_gem + a1_source = Gem::Source::SpecificFile.new a1_gem + a1a_source = Gem::Source::SpecificFile.new a1a_gem set = Gem::AvailableSet.new - set.add a1, source + set.add a1, a1_source + set.add a1a, a1a_source dep = Gem::Resolver::DependencyRequest.new dep('a'), nil - specs = set.find_all dep - - spec = specs.first + assert_equal %w[a-1], set.find_all(dep).map { |spec| spec.full_name } - assert_kind_of Gem::Resolver::LocalSpecification, spec + dep = Gem::Resolver::DependencyRequest.new dep('a', '>= 0.a'), nil - assert_equal 'a-1', spec.full_name + assert_equal %w[a-1 a-1.a], + set.find_all(dep).map { |spec| spec.full_name }.sort end def test_match_platform diff --git a/test/rubygems/test_gem_command.rb b/test/rubygems/test_gem_command.rb index 712259c6cd..48cbc98d8c 100644 --- a/test/rubygems/test_gem_command.rb +++ b/test/rubygems/test_gem_command.rb @@ -184,5 +184,60 @@ class TestGemCommand < Gem::TestCase assert_equal ['-h', 'command'], args end + def test_show_lookup_failure_suggestions_local + correct = "non_existent_with_hint" + misspelled = "nonexistent_with_hint" + + spec_fetcher do |fetcher| + fetcher.spec correct, 2 + end + + use_ui @ui do + @cmd.show_lookup_failure misspelled, Gem::Requirement.default, [], :local + end + + expected = <<-EXPECTED +ERROR: Could not find a valid gem 'nonexistent_with_hint' (>= 0) in any repository + EXPECTED + + assert_equal expected, @ui.error + end + + def test_show_lookup_failure_suggestions_none + spec_fetcher do |fetcher| + fetcher.spec 'correct', 2 + end + + use_ui @ui do + @cmd.show_lookup_failure 'other', Gem::Requirement.default, [], :remote + end + + expected = <<-EXPECTED +ERROR: Could not find a valid gem 'other' (>= 0) in any repository + EXPECTED + + assert_equal expected, @ui.error + end + + def test_show_lookup_failure_suggestions_remote + correct = "non_existent_with_hint" + misspelled = "nonexistent_with_hint" + + spec_fetcher do |fetcher| + fetcher.spec correct, 2 + end + + use_ui @ui do + @cmd.show_lookup_failure misspelled, Gem::Requirement.default, [], :remote + end + + expected = <<-EXPECTED +ERROR: Could not find a valid gem 'nonexistent_with_hint' (>= 0) in any repository +ERROR: Possible alternatives: non_existent_with_hint + EXPECTED + + assert_equal expected, @ui.error + end + end diff --git a/test/rubygems/test_gem_commands_cert_command.rb b/test/rubygems/test_gem_commands_cert_command.rb index 03063859f5..4c1dcc25c0 100644 --- a/test/rubygems/test_gem_commands_cert_command.rb +++ b/test/rubygems/test_gem_commands_cert_command.rb @@ -179,6 +179,7 @@ Added '/CN=alternate/DC=example' assert_empty @ui.error assert_path_exists File.join(@tempdir, 'gem-public_cert.pem') + refute_path_exists File.join(@tempdir, 'gem-private_key.pem') end def test_execute_build_encrypted_key diff --git a/test/rubygems/test_gem_commands_contents_command.rb b/test/rubygems/test_gem_commands_contents_command.rb index 7f5cf22223..fb6906afd2 100644 --- a/test/rubygems/test_gem_commands_contents_command.rb +++ b/test/rubygems/test_gem_commands_contents_command.rb @@ -9,8 +9,8 @@ class TestGemCommandsContentsCommand < Gem::TestCase @cmd = Gem::Commands::ContentsCommand.new end - def gem name - spec = quick_gem name do |gem| + def gem name, version = 2 + spec = quick_gem name, version do |gem| gem.files = %W[lib/#{name}.rb Rakefile] end write_file File.join(*%W[gems #{spec.full_name} lib #{name}.rb]) @@ -135,6 +135,40 @@ class TestGemCommandsContentsCommand < Gem::TestCase assert_equal "", @ui.error end + def test_execute_show_install_dir + @cmd.options[:args] = %w[foo] + @cmd.options[:show_install_dir] = true + + gem 'foo' + + use_ui @ui do + @cmd.execute + end + + expected = File.join @gemhome, 'gems', 'foo-2' + + assert_equal "#{expected}\n", @ui.output + assert_equal "", @ui.error + end + + def test_execute_show_install_dir_version + @cmd.options[:args] = %w[foo] + @cmd.options[:show_install_dir] = true + @cmd.options[:version] = Gem::Requirement.new '= 1' + + gem 'foo', 1 + gem 'foo', 2 + + use_ui @ui do + @cmd.execute + end + + expected = File.join @gemhome, 'gems', 'foo-1' + + assert_equal "#{expected}\n", @ui.output + assert_equal "", @ui.error + end + def test_execute_no_prefix @cmd.options[:args] = %w[foo] @cmd.options[:prefix] = false @@ -183,13 +217,22 @@ lib/foo.rb assert @cmd.options[:prefix] assert_empty @cmd.options[:specdirs] assert_nil @cmd.options[:version] + refute @cmd.options[:show_install_dir] - @cmd.send :handle_options, %w[-l -s foo --version 0.0.2 --no-prefix] + @cmd.send :handle_options, %w[ + -l + -s + foo + --version 0.0.2 + --no-prefix + --show-install-dir + ] assert @cmd.options[:lib_only] refute @cmd.options[:prefix] assert_equal %w[foo], @cmd.options[:specdirs] assert_equal Gem::Requirement.new('0.0.2'), @cmd.options[:version] + assert @cmd.options[:show_install_dir] end end diff --git a/test/rubygems/test_gem_commands_environment_command.rb b/test/rubygems/test_gem_commands_environment_command.rb index bb7589f50d..81ff55d357 100644 --- a/test/rubygems/test_gem_commands_environment_command.rb +++ b/test/rubygems/test_gem_commands_environment_command.rb @@ -28,6 +28,7 @@ class TestGemCommandsEnvironmentCommand < Gem::TestCase assert_match %r|RUBYGEMS PREFIX: |, @ui.output assert_match %r|RUBY EXECUTABLE:.*#{RbConfig::CONFIG['ruby_install_name']}|, @ui.output + assert_match %r|SYSTEM CONFIGURATION DIRECTORY:|, @ui.output assert_match %r|EXECUTABLE DIRECTORY:|, @ui.output assert_match %r|RUBYGEMS PLATFORMS:|, @ui.output assert_match %r|- #{Gem::Platform.local}|, @ui.output diff --git a/test/rubygems/test_gem_commands_help_command.rb b/test/rubygems/test_gem_commands_help_command.rb index 3a6f2fa523..bed6095827 100644 --- a/test/rubygems/test_gem_commands_help_command.rb +++ b/test/rubygems/test_gem_commands_help_command.rb @@ -22,6 +22,13 @@ class TestGemCommandsHelpCommand < Gem::TestCase end end + def test_gem_help_gem_dependencies + util_gem 'gem_dependencies' do |out, err| + assert_match 'gem.deps.rb', out + assert_equal '', err + end + end + def test_gem_help_platforms util_gem 'platforms' do |out, err| assert_match(/x86-freebsd/, out) diff --git a/test/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb index 6315cb5d95..f03285ae85 100644 --- a/test/rubygems/test_gem_commands_install_command.rb +++ b/test/rubygems/test_gem_commands_install_command.rb @@ -24,6 +24,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase Gem::Command.build_args = @orig_args File.unlink @gemdeps if File.file? @gemdeps + File.unlink "#{@gemdeps}.lock" if File.file? "#{@gemdeps}.lock" end def test_execute_exclude_prerelease @@ -194,6 +195,32 @@ class TestGemCommandsInstallCommand < Gem::TestCase assert_match(%r!Unable to download data from http://not-there.nothing!, errs.shift) end + def test_execute_nonexistent_hint_disabled + misspelled = "nonexistent_with_hint" + correctly_spelled = "non_existent_with_hint" + + spec_fetcher do |fetcher| + fetcher.spec correctly_spelled, 2 + end + + @cmd.options[:args] = [misspelled] + @cmd.options[:suggest_alternate] = false + + use_ui @ui do + e = assert_raises Gem::MockGemUi::TermError do + @cmd.execute + end + + assert_equal 2, e.exit_code + end + + expected = <<-EXPECTED +ERROR: Could not find a valid gem 'nonexistent_with_hint' (>= 0) in any repository + EXPECTED + + assert_equal expected, @ui.error + end + def test_execute_nonexistent_with_hint misspelled = "nonexistent_with_hint" correctly_spelled = "non_existent_with_hint" @@ -238,7 +265,10 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal 2, e.exit_code end - expected = ["ERROR: Could not find a valid gem 'non-existent_with-hint' (>= 0) in any repository", "ERROR: Possible alternatives: nonexistent-with_hint"] + expected = [ + "ERROR: Could not find a valid gem 'non-existent_with-hint' (>= 0) in any repository", + "ERROR: Possible alternatives: nonexistent-with_hint" + ] output = @ui.error.split "\n" @@ -535,6 +565,11 @@ ERROR: Possible alternatives: non_existent_with_hint end def test_install_gem_ignore_dependencies_both + done_installing = false + Gem.done_installing do + done_installing = true + end + spec = quick_spec 'a', 2 util_build_gem spec @@ -546,6 +581,8 @@ ERROR: Possible alternatives: non_existent_with_hint @cmd.install_gem 'a', '>= 0' assert_equal %w[a-2], @cmd.installed_specs.map { |s| s.full_name } + + assert done_installing, 'documentation was not generated' end def test_install_gem_ignore_dependencies_remote @@ -622,8 +659,8 @@ ERROR: Possible alternatives: non_existent_with_hint end assert_equal 2, e.exit_code - assert_match %r!Could not find a valid gem 'blah' \(>= 0\)!, @ui.error - assert_match %r!Unable to download data from http://not-there\.nothing!, @ui.error + + assert_match 'Unable to download data', @ui.error end def test_show_source_problems_even_on_success @@ -648,7 +685,7 @@ ERROR: Possible alternatives: non_existent_with_hint e = @ui.error - x = "WARNING: Unable to pull data from 'http://nonexistent.example': no data for http://nonexistent.example/latest_specs.4.8.gz (http://nonexistent.example/latest_specs.4.8.gz)\n" + x = "WARNING: Unable to pull data from 'http://nonexistent.example': no data for http://nonexistent.example/specs.4.8.gz (http://nonexistent.example/specs.4.8.gz)\n" assert_equal x, e end @@ -672,6 +709,56 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal %w[], @cmd.installed_specs.map { |spec| spec.full_name } assert_match "Using a (2)", @ui.output + assert File.exist?("#{@gemdeps}.lock") + end + + def test_execute_uses_from_a_gemdeps_with_no_lock + spec_fetcher do |fetcher| + fetcher.gem 'a', 2 + end + + File.open @gemdeps, "w" do |f| + f << "gem 'a'" + end + + @cmd.handle_options %w[--no-lock] + @cmd.options[:gemdeps] = @gemdeps + + use_ui @ui do + assert_raises Gem::MockGemUi::SystemExitException, @ui.error do + @cmd.execute + end + end + + assert_equal %w[], @cmd.installed_specs.map { |spec| spec.full_name } + + assert_match "Using a (2)", @ui.output + assert !File.exist?("#{@gemdeps}.lock") + end + + def test_execute_installs_from_a_gemdeps_with_conservative + spec_fetcher do |fetcher| + fetcher.gem 'a', 2 + fetcher.clear + fetcher.gem 'a', 1 + end + + File.open @gemdeps, "w" do |f| + f << "gem 'a'" + end + + @cmd.handle_options %w[--conservative] + @cmd.options[:gemdeps] = @gemdeps + + use_ui @ui do + assert_raises Gem::MockGemUi::SystemExitException, @ui.error do + @cmd.execute + end + end + + assert_equal %w[], @cmd.installed_specs.map { |spec| spec.full_name } + + assert_match "Using a (1)", @ui.output end def test_execute_installs_from_a_gemdeps @@ -885,6 +972,18 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal 'gem.deps.rb', @cmd.options[:gemdeps] end + def test_handle_options_suggest + assert @cmd.options[:suggest_alternate] + + @cmd.handle_options %w[--no-suggestions] + + refute @cmd.options[:suggest_alternate] + + @cmd.handle_options %w[--suggestions] + + assert @cmd.options[:suggest_alternate] + end + def test_handle_options_without @cmd.handle_options %w[--without test] diff --git a/test/rubygems/test_gem_commands_open_command.rb b/test/rubygems/test_gem_commands_open_command.rb new file mode 100644 index 0000000000..25f22c81b3 --- /dev/null +++ b/test/rubygems/test_gem_commands_open_command.rb @@ -0,0 +1,46 @@ +require 'rubygems/test_case' +require 'rubygems/commands/open_command' + +class TestGemCommandsOpenCommand < Gem::TestCase + + def setup + super + + @cmd = Gem::Commands::OpenCommand.new + end + + def gem name + spec = quick_gem name do |gem| + gem.files = %W[lib/#{name}.rb Rakefile] + end + write_file File.join(*%W[gems #{spec.full_name} lib #{name}.rb]) + write_file File.join(*%W[gems #{spec.full_name} Rakefile]) + end + + def test_execute + @cmd.options[:args] = %w[foo] + @cmd.options[:editor] = "#{Gem.ruby} -e0 --" + + gem 'foo' + + use_ui @ui do + @cmd.execute + end + + assert_equal "", @ui.error + end + + def test_execute_bad_gem + @cmd.options[:args] = %w[foo] + + assert_raises Gem::MockGemUi::TermError do + use_ui @ui do + @cmd.execute + end + end + + assert_match %r|Unable to find gem 'foo'|, @ui.output + assert_equal "", @ui.error + end + +end diff --git a/test/rubygems/test_gem_commands_setup_command.rb b/test/rubygems/test_gem_commands_setup_command.rb index 9c5ee7a5a8..2fe3384954 100644 --- a/test/rubygems/test_gem_commands_setup_command.rb +++ b/test/rubygems/test_gem_commands_setup_command.rb @@ -111,6 +111,12 @@ class TestGemCommandsSetupCommand < Gem::TestCase end expected = <<-EXPECTED +=== #{Gem::VERSION} / 2013-03-26 + +* Bug fixes: + * Fixed release note display for LANG=C when installing rubygems + * π is tasty + === 2.0.2 / 2013-03-06 * Bug fixes: @@ -118,6 +124,9 @@ class TestGemCommandsSetupCommand < Gem::TestCase EXPECTED + output = @ui.output + output.force_encoding Encoding::UTF_8 if Object.const_defined? :Encoding + assert_equal expected, @ui.output ensure capture_io do diff --git a/test/rubygems/test_gem_commands_uninstall_command.rb b/test/rubygems/test_gem_commands_uninstall_command.rb index 6f9ec104a5..4f045c5e3d 100644 --- a/test/rubygems/test_gem_commands_uninstall_command.rb +++ b/test/rubygems/test_gem_commands_uninstall_command.rb @@ -239,6 +239,42 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase assert_equal nil, @cmd.options[:install_dir] assert_equal true, @cmd.options[:user_install] assert_equal Gem::Requirement.default, @cmd.options[:version] + assert_equal false, @cmd.options[:vendor] + end + + def test_handle_options_vendor + use_ui @ui do + @cmd.handle_options %w[--vendor] + end + + assert @cmd.options[:vendor] + assert_equal Gem.vendor_dir, @cmd.options[:install_dir] + + assert_empty @ui.output + + expected = <<-EXPECTED +WARNING: Use your OS package manager to uninstall vendor gems + EXPECTED + + assert_match expected, @ui.error + end + + def test_handle_options_vendor_missing + orig_vendordir = RbConfig::CONFIG['vendordir'] + RbConfig::CONFIG.delete 'vendordir' + + e = assert_raises OptionParser::InvalidOption do + @cmd.handle_options %w[--vendor] + end + + assert_equal 'invalid option: --vendor your platform is not supported', + e.message + + refute @cmd.options[:vendor] + refute @cmd.options[:install_dir] + + ensure + RbConfig::CONFIG['vendordir'] = orig_vendordir end end diff --git a/test/rubygems/test_gem_commands_update_command.rb b/test/rubygems/test_gem_commands_update_command.rb index d259383ba2..2b3bb56855 100644 --- a/test/rubygems/test_gem_commands_update_command.rb +++ b/test/rubygems/test_gem_commands_update_command.rb @@ -52,6 +52,30 @@ class TestGemCommandsUpdateCommand < Gem::TestCase assert_empty out end + def test_execute_multiple + spec_fetcher do |fetcher| + fetcher.gem 'a', 2 + fetcher.gem 'ab', 2 + + fetcher.clear + + fetcher.spec 'a', 1 + fetcher.spec 'ab', 1 + end + + @cmd.options[:args] = %w[a] + + use_ui @ui do + @cmd.execute + end + + out = @ui.output.split "\n" + assert_equal "Updating installed gems", out.shift + assert_equal "Updating a", out.shift + assert_equal "Gems updated: a", out.shift + assert_empty out + end + def test_execute_system spec_fetcher do |fetcher| fetcher.gem 'rubygems-update', 9 do |s| s.files = %w[setup.rb] end @@ -266,6 +290,30 @@ class TestGemCommandsUpdateCommand < Gem::TestCase assert_empty out end + def test_execute_named_some_up_to_date + spec_fetcher do |fetcher| + fetcher.gem 'a', 2 + fetcher.clear + fetcher.spec 'a', 1 + + fetcher.spec 'b', 2 + end + + @cmd.options[:args] = %w[a b] + + use_ui @ui do + @cmd.execute + end + + out = @ui.output.split "\n" + assert_equal "Updating installed gems", out.shift + assert_equal "Updating a", out.shift + assert_equal "Gems updated: a", out.shift + assert_equal "Gems already up-to-date: b", out.shift + + assert_empty out + end + def test_execute_named_up_to_date spec_fetcher do |fetcher| fetcher.spec 'a', 2 @@ -437,6 +485,21 @@ class TestGemCommandsUpdateCommand < Gem::TestCase assert_equal expected, @cmd.options end + def test_update_gem_unresolved_dependency + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.gem 'a', 2 do |s| + s.add_dependency 'b', '>= 2' + end + + fetcher.spec 'b', 1 + end + + @cmd.update_gem 'a' + + assert_empty @cmd.updated + end + def test_update_rubygems_arguments @cmd.options[:system] = true diff --git a/test/rubygems/test_gem_commands_yank_command.rb b/test/rubygems/test_gem_commands_yank_command.rb index e627452243..469fd15bd9 100644 --- a/test/rubygems/test_gem_commands_yank_command.rb +++ b/test/rubygems/test_gem_commands_yank_command.rb @@ -18,7 +18,7 @@ class TestGemCommandsYankCommand < Gem::TestCase @cmd.handle_options %w[a --version 1.0 --platform x86-darwin -k KEY] assert_equal %w[a], @cmd.options[:args] - assert_equal 'KEY', @cmd.options[:key] + assert_equal :KEY, @cmd.options[:key] assert_nil @cmd.options[:platform] assert_equal req('= 1.0'), @cmd.options[:version] end @@ -61,7 +61,7 @@ class TestGemCommandsYankCommand < Gem::TestCase @cmd.options[:args] = %w[a] @cmd.options[:version] = req('= 1.0') - @cmd.options[:key] = 'KEY' + @cmd.options[:key] = :KEY use_ui @ui do @cmd.execute diff --git a/test/rubygems/test_gem_config_file.rb b/test/rubygems/test_gem_config_file.rb index e9cd33579d..5077f37359 100644 --- a/test/rubygems/test_gem_config_file.rb +++ b/test/rubygems/test_gem_config_file.rb @@ -234,16 +234,19 @@ if you believe they were disclosed to a third party. end def test_handle_arguments_debug - old_dollar_DEBUG = $DEBUG assert_equal false, $DEBUG args = %w[--debug] - @cfg.handle_arguments args + _, err = capture_io do + @cfg.handle_arguments args + end + + assert_match 'NOTE', err assert_equal true, $DEBUG ensure - $DEBUG = old_dollar_DEBUG + $DEBUG = false end def test_handle_arguments_override @@ -377,6 +380,9 @@ if you believe they were disclosed to a third party. fp.puts ":verbose: false" fp.puts ":sources:" fp.puts " - http://more-gems.example.com" + fp.puts ":ssl_verify_mode: 2" + fp.puts ":ssl_ca_cert: /nonexistent/ca_cert.pem" + fp.puts ":ssl_client_cert: /nonexistent/client_cert.pem" fp.puts "install: --wrappers" end @@ -399,6 +405,10 @@ if you believe they were disclosed to a third party. assert_equal false, @cfg.update_sources, 'update_sources' assert_equal false, @cfg.verbose, 'verbose' + assert_equal 2, @cfg.ssl_verify_mode + assert_equal '/nonexistent/ca_cert.pem', @cfg.ssl_ca_cert + assert_equal '/nonexistent/client_cert.pem', @cfg.ssl_client_cert + assert_equal '--wrappers --no-rdoc', @cfg[:install], 'install' assert_equal %w[http://even-more-gems.example.com], Gem.sources @@ -409,11 +419,13 @@ if you believe they were disclosed to a third party. fp.puts "some-non-yaml-hash-string" end - # Avoid writing stuff to output when running tests - Gem::ConfigFile.class_eval { def warn(args); end } + begin + verbose, $VERBOSE = $VERBOSE, nil - # This should not raise exception - util_config_file + util_config_file + ensure + $VERBOSE = verbose + end end def test_load_ssl_verify_mode_from_config diff --git a/test/rubygems/test_gem_dependency.rb b/test/rubygems/test_gem_dependency.rb index 7fc4dbbebf..c43ff0e03d 100644 --- a/test/rubygems/test_gem_dependency.rb +++ b/test/rubygems/test_gem_dependency.rb @@ -2,6 +2,7 @@ require 'rubygems/test_case' require 'rubygems/dependency' class TestGemDependency < Gem::TestCase + def test_initialize d = dep "pkg", "> 1.0" @@ -28,6 +29,16 @@ class TestGemDependency < Gem::TestCase assert_equal req(">= 0"), d.requirement end + def test_initialize_prerelease + d = dep 'd', '1.a' + + assert d.prerelease? + + d = dep 'd', '= 1.a' + + assert d.prerelease? + end + def test_initialize_type assert_equal :runtime, dep("pkg").type assert_equal :development, dep("pkg", [], :development).type @@ -115,6 +126,106 @@ class TestGemDependency < Gem::TestCase refute_equal dep("pkg", :development), dep("pkg", :runtime), "type" end + def test_match_eh_name_tuple + a_dep = dep 'a' + + a_tup = Gem::NameTuple.new 'a', 1 + b_tup = Gem::NameTuple.new 'b', 2 + c_tup = Gem::NameTuple.new 'c', '2.a' + + assert a_dep.match? a_tup + refute a_dep.match? b_tup + + b_dep = dep 'b', '>= 3' + + refute b_dep.match? b_tup + + c_dep = dep 'c', '>= 1' + + refute c_dep.match? c_tup + + c_dep = dep 'c' + + refute c_dep.match? c_tup + + c_dep = dep 'c', '2.a' + + assert c_dep.match? c_tup + end + + def test_match_eh_allow_prerelease + a_dep = dep 'a' + + a_tup = Gem::NameTuple.new 'a', 1 + b_tup = Gem::NameTuple.new 'b', 2 + c_tup = Gem::NameTuple.new 'c', '2.a' + + assert a_dep.match? a_tup, nil, true + refute a_dep.match? b_tup, nil, true + + b_dep = dep 'b', '>= 3' + + refute b_dep.match? b_tup, nil, true + + c_dep = dep 'c', '>= 1' + + assert c_dep.match? c_tup, nil, true + + c_dep = dep 'c' + + assert c_dep.match? c_tup, nil, true + + c_dep = dep 'c', '2.a' + + assert c_dep.match? c_tup, nil, true + end + + def test_match_eh_specification + a_dep = dep 'a' + + a_spec = util_spec 'a', 1 + b_spec = util_spec 'b', 2 + c_spec = util_spec 'c', '2.a' + + assert a_dep.match? a_spec + refute a_dep.match? b_spec + + b_dep = dep 'b', '>= 3' + + refute b_dep.match? b_spec + + c_dep = dep 'c', '>= 1' + + refute c_dep.match? c_spec + + c_dep = dep 'c' + + refute c_dep.match? c_spec + + c_dep = dep 'c', '2.a' + + assert c_dep.match? c_spec + end + + def test_matches_spec_eh + spec = util_spec 'b', 2 + + refute dep('a') .matches_spec?(spec), 'name mismatch' + assert dep('b') .matches_spec?(spec), 'name match' + refute dep('b', '= 1') .matches_spec?(spec), 'requirement mismatch' + assert dep('b', '~> 2').matches_spec?(spec), 'requirement match' + end + + def test_matches_spec_eh_prerelease + spec = util_spec 'b', '2.1.a' + + refute dep('a') .matches_spec?(spec), 'name mismatch' + assert dep('b') .matches_spec?(spec), 'name match' + refute dep('b', '= 1') .matches_spec?(spec), 'requirement mismatch' + assert dep('b', '~> 2') .matches_spec?(spec), 'requirement match' + assert dep('b', '~> 2.a').matches_spec?(spec), 'prerelease requirement' + end + def test_merge a1 = dep 'a', '~> 1.0' a2 = dep 'a', '= 1.0' @@ -182,6 +293,29 @@ class TestGemDependency < Gem::TestCase assert dep('a', '= 1').specific? end + def test_to_spec + util_spec 'a', '1' + a_2 = util_spec 'a', '2' + + a_dep = dep 'a', '>= 0' + + assert_equal a_2, a_dep.to_spec + end + + def test_to_spec_prerelease + a_1 = util_spec 'a', '1' + a_1_1_a = util_spec 'a', '1.1.a' + + a_dep = dep 'a', '>= 0' + + assert_equal a_1, a_dep.to_spec + + a_pre_dep = dep 'a', '>= 0' + a_pre_dep.prerelease = true + + assert_equal a_1_1_a, a_pre_dep.to_spec + end + def test_to_specs_suggests_other_versions a = util_spec 'a', '1.0', 'b' => '>= 1.0' @@ -197,7 +331,7 @@ class TestGemDependency < Gem::TestCase dep.to_specs end - assert_equal "Could not find 'a' (= 2.0) - did find: [a-1.0]", e.message + assert_match "Could not find 'a' (= 2.0) - did find: [a-1.0]", e.message end def test_to_specs_indicates_total_gem_set_size @@ -215,7 +349,7 @@ class TestGemDependency < Gem::TestCase dep.to_specs end - assert_equal "Could not find 'b' (= 2.0) among 1 total gem(s)", e.message + assert_match "Could not find 'b' (= 2.0) among 1 total gem(s)", e.message end diff --git a/test/rubygems/test_gem_dependency_installer.rb b/test/rubygems/test_gem_dependency_installer.rb index 352ebbb54f..8a0470761e 100644 --- a/test/rubygems/test_gem_dependency_installer.rb +++ b/test/rubygems/test_gem_dependency_installer.rb @@ -126,6 +126,27 @@ class TestGemDependencyInstaller < Gem::TestCase assert_equal [p1a], inst.installed_gems end + def test_install_prerelease_bug_990 + spec_fetcher do |fetcher| + fetcher.gem 'a', '1.b' do |s| + s.add_dependency 'b', '~> 1.a' + end + + fetcher.gem 'b', '1.b' do |s| + s.add_dependency 'c', '>= 1' + end + + fetcher.gem 'c', '1.1.b' + end + + dep = Gem::Dependency.new 'a' + + inst = Gem::DependencyInstaller.new :prerelease => true + inst.install dep + + assert_equal %w[a-1.b b-1.b c-1.1.b], Gem::Specification.map(&:full_name) + end + def test_install_when_only_prerelease p1a, gem = util_gem 'p', '1.a' @@ -138,7 +159,9 @@ class TestGemDependencyInstaller < Gem::TestCase dep = Gem::Dependency.new "p" inst = Gem::DependencyInstaller.new - inst.install dep + assert_raises Gem::UnsatisfiableDependencyError do + inst.install dep + end assert_equal %w[], Gem::Specification.map(&:full_name) assert_equal [], inst.installed_gems @@ -291,7 +314,7 @@ class TestGemDependencyInstaller < Gem::TestCase Gem.done_installing do |installer, specs| done_installing_ran = true - assert_equal inst, installer + refute_nil installer assert_equal [@a1, @b1], specs end @@ -455,6 +478,20 @@ class TestGemDependencyInstaller < Gem::TestCase assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } end + def test_install_local_prerelease + util_setup_gems + + FileUtils.mv @a1_pre_gem, @tempdir + inst = nil + + Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new :domain => :local + inst.install 'a-1.a.gem' + end + + assert_equal %w[a-1.a], inst.installed_gems.map { |s| s.full_name } + end + def test_install_local_dependency util_setup_gems @@ -538,6 +575,23 @@ class TestGemDependencyInstaller < Gem::TestCase assert_equal %w[a-1 e-1], inst.installed_gems.map { |s| s.full_name } end + def test_install_no_document + util_setup_gems + + done_installing_called = false + + Gem.done_installing do |dep_installer, specs| + done_installing_called = true + assert_empty dep_installer.document + end + + inst = Gem::DependencyInstaller.new :domain => :local, :document => [] + + inst.install @a1_gem + + assert done_installing_called + end + def test_install_env_shebang util_setup_gems @@ -682,7 +736,7 @@ class TestGemDependencyInstaller < Gem::TestCase inst.install 'b' end - expected = "Unable to resolve dependency: 'b (= 1)' requires 'a (>= 0)'" + expected = "Unable to resolve dependency: 'b (>= 0)' requires 'a (>= 0)'" assert_equal expected, e.message end @@ -796,10 +850,10 @@ class TestGemDependencyInstaller < Gem::TestCase s.platform = Gem::Platform.new %w[cpu other_platform 1] end - util_clear_gems - si = util_setup_spec_fetcher @a1, a2_o + util_clear_gems + @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml a1_data = nil @@ -1043,165 +1097,6 @@ class TestGemDependencyInstaller < Gem::TestCase assert_kind_of Gem::SourceFetchProblem, installer.errors.first end - def assert_resolve expected, *specs - util_clear_gems - util_setup_spec_fetcher(*specs) - Gem::Specification.reset - - inst = Gem::DependencyInstaller.new - inst.find_spec_by_name_and_version specs.first.name - inst.gather_dependencies - - actual = inst.gems_to_install.map { |s| s.full_name } - assert_equal expected, actual - end - - def assert_resolve_pre expected, *specs - util_clear_gems - - util_setup_spec_fetcher(*specs) - Gem::Specification.reset - - spec = specs.first - - inst = Gem::DependencyInstaller.new :prerelease => true - inst.find_spec_by_name_and_version spec.name, spec.version - inst.gather_dependencies - - actual = inst.gems_to_install.map { |s| s.full_name } - assert_equal expected, actual - end - - def test_gather_dependencies - util_setup_gems - util_reset_gems - - inst = Gem::DependencyInstaller.new - inst.find_spec_by_name_and_version 'b' - inst.gather_dependencies - - assert_equal %w[a-1 b-1], inst.gems_to_install.map { |s| s.full_name } - end - - ## - # [A1] depends on - # [B] > 0 (satisfied by 2.0) - # [B1] depends on - # [C] > 0 (satisfied by 1.0) - # [B2] depends on nothing! - # [C1] depends on nothing - - def test_gather_dependencies_dropped - a1, = util_spec 'a', '1', 'b' => nil - b1, = util_spec 'b', '1', 'c' => nil - b2, = util_spec 'b', '2' - c1, = util_spec 'c', '1' - - assert_resolve %w[b-2 a-1], a1, b1, b2, c1 - end - - ## - # [A] depends on - # [B] >= 1.0 (satisfied by 1.1) depends on - # [Z] - # [C] >= 1.0 depends on - # [B] = 1.0 - # - # and should backtrack to resolve using b-1.0, pruning Z from the - # resolve. - - def test_gather_dependencies_raggi_the_edgecase_generator - a, _ = util_spec 'a', '1.0', 'b' => '>= 1.0', 'c' => '>= 1.0' - b1, _ = util_spec 'b', '1.0' - b2, _ = util_spec 'b', '1.1', 'z' => '>= 1.0' - c, _ = util_spec 'c', '1.0', 'b' => '= 1.0' - - assert_resolve %w[b-1.0 c-1.0 a-1.0], a, b1, b2, c - end - - ## - # [A] depends on - # [B] >= 1.0 (satisfied by 2.0) - # [C] = 1.0 depends on - # [B] ~> 1.0 - # - # and should resolve using b-1.0 - - def test_gather_dependencies_over - a, _ = util_spec 'a', '1.0', 'b' => '>= 1.0', 'c' => '= 1.0' - b1, _ = util_spec 'b', '1.0' - b2, _ = util_spec 'b', '2.0' - c, _ = util_spec 'c', '1.0', 'b' => '~> 1.0' - - assert_resolve %w[b-1.0 c-1.0 a-1.0], a, b1, b2, c - end - - ## - # [A] depends on - # [B] ~> 1.0 (satisfied by 1.1) - # [C] = 1.0 depends on - # [B] = 1.0 - # - # and should resolve using b-1.0 - # - # TODO: this is not under, but over... under would require depth - # first resolve through a dependency that is later pruned. - - def test_gather_dependencies_under - a, _ = util_spec 'a', '1.0', 'b' => '~> 1.0', 'c' => '= 1.0' - b10, _ = util_spec 'b', '1.0' - b11, _ = util_spec 'b', '1.1' - c, _ = util_spec 'c', '1.0', 'b' => '= 1.0' - - assert_resolve %w[b-1.0 c-1.0 a-1.0], a, b10, b11, c - end - - # under - # - # [A] depends on - # [B] ~> 1.0 (satisfied by 1.0) - # [C] = 1.0 depends on - # [B] = 2.0 - - def test_gather_dependencies_divergent - a, _ = util_spec 'a', '1.0', 'b' => '~> 1.0', 'c' => '= 1.0' - b1, _ = util_spec 'b', '1.0' - b2, _ = util_spec 'b', '2.0' - c, _ = util_spec 'c', '1.0', 'b' => '= 2.0' - - assert_raises Gem::DependencyError do - assert_resolve :ignored, a, b1, b2, c - end - end - - def test_gather_dependencies_platform_alternate - util_setup_wxyz - util_set_arch 'cpu-my_platform1' - - assert_resolve %w[x-1-cpu-my_platform-1 w-1], @w1, @x1_m - end - - def test_gather_dependencies_platform_bump - util_setup_wxyz - - assert_resolve %w[y-1 z-1], @z1, @y1 - end - - def test_gather_dependencies_prerelease - util_setup_gems - util_setup_c1_pre - - assert_resolve_pre %w[a-1.a b-1 c-1.a], @c1_pre, @a1_pre, @b1 - end - - def test_gather_dependencies_old_required - util_setup_d - e1, = util_spec 'e', '1', 'd' => '= 1' - util_clear_gems - - assert_resolve %w[d-1 e-1], e1, @d1, @d2 - end - def test_resolve_dependencies util_setup_gems @@ -1232,6 +1127,21 @@ class TestGemDependencyInstaller < Gem::TestCase assert_equal %w[b-1], requests end + def test_resolve_dependencies_local + util_setup_gems + + @a2, @a2_gem = util_gem 'a', '2' + FileUtils.mv @a1_gem, @tempdir + FileUtils.mv @a2_gem, @tempdir + + inst = Gem::DependencyInstaller.new + request_set = inst.resolve_dependencies 'a-1.gem', req('>= 0') + + requests = request_set.sorted_requests.map { |req| req.full_name } + + assert_equal %w[a-1], requests + end + def util_write_a1_bin write_file File.join('gems', 'a-1', 'bin', 'a_bin') do |fp| fp.puts "#!/usr/bin/ruby" diff --git a/test/rubygems/test_gem_ext_builder.rb b/test/rubygems/test_gem_ext_builder.rb index eb86f53872..5607096a0b 100644 --- a/test/rubygems/test_gem_ext_builder.rb +++ b/test/rubygems/test_gem_ext_builder.rb @@ -132,6 +132,17 @@ install: assert_path_exists File.join @spec.gem_dir, 'lib', 'a', 'b.rb' end + def test_build_extensions_with_gemhome_with_space + new_gemhome = File.join @tempdir, 'gem home' + File.rename(@gemhome, new_gemhome) + @gemhome = new_gemhome + Gem.use_paths(@gemhome) + @spec = util_spec 'a' + @builder = Gem::Ext::Builder.new @spec, '' + + test_build_extensions + end + def test_build_extensions_install_ext_only class << Gem alias orig_install_extension_in_lib install_extension_in_lib @@ -226,7 +237,7 @@ install: gem_make_out = File.join @spec.extension_dir, 'gem_make.out' - assert_match %r%#{Regexp.escape Gem.ruby} extconf\.rb%, + assert_match %r%#{Regexp.escape Gem.ruby}.* extconf\.rb%, File.read(gem_make_out) assert_match %r%: No such file%, File.read(gem_make_out) diff --git a/test/rubygems/test_gem_ext_ext_conf_builder.rb b/test/rubygems/test_gem_ext_ext_conf_builder.rb index 367c933a4c..f2f467e871 100644 --- a/test/rubygems/test_gem_ext_ext_conf_builder.rb +++ b/test/rubygems/test_gem_ext_ext_conf_builder.rb @@ -33,7 +33,7 @@ class TestGemExtExtConfBuilder < Gem::TestCase assert_same result, output end - assert_match(/^#{Gem.ruby} extconf.rb/, output[0]) + assert_match(/^#{Gem.ruby}.* extconf.rb/, output[0]) assert_equal "creating Makefile\n", output[1] assert_contains_make_command 'clean', output[2] assert_contains_make_command '', output[4] @@ -106,7 +106,7 @@ class TestGemExtExtConfBuilder < Gem::TestCase assert_equal 'extconf failed, exit code 1', error.message - assert_equal("#{Gem.ruby} extconf.rb", output[0]) + assert_match(/^#{Gem.ruby}.* extconf.rb/, output[0]) assert_path_exists File.join @dest_path, 'mkmf.log' end diff --git a/test/rubygems/test_gem_gemcutter_utilities.rb b/test/rubygems/test_gem_gemcutter_utilities.rb index d70ac35beb..c117c8f826 100644 --- a/test/rubygems/test_gem_gemcutter_utilities.rb +++ b/test/rubygems/test_gem_gemcutter_utilities.rb @@ -148,6 +148,15 @@ class TestGemGemcutterUtilities < Gem::TestCase assert_equal "", @sign_in_ui.output end + def test_sign_in_skips_with_key_override + api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' + Gem.configuration.api_keys[:KEY] = 'other' + @cmd.options[:key] = :KEY + util_sign_in [api_key, 200, 'OK'] + + assert_equal "", @sign_in_ui.output + end + def test_sign_in_with_other_credentials_doesnt_overwrite_other_keys api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' other_api_key = 'f46dbb18bb6a9c97cdc61b5b85c186a17403cdcbf' diff --git a/test/rubygems/test_gem_impossible_dependencies_error.rb b/test/rubygems/test_gem_impossible_dependencies_error.rb index 577ee580ec..9c9825ca9a 100644 --- a/test/rubygems/test_gem_impossible_dependencies_error.rb +++ b/test/rubygems/test_gem_impossible_dependencies_error.rb @@ -28,14 +28,30 @@ class TestGemImpossibleDependenciesError < Gem::TestCase expected = <<-EXPECTED rye-0.9.8 requires net-ssh (>= 2.0.13) but it conflicted: - Activated net-ssh-2.6.5 via: - net-ssh-2.6.5 (>= 2.0.13), rye-0.9.8 (= 0.9.8) - instead of (~> 2.2.2) via: - net-ssh-2.6.5 (>= 2.0.13), rye-0.9.8 (= 0.9.8) - Activated net-ssh-2.2.2 via: - net-ssh-2.2.2 (>= 2.0.13), rye-0.9.8 (= 0.9.8) - instead of (>= 2.6.5) via: - net-ssh-2.2.2 (>= 2.0.13), rye-0.9.8 (= 0.9.8) + Activated net-ssh-2.6.5 + which does not match conflicting dependency (~> 2.2.2) + + Conflicting dependency chains: + rye (= 0.9.8), 0.9.8 activated, depends on + net-ssh (>= 2.0.13), 2.6.5 activated + + versus: + rye (= 0.9.8), 0.9.8 activated, depends on + net-ssh (>= 2.0.13), 2.6.5 activated, depends on + net-ssh (~> 2.2.2) + + Activated net-ssh-2.2.2 + which does not match conflicting dependency (>= 2.6.5) + + Conflicting dependency chains: + rye (= 0.9.8), 0.9.8 activated, depends on + net-ssh (>= 2.0.13), 2.2.2 activated + + versus: + rye (= 0.9.8), 0.9.8 activated, depends on + net-ssh (>= 2.0.13), 2.2.2 activated, depends on + net-ssh (>= 2.6.5) + EXPECTED assert_equal expected, error.message diff --git a/test/rubygems/test_gem_install_update_options.rb b/test/rubygems/test_gem_install_update_options.rb index 3f63896999..de09d7a171 100644 --- a/test/rubygems/test_gem_install_update_options.rb +++ b/test/rubygems/test_gem_install_update_options.rb @@ -17,6 +17,7 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase def test_add_install_update_options args = %w[ --document + --build-root build_root --format-exec --ignore-dependencies --rdoc @@ -25,6 +26,7 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase -f -i /install_to -w + --vendor ] args.concat %w[-P HighSecurity] if defined?(OpenSSL::SSL) @@ -32,6 +34,12 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase assert @cmd.handles?(args) end + def test_build_root + @cmd.handle_options %w[--build-root build_root] + + assert_equal File.expand_path('build_root'), @cmd.options[:build_root] + end + def test_doc @cmd.handle_options %w[--doc] @@ -147,4 +155,30 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase ensure FileUtils.chmod 0755, @gemhome end + + def test_vendor + @cmd.handle_options %w[--vendor] + + assert @cmd.options[:vendor] + assert_equal Gem.vendor_dir, @cmd.options[:install_dir] + end + + def test_vendor_missing + orig_vendordir = RbConfig::CONFIG['vendordir'] + RbConfig::CONFIG.delete 'vendordir' + + e = assert_raises OptionParser::InvalidOption do + @cmd.handle_options %w[--vendor] + end + + assert_equal 'invalid option: --vendor your platform is not supported', + e.message + + refute @cmd.options[:vendor] + refute @cmd.options[:install_dir] + + ensure + RbConfig::CONFIG['vendordir'] = orig_vendordir + end + end diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb index eff62ab28b..6f8012feb8 100644 --- a/test/rubygems/test_gem_installer.rb +++ b/test/rubygems/test_gem_installer.rb @@ -188,6 +188,56 @@ gem 'other', version assert_match %r|generated by RubyGems|, wrapper end unless Gem.win_platform? + def test_check_that_user_bin_dir_is_in_path + bin_dir = @installer.bin_dir + + if Gem.win_platform? + bin_dir = bin_dir.downcase.gsub(File::SEPARATOR, File::ALT_SEPARATOR) + end + + orig_PATH, ENV['PATH'] = + ENV['PATH'], [ENV['PATH'], bin_dir].join(File::PATH_SEPARATOR) + + use_ui @ui do + @installer.check_that_user_bin_dir_is_in_path + end + + assert_empty @ui.error + ensure + ENV['PATH'] = orig_PATH + end + + def test_check_that_user_bin_dir_is_in_path_tilde + skip "Tilde is PATH is not supported under MS Windows" if win_platform? + + orig_PATH, ENV['PATH'] = + ENV['PATH'], [ENV['PATH'], '~/bin'].join(File::PATH_SEPARATOR) + + @installer.bin_dir.replace File.join @userhome, 'bin' + + use_ui @ui do + @installer.check_that_user_bin_dir_is_in_path + end + + assert_empty @ui.error + ensure + ENV['PATH'] = orig_PATH unless win_platform? + end + + def test_check_that_user_bin_dir_is_in_path_not_in_path + use_ui @ui do + @installer.check_that_user_bin_dir_is_in_path + end + + expected = @installer.bin_dir + + if Gem.win_platform? then + expected = expected.downcase.gsub(File::SEPARATOR, File::ALT_SEPARATOR) + end + + assert_match expected, @ui.error + end + def test_ensure_dependency util_spec 'a' @@ -574,6 +624,9 @@ gem 'other', version def test_generate_bin_symlink_win32 old_win_platform = Gem.win_platform? Gem.win_platform = true + old_alt_separator = File::ALT_SEPARATOR + File.__send__(:remove_const, :ALT_SEPARATOR) + File.const_set(:ALT_SEPARATOR, '\\') @installer.wrappers = false util_make_exec @installer.gem_dir = util_gem_dir @@ -592,6 +645,8 @@ gem 'other', version wrapper = File.read installed_exec assert_match(/generated by RubyGems/, wrapper) ensure + File.__send__(:remove_const, :ALT_SEPARATOR) + File.const_set(:ALT_SEPARATOR, old_alt_separator) Gem.win_platform = old_win_platform end @@ -1053,7 +1108,7 @@ gem 'other', version path = File.join(@gemhome, 'gems', 'a-2', 'gem_make.out') - if File.exists?(path) + if File.exist?(path) puts File.read(path) puts '-' * 78 end @@ -1071,6 +1126,16 @@ gem 'other', version refute @installer.installation_satisfies_dependency?(dep) end + def test_installation_satisfies_dependency_eh_development + @installer.options[:development] = true + @installer.options[:dev_shallow] = true + + util_spec 'a' + + dep = Gem::Dependency.new 'a', :development + assert @installer.installation_satisfies_dependency?(dep) + end + def test_pre_install_checks_dependencies @spec.add_dependency 'b', '> 5' util_setup_gem @@ -1157,6 +1222,22 @@ gem 'other', version assert_equal "#!#{Gem.ruby}", shebang end + def test_process_options + assert_nil @installer.build_root + assert_equal File.join(@gemhome, 'bin'), @installer.bin_dir + assert_equal @gemhome, @installer.gem_home + end + + def test_process_options_build_root + build_root = File.join @tempdir, 'build_root' + + @installer = Gem::Installer.new @gem, :build_root => build_root + + assert_equal Pathname(build_root), @installer.build_root + assert_equal File.join(build_root, @gemhome, 'bin'), @installer.bin_dir + assert_equal File.join(build_root, @gemhome), @installer.gem_home + end + def test_shebang_arguments util_make_exec @spec, "#!/usr/bin/ruby -ws" diff --git a/test/rubygems/test_gem_local_remote_options.rb b/test/rubygems/test_gem_local_remote_options.rb index 2b4ca806da..1a0338bfe1 100644 --- a/test/rubygems/test_gem_local_remote_options.rb +++ b/test/rubygems/test_gem_local_remote_options.rb @@ -90,6 +90,19 @@ class TestGemLocalRemoteOptions < Gem::TestCase assert_equal original_sources, Gem.sources end + def test_short_source_option + @cmd.add_source_option + + original_sources = Gem.sources.dup + + source = URI.parse 'http://more-gems.example.com/' + @cmd.handle_options %W[-s #{source}] + + original_sources << source + + assert_equal original_sources, Gem.sources + end + def test_update_sources_option @cmd.add_update_sources_option diff --git a/test/rubygems/test_gem_name_tuple.rb b/test/rubygems/test_gem_name_tuple.rb index 170a9c2ae0..38320f7590 100644 --- a/test/rubygems/test_gem_name_tuple.rb +++ b/test/rubygems/test_gem_name_tuple.rb @@ -33,5 +33,12 @@ class TestGemNameTuple < Gem::TestCase assert_equal "a-0.gemspec", n.spec_name end + def test_spaceship + a = Gem::NameTuple.new 'a', Gem::Version.new(0), Gem::Platform::RUBY + a_p = Gem::NameTuple.new 'a', Gem::Version.new(0), Gem::Platform.local + + assert_equal 1, a_p.<=>(a) + end + end diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb index 1e592fcb05..128dcdb1c4 100644 --- a/test/rubygems/test_gem_package.rb +++ b/test/rubygems/test_gem_package.rb @@ -638,7 +638,7 @@ class TestGemPackage < Gem::Package::TarTestCase e.message io end - tf.close! + tf.close! if tf.respond_to? :close! end def test_verify_empty @@ -780,6 +780,23 @@ class TestGemPackage < Gem::Package::TarTestCase assert_equal @spec, package.spec end + def test_spec_from_io + # This functionality is used by rubygems.org to extract spec data from an + # uploaded gem before it is written to storage. + io = StringIO.new Gem.read_binary @gem + package = Gem::Package.new io + + assert_equal @spec, package.spec + end + + def test_spec_from_io_raises_gem_error_for_io_not_at_start + io = StringIO.new Gem.read_binary @gem + io.read(1) + assert_raises(Gem::Package::Error) do + Gem::Package.new io + end + end + def util_tar tar_io = StringIO.new diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb index ea78d07e0b..3769911522 100644 --- a/test/rubygems/test_gem_remote_fetcher.rb +++ b/test/rubygems/test_gem_remote_fetcher.rb @@ -244,6 +244,36 @@ gems: assert File.exist?(a1_cache_gem) end + def test_download_with_auth + a1_data = nil + File.open @a1_gem, 'rb' do |fp| + a1_data = fp.read + end + + fetcher = util_fuck_with_fetcher a1_data + + a1_cache_gem = @a1.cache_file + assert_equal a1_cache_gem, fetcher.download(@a1, 'http://user:[email protected]') + assert_equal("http://user:[email protected]/gems/a-1.gem", + fetcher.instance_variable_get(:@test_arg).to_s) + assert File.exist?(a1_cache_gem) + end + + def test_download_with_encoded_auth + a1_data = nil + File.open @a1_gem, 'rb' do |fp| + a1_data = fp.read + end + + fetcher = util_fuck_with_fetcher a1_data + + a1_cache_gem = @a1.cache_file + assert_equal a1_cache_gem, fetcher.download(@a1, 'http://user:%25pas%[email protected]') + assert_equal("http://user:%25pas%[email protected]/gems/a-1.gem", + fetcher.instance_variable_get(:@test_arg).to_s) + assert File.exist?(a1_cache_gem) + end + def test_download_cached FileUtils.mv @a1_gem, @cache_dir @@ -557,6 +587,40 @@ gems: assert_equal "too many redirects (#{url})", e.message end + def test_fetch_s3 + fetcher = Gem::RemoteFetcher.new nil + url = 's3://testuser:testpass@my-bucket/gems/specs.4.8.gz' + $fetched_uri = nil + + def fetcher.request(uri, request_class, last_modified = nil) + $fetched_uri = uri + res = Net::HTTPOK.new nil, 200, nil + def res.body() 'success' end + res + end + + def fetcher.s3_expiration + 1395098371 + end + + data = fetcher.fetch_s3 URI.parse(url) + + assert_equal 'https://my-bucket.s3.amazonaws.com/gems/specs.4.8.gz?AWSAccessKeyId=testuser&Expires=1395098371&Signature=eUTr7NkpZEet%2BJySE%2BfH6qukroI%3D', $fetched_uri.to_s + assert_equal 'success', data + ensure + $fetched_uri = nil + end + + def test_fetch_s3_no_creds + fetcher = Gem::RemoteFetcher.new nil + url = 's3://my-bucket/gems/specs.4.8.gz' + e = assert_raises Gem::RemoteFetcher::FetchError do + fetcher.fetch_s3 URI.parse(url) + end + + assert_match "credentials needed", e.message + end + def test_observe_no_proxy_env_single_host use_ui @ui do ENV["http_proxy"] = @proxy_uri @@ -711,6 +775,8 @@ gems: @proxy_server ||= start_server(PROXY_DATA) @enable_yaml = true @enable_zip = false + @ssl_server = nil + @ssl_server_thread = nil end def stop_servers diff --git a/test/rubygems/test_gem_request.rb b/test/rubygems/test_gem_request.rb index bcbbcf1f99..c45d5d86fd 100644 --- a/test/rubygems/test_gem_request.rb +++ b/test/rubygems/test_gem_request.rb @@ -11,6 +11,10 @@ class TestGemRequest < Gem::TestCase PUBLIC_CERT_FILE = cert_path 'public' SSL_CERT = load_cert 'ssl' + def make_request uri, request_class, last_modified, proxy + Gem::Request.create_with_proxy uri, request_class, last_modified, proxy + end + def setup @proxies = %w[http_proxy HTTP_PROXY http_proxy_user HTTP_PROXY_USER http_proxy_pass HTTP_PROXY_PASS no_proxy NO_PROXY] @old_proxies = @proxies.map {|k| ENV[k] } @@ -21,7 +25,7 @@ class TestGemRequest < Gem::TestCase @proxy_uri = "http://localhost:1234" @uri = URI('http://example') - @request = Gem::Request.new @uri, nil, nil, nil + @request = make_request @uri, nil, nil, nil end def teardown @@ -33,7 +37,7 @@ class TestGemRequest < Gem::TestCase def test_initialize_proxy proxy_uri = 'http://proxy.example.com' - request = Gem::Request.new @uri, nil, nil, proxy_uri + request = make_request @uri, nil, nil, proxy_uri assert_equal proxy_uri, request.proxy_uri.to_s end @@ -41,7 +45,7 @@ class TestGemRequest < Gem::TestCase def test_initialize_proxy_URI proxy_uri = 'http://proxy.example.com' - request = Gem::Request.new @uri, nil, nil, URI(proxy_uri) + request = make_request @uri, nil, nil, URI(proxy_uri) assert_equal proxy_uri, request.proxy_uri.to_s end @@ -51,7 +55,7 @@ class TestGemRequest < Gem::TestCase ENV['http_proxy_user'] = 'foo' ENV['http_proxy_pass'] = 'bar' - request = Gem::Request.new @uri, nil, nil, nil + request = make_request @uri, nil, nil, nil proxy = request.proxy_uri @@ -62,7 +66,7 @@ class TestGemRequest < Gem::TestCase def test_initialize_proxy_ENV_https ENV['https_proxy'] = @proxy_uri - request = Gem::Request.new URI('https://example'), nil, nil, nil + request = make_request URI('https://example'), nil, nil, nil proxy = request.proxy_uri @@ -72,13 +76,13 @@ class TestGemRequest < Gem::TestCase def test_configure_connection_for_https connection = Net::HTTP.new 'localhost', 443 - request = Gem::Request.new URI('https://example'), nil, nil, nil - - def request.add_rubygems_trusted_certs store - store.add_cert TestGemRequest::PUBLIC_CERT - end + request = Class.new(Gem::Request) { + def self.get_cert_files + [TestGemRequest::PUBLIC_CERT_FILE] + end + }.create_with_proxy URI('https://example'), nil, nil, nil - request.configure_connection_for_https connection + Gem::Request.configure_connection_for_https connection, request.cert_files cert_store = connection.cert_store @@ -91,13 +95,13 @@ class TestGemRequest < Gem::TestCase connection = Net::HTTP.new 'localhost', 443 - request = Gem::Request.new URI('https://example'), nil, nil, nil + request = Class.new(Gem::Request) { + def self.get_cert_files + [TestGemRequest::PUBLIC_CERT_FILE] + end + }.create_with_proxy URI('https://example'), nil, nil, nil - def request.add_rubygems_trusted_certs store - store.add_cert TestGemRequest::PUBLIC_CERT - end - - request.configure_connection_for_https connection + Gem::Request.configure_connection_for_https connection, request.cert_files cert_store = connection.cert_store @@ -109,16 +113,18 @@ class TestGemRequest < Gem::TestCase def test_get_proxy_from_env_fallback ENV['http_proxy'] = @proxy_uri - - proxy = @request.get_proxy_from_env 'https' + request = make_request @uri, nil, nil, nil + proxy = request.proxy_uri assert_equal URI(@proxy_uri), proxy end def test_get_proxy_from_env_https ENV['https_proxy'] = @proxy_uri + uri = URI('https://example') + request = make_request uri, nil, nil, nil - proxy = @request.get_proxy_from_env 'https' + proxy = request.proxy_uri assert_equal URI(@proxy_uri), proxy end @@ -127,8 +133,9 @@ class TestGemRequest < Gem::TestCase ENV['http_proxy'] = @proxy_uri ENV['http_proxy_user'] = 'foo\user' ENV['http_proxy_pass'] = 'my bar' + request = make_request @uri, nil, nil, nil - proxy = @request.get_proxy_from_env + proxy = request.proxy_uri assert_equal 'foo\user', Gem::UriFormatter.new(proxy.user).unescape assert_equal 'my bar', Gem::UriFormatter.new(proxy.password).unescape @@ -138,8 +145,9 @@ class TestGemRequest < Gem::TestCase ENV['http_proxy'] = @proxy_uri ENV['http_proxy_user'] = 'foo@user' ENV['http_proxy_pass'] = 'my@bar' + request = make_request @uri, nil, nil, nil - proxy = @request.get_proxy_from_env + proxy = request.proxy_uri assert_equal 'foo%40user', proxy.user assert_equal 'my%40bar', proxy.password @@ -147,23 +155,26 @@ class TestGemRequest < Gem::TestCase def test_get_proxy_from_env_normalize ENV['HTTP_PROXY'] = 'fakeurl:12345' + request = make_request @uri, nil, nil, nil - assert_equal 'http://fakeurl:12345', @request.get_proxy_from_env.to_s + assert_equal 'http://fakeurl:12345', request.proxy_uri.to_s end def test_get_proxy_from_env_empty ENV['HTTP_PROXY'] = '' ENV.delete 'http_proxy' + request = make_request @uri, nil, nil, nil - assert_nil @request.get_proxy_from_env + assert_nil request.proxy_uri end def test_fetch uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}" - @request = Gem::Request.new(uri, Net::HTTP::Get, nil, nil) - util_stub_connection_for :body => :junk, :code => 200 + response = util_stub_net_http(:body => :junk, :code => 200) do + @request = make_request(uri, Net::HTTP::Get, nil, nil) - response = @request.fetch + @request.fetch + end assert_equal 200, response.code assert_equal :junk, response.body @@ -171,34 +182,34 @@ class TestGemRequest < Gem::TestCase def test_fetch_basic_auth uri = URI.parse "https://user:[email protected]/specs.#{Gem.marshal_version}" - @request = Gem::Request.new(uri, Net::HTTP::Get, nil, nil) - conn = util_stub_connection_for :body => :junk, :code => 200 - - @request.fetch + conn = util_stub_net_http(:body => :junk, :code => 200) do |c| + @request = make_request(uri, Net::HTTP::Get, nil, nil) + @request.fetch + c + end auth_header = conn.payload['Authorization'] - assert_equal "Basic #{Base64.encode64('user:pass')}".strip, auth_header end def test_fetch_basic_auth_encoded uri = URI.parse "https://user:%7BDEScede%[email protected]/specs.#{Gem.marshal_version}" - @request = Gem::Request.new(uri, Net::HTTP::Get, nil, nil) - conn = util_stub_connection_for :body => :junk, :code => 200 - - @request.fetch + conn = util_stub_net_http(:body => :junk, :code => 200) do |c| + @request = make_request(uri, Net::HTTP::Get, nil, nil) + @request.fetch + c + end auth_header = conn.payload['Authorization'] - assert_equal "Basic #{Base64.encode64('user:{DEScede}pass')}".strip, auth_header end def test_fetch_head uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}" - @request = Gem::Request.new(uri, Net::HTTP::Get, nil, nil) - util_stub_connection_for :body => '', :code => 200 - - response = @request.fetch + response = util_stub_net_http(:body => '', :code => 200) do |conn| + @request = make_request(uri, Net::HTTP::Get, nil, nil) + @request.fetch + end assert_equal 200, response.code assert_equal '', response.body @@ -207,10 +218,10 @@ class TestGemRequest < Gem::TestCase def test_fetch_unmodified uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}" t = Time.utc(2013, 1, 2, 3, 4, 5) - @request = Gem::Request.new(uri, Net::HTTP::Get, t, nil) - conn = util_stub_connection_for :body => '', :code => 304 - - response = @request.fetch + conn, response = util_stub_net_http(:body => '', :code => 304) do |c| + @request = make_request(uri, Net::HTTP::Get, t, nil) + [c, @request.fetch] + end assert_equal 304, response.code assert_equal '', response.body @@ -221,7 +232,7 @@ class TestGemRequest < Gem::TestCase end def test_user_agent - ua = Gem::Request.new(@uri, nil, nil, nil).user_agent + ua = make_request(@uri, nil, nil, nil).user_agent assert_match %r%^RubyGems/\S+ \S+ Ruby/\S+ \(.*?\)%, ua assert_match %r%RubyGems/#{Regexp.escape Gem::VERSION}%, ua @@ -236,7 +247,7 @@ class TestGemRequest < Gem::TestCase Object.send :remove_const, :RUBY_ENGINE if defined?(RUBY_ENGINE) Object.send :const_set, :RUBY_ENGINE, 'vroom' - ua = Gem::Request.new(@uri, nil, nil, nil).user_agent + ua = make_request(@uri, nil, nil, nil).user_agent assert_match %r%\) vroom%, ua ensure @@ -249,7 +260,7 @@ class TestGemRequest < Gem::TestCase Object.send :remove_const, :RUBY_ENGINE if defined?(RUBY_ENGINE) Object.send :const_set, :RUBY_ENGINE, 'ruby' - ua = Gem::Request.new(@uri, nil, nil, nil).user_agent + ua = make_request(@uri, nil, nil, nil).user_agent assert_match %r%\)%, ua ensure @@ -262,7 +273,7 @@ class TestGemRequest < Gem::TestCase Object.send :remove_const, :RUBY_PATCHLEVEL Object.send :const_set, :RUBY_PATCHLEVEL, 5 - ua = Gem::Request.new(@uri, nil, nil, nil).user_agent + ua = make_request(@uri, nil, nil, nil).user_agent assert_match %r% patchlevel 5\)%, ua ensure @@ -277,7 +288,7 @@ class TestGemRequest < Gem::TestCase Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION) Object.send :const_set, :RUBY_REVISION, 6 - ua = Gem::Request.new(@uri, nil, nil, nil).user_agent + ua = make_request(@uri, nil, nil, nil).user_agent assert_match %r% revision 6\)%, ua assert_match %r%Ruby/#{Regexp.escape RUBY_VERSION}dev%, ua @@ -292,7 +303,7 @@ class TestGemRequest < Gem::TestCase Object.send :const_set, :RUBY_PATCHLEVEL, -1 Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION) - ua = Gem::Request.new(@uri, nil, nil, nil).user_agent + ua = make_request(@uri, nil, nil, nil).user_agent assert_match %r%\(#{Regexp.escape RUBY_RELEASE_DATE}\)%, ua ensure @@ -318,21 +329,24 @@ class TestGemRequest < Gem::TestCase @orig_RUBY_REVISION = RUBY_REVISION if defined? RUBY_REVISION end - def util_stub_connection_for hash - def @request.connection= conn - @conn = conn - end - - def @request.connection_for uri - @conn - end - - @request.connection = Conn.new OpenStruct.new(hash) + def util_stub_net_http hash + old_client = Gem::Request::ConnectionPools.client + conn = Conn.new OpenStruct.new(hash) + Gem::Request::ConnectionPools.client = conn + yield conn + ensure + Gem::Request::ConnectionPools.client = old_client end class Conn attr_accessor :payload + def new *args; self; end + def use_ssl=(bool); end + def verify_mode=(setting); end + def cert_store=(setting); end + def start; end + def initialize(response) @response = response self.payload = nil diff --git a/test/rubygems/test_gem_request_connection_pools.rb b/test/rubygems/test_gem_request_connection_pools.rb new file mode 100644 index 0000000000..1cf6b27979 --- /dev/null +++ b/test/rubygems/test_gem_request_connection_pools.rb @@ -0,0 +1,120 @@ +require 'rubygems/test_case' +require 'rubygems/request' +require 'timeout' + +class TestGemRequestConnectionPool < Gem::TestCase + class FakeHttp + def initialize *args + end + + def start + end + end + + def setup + super + @old_client = Gem::Request::ConnectionPools.client + Gem::Request::ConnectionPools.client = FakeHttp + + @proxy = URI 'http://proxy.example' + end + + def teardown + Gem::Request::ConnectionPools.client = @old_client + super + end + + def test_checkout_same_connection + uri = URI.parse('http://example/some_endpoint') + + pools = Gem::Request::ConnectionPools.new nil, [] + pool = pools.pool_for uri + conn = pool.checkout + pool.checkin conn + + assert_equal conn, pool.checkout + end + + def test_to_proxy_eh + pools = Gem::Request::ConnectionPools.new nil, [] + + env_no_proxy = %w[ + 1.no-proxy.example + 2.no-proxy.example + ] + + no_proxy = pools.send :no_proxy?, '2.no-proxy.example', env_no_proxy + + assert no_proxy, 'match' + + no_proxy = pools.send :no_proxy?, 'proxy.example', env_no_proxy + + refute no_proxy, 'mismatch' + end + + def test_to_proxy_eh_wildcard + pools = Gem::Request::ConnectionPools.new nil, [] + + env_no_proxy = %w[ + .no-proxy.example + ] + + no_proxy = pools.send :no_proxy?, '2.no-proxy.example', env_no_proxy + + assert no_proxy, 'wildcard matching subdomain' + + no_proxy = pools.send :no_proxy?, 'no-proxy.example', env_no_proxy + + assert no_proxy, 'wildcard matching dotless domain' + + no_proxy = pools.send :no_proxy?, 'proxy.example', env_no_proxy + + refute no_proxy, 'wildcard mismatch' + end + + def test_net_http_args + pools = Gem::Request::ConnectionPools.new nil, [] + + net_http_args = pools.send :net_http_args, URI('http://example'), nil + + assert_equal ['example', 80], net_http_args + end + + def test_net_http_args_proxy + pools = Gem::Request::ConnectionPools.new nil, [] + + net_http_args = pools.send :net_http_args, URI('http://example'), @proxy + + assert_equal ['example', 80, 'proxy.example', 80, nil, nil], net_http_args + end + + def test_net_http_args_no_proxy + orig_no_proxy, ENV['no_proxy'] = ENV['no_proxy'], 'example' + + pools = Gem::Request::ConnectionPools.new nil, [] + + net_http_args = pools.send :net_http_args, URI('http://example'), @proxy + + assert_equal ['example', 80, nil, nil], net_http_args + + ensure + ENV['no_proxy'] = orig_no_proxy + end + + def test_thread_waits_for_connection + uri = URI.parse('http://example/some_endpoint') + pools = Gem::Request::ConnectionPools.new nil, [] + pool = pools.pool_for uri + + pool.checkout + + t1 = Thread.new { + timeout(1) do + pool.checkout + end + } + assert_raises(Timeout::Error) do + t1.join + end + end +end diff --git a/test/rubygems/test_gem_request_set.rb b/test/rubygems/test_gem_request_set.rb index 130728e249..3c1d5ac1d1 100644 --- a/test/rubygems/test_gem_request_set.rb +++ b/test/rubygems/test_gem_request_set.rb @@ -42,6 +42,12 @@ class TestGemRequestSet < Gem::TestCase fetcher.gem 'a', 2 end + done_installing_ran = false + + Gem.done_installing do |installer, specs| + done_installing_ran = true + end + rs = Gem::RequestSet.new installed = [] @@ -61,6 +67,29 @@ class TestGemRequestSet < Gem::TestCase assert_path_exists 'gem.deps.rb.lock' assert rs.remote + refute done_installing_ran + end + + def test_install_from_gemdeps_explain + spec_fetcher do |fetcher| + fetcher.gem 'a', 2 + end + + rs = Gem::RequestSet.new + + open 'gem.deps.rb', 'w' do |io| + io.puts 'gem "a"' + io.flush + + expected = <<-EXPECTED +Gems to install: + a-2 + EXPECTED + + assert_output expected do + rs.install_from_gemdeps :gemdeps => io.path, :explain => true + end + end end def test_install_from_gemdeps_install_dir @@ -153,6 +182,30 @@ DEPENDENCIES assert_path_exists File.join @gemhome, 'specifications', 'b-1.gemspec' end + def test_install_from_gemdeps_version_mismatch + spec_fetcher do |fetcher| + fetcher.gem 'a', 2 + end + + rs = Gem::RequestSet.new + installed = [] + + open 'gem.deps.rb', 'w' do |io| + io.puts <<-GEM_DEPS +gem "a" +ruby "0" + GEM_DEPS + + io.flush + + rs.install_from_gemdeps :gemdeps => io.path do |req, installer| + installed << req.full_name + end + end + + assert_includes installed, 'a-2' + end + def test_load_gemdeps rs = Gem::RequestSet.new @@ -160,10 +213,12 @@ DEPENDENCIES io.puts 'gem "a"' io.flush - rs.load_gemdeps io.path + gem_deps = rs.load_gemdeps io.path + + assert_kind_of Gem::RequestSet::GemDependencyAPI, gem_deps io end - tf.close! + tf.close! if tf.respond_to? :close! assert_equal [dep('a')], rs.dependencies @@ -171,6 +226,24 @@ DEPENDENCIES assert rs.vendor_set end + def test_load_gemdeps_installing + rs = Gem::RequestSet.new + + tf = Tempfile.open 'gem.deps.rb' do |io| + io.puts 'ruby "0"' + io.puts 'gem "a"' + io.flush + + gem_deps = rs.load_gemdeps io.path, [], true + + assert_kind_of Gem::RequestSet::GemDependencyAPI, gem_deps + io + end + tf.close! if tf.respond_to? :close! + + assert_equal [dep('a')], rs.dependencies + end + def test_load_gemdeps_without_groups rs = Gem::RequestSet.new @@ -181,7 +254,7 @@ DEPENDENCIES rs.load_gemdeps io.path, [:test] io end - tf.close! + tf.close! if tf.respond_to? :close! assert_empty rs.dependencies end @@ -193,12 +266,69 @@ DEPENDENCIES rs = Gem::RequestSet.new rs.gem "a" + orig_errors = rs.errors + res = rs.resolve StaticSet.new([a, b]) assert_equal 2, res.size names = res.map { |s| s.full_name }.sort assert_equal ["a-2", "b-2"], names + + refute_same orig_errors, rs.errors + end + + def test_bug_bug_990 + a = util_spec 'a', '1.b', 'b' => '~> 1.a' + b = util_spec 'b', '1.b', 'c' => '>= 1' + c = util_spec 'c', '1.1.b' + + rs = Gem::RequestSet.new + rs.gem 'a' + rs.prerelease = true + + res = rs.resolve StaticSet.new([a, b, c]) + assert_equal 3, res.size + + names = res.map { |s| s.full_name }.sort + + assert_equal %w[a-1.b b-1.b c-1.1.b], names + end + + def test_resolve_development + a = util_spec 'a', 1 + spec = Gem::Resolver::SpecSpecification.new nil, a + + rs = Gem::RequestSet.new + rs.gem 'a' + rs.development = true + + res = rs.resolve StaticSet.new [spec] + assert_equal 1, res.size + + assert rs.resolver.development + refute rs.resolver.development_shallow + end + + def test_resolve_development_shallow + a = util_spec 'a', 1 do |s| s.add_development_dependency 'b' end + b = util_spec 'b', 1 do |s| s.add_development_dependency 'c' end + c = util_spec 'c', 1 + + a_spec = Gem::Resolver::SpecSpecification.new nil, a + b_spec = Gem::Resolver::SpecSpecification.new nil, b + c_spec = Gem::Resolver::SpecSpecification.new nil, c + + rs = Gem::RequestSet.new + rs.gem 'a' + rs.development = true + rs.development_shallow = true + + res = rs.resolve StaticSet.new [a_spec, b_spec, c_spec] + assert_equal 2, res.size + + assert rs.resolver.development + assert rs.resolver.development_shallow end def test_resolve_git @@ -216,7 +346,7 @@ DEPENDENCIES rs.load_gemdeps io.path io end - tf.close! + tf.close! if tf.respond_to? :close! res = rs.resolve assert_equal 1, res.size @@ -280,7 +410,7 @@ DEPENDENCIES rs.load_gemdeps io.path io end - tf.close! + tf.close! if tf.respond_to? :close! res = rs.resolve assert_equal 2, res.size @@ -308,6 +438,12 @@ DEPENDENCIES end def test_install + done_installing_ran = false + + Gem.done_installing do + done_installing_ran = true + end + spec_fetcher do |fetcher| fetcher.gem "a", "1", "b" => "= 1" fetcher.gem "b", "1" @@ -336,6 +472,8 @@ DEPENDENCIES assert_path_exists File.join @gemhome, 'specifications', 'b-1.gemspec' assert_equal %w[b-1 a-1], installed.map { |s| s.full_name } + + assert done_installing_ran end def test_install_into @@ -358,4 +496,102 @@ DEPENDENCIES assert_equal %w!b-1 a-1!, installed.map { |s| s.full_name } end + + def test_install_into_development_shallow + spec_fetcher do |fetcher| + fetcher.gem 'a', '1' do |s| + s.add_development_dependency 'b', '= 1' + end + + fetcher.gem 'b', '1' do |s| + s.add_development_dependency 'c', '= 1' + end + + fetcher.spec 'c', '1' + end + + rs = Gem::RequestSet.new + rs.development = true + rs.development_shallow = true + rs.gem 'a' + + rs.resolve + + options = { + :development => true, + :development_shallow => true, + } + + installed = rs.install_into @tempdir, true, options do + assert_equal @tempdir, ENV['GEM_HOME'] + end + + assert_equal %w[a-1 b-1], installed.map { |s| s.full_name }.sort + end + + def test_sorted_requests_development_shallow + a = util_spec 'a', 1 do |s| s.add_development_dependency 'b' end + b = util_spec 'b', 1 do |s| s.add_development_dependency 'c' end + c = util_spec 'c', 1 + + rs = Gem::RequestSet.new + rs.gem 'a' + rs.development = true + rs.development_shallow = true + + a_spec = Gem::Resolver::SpecSpecification.new nil, a + b_spec = Gem::Resolver::SpecSpecification.new nil, b + c_spec = Gem::Resolver::SpecSpecification.new nil, c + + rs.resolve StaticSet.new [a_spec, b_spec, c_spec] + + assert_equal %w[b-1 a-1], rs.sorted_requests.map { |req| req.full_name } + end + + def test_tsort_each_child_development + a = util_spec 'a', 1 do |s| s.add_development_dependency 'b' end + b = util_spec 'b', 1 do |s| s.add_development_dependency 'c' end + c = util_spec 'c', 1 + + rs = Gem::RequestSet.new + rs.gem 'a' + rs.development = true + rs.development_shallow = true + + a_spec = Gem::Resolver::SpecSpecification.new nil, a + b_spec = Gem::Resolver::SpecSpecification.new nil, b + c_spec = Gem::Resolver::SpecSpecification.new nil, c + + rs.resolve StaticSet.new [a_spec, b_spec, c_spec] + + a_req = Gem::Resolver::ActivationRequest.new a_spec, nil + + deps = rs.enum_for(:tsort_each_child, a_req).to_a + + assert_equal %w[b], deps.map { |dep| dep.name } + end + + def test_tsort_each_child_development_shallow + a = util_spec 'a', 1 do |s| s.add_development_dependency 'b' end + b = util_spec 'b', 1 do |s| s.add_development_dependency 'c' end + c = util_spec 'c', 1 + + rs = Gem::RequestSet.new + rs.gem 'a' + rs.development = true + rs.development_shallow = true + + a_spec = Gem::Resolver::SpecSpecification.new nil, a + b_spec = Gem::Resolver::SpecSpecification.new nil, b + c_spec = Gem::Resolver::SpecSpecification.new nil, c + + rs.resolve StaticSet.new [a_spec, b_spec, c_spec] + + b_req = Gem::Resolver::ActivationRequest.new b_spec, nil + + deps = rs.enum_for(:tsort_each_child, b_req).to_a + + assert_empty deps + end + end diff --git a/test/rubygems/test_gem_request_set_gem_dependency_api.rb b/test/rubygems/test_gem_request_set_gem_dependency_api.rb index 08649ebff1..c2bf5ff378 100644 --- a/test/rubygems/test_gem_request_set_gem_dependency_api.rb +++ b/test/rubygems/test_gem_request_set_gem_dependency_api.rb @@ -68,6 +68,22 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase assert_equal [dep('a')], @set.dependencies assert_equal %w[a], @gda.requires['a'] + + expected = { 'a' => nil } + + assert_equal expected, @gda.dependencies + end + + def test_gem_duplicate + @gda.gem 'a' + + _, err = capture_io do + @gda.gem 'a' + end + + expected = "Gem dependencies file gem.deps.rb requires a more than once." + + assert_match expected, err end def test_gem_git @@ -76,6 +92,36 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase assert_equal [dep('a')], @set.dependencies assert_equal %w[git/a master], @git_set.repositories['a'] + + expected = { 'a' => '!' } + + assert_equal expected, @gda.dependencies + end + + def test_gem_bitbucket + @gda.gem 'a', :bitbucket => 'example/repository' + + assert_equal [dep('a')], @set.dependencies + + assert_equal %w[https://[email protected]/example/repository.git master], + @git_set.repositories['a'] + + expected = { 'a' => '!' } + + assert_equal expected, @gda.dependencies + end + + def test_gem_bitbucket_expand_path + @gda.gem 'a', :bitbucket => 'example' + + assert_equal [dep('a')], @set.dependencies + + assert_equal %w[https://[email protected]/example/example.git master], + @git_set.repositories['a'] + + expected = { 'a' => '!' } + + assert_equal expected, @gda.dependencies end def test_gem_git_branch @@ -127,6 +173,23 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase assert_equal %w[git://github.com/example/repository.git master], @git_set.repositories['a'] + + expected = { 'a' => '!' } + + assert_equal expected, @gda.dependencies + end + + def test_gem_github_expand_path + @gda.gem 'a', :github => 'example' + + assert_equal [dep('a')], @set.dependencies + + assert_equal %w[git://github.com/example/example.git master], + @git_set.repositories['a'] + + expected = { 'a' => '!' } + + assert_equal expected, @gda.dependencies end def test_gem_group @@ -141,6 +204,10 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase @gda.gem 'a', :group => :test assert_empty @set.dependencies + + expected = { 'a' => nil } + + assert_equal expected, @gda.dependencies end def test_gem_groups @@ -159,6 +226,10 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase loaded = @vendor_set.load_spec(name, version, Gem::Platform::RUBY, nil) assert_equal "#{name}-#{version}", loaded.full_name + + expected = { name => '!' } + + assert_equal expected, @gda.dependencies end def test_gem_platforms @@ -254,6 +325,18 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase Gem.win_platform = win_platform end + def test_gem_platforms_platform + win_platform, Gem.win_platform = Gem.win_platform?, false + + with_engine_version 'ruby', '2.0.0' do + @gda.gem 'a', :platforms => :jruby, :platform => :ruby + + refute_empty @set.dependencies + end + ensure + Gem.win_platform = win_platform + end + def test_gem_platforms_version with_engine_version 'ruby', '2.0.0' do @gda.gem 'a', :platforms => :ruby_18 @@ -270,7 +353,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase assert_equal 'unknown platform :unknown', e.message end - def test_gem_require + def test_gem_requires @gda.gem 'a', :require => %w[b c] @gda.gem 'd', :require => 'e' @@ -280,7 +363,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase assert_equal %w[e], @gda.requires['d'] end - def test_gem_require_false + def test_gem_requires_false @gda.gem 'a', :require => false assert_equal [dep('a')], @set.dependencies @@ -288,7 +371,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase assert_empty @gda.requires end - def test_gem_require_without_group + def test_gem_requires_without_group @gda.without_groups << :test @gda.gem 'a', :group => :test @@ -302,12 +385,20 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase @gda.gem 'a', '~> 1.0' assert_equal [dep('a', '~> 1.0')], @set.dependencies + + expected = { 'a' => ['~> 1.0'] } + + assert_equal expected, @gda.dependencies end def test_gem_requirements @gda.gem 'b', '~> 1.0', '>= 1.0.2' assert_equal [dep('b', '~> 1.0', '>= 1.0.2')], @set.dependencies + + expected = { 'b' => ['~> 1.0', '>= 1.0.2'] } + + assert_equal expected, @gda.dependencies end def test_gem_requirements_options @@ -483,6 +574,16 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase assert_equal %w[git://example/repo.git master], @git_set.repositories['b'] end + def test_git_source + @gda.git_source :example do |repo_name| + "git://example/#{repo_name}.git" + end + + @gda.gem 'a', :example => 'repo' + + assert_equal %w[git://example/repo.git master], @git_set.repositories['a'] + end + def test_group @gda.group :test do @gda.gem 'a' @@ -504,12 +605,12 @@ end gda = @GDA.new @set, io.path - gda.load + assert_equal gda, gda.load assert_equal [dep('a'), dep('b')], @set.dependencies io end - tf.close! + tf.close! if tf.respond_to? :close! end def test_name_typo @@ -538,18 +639,42 @@ end end def test_platform_mswin + util_set_arch 'i686-darwin8.10.1' do + @gda.platform :mswin do + @gda.gem 'a' + end + + assert_empty @set.dependencies + end + + util_set_arch 'x86-mswin32-60' do + @gda.platform :mswin do + @gda.gem 'a' + end + + refute_empty @set.dependencies + end + end + + def test_platform_multiple win_platform, Gem.win_platform = Gem.win_platform?, false - @gda.platform :mswin do - @gda.gem 'a' + gda = @GDA.new @set, nil + + with_engine_version 'ruby', '1.8.7' do + gda.platform :mri_19, :mri_20 do + gda.gem 'a' + end end assert_empty @set.dependencies - Gem.win_platform = true + gda = @GDA.new @set, nil - @gda.platform :mswin do - @gda.gem 'a' + with_engine_version 'ruby', '2.0.0' do + gda.platform :mri_19, :mri_20 do + gda.gem 'a' + end end refute_empty @set.dependencies @@ -570,30 +695,27 @@ end end def test_platforms - win_platform, Gem.win_platform = Gem.win_platform?, false + util_set_arch 'i686-darwin8.10.1' do + @gda.platforms :ruby do + @gda.gem 'a' + end - @gda.platforms :ruby do - @gda.gem 'a' - end + assert_equal [dep('a')], @set.dependencies - assert_equal [dep('a')], @set.dependencies + @gda.platforms :mswin do + @gda.gem 'b' + end - @gda.platforms :mswin do - @gda.gem 'b' + assert_equal [dep('a')], @set.dependencies end - assert_equal [dep('a')], @set.dependencies - - Gem.win_platform = true + util_set_arch 'x86-mswin32-60' do + @gda.platforms :mswin do + @gda.gem 'c' + end - @gda.platforms :mswin do - @gda.gem 'c' + assert_equal [dep('a'), dep('c')], @set.dependencies end - - assert_equal [dep('a'), dep('c')], @set.dependencies - - ensure - Gem.win_platform = win_platform end def test_ruby @@ -647,6 +769,12 @@ end assert_equal "Your Ruby version is #{RUBY_VERSION}, but your gem.deps.rb requires 1.8.0", e.message end + def test_ruby_mismatch_installing + @gda.installing = true + + assert @gda.ruby '1.8.0' + end + def test_source sources = Gem.sources diff --git a/test/rubygems/test_gem_request_set_lockfile.rb b/test/rubygems/test_gem_request_set_lockfile.rb index 0be69bf92b..96cc12e164 100644 --- a/test/rubygems/test_gem_request_set_lockfile.rb +++ b/test/rubygems/test_gem_request_set_lockfile.rb @@ -38,6 +38,127 @@ class TestGemRequestSetLockfile < Gem::TestCase end end + def test_add_DEPENDENCIES + spec_fetcher do |fetcher| + fetcher.spec 'a', 2 do |s| + s.add_development_dependency 'b' + end + end + + @set.gem 'a' + @set.resolve + @lockfile.instance_variable_set :@requests, @set.sorted_requests + + out = [] + + @lockfile.add_DEPENDENCIES out + + expected = [ + 'DEPENDENCIES', + ' a', + nil + ] + + assert_equal expected, out + end + + def test_add_DEPENDENCIES_from_gem_deps + spec_fetcher do |fetcher| + fetcher.spec 'a', 2 do |s| + s.add_development_dependency 'b' + end + end + + dependencies = { 'a' => '~> 2.0' } + + @set.gem 'a' + @set.resolve + @lockfile = + Gem::RequestSet::Lockfile.new @set, @gem_deps_file, dependencies + @lockfile.instance_variable_set :@requests, @set.sorted_requests + + out = [] + + @lockfile.add_DEPENDENCIES out + + expected = [ + 'DEPENDENCIES', + ' a (~> 2.0)', + nil + ] + + assert_equal expected, out + end + + def test_add_GEM + spec_fetcher do |fetcher| + fetcher.spec 'a', 2 do |s| + s.add_dependency 'b' + s.add_development_dependency 'c' + end + + fetcher.spec 'b', 2 + + fetcher.spec 'bundler', 1 + end + + @set.gem 'a' + @set.gem 'bundler' + @set.resolve + @lockfile.instance_variable_set :@requests, @set.sorted_requests + + spec_groups = @set.sorted_requests.group_by do |request| + request.spec.class + end + @lockfile.instance_variable_set :@spec_groups, spec_groups + + + out = [] + + @lockfile.add_GEM out + + expected = [ + 'GEM', + ' remote: http://gems.example.com/', + ' specs:', + ' a (2)', + ' b', + ' b (2)', + nil + ] + + assert_equal expected, out + end + + def test_add_PLATFORMS + spec_fetcher do |fetcher| + fetcher.spec 'a', 2 do |s| + s.add_dependency 'b' + end + + fetcher.spec 'b', 2 do |s| + s.platform = Gem::Platform::CURRENT + end + end + + @set.gem 'a' + @set.resolve + @lockfile.instance_variable_set :@requests, @set.sorted_requests + + out = [] + + @lockfile.add_PLATFORMS out + + expected = [ + 'PLATFORMS', + ' ruby', + ' x86-darwin-8', + nil + ] + + assert_equal expected, out + end + def test_get @lockfile.instance_variable_set :@tokens, [:token] @@ -142,7 +263,106 @@ DEPENDENCIES assert_equal %w[a-2], lockfile_set.specs.map { |tuple| tuple.full_name } end + def test_parse_DEPENDENCIES_git + write_lockfile <<-LOCKFILE +GIT + remote: git://git.example/josevalim/rails-footnotes.git + revision: 3a6ac1971e91d822f057650cc5916ebfcbd6ee37 + specs: + rails-footnotes (3.7.9) + rails (>= 3.0.0) + +GIT + remote: git://git.example/svenfuchs/i18n-active_record.git + revision: 55507cf59f8f2173d38e07e18df0e90d25b1f0f6 + specs: + i18n-active_record (0.0.2) + i18n (>= 0.5.0) + +GEM + remote: http://gems.example/ + specs: + i18n (0.6.9) + rails (4.0.0) + +PLATFORMS + ruby + +DEPENDENCIES + i18n-active_record! + rails-footnotes! + LOCKFILE + + @lockfile.parse + + expected = [ + dep('i18n-active_record', '= 0.0.2'), + dep('rails-footnotes', '= 3.7.9'), + ] + + assert_equal expected, @set.dependencies + end + + def test_parse_GEM + write_lockfile <<-LOCKFILE +GEM + specs: + a (2) + +PLATFORMS + ruby + +DEPENDENCIES + a + LOCKFILE + + @lockfile.parse + + assert_equal [dep('a', '>= 0')], @set.dependencies + + lockfile_set = @set.sets.find do |set| + Gem::Resolver::LockSet === set + end + + assert lockfile_set, 'found a LockSet' + + assert_equal %w[a-2], lockfile_set.specs.map { |s| s.full_name } + end + + def test_parse_GEM_remote_multiple + write_lockfile <<-LOCKFILE +GEM + remote: https://gems.example/ + remote: https://other.example/ + specs: + a (2) + +PLATFORMS + ruby + +DEPENDENCIES + a + LOCKFILE + + @lockfile.parse + + assert_equal [dep('a', '>= 0')], @set.dependencies + + lockfile_set = @set.sets.find do |set| + Gem::Resolver::LockSet === set + end + + assert lockfile_set, 'found a LockSet' + + assert_equal %w[a-2 a-2], lockfile_set.specs.map { |s| s.full_name } + + assert_equal %w[https://gems.example/ https://other.example/], + lockfile_set.specs.map { |s| s.source.uri.to_s } + end + def test_parse_GIT + @set.instance_variable_set :@install_dir, 'install_dir' + write_lockfile <<-LOCKFILE GIT remote: git://example/a.git @@ -150,6 +370,7 @@ GIT specs: a (2) b (>= 3) + c DEPENDENCIES a! @@ -173,7 +394,126 @@ DEPENDENCIES assert_equal %w[a-2], git_set.specs.values.map { |s| s.full_name } - assert_equal [dep('b', '>= 3')], git_set.specs.values.first.dependencies + assert_equal [dep('b', '>= 3'), dep('c')], + git_set.specs.values.first.dependencies + + expected = { + 'a' => %w[git://example/a.git master], + } + + assert_equal expected, git_set.repositories + assert_equal 'install_dir', git_set.root_dir + end + + def test_parse_GIT_branch + write_lockfile <<-LOCKFILE +GIT + remote: git://example/a.git + revision: 1234abc + branch: 0-9-12-stable + specs: + a (2) + b (>= 3) + +DEPENDENCIES + a! + LOCKFILE + + @lockfile.parse + + assert_equal [dep('a', '= 2')], @set.dependencies + + lockfile_set = @set.sets.find do |set| + Gem::Resolver::LockSet === set + end + + refute lockfile_set, 'fount a LockSet' + + git_set = @set.sets.find do |set| + Gem::Resolver::GitSet === set + end + + assert git_set, 'could not find a GitSet' + + expected = { + 'a' => %w[git://example/a.git 1234abc], + } + + assert_equal expected, git_set.repositories + end + + def test_parse_GIT_ref + write_lockfile <<-LOCKFILE +GIT + remote: git://example/a.git + revision: 1234abc + ref: 1234abc + specs: + a (2) + b (>= 3) + +DEPENDENCIES + a! + LOCKFILE + + @lockfile.parse + + assert_equal [dep('a', '= 2')], @set.dependencies + + lockfile_set = @set.sets.find do |set| + Gem::Resolver::LockSet === set + end + + refute lockfile_set, 'fount a LockSet' + + git_set = @set.sets.find do |set| + Gem::Resolver::GitSet === set + end + + assert git_set, 'could not find a GitSet' + + expected = { + 'a' => %w[git://example/a.git 1234abc], + } + + assert_equal expected, git_set.repositories + end + + def test_parse_GIT_tag + write_lockfile <<-LOCKFILE +GIT + remote: git://example/a.git + revision: 1234abc + tag: v0.9.12 + specs: + a (2) + b (>= 3) + +DEPENDENCIES + a! + LOCKFILE + + @lockfile.parse + + assert_equal [dep('a', '= 2')], @set.dependencies + + lockfile_set = @set.sets.find do |set| + Gem::Resolver::LockSet === set + end + + refute lockfile_set, 'fount a LockSet' + + git_set = @set.sets.find do |set| + Gem::Resolver::GitSet === set + end + + assert git_set, 'could not find a GitSet' + + expected = { + 'a' => %w[git://example/a.git 1234abc], + } + + assert_equal expected, git_set.repositories end def test_parse_PATH @@ -184,6 +524,7 @@ PATH remote: #{directory} specs: a (1) + b (2) DEPENDENCIES a! @@ -206,6 +547,28 @@ DEPENDENCIES assert vendor_set, 'could not find a VendorSet' assert_equal %w[a-1], vendor_set.specs.values.map { |s| s.full_name } + + spec = vendor_set.load_spec 'a', nil, nil, nil + + assert_equal [dep('b', '= 2')], spec.dependencies + end + + def test_parse_dependency + write_lockfile ' 1)' + + @lockfile.tokenize + + parsed = @lockfile.parse_dependency 'a', '=' + + assert_equal dep('a', '= 1'), parsed + + write_lockfile ')' + + @lockfile.tokenize + + parsed = @lockfile.parse_dependency 'a', '2' + + assert_equal dep('a', '= 2'), parsed end def test_parse_gem_specs_dependency @@ -853,5 +1216,23 @@ DEPENDENCIES refute_empty File.read gem_deps_lock_file end + def test_write_error + @set.gem 'nonexistent' + + gem_deps_lock_file = "#{@gem_deps_file}.lock" + + open gem_deps_lock_file, 'w' do |io| + io.write 'hello' + end + + assert_raises Gem::UnsatisfiableDependencyError do + @lockfile.write + end + + assert_path_exists gem_deps_lock_file + + assert_equal 'hello', File.read(gem_deps_lock_file) + end + end diff --git a/test/rubygems/test_gem_requirement.rb b/test/rubygems/test_gem_requirement.rb index 8adaf898bc..6974ff0810 100644 --- a/test/rubygems/test_gem_requirement.rb +++ b/test/rubygems/test_gem_requirement.rb @@ -207,6 +207,14 @@ class TestGemRequirement < Gem::TestCase end end + def test_satisfied_by_eh_tilde_gt_v0 + r = req "~> 0.0.1" + + refute_satisfied_by "0.1.1", r + assert_satisfied_by "0.0.2", r + assert_satisfied_by "0.0.1", r + end + def test_satisfied_by_eh_good assert_satisfied_by "0.2.33", "= 0.2.33" assert_satisfied_by "0.2.34", "> 0.2.33" @@ -277,6 +285,11 @@ class TestGemRequirement < Gem::TestCase refute_satisfied_by "1.1.pre", "~> 1.1" refute_satisfied_by "2.0.a", "~> 1.0" refute_satisfied_by "2.0.a", "~> 2.0" + + refute_satisfied_by "0.9", "~> 1" + assert_satisfied_by "1.0", "~> 1" + assert_satisfied_by "1.1", "~> 1" + refute_satisfied_by "2.0", "~> 1" end def test_satisfied_by_eh_multiple diff --git a/test/rubygems/test_gem_resolver.rb b/test/rubygems/test_gem_resolver.rb index c97e9e710c..2b9e9fe137 100644 --- a/test/rubygems/test_gem_resolver.rb +++ b/test/rubygems/test_gem_resolver.rb @@ -13,6 +13,12 @@ class TestGemResolver < Gem::TestCase end def set(*specs) + source = Gem::Source.new URI @gem_repo + + specs = specs.map do |spec| + Gem::Resolver::SpecSpecification.new nil, spec, source + end + StaticSet.new(specs) end @@ -20,7 +26,7 @@ class TestGemResolver < Gem::TestCase actual = resolver.resolve exp = expected.sort_by { |s| s.full_name } - act = actual.map { |a| a.spec }.sort_by { |s| s.full_name } + act = actual.map { |a| a.spec.spec }.sort_by { |s| s.full_name } msg = "Set of gems was not the same: #{exp.map { |x| x.full_name}.inspect} != #{act.map { |x| x.full_name}.inspect}" @@ -123,6 +129,30 @@ class TestGemResolver < Gem::TestCase assert_equal ['b (= 2)'], reqs.to_a.map { |req| req.to_s } end + def test_requests_development + a1 = util_spec 'a', 1, 'b' => 2 + + spec = Gem::Resolver::SpecSpecification.new nil, a1 + def spec.fetch_development_dependencies + @called = true + end + + r1 = Gem::Resolver::DependencyRequest.new dep('a', '= 1'), nil + + act = Gem::Resolver::ActivationRequest.new spec, r1, false + + res = Gem::Resolver.new [act] + res.development = true + + reqs = Gem::Resolver::RequirementList.new + + res.requests spec, act, reqs + + assert_equal ['b (= 2)'], reqs.to_a.map { |req| req.to_s } + + assert spec.instance_variable_defined? :@called + end + def test_requests_ignore_dependencies a1 = util_spec 'a', 1, 'b' => 2 @@ -140,6 +170,104 @@ class TestGemResolver < Gem::TestCase assert_empty reqs end + def test_resolve_conservative + a1_spec = util_spec 'a', 1 + a2_spec = util_spec 'a', 2 do |s| + s.add_dependency 'b', 2 + s.add_dependency 'c' + end + b1_spec = util_spec 'b', 1 + b2_spec = util_spec 'b', 2 + c1_spec = util_spec 'c', 1 do |s| s.add_dependency 'd', 2 end + c2_spec = util_spec 'c', 2 do |s| s.add_dependency 'd', 2 end + d1_spec = util_spec 'd', 1 do |s| s.add_dependency 'e' end + d2_spec = util_spec 'd', 2 do |s| s.add_dependency 'e' end + e1_spec = util_spec 'e', 1 + e2_spec = util_spec 'e', 2 + + a_dep = make_dep 'a', '= 2' + e_dep = make_dep 'e' + + # When requesting to install: + # a-2, e + deps = [a_dep, e_dep] + + s = set a1_spec, a2_spec, b1_spec, b2_spec, c1_spec, c2_spec, d1_spec, d2_spec, e1_spec, e2_spec + + res = Gem::Resolver.new deps, s + + # With the following gems already installed: + # a-1, b-1, c-1, e-1 + res.skip_gems = {'a'=>[a1_spec], 'b'=>[b1_spec], 'c'=>[c1_spec], 'e'=>[e1_spec]} + + # Make sure the following gems end up getting used/installed/upgraded: + # a-2 (upgraded) + # b-2 (upgraded), specific dependency from a-2 + # c-1 (used, not upgraded), open dependency from a-2 + # d-2 (installed), specific dependency from c-2 + # e-1 (used, not upgraded), open dependency from request + assert_resolves_to [a2_spec, b2_spec, c1_spec, d2_spec, e1_spec], res + end + + def test_resolve_development + a_spec = util_spec 'a', 1 do |s| s.add_development_dependency 'b' end + b_spec = util_spec 'b', 1 do |s| s.add_development_dependency 'c' end + c_spec = util_spec 'c', 1 + + a_dep = make_dep 'a', '= 1' + + deps = [a_dep] + + s = set a_spec, b_spec, c_spec + + res = Gem::Resolver.new deps, s + + res.development = true + + assert_resolves_to [a_spec, b_spec, c_spec], res + end + + def test_resolve_development_shallow + a_spec = util_spec 'a', 1 do |s| + s.add_development_dependency 'b' + s.add_runtime_dependency 'd' + end + + b_spec = util_spec 'b', 1 do |s| s.add_development_dependency 'c' end + c_spec = util_spec 'c', 1 + + d_spec = util_spec 'd', 1 do |s| s.add_development_dependency 'e' end + e_spec = util_spec 'e', 1 + + a_dep = make_dep 'a', '= 1' + + deps = [a_dep] + + s = set a_spec, b_spec, c_spec, d_spec, e_spec + + res = Gem::Resolver.new deps, s + + res.development = true + res.development_shallow = true + + assert_resolves_to [a_spec, b_spec, d_spec], res + end + + def test_resolve_remote_missing_dependency + @fetcher = Gem::FakeFetcher.new + Gem::RemoteFetcher.fetcher = @fetcher + + a_dep = make_dep 'a', '= 1' + + res = Gem::Resolver.new [a_dep], Gem::Resolver::IndexSet.new + + e = assert_raises Gem::UnsatisfiableDepedencyError do + res.resolve + end + + refute_empty e.errors + end + def test_no_overlap_specificly a = util_spec "a", '1' b = util_spec "b", "1" @@ -215,7 +343,7 @@ class TestGemResolver < Gem::TestCase res = Gem::Resolver.new([ad], s) - assert_resolves_to [a2_p1], res + assert_resolves_to [a2_p1.spec], res end def test_only_returns_spec_once diff --git a/test/rubygems/test_gem_resolver_activation_request.rb b/test/rubygems/test_gem_resolver_activation_request.rb index 54de6bf16a..c9163e25de 100644 --- a/test/rubygems/test_gem_resolver_activation_request.rb +++ b/test/rubygems/test_gem_resolver_activation_request.rb @@ -19,6 +19,16 @@ class TestGemResolverActivationRequest < Gem::TestCase @req = @DR::ActivationRequest.new @a3, @dep, [@a1, @a2] end + def test_development_eh + refute @req.development? + + dep_req = @DR::DependencyRequest.new dep('a', '>= 0', :development), nil + + act_req = @DR::ActivationRequest.new @a3, dep_req, [@a1, @a2] + + assert act_req.development? + end + def test_inspect assert_match 'a-3', @req.inspect assert_match 'from a (>= 0)', @req.inspect diff --git a/test/rubygems/test_gem_resolver_api_set.rb b/test/rubygems/test_gem_resolver_api_set.rb index 245f6c1d24..4ae54d71b3 100644 --- a/test/rubygems/test_gem_resolver_api_set.rb +++ b/test/rubygems/test_gem_resolver_api_set.rb @@ -73,13 +73,13 @@ class TestGemResolverAPISet < Gem::TestCase set.prefetch [a_dep] - @fetcher.data.delete "#{@dep_uri}?gems=a" - expected = [ @DR::APISpecification.new(set, data.first) ] assert_equal expected, set.find_all(a_dep) + + @fetcher.data.delete "#{@dep_uri}?gems=a" end def test_find_all_local diff --git a/test/rubygems/test_gem_resolver_api_specification.rb b/test/rubygems/test_gem_resolver_api_specification.rb index 6b21a9d4d8..cfeca43453 100644 --- a/test/rubygems/test_gem_resolver_api_specification.rb +++ b/test/rubygems/test_gem_resolver_api_specification.rb @@ -28,6 +28,46 @@ class TestGemResolverAPISpecification < Gem::TestCase assert_equal expected, spec.dependencies end + def test_fetch_development_dependencies + specs = spec_fetcher do |fetcher| + fetcher.spec 'rails', '3.0.3' do |s| + s.add_runtime_dependency 'bundler', '~> 1.0' + s.add_runtime_dependency 'railties', '= 3.0.3' + s.add_development_dependency 'a', '= 1' + end + end + + rails = specs['rails-3.0.3'] + + repo = @gem_repo + 'api/v1/dependencies' + + set = Gem::Resolver::APISet.new repo + + data = { + :name => 'rails', + :number => '3.0.3', + :platform => 'ruby', + :dependencies => [ + ['bundler', '~> 1.0'], + ['railties', '= 3.0.3'], + ], + } + + util_setup_spec_fetcher rails + + spec = Gem::Resolver::APISpecification.new set, data + + spec.fetch_development_dependencies + + expected = [ + Gem::Dependency.new('bundler', '~> 1.0'), + Gem::Dependency.new('railties', '= 3.0.3'), + Gem::Dependency.new('a', '= 1', :development), + ] + + assert_equal expected, spec.dependencies + end + def test_installable_platform_eh set = Gem::Resolver::APISet.new data = { diff --git a/test/rubygems/test_gem_resolver_best_set.rb b/test/rubygems/test_gem_resolver_best_set.rb index 2d16f8b701..055438c89b 100644 --- a/test/rubygems/test_gem_resolver_best_set.rb +++ b/test/rubygems/test_gem_resolver_best_set.rb @@ -32,6 +32,26 @@ class TestGemResolverBestSet < Gem::TestCase assert_equal %w[a-1], found.map { |s| s.full_name } end + def test_find_all_fallback + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + end + + set = @DR::BestSet.new + + api_uri = URI(@gem_repo) + './api/v1/dependencies' + + set.sets << Gem::Resolver::APISet.new(api_uri) + + dependency = dep 'a', '~> 1' + + req = @DR::DependencyRequest.new dependency, nil + + found = set.find_all req + + assert_equal %w[a-1], found.map { |s| s.full_name } + end + def test_find_all_local spec_fetcher do |fetcher| fetcher.spec 'a', 1 @@ -76,5 +96,42 @@ class TestGemResolverBestSet < Gem::TestCase assert_empty set.sets end + def test_replace_failed_api_set + set = @DR::BestSet.new + + api_uri = URI(@gem_repo) + './api/v1/dependencies' + api_set = Gem::Resolver::APISet.new api_uri + + set.sets << api_set + + error_uri = api_uri + '?gems=a' + + error = Gem::RemoteFetcher::FetchError.new 'bogus', error_uri + + set.replace_failed_api_set error + + assert_equal 1, set.sets.size + + refute_includes set.sets, api_set + + assert_kind_of Gem::Resolver::IndexSet, set.sets.first + end + + def test_replace_failed_api_set_no_api_set + set = @DR::BestSet.new + + index_set = Gem::Resolver::IndexSet.new Gem::Source.new @gem_repo + + set.sets << index_set + + error = Gem::RemoteFetcher::FetchError.new 'bogus', @gem_repo + + e = assert_raises Gem::RemoteFetcher::FetchError do + set.replace_failed_api_set error + end + + assert_equal error, e + end + end diff --git a/test/rubygems/test_gem_resolver_composed_set.rb b/test/rubygems/test_gem_resolver_composed_set.rb index 85026f7eb9..f8455e1aa4 100644 --- a/test/rubygems/test_gem_resolver_composed_set.rb +++ b/test/rubygems/test_gem_resolver_composed_set.rb @@ -2,6 +2,33 @@ require 'rubygems/test_case' class TestGemResolverComposedSet < Gem::TestCase + def test_errors + index_set = Gem::Resolver::IndexSet.new + current_set = Gem::Resolver::CurrentSet.new + + set = Gem::Resolver::ComposedSet.new index_set, current_set + + set.instance_variable_get(:@errors) << :a + current_set.errors << :b + + assert_includes set.errors, :a + assert_includes set.errors, :b + assert_includes set.errors, index_set.errors.first + end + + def test_prerelease_equals + best_set = Gem::Resolver::BestSet.new + current_set = Gem::Resolver::CurrentSet.new + + set = Gem::Resolver::ComposedSet.new best_set, current_set + + set.prerelease = true + + assert set.prerelease + assert best_set.prerelease + assert current_set.prerelease + end + def test_remote_equals best_set = Gem::Resolver::BestSet.new current_set = Gem::Resolver::CurrentSet.new diff --git a/test/rubygems/test_gem_resolver_conflict.rb b/test/rubygems/test_gem_resolver_conflict.rb index f8bba3f16f..0cef0cad2a 100644 --- a/test/rubygems/test_gem_resolver_conflict.rb +++ b/test/rubygems/test_gem_resolver_conflict.rb @@ -22,10 +22,17 @@ class TestGemResolverConflict < Gem::TestCase Gem::Resolver::Conflict.new child, active expected = <<-EXPECTED - Activated net-ssh-2.2.2 via: - net-ssh-2.2.2 (>= 2.0.13) - instead of (>= 2.6.5) via: - net-ssh-2.2.2 (>= 2.0.13), rye-0.9.8 (= 0.9.8) + Activated net-ssh-2.2.2 + which does not match conflicting dependency (>= 2.6.5) + + Conflicting dependency chains: + net-ssh (>= 2.0.13), 2.2.2 activated + + versus: + rye (= 0.9.8), 0.9.8 activated, depends on + net-ssh (>= 2.0.13), 2.2.2 activated, depends on + net-ssh (>= 2.6.5) + EXPECTED assert_equal expected, conflict.explanation @@ -44,10 +51,15 @@ class TestGemResolverConflict < Gem::TestCase conflict = @DR::Conflict.new a1_req, activated expected = <<-EXPECTED - Activated a-2 via: - a-2 (= 2) - instead of (= 1) via: - user request (gem command or Gemfile) + Activated a-2 + which does not match conflicting dependency (= 1) + + Conflicting dependency chains: + a (= 2), 2 activated + + versus: + a (= 1) + EXPECTED assert_equal expected, conflict.explanation @@ -64,8 +76,8 @@ class TestGemResolverConflict < Gem::TestCase Gem::Resolver::Conflict.new nil, nil expected = [ - 'net-ssh-2.2.2 (>= 2.0.13)', - 'rye-0.9.8 (= 0.9.8)' + 'net-ssh (>= 2.0.13), 2.2.2 activated', + 'rye (= 0.9.8), 0.9.8 activated' ] assert_equal expected, conflict.request_path(child.requester) diff --git a/test/rubygems/test_gem_resolver_dependency_request.rb b/test/rubygems/test_gem_resolver_dependency_request.rb index e1a98826fb..0665883971 100644 --- a/test/rubygems/test_gem_resolver_dependency_request.rb +++ b/test/rubygems/test_gem_resolver_dependency_request.rb @@ -8,6 +8,70 @@ class TestGemResolverDependencyRequest < Gem::TestCase @DR = Gem::Resolver::DependencyRequest end + def test_development_eh + a_dep = dep 'a', '>= 1' + + a_dep_req = @DR.new a_dep, nil + + refute a_dep_req.development? + + b_dep = dep 'b', '>= 1', :development + + b_dep_req = @DR.new b_dep, nil + + assert b_dep_req.development? + end + + def test_match_eh + spec = util_spec 'a', 1 + dependency = dep 'a', '>= 1' + + dr = @DR.new dependency, nil + + assert dr.match? spec + end + + def test_match_eh_prerelease + spec = util_spec 'a', '1.a' + + a_dep = dep 'a', '>= 1' + a_dr = @DR.new a_dep, nil + + refute a_dr.match? spec + + a_pre_dep = dep 'a', '>= 1.a' + a_pre_dr = @DR.new a_pre_dep, nil + + assert a_pre_dr.match? spec + end + + def test_match_eh_prerelease_allow_prerelease + spec = util_spec 'a', '2.a' + + a_dep = dep 'a', '>= 1' + a_dr = @DR.new a_dep, nil + + assert a_dr.match? spec, true + end + + def test_matches_spec_eh + spec = util_spec 'a', 1 + dependency = dep 'a', '>= 1' + + dr = @DR.new dependency, nil + + assert dr.matches_spec? spec + end + + def test_matches_spec_eh_prerelease + spec = util_spec 'a', '1.a' + + dependency = dep 'a', '>= 0' + dr = @DR.new dependency, nil + + assert dr.matches_spec? spec + end + def test_requirement dependency = dep 'a', '>= 1' diff --git a/test/rubygems/test_gem_resolver_git_set.rb b/test/rubygems/test_gem_resolver_git_set.rb index f82b942777..3659193456 100644 --- a/test/rubygems/test_gem_resolver_git_set.rb +++ b/test/rubygems/test_gem_resolver_git_set.rb @@ -85,6 +85,32 @@ class TestGemResolverGitSet < Gem::TestCase assert_empty @set.find_all dependency end + def test_find_all_prerelease + name, _, repository, = git_gem 'a', '1.a' + + @set.add_git_gem name, repository, 'master', false + + dependency = dep 'a', '>= 0' + req = Gem::Resolver::DependencyRequest.new dependency, nil + @reqs.add req + + @set.prefetch @reqs + + found = @set.find_all dependency + + assert_empty found + + dependency = dep 'a', '>= 0.a' + req = Gem::Resolver::DependencyRequest.new dependency, nil + @reqs.add req + + @set.prefetch @reqs + + found = @set.find_all dependency + + refute_empty found + end + def test_root_dir assert_equal Gem.dir, @set.root_dir diff --git a/test/rubygems/test_gem_resolver_git_specification.rb b/test/rubygems/test_gem_resolver_git_specification.rb index c9b040c117..a31674a218 100644 --- a/test/rubygems/test_gem_resolver_git_specification.rb +++ b/test/rubygems/test_gem_resolver_git_specification.rb @@ -32,6 +32,18 @@ class TestGemResolverGitSpecification < Gem::TestCase refute_equal g_spec_a, i_spec end + def test_add_dependency + git_gem 'a', 1 + + git_spec = Gem::Resolver::GitSpecification.new @set, @spec + + b_dep = dep 'b' + + git_spec.add_dependency b_dep + + assert_equal [b_dep], git_spec.dependencies + end + def test_install git_gem 'a', 1 diff --git a/test/rubygems/test_gem_resolver_index_set.rb b/test/rubygems/test_gem_resolver_index_set.rb index b0adc511c9..04ef8844c1 100644 --- a/test/rubygems/test_gem_resolver_index_set.rb +++ b/test/rubygems/test_gem_resolver_index_set.rb @@ -22,6 +22,8 @@ class TestGemResolverIndexSet < Gem::TestCase fetcher = set.instance_variable_get :@f refute_same Gem::SpecFetcher.fetcher, fetcher + + refute_empty set.errors end def test_find_all @@ -31,7 +33,7 @@ class TestGemResolverIndexSet < Gem::TestCase fetcher.spec 'b', 1 end - set = @DR::BestSet.new + set = @DR::IndexSet.new dependency = dep 'a', '~> 1' @@ -49,7 +51,7 @@ class TestGemResolverIndexSet < Gem::TestCase fetcher.spec 'b', 1 end - set = @DR::BestSet.new + set = @DR::IndexSet.new set.remote = false dependency = dep 'a', '~> 1' @@ -59,5 +61,29 @@ class TestGemResolverIndexSet < Gem::TestCase assert_empty set.find_all req end + def test_find_all_prerelease + spec_fetcher do |fetcher| + fetcher.spec 'a', '1.a' + end + + set = @DR::IndexSet.new + + dependency = dep 'a' + + req = @DR::DependencyRequest.new dependency, nil + + found = set.find_all req + + assert_empty found + + dependency.prerelease = true + + req = @DR::DependencyRequest.new dependency, nil + + found = set.find_all req + + assert_equal %w[a-1.a], found.map { |s| s.full_name } + end + end diff --git a/test/rubygems/test_gem_resolver_installer_set.rb b/test/rubygems/test_gem_resolver_installer_set.rb index 258f9bc803..3096a23011 100644 --- a/test/rubygems/test_gem_resolver_installer_set.rb +++ b/test/rubygems/test_gem_resolver_installer_set.rb @@ -2,6 +2,101 @@ require 'rubygems/test_case' class TestGemResolverInstallerSet < Gem::TestCase + def test_add_always_install + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', 2 + fetcher.clear + end + + util_gem 'a', 1 + + set = Gem::Resolver::InstallerSet.new :both + + set.add_always_install dep('a') + + assert_equal %w[a-2], set.always_install.map { |s| s.full_name } + + e = assert_raises Gem::UnsatisfiableDependencyError do + set.add_always_install dep('b') + end + + assert_equal dep('b'), e.dependency.dependency + end + + def test_add_always_install_errors + @fetcher = Gem::FakeFetcher.new + Gem::RemoteFetcher.fetcher = @fetcher + + set = Gem::Resolver::InstallerSet.new :both + + e = assert_raises Gem::UnsatisfiableDependencyError do + set.add_always_install dep 'a' + end + + refute_empty e.errors + end + + def test_add_always_install_platform + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', 2 do |s| + s.platform = Gem::Platform.new 'x86-freebsd-9' + end + fetcher.clear + end + + set = Gem::Resolver::InstallerSet.new :both + + set.add_always_install dep('a') + + assert_equal %w[a-1], set.always_install.map { |s| s.full_name } + end + + def test_add_always_install_prerelease + spec_fetcher do |fetcher| + fetcher.gem 'a', 1 + fetcher.gem 'a', '3.a' + end + + set = Gem::Resolver::InstallerSet.new :both + + set.add_always_install dep('a') + + assert_equal %w[a-1], set.always_install.map { |s| s.full_name } + end + + def test_add_always_install_prerelease_only + spec_fetcher do |fetcher| + fetcher.gem 'a', '3.a' + end + + set = Gem::Resolver::InstallerSet.new :both + + assert_raises Gem::UnsatisfiableDependencyError do + set.add_always_install dep('a') + end + end + + def test_add_local + a_1, a_1_gem = util_gem 'a', 1 + + a_1_source = Gem::Source::SpecificFile.new a_1_gem + + set = Gem::Resolver::InstallerSet.new :both + + set.add_local File.basename(a_1_gem), a_1, a_1_source + + assert set.local? File.basename(a_1_gem) + + FileUtils.rm a_1_gem + util_clear_gems + + req = Gem::Resolver::DependencyRequest.new dep('a'), nil + + assert_equal %w[a-1], set.find_all(req).map { |spec| spec.full_name } + end + def test_consider_local_eh set = Gem::Resolver::InstallerSet.new :remote @@ -30,6 +125,54 @@ class TestGemResolverInstallerSet < Gem::TestCase refute set.consider_remote? end + def test_errors + set = Gem::Resolver::InstallerSet.new :both + + set.instance_variable_get(:@errors) << :a + + req = Gem::Resolver::DependencyRequest.new dep('a'), nil + + set.find_all req + + assert_equal [:a, set.remote_set.errors.first], set.errors + end + + def test_find_all_always_install + spec_fetcher do |fetcher| + fetcher.spec 'a', 2 + fetcher.clear + end + + util_gem 'a', 1 + + set = Gem::Resolver::InstallerSet.new :both + + set.add_always_install dep 'a' + + req = Gem::Resolver::DependencyRequest.new dep('a'), nil + + assert_equal %w[a-2], set.find_all(req).map { |spec| spec.full_name } + end + + def test_find_all_prerelease + spec_fetcher do |fetcher| + fetcher.spec 'a', '1' + fetcher.spec 'a', '1.a' + fetcher.clear + end + + set = Gem::Resolver::InstallerSet.new :both + + req = Gem::Resolver::DependencyRequest.new dep('a'), nil + + assert_equal %w[a-1], set.find_all(req).map { |spec| spec.full_name } + + req = Gem::Resolver::DependencyRequest.new dep('a', '>= 0.a'), nil + + assert_equal %w[a-1 a-1.a], + set.find_all(req).map { |spec| spec.full_name }.sort + end + def test_load_spec specs = spec_fetcher do |fetcher| fetcher.spec 'a', 2 @@ -46,6 +189,18 @@ class TestGemResolverInstallerSet < Gem::TestCase assert_equal specs["a-2-#{Gem::Platform.local}"].full_name, spec.full_name end + def test_prerelease_equals + set = Gem::Resolver::InstallerSet.new :remote + + refute set.prerelease + refute set.remote_set.prerelease + + set.prerelease = true + + assert set.prerelease + assert set.remote_set.prerelease + end + def test_remote_equals_both set = Gem::Resolver::InstallerSet.new :both set.remote = true diff --git a/test/rubygems/test_gem_resolver_lock_set.rb b/test/rubygems/test_gem_resolver_lock_set.rb index 51ddad42f0..fdcb8ffa98 100644 --- a/test/rubygems/test_gem_resolver_lock_set.rb +++ b/test/rubygems/test_gem_resolver_lock_set.rb @@ -5,14 +5,15 @@ class TestGemResolverLockSet < Gem::TestCase def setup super - @source = Gem::Source.new @gem_repo - @lock_source = Gem::Source::Lock.new @source + @sources = [Gem::Source.new(@gem_repo)] + @lock_source = Gem::Source::Lock.new @sources.first - @set = Gem::Resolver::LockSet.new @source + @set = Gem::Resolver::LockSet.new @sources end def test_add - spec = @set.add 'a', '2', Gem::Platform::RUBY + specs = @set.add 'a', '2', Gem::Platform::RUBY + spec = specs.first assert_equal %w[a-2], @set.specs.map { |t| t.full_name } @@ -26,12 +27,17 @@ class TestGemResolverLockSet < Gem::TestCase end def test_find_all - @set.add 'a', '2', Gem::Platform::RUBY - @set.add 'b', '2', Gem::Platform::RUBY + @set.add 'a', '1.a', Gem::Platform::RUBY + @set.add 'a', '2', Gem::Platform::RUBY + @set.add 'b', '2', Gem::Platform::RUBY found = @set.find_all dep 'a' assert_equal %w[a-2], found.map { |s| s.full_name } + + found = @set.find_all dep 'a', '>= 0.a' + + assert_equal %w[a-1.a a-2], found.map { |s| s.full_name } end def test_load_spec diff --git a/test/rubygems/test_gem_resolver_lock_specification.rb b/test/rubygems/test_gem_resolver_lock_specification.rb index 5741950fe0..f8a336e658 100644 --- a/test/rubygems/test_gem_resolver_lock_specification.rb +++ b/test/rubygems/test_gem_resolver_lock_specification.rb @@ -9,7 +9,7 @@ class TestGemResolverLockSpecification < Gem::TestCase @LS = Gem::Resolver::LockSpecification @source = Gem::Source.new @gem_repo - @set = Gem::Resolver::LockSet.new @source + @set = Gem::Resolver::LockSet.new [@source] end def test_initialize @@ -83,5 +83,16 @@ class TestGemResolverLockSpecification < Gem::TestCase assert_equal [b_dep, c_dep], l_spec.spec.dependencies end + def test_spec_loaded + real_spec = util_spec 'a', 2 + real_spec.activate + + version = v(2) + + l_spec = @LS.new @set, 'a', version, @source, Gem::Platform::RUBY + + assert_same real_spec, l_spec.spec + end + end diff --git a/test/rubygems/test_gem_resolver_specification.rb b/test/rubygems/test_gem_resolver_specification.rb index 2c9c143cee..e1ec68a22c 100644 --- a/test/rubygems/test_gem_resolver_specification.rb +++ b/test/rubygems/test_gem_resolver_specification.rb @@ -3,6 +3,7 @@ require 'rubygems/test_case' class TestGemResolverSpecification < Gem::TestCase class TestSpec < Gem::Resolver::Specification + attr_writer :source attr_reader :spec def initialize spec @@ -12,6 +13,26 @@ class TestGemResolverSpecification < Gem::TestCase end end + def test_install + gemhome = "#{@gemhome}2" + spec_fetcher do |fetcher| + fetcher.gem 'a', 1 + end + + a = util_spec 'a', 1 + + a_spec = TestSpec.new a + a_spec.source = Gem::Source.new @gem_repo + + a_spec.install :install_dir => gemhome + + assert_path_exists File.join gemhome, 'gems', a.full_name + + expected = File.join gemhome, 'specifications', a.spec_name + + assert_equal expected, a_spec.spec.loaded_from + end + def test_installable_platform_eh a = util_spec 'a', 1 @@ -28,5 +49,16 @@ class TestGemResolverSpecification < Gem::TestCase refute b_spec.installable_platform? end + def test_source + a = util_spec 'a', 1 + + source = Gem::Source.new @gem_repo + + a_spec = TestSpec.new a + a_spec.source = source + + assert_equal source, a_spec.source + end + end diff --git a/test/rubygems/test_gem_resolver_vendor_set.rb b/test/rubygems/test_gem_resolver_vendor_set.rb index 4c1e14609d..618e251de2 100644 --- a/test/rubygems/test_gem_resolver_vendor_set.rb +++ b/test/rubygems/test_gem_resolver_vendor_set.rb @@ -11,10 +11,12 @@ class TestGemResolverVendorSet < Gem::TestCase def test_add_vendor_gem name, version, directory = vendor_gem - @set.add_vendor_gem name, directory + added = @set.add_vendor_gem name, directory spec = @set.load_spec name, version, Gem::Platform::RUBY, nil + assert_equal spec, added + assert_equal "#{name}-#{version}", spec.full_name assert_equal File.expand_path(directory), spec.full_gem_path @@ -55,6 +57,20 @@ class TestGemResolverVendorSet < Gem::TestCase assert_equal expected, found end + def test_find_all_prerelease + name, _, directory = vendor_gem 'a', '1.a' + + @set.add_vendor_gem name, directory + + req = Gem::Resolver::DependencyRequest.new dep('a'), nil + + assert_empty @set.find_all req + + req = Gem::Resolver::DependencyRequest.new dep('a', '>= 0.a'), nil + + refute_empty @set.find_all req + end + def test_load_spec error = Object.const_defined?(:KeyError) ? KeyError : IndexError diff --git a/test/rubygems/test_gem_security_policy.rb b/test/rubygems/test_gem_security_policy.rb index a2115e709a..d708306e79 100644 --- a/test/rubygems/test_gem_security_policy.rb +++ b/test/rubygems/test_gem_security_policy.rb @@ -347,7 +347,7 @@ class TestGemSecurityPolicy < Gem::TestCase assert_match "WARNING: some_gem is not signed\n", @ui.error assert_raises Gem::Security::Exception do - @almost_no.verify [PUBLIC_CERT], nil, digests, {} + @high.verify [PUBLIC_CERT], nil, digests, {} end end @@ -513,7 +513,7 @@ class TestGemSecurityPolicy < Gem::TestCase digests['SHA1']['data.tar.gz'] = OpenSSL::Digest.new 'SHA1', 'hello' assert_raises Gem::Security::Exception do - @almost_no.verify_signatures @spec, digests, {} + @high.verify_signatures @spec, digests, {} end end diff --git a/test/rubygems/test_gem_server.rb b/test/rubygems/test_gem_server.rb index b55b019268..964048615c 100644 --- a/test/rubygems/test_gem_server.rb +++ b/test/rubygems/test_gem_server.rb @@ -10,8 +10,9 @@ class TestGemServer < Gem::TestCase def setup super - @a1 = quick_gem 'a', '1' - @a2 = quick_gem 'a', '2' + @a1 = quick_gem 'a', '1' + @a2 = quick_gem 'a', '2' + @a3_p = quick_gem 'a', '3.a' @server = Gem::Server.new Gem.dir, process_based_port, false @req = WEBrick::HTTPRequest.new :Logger => nil @@ -144,6 +145,36 @@ class TestGemServer < Gem::TestCase assert_equal 2, @server.server.listeners.length end + def test_prerelease_specs + data = StringIO.new "GET /prerelease_specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n" + @req.parse data + + Gem::Deprecate.skip_during do + @server.prerelease_specs @req, @res + end + + assert_equal 200, @res.status, @res.body + assert_match %r| \d\d:\d\d:\d\d |, @res['date'] + assert_equal 'application/octet-stream', @res['content-type'] + assert_equal [['a', v('3.a'), Gem::Platform::RUBY]], + Marshal.load(@res.body) + end + + def test_prerelease_specs_gz + data = StringIO.new "GET /prerelease_specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n" + @req.parse data + + Gem::Deprecate.skip_during do + @server.prerelease_specs @req, @res + end + + assert_equal 200, @res.status, @res.body + assert_match %r| \d\d:\d\d:\d\d |, @res['date'] + assert_equal 'application/x-gzip', @res['content-type'] + assert_equal [['a', v('3.a'), Gem::Platform::RUBY]], + Marshal.load(Gem.gunzip(@res.body)) + end + def test_quick_gemdirs data = StringIO.new "GET /quick/Marshal.4.8/z-9.gemspec.rz HTTP/1.0\r\n\r\n" dir = "#{@gemhome}2" @@ -223,6 +254,38 @@ class TestGemServer < Gem::TestCase assert_equal Gem::Platform.local, spec.platform end + def test_quick_marshal_a_3_a_gemspec_rz + data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-3.a.gemspec.rz HTTP/1.0\r\n\r\n" + @req.parse data + + @server.quick @req, @res + + assert_equal 200, @res.status, @res.body + assert @res['date'] + assert_equal 'application/x-deflate', @res['content-type'] + + spec = Marshal.load Gem.inflate(@res.body) + assert_equal 'a', spec.name + assert_equal v('3.a'), spec.version + end + + def test_quick_marshal_a_b_3_a_gemspec_rz + quick_gem 'a-b', '3.a' + + data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-b-3.a.gemspec.rz HTTP/1.0\r\n\r\n" + @req.parse data + + @server.quick @req, @res + + assert_equal 200, @res.status, @res.body + assert @res['date'] + assert_equal 'application/x-deflate', @res['content-type'] + + spec = Marshal.load Gem.inflate(@res.body) + assert_equal 'a-b', spec.name + assert_equal v('3.a'), spec.version + end + def test_rdoc data = StringIO.new "GET /rdoc?q=a HTTP/1.0\r\n\r\n" @req.parse data @@ -279,7 +342,8 @@ class TestGemServer < Gem::TestCase assert_equal 'application/octet-stream', @res['content-type'] assert_equal [['a', Gem::Version.new(1), Gem::Platform::RUBY], - ['a', Gem::Version.new(2), Gem::Platform::RUBY]], + ['a', Gem::Version.new(2), Gem::Platform::RUBY], + ['a', v('3.a'), Gem::Platform::RUBY]], Marshal.load(@res.body) end @@ -318,7 +382,8 @@ class TestGemServer < Gem::TestCase assert_equal 'application/x-gzip', @res['content-type'] assert_equal [['a', Gem::Version.new(1), Gem::Platform::RUBY], - ['a', Gem::Version.new(2), Gem::Platform::RUBY]], + ['a', Gem::Version.new(2), Gem::Platform::RUBY], + ['a', v('3.a'), Gem::Platform::RUBY]], Marshal.load(Gem.gunzip(@res.body)) end diff --git a/test/rubygems/test_gem_source.rb b/test/rubygems/test_gem_source.rb index d207bcac7f..9ded7f7c03 100644 --- a/test/rubygems/test_gem_source.rb +++ b/test/rubygems/test_gem_source.rb @@ -1,5 +1,6 @@ require 'rubygems/test_case' require 'rubygems/source' +require 'rubygems/indexer' class TestGemSource < Gem::TestCase @@ -40,13 +41,28 @@ class TestGemSource < Gem::TestCase end def test_dependency_resolver_set_bundler_api - @fetcher.data["#{@gem_repo}api/v1/dependencies"] = 'data' + response = Net::HTTPResponse.new '1.1', 200, 'OK' + response.uri = URI('http://example') if response.respond_to? :uri + + @fetcher.data["#{@gem_repo}api/v1/dependencies"] = response set = @source.dependency_resolver_set assert_kind_of Gem::Resolver::APISet, set end + def test_dependency_resolver_set_file_uri + skip 'install builder gem' unless defined? Builder::XChar + + Gem::Indexer.new(@tempdir).generate_index + + source = Gem::Source.new "file://#{@tempdir}/" + + set = source.dependency_resolver_set + + assert_kind_of Gem::Resolver::IndexSet, set + end + def test_dependency_resolver_set_marshal_api set = @source.dependency_resolver_set diff --git a/test/rubygems/test_gem_source_git.rb b/test/rubygems/test_gem_source_git.rb index 58bff84490..cf5f088c03 100644 --- a/test/rubygems/test_gem_source_git.rb +++ b/test/rubygems/test_gem_source_git.rb @@ -27,6 +27,21 @@ class TestGemSourceGit < Gem::TestCase assert_path_exists File.join @source.install_dir, 'a.gemspec' end + def test_checkout_master + Dir.chdir @repository do + system @git, 'checkout', '-q', '-b', 'other' + system @git, 'mv', 'a.gemspec', 'b.gemspec' + system @git, 'commit', '-q', '-a', '-m', 'rename gemspec' + system @git, 'checkout', '-q', 'master' + end + + @source = Gem::Source::Git.new @name, @repository, 'other', false + + @source.checkout + + assert_path_exists File.join @source.install_dir, 'b.gemspec' + end + def test_checkout_local @source.remote = false @@ -179,14 +194,18 @@ class TestGemSourceGit < Gem::TestCase git = Gem::Source::Git.new 'a', 'git/a', 'master', false remote = Gem::Source.new @gem_repo installed = Gem::Source::Installed.new + vendor = Gem::Source::Vendor.new 'vendor/foo' assert_equal( 0, git. <=>(git), 'git <=> git') assert_equal( 1, git. <=>(remote), 'git <=> remote') assert_equal(-1, remote. <=>(git), 'remote <=> git') - assert_equal( 1, installed.<=>(git), 'installed <=> git') - assert_equal(-1, git. <=>(installed), 'git <=> installed') + assert_equal( 1, git. <=>(installed), 'git <=> installed') + assert_equal(-1, installed.<=>(git), 'installed <=> git') + + assert_equal(-1, git. <=>(vendor), 'git <=> vendor') + assert_equal( 1, vendor. <=>(git), 'vendor <=> git') end def test_specs @@ -254,6 +273,10 @@ class TestGemSourceGit < Gem::TestCase end end + def test_uri + assert_equal URI(@repository), @source.uri + end + def test_uri_hash assert_equal @hash, @source.uri_hash diff --git a/test/rubygems/test_gem_source_installed.rb b/test/rubygems/test_gem_source_installed.rb index 1119ad0c2b..9eaddf72fd 100644 --- a/test/rubygems/test_gem_source_installed.rb +++ b/test/rubygems/test_gem_source_installed.rb @@ -11,6 +11,8 @@ class TestGemSourceInstalled < Gem::TestCase specific = Gem::Source::SpecificFile.new a1.cache_file installed = Gem::Source::Installed.new local = Gem::Source::Local.new + git = Gem::Source::Git.new 'a', 'a', 'master' + vendor = Gem::Source::Vendor.new 'a' assert_equal( 0, installed.<=>(installed), 'installed <=> installed') @@ -22,6 +24,12 @@ class TestGemSourceInstalled < Gem::TestCase assert_equal(-1, specific. <=>(installed), 'specific <=> installed') assert_equal( 1, installed.<=>(specific), 'installed <=> specific') + + assert_equal( 1, git. <=>(installed), 'git <=> installed') + assert_equal(-1, installed.<=>(git), 'installed <=> git') + + assert_equal( 1, vendor. <=>(installed), 'vendor <=> installed') + assert_equal(-1, installed.<=>(vendor), 'installed <=> vendor') end end diff --git a/test/rubygems/test_gem_source_lock.rb b/test/rubygems/test_gem_source_lock.rb index c7c4b8ca3f..23f063da92 100644 --- a/test/rubygems/test_gem_source_lock.rb +++ b/test/rubygems/test_gem_source_lock.rb @@ -43,8 +43,8 @@ class TestGemSourceLock < Gem::TestCase assert_equal( 0, i_lock.<=>(i_lock), 'i_lock <=> i_lock') assert_equal( 0, v_lock.<=>(v_lock), 'v_lock <=> v_lock') - assert_equal(-1, g_lock.<=>(i_lock), 'g_lock <=> i_lock') - assert_equal( 1, i_lock.<=>(g_lock), 'i_lock <=> g_lock') + assert_equal( 1, g_lock.<=>(i_lock), 'g_lock <=> i_lock') + assert_equal(-1, i_lock.<=>(g_lock), 'i_lock <=> g_lock') assert_equal(-1, g_lock.<=>(v_lock), 'g_lock <=> v_lock') assert_equal( 1, v_lock.<=>(g_lock), 'v_lock <=> g_lock') diff --git a/test/rubygems/test_gem_source_specific_file.rb b/test/rubygems/test_gem_source_specific_file.rb index fd1f4491ac..12ef7f5b7c 100644 --- a/test/rubygems/test_gem_source_specific_file.rb +++ b/test/rubygems/test_gem_source_specific_file.rb @@ -9,6 +9,10 @@ class TestGemSourceSpecificFile < Gem::TestCase @sf = Gem::Source::SpecificFile.new(@a_gem) end + def test_path + assert_equal @a_gem, @sf.path + end + def test_spec assert_equal @a, @sf.spec end diff --git a/test/rubygems/test_gem_source_vendor.rb b/test/rubygems/test_gem_source_vendor.rb index 3f4121e5f6..1d9ae35e84 100644 --- a/test/rubygems/test_gem_source_vendor.rb +++ b/test/rubygems/test_gem_source_vendor.rb @@ -12,6 +12,7 @@ class TestGemSourceVendor < Gem::TestCase def test_spaceship vendor = Gem::Source::Vendor.new 'vendor/foo' remote = Gem::Source.new @gem_repo + git = Gem::Source::Git.new 'a', 'a', 'master' installed = Gem::Source::Installed.new assert_equal( 0, vendor. <=>(vendor), 'vendor <=> vendor') @@ -19,6 +20,9 @@ class TestGemSourceVendor < Gem::TestCase assert_equal( 1, vendor. <=>(remote), 'vendor <=> remote') assert_equal(-1, remote. <=>(vendor), 'remote <=> vendor') + assert_equal( 1, vendor. <=>(git), 'vendor <=> git') + assert_equal(-1, git. <=>(vendor), 'git <=> vendor') + assert_equal( 1, vendor. <=>(installed), 'vendor <=> installed') assert_equal(-1, installed.<=>(vendor), 'installed <=> vendor') end diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb index e1c6a1b549..146e249381 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -225,7 +225,7 @@ end util_spec 'b', '2.0' c, _ = util_spec 'c', '1.0', 'b' => '= 2.0' - e = assert_raises Gem::LoadError do + e = assert_raises Gem::ConflictError do assert_activate nil, a, c, "b" end @@ -1135,6 +1135,24 @@ dependencies: [] assert_equal %w[lib/code.rb], @a2.files end + def test_build_args + ext_spec + + assert_empty @ext.build_args + + open @ext.build_info_file, 'w' do |io| + io.puts + end + + assert_empty @ext.build_args + + open @ext.build_info_file, 'w' do |io| + io.puts '--with-foo-dir=wherever' + end + + assert_equal %w[--with-foo-dir=wherever], @ext.build_args + end + def test_build_extensions ext_spec @@ -1231,11 +1249,10 @@ dependencies: [] FileUtils.chmod 0555, @ext.base_dir FileUtils.chmod 0555, File.join(@ext.base_dir, 'extensions') - assert_raises Errno::EACCES do - @ext.build_extensions - end + @ext.build_extensions + refute_path_exists @ext.extension_dir ensure - unless Gem.win_platform? then + unless ($DEBUG or win_platform?) then FileUtils.chmod 0755, File.join(@ext.base_dir, 'extensions') FileUtils.chmod 0755, @ext.base_dir end @@ -1331,22 +1348,14 @@ dependencies: [] def test_contains_requirable_file_eh_extension ext_spec - extconf_rb = File.join @ext.gem_dir, @ext.extensions.first - FileUtils.mkdir_p File.dirname extconf_rb - - open extconf_rb, 'w' do |f| - f.write <<-'RUBY' - open 'Makefile', 'w' do |f| - f.puts "clean:\n\techo cleaned" - f.puts "default:\n\techo built" - f.puts "install:\n\techo installed" - end - RUBY + _, err = capture_io do + refute @ext.contains_requirable_file? 'nonexistent' end - refute @ext.contains_requirable_file? 'nonexistent' + expected = "Ignoring ext-1 because its extensions are not built. " + + "Try: gem pristine ext-1\n" - assert_path_exists @ext.extension_dir + assert_equal expected, err end def test_date @@ -1791,13 +1800,33 @@ dependencies: [] enable_shared 'no' do ext_spec - @ext.require_path = 'lib' + @ext.require_paths = 'lib' - ext_install_dir = Pathname(@ext.extension_dir) - full_gem_path = Pathname(@ext.full_gem_path) - relative_install_dir = ext_install_dir.relative_path_from full_gem_path + assert_equal [@ext.extension_dir, 'lib'], @ext.require_paths + end + end - assert_equal [relative_install_dir.to_s, 'lib'], @ext.require_paths + def test_require_paths_default_ext_dir_for + class << Gem + send :alias_method, :orig_default_ext_dir_for, :default_ext_dir_for + end + + def Gem.default_ext_dir_for base_dir + '/foo' + end + + enable_shared 'no' do + ext_spec + + @ext.require_paths = 'lib' + + assert_equal ['/foo/ext-1', 'lib'], @ext.require_paths + end + ensure + class << Gem + send :remove_method, :default_ext_dir_for + send :alias_method, :default_ext_dir_for, :orig_default_ext_dir_for + send :remove_method, :orig_default_ext_dir_for end end @@ -1824,7 +1853,7 @@ dependencies: [] def test_full_require_paths ext_spec - @ext.require_path = 'lib' + @ext.require_paths = 'lib' expected = [ @ext.extension_dir, @@ -2268,6 +2297,7 @@ end @a1.add_runtime_dependency 'k', '> 1.2' @a1.add_runtime_dependency 'l', '> 1.2.3' @a1.add_runtime_dependency 'm', '~> 2.1.0' + @a1.add_runtime_dependency 'n', '~> 0.1.0' use_ui @ui do @a1.validate @@ -2874,14 +2904,76 @@ end assert_equal @m1.to_ruby, valid_ruby_spec end + def test_missing_extensions_eh + ext_spec + + assert @ext.missing_extensions? + + extconf_rb = File.join @ext.gem_dir, @ext.extensions.first + FileUtils.mkdir_p File.dirname extconf_rb + + open extconf_rb, 'w' do |f| + f.write <<-'RUBY' + open 'Makefile', 'w' do |f| + f.puts "clean:\n\techo clean" + f.puts "default:\n\techo built" + f.puts "install:\n\techo installed" + end + RUBY + end + + @ext.build_extensions + + refute @ext.missing_extensions? + end + + def test_missing_extensions_eh_default_gem + spec = new_default_spec 'default', 1 + spec.extensions << 'extconf.rb' + + refute spec.missing_extensions? + end + + def test_missing_extensions_eh_legacy + ext_spec + + @ext.installed_by_version = v '2.2.0.preview.2' + + assert @ext.missing_extensions? + + @ext.installed_by_version = v '2.2.0.preview.1' + + refute @ext.missing_extensions? + end + + def test_missing_extensions_eh_none + refute @a1.missing_extensions? + end + def test_find_by_name - util_make_gems - assert(Gem::Specification.find_by_name("a")) - assert(Gem::Specification.find_by_name("a", "1")) - assert(Gem::Specification.find_by_name("a", ">1")) - assert_raises(Gem::LoadError) do - Gem::Specification.find_by_name("monkeys") + util_spec "a" + + assert Gem::Specification.find_by_name "a" + assert Gem::Specification.find_by_name "a", "1" + assert Gem::Specification.find_by_name "a", ">1" + + assert_raises Gem::LoadError do + Gem::Specification.find_by_name "monkeys" + end + end + + def test_find_by_name_prerelease + b = util_spec "b", "2.a" + + b.activate + + assert Gem::Specification.find_by_name "b" + + assert_raises Gem::LoadError do + Gem::Specification.find_by_name "b", "1" end + + assert Gem::Specification.find_by_name "b", ">1" end def test_find_by_path diff --git a/test/rubygems/test_gem_stub_specification.rb b/test/rubygems/test_gem_stub_specification.rb index c4c07597f5..d992567a5c 100644 --- a/test/rubygems/test_gem_stub_specification.rb +++ b/test/rubygems/test_gem_stub_specification.rb @@ -23,16 +23,11 @@ class TestStubSpecification < Gem::TestCase def test_initialize_extension stub = stub_with_extension - ext_install_dir = Pathname(stub.extension_dir) - full_gem_path = Pathname(stub.full_gem_path) - relative_install_dir = ext_install_dir.relative_path_from full_gem_path - relative_install_dir = relative_install_dir.to_s - - assert_equal 'stub_e', stub.name - assert_equal v(2), stub.version - assert_equal Gem::Platform::RUBY, stub.platform - assert_equal [relative_install_dir, 'lib'], stub.require_paths - assert_equal %w[ext/stub_e/extconf.rb], stub.extensions + assert_equal 'stub_e', stub.name + assert_equal v(2), stub.version + assert_equal Gem::Platform::RUBY, stub.platform + assert_equal [stub.extension_dir, 'lib'], stub.require_paths + assert_equal %w[ext/stub_e/extconf.rb], stub.extensions end def test_initialize_missing_stubline @@ -55,22 +50,14 @@ class TestStubSpecification < Gem::TestCase def test_contains_requirable_file_eh_extension stub_with_extension do |stub| - extconf_rb = File.join stub.gem_dir, stub.extensions.first - FileUtils.mkdir_p File.dirname extconf_rb - - open extconf_rb, 'w' do |f| - f.write <<-'RUBY' - open 'Makefile', 'w' do |f| - f.puts "clean:\n\techo cleaned" - f.puts "default:\n\techo built" - f.puts "install:\n\techo installed" - end - RUBY + _, err = capture_io do + refute stub.contains_requirable_file? 'nonexistent' end - refute stub.contains_requirable_file? 'nonexistent' + expected = "Ignoring stub_e-2 because its extensions are not built. " + + "Try: gem pristine stub_e-2\n" - assert_path_exists stub.extension_dir + assert_equal expected, err end end @@ -85,9 +72,70 @@ class TestStubSpecification < Gem::TestCase assert_equal expected, stub.full_require_paths end + def test_missing_extensions_eh + stub = stub_with_extension do |s| + extconf_rb = File.join s.gem_dir, s.extensions.first + FileUtils.mkdir_p File.dirname extconf_rb + + open extconf_rb, 'w' do |f| + f.write <<-'RUBY' + open 'Makefile', 'w' do |f| + f.puts "clean:\n\techo clean" + f.puts "default:\n\techo built" + f.puts "install:\n\techo installed" + end + RUBY + end + end + + assert stub.missing_extensions? + + stub.build_extensions + + refute stub.missing_extensions? + end + + def test_missing_extensions_eh_default_gem + spec = new_default_spec 'default', 1 + spec.extensions << 'extconf.rb' + + open spec.loaded_from, 'w' do |io| + io.write spec.to_ruby_for_cache + end + + default_spec = Gem::StubSpecification.new spec.loaded_from + + refute default_spec.missing_extensions? + end + + def test_missing_extensions_eh_none + refute @foo.missing_extensions? + end + def test_to_spec + real_foo = util_spec @foo.name, @foo.version + real_foo.activate + + assert_equal @foo.version, Gem.loaded_specs[@foo.name].version, + 'sanity check' + + assert_same real_foo, @foo.to_spec + end + + def test_to_spec_activated assert @foo.to_spec.is_a?(Gem::Specification) assert_equal "foo", @foo.to_spec.name + refute @foo.to_spec.instance_variable_defined? :@ignored + end + + def test_to_spec_missing_extensions + stub = stub_with_extension + + capture_io do + stub.contains_requirable_file? 'nonexistent' + end + + assert stub.to_spec.instance_variable_get :@ignored end def stub_with_extension diff --git a/test/rubygems/test_gem_uninstaller.rb b/test/rubygems/test_gem_uninstaller.rb index 11fdaf68e2..2a9a15d5b1 100644 --- a/test/rubygems/test_gem_uninstaller.rb +++ b/test/rubygems/test_gem_uninstaller.rb @@ -325,6 +325,29 @@ create_makefile '#{@spec.name}' assert_equal expected, e.message end + def test_uninstall_selection + util_make_gems + + list = Gem::Specification.find_all_by_name 'a' + + uninstaller = Gem::Uninstaller.new 'a' + + ui = Gem::MockGemUi.new "1\ny\n" + + use_ui ui do + uninstaller.uninstall + end + + updated_list = Gem::Specification.find_all_by_name('a') + assert_equal list.length - 1, updated_list.length + + assert_match ' 1. a-1', ui.output + assert_match ' 2. a-2', ui.output + assert_match ' 3. a-3.a', ui.output + assert_match ' 4. All versions', ui.output + assert_match 'uninstalled a-1', ui.output + end + def test_uninstall_selection_greater_than_one util_make_gems diff --git a/test/rubygems/test_gem_unsatisfiable_dependency_error.rb b/test/rubygems/test_gem_unsatisfiable_dependency_error.rb new file mode 100644 index 0000000000..6418c5d20e --- /dev/null +++ b/test/rubygems/test_gem_unsatisfiable_dependency_error.rb @@ -0,0 +1,32 @@ +require 'rubygems/test_case' + +class TestGemUnsatisfiableDependencyError < Gem::TestCase + + def setup + super + + @a_dep = dep 'a', '~> 1' + + @req = Gem::Resolver::DependencyRequest.new @a_dep, nil + + @e = Gem::UnsatisfiableDependencyError.new @req + end + + def test_errors + assert_equal [], @e.errors + + @e.errors << :a + + assert_equal [:a], @e.errors + end + + def test_name + assert_equal 'a', @e.name + end + + def test_version + assert_equal @a_dep.requirement, @e.version + end + +end + diff --git a/test/rubygems/test_kernel.rb b/test/rubygems/test_kernel.rb index 6210422506..6d25c48bc1 100644 --- a/test/rubygems/test_kernel.rb +++ b/test/rubygems/test_kernel.rb @@ -33,6 +33,12 @@ class TestKernel < Gem::TestCase assert_equal 1, $:.select { |p| %r{a-1/lib} =~ p }.size end + def test_gem_prerelease + quick_gem 'd', '1.1.a' + refute gem('d', '>= 1'), 'release requirement must not load prerelease' + assert gem('d', '>= 1.a'), 'prerelease requirement may load prerelease' + end + def test_gem_conflicting assert gem('a', '= 1'), "Should load" diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb index c52c9937fe..dec5285d21 100644 --- a/test/rubygems/test_require.rb +++ b/test/rubygems/test_require.rb @@ -2,6 +2,26 @@ require 'rubygems/test_case' require 'rubygems' class TestGemRequire < Gem::TestCase + class Latch + def initialize count = 1 + @count = count + @lock = Monitor.new + @cv = @lock.new_cond + end + + def release + @lock.synchronize do + @count -= 1 if @count > 0 + @cv.broadcast if @count.zero? + end + end + + def await + @lock.synchronize do + @cv.wait_while { @count > 0 } + end + end + end def setup super @@ -17,6 +37,46 @@ class TestGemRequire < Gem::TestCase assert require(path), "'#{path}' was already required" end + def append_latch spec + dir = spec.gem_dir + Dir.chdir dir do + spec.files.each do |file| + File.open file, 'a' do |fp| + fp.puts "FILE_ENTERED_LATCH.release" + fp.puts "FILE_EXIT_LATCH.await" + end + end + end + end + + def test_concurrent_require + Object.const_set :FILE_ENTERED_LATCH, Latch.new(2) + Object.const_set :FILE_EXIT_LATCH, Latch.new(1) + + a1 = new_spec "a", "1", nil, "lib/a.rb" + b1 = new_spec "b", "1", nil, "lib/b.rb" + + install_specs a1, b1 + + append_latch a1 + append_latch b1 + + t1 = Thread.new { assert_require 'a' } + t2 = Thread.new { assert_require 'b' } + + # wait until both files are waiting on the exit latch + FILE_ENTERED_LATCH.await + + # now let them finish + FILE_EXIT_LATCH.release + + assert t1.join, "thread 1 should exit" + assert t2.join, "thread 2 should exit" + ensure + Object.send :remove_const, :FILE_ENTERED_LATCH + Object.send :remove_const, :FILE_EXIT_LATCH + end + def test_require_is_not_lazy_with_exact_req a1 = new_spec "a", "1", {"b" => "= 1"}, "lib/test_gem_require_a.rb" b1 = new_spec "b", "1", nil, "lib/b/c.rb" |