summaryrefslogtreecommitdiff
path: root/test/rubygems/test_gem.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/rubygems/test_gem.rb')
-rw-r--r--test/rubygems/test_gem.rb557
1 files changed, 454 insertions, 103 deletions
diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb
index 45db153c22..fda83767f2 100644
--- a/test/rubygems/test_gem.rb
+++ b/test/rubygems/test_gem.rb
@@ -13,21 +13,128 @@ end
class TestGem < Gem::TestCase
- PLUGINS_LOADED = []
-
def setup
super
- PLUGINS_LOADED.clear
-
- common_installer_setup
-
ENV.delete 'RUBYGEMS_GEMDEPS'
@additional = %w[a b].map { |d| File.join @tempdir, d }
util_remove_interrupt_command
end
+ def assert_activate expected, *specs
+ specs.each do |spec|
+ case spec
+ when String then
+ Gem::Specification.find_by_name(spec).activate
+ when Gem::Specification then
+ spec.activate
+ else
+ flunk spec.inspect
+ end
+ end
+
+ loaded = Gem.loaded_specs.values.map(&:full_name)
+
+ assert_equal expected.sort, loaded.sort if expected
+ end
+
+ def test_self_activate
+ foo = util_spec 'foo', '1'
+
+ assert_activate %w[foo-1], foo
+ end
+
+ def loaded_spec_names
+ Gem.loaded_specs.values.map(&:full_name).sort
+ end
+
+ def unresolved_names
+ Gem::Specification.unresolved_deps.values.map(&:to_s).sort
+ end
+
+ # TODO: move these to specification
+ def test_self_activate_via_require
+ a1 = new_spec "a", "1", "b" => "= 1"
+ b1 = new_spec "b", "1", nil, "lib/b/c.rb"
+ b2 = new_spec "b", "2", nil, "lib/b/c.rb"
+
+ install_specs a1, b1, b2
+
+ a1.activate
+ save_loaded_features do
+ require "b/c"
+ end
+
+ assert_equal %w(a-1 b-1), loaded_spec_names
+ end
+
+ # TODO: move these to specification
+ def test_self_activate_deep_unambiguous
+ a1 = new_spec "a", "1", "b" => "= 1"
+ b1 = new_spec "b", "1", "c" => "= 1"
+ b2 = new_spec "b", "2", "c" => "= 2"
+ c1 = new_spec "c", "1"
+ c2 = new_spec "c", "2"
+
+ install_specs a1, b1, b2, c1, c2
+
+ a1.activate
+ assert_equal %w(a-1 b-1 c-1), loaded_spec_names
+ end
+
+ def save_loaded_features
+ old_loaded_features = $LOADED_FEATURES.dup
+ yield
+ ensure
+ $LOADED_FEATURES.replace old_loaded_features
+ end
+
+ # TODO: move these to specification
+ def test_self_activate_ambiguous_direct
+ save_loaded_features do
+ a1 = new_spec "a", "1", "b" => "> 0"
+ b1 = new_spec("b", "1", { "c" => ">= 1" }, "lib/d.rb")
+ b2 = new_spec("b", "2", { "c" => ">= 2" }, "lib/d.rb")
+ c1 = new_spec "c", "1"
+ c2 = new_spec "c", "2"
+
+ Gem::Specification.reset
+ install_specs a1, b1, b2, c1, c2
+
+ a1.activate
+ assert_equal %w(a-1), loaded_spec_names
+ assert_equal ["b (> 0)"], unresolved_names
+
+ require "d"
+
+ assert_equal %w(a-1 b-2 c-2), loaded_spec_names
+ assert_equal [], unresolved_names
+ end
+ end
+
+ # TODO: move these to specification
+ def test_self_activate_ambiguous_indirect
+ save_loaded_features do
+ a1 = new_spec "a", "1", "b" => "> 0"
+ b1 = new_spec "b", "1", "c" => ">= 1"
+ b2 = new_spec "b", "2", "c" => ">= 2"
+ c1 = new_spec "c", "1", nil, "lib/d.rb"
+ c2 = new_spec "c", "2", nil, "lib/d.rb"
+
+ install_specs a1, b1, b2, c1, c2
+
+ a1.activate
+ assert_equal %w(a-1), loaded_spec_names
+ assert_equal ["b (> 0)"], unresolved_names
+
+ require "d"
+
+ assert_equal %w(a-1 b-2 c-2), loaded_spec_names
+ assert_equal [], unresolved_names
+ end
+ end
+
def test_self_finish_resolve
save_loaded_features do
a1 = new_spec "a", "1", "b" => "> 0"
@@ -50,6 +157,36 @@ class TestGem < Gem::TestCase
end
end
+ def test_self_activate_via_require_wtf
+ save_loaded_features do
+ a1 = new_spec "a", "1", "b" => "> 0", "d" => "> 0" # this
+ b1 = new_spec "b", "1", { "c" => ">= 1" }, "lib/b.rb"
+ b2 = new_spec "b", "2", { "c" => ">= 2" }, "lib/b.rb" # this
+ c1 = new_spec "c", "1"
+ c2 = new_spec "c", "2" # this
+ d1 = new_spec "d", "1", { "c" => "< 2" }, "lib/d.rb"
+ d2 = new_spec "d", "2", { "c" => "< 2" }, "lib/d.rb" # this
+
+ install_specs a1, b1, b2, c1, c2, d1, d2
+
+ a1.activate
+
+ assert_equal %w(a-1), loaded_spec_names
+ assert_equal ["b (> 0)", "d (> 0)"], unresolved_names
+
+ require "b"
+
+ e = assert_raises Gem::LoadError do
+ require "d"
+ end
+
+ assert_equal "unable to find a version of 'd' to activate", e.message
+
+ assert_equal %w(a-1 b-2 c-2), loaded_spec_names
+ assert_equal ["d (> 0)"], unresolved_names
+ end
+ end
+
def test_self_finish_resolve_wtf
save_loaded_features do
a1 = new_spec "a", "1", "b" => "> 0", "d" => "> 0" # this
@@ -74,6 +211,94 @@ class TestGem < Gem::TestCase
end
end
+ # TODO: move these to specification
+ def test_self_activate_ambiguous_unrelated
+ save_loaded_features do
+ a1 = new_spec "a", "1", "b" => "> 0"
+ b1 = new_spec "b", "1", "c" => ">= 1"
+ b2 = new_spec "b", "2", "c" => ">= 2"
+ c1 = new_spec "c", "1"
+ c2 = new_spec "c", "2"
+ d1 = new_spec "d", "1", nil, "lib/d.rb"
+
+ install_specs a1, b1, b2, c1, c2, d1
+
+ a1.activate
+ assert_equal %w(a-1), loaded_spec_names
+ assert_equal ["b (> 0)"], unresolved_names
+
+ require "d"
+
+ assert_equal %w(a-1 d-1), loaded_spec_names
+ assert_equal ["b (> 0)"], unresolved_names
+ end
+ end
+
+ # TODO: move these to specification
+ def test_self_activate_ambiguous_indirect_conflict
+ save_loaded_features do
+ a1 = new_spec "a", "1", "b" => "> 0"
+ a2 = new_spec "a", "2", "b" => "> 0"
+ b1 = new_spec "b", "1", "c" => ">= 1"
+ b2 = new_spec "b", "2", "c" => ">= 2"
+ c1 = new_spec "c", "1", nil, "lib/d.rb"
+ c2 = new_spec("c", "2", { "a" => "1" }, "lib/d.rb") # conflicts with a-2
+
+ install_specs a1, a2, b1, b2, c1, c2
+
+ a2.activate
+ assert_equal %w(a-2), loaded_spec_names
+ assert_equal ["b (> 0)"], unresolved_names
+
+ require "d"
+
+ assert_equal %w(a-2 b-1 c-1), loaded_spec_names
+ assert_equal [], unresolved_names
+ end
+ end
+
+ # TODO: move these to specification
+ def test_require_already_activated
+ save_loaded_features do
+ a1 = new_spec "a", "1", nil, "lib/d.rb"
+
+ install_specs a1 # , a2, b1, b2, c1, c2
+
+ a1.activate
+ assert_equal %w(a-1), loaded_spec_names
+ assert_equal [], unresolved_names
+
+ assert require "d"
+
+ assert_equal %w(a-1), loaded_spec_names
+ assert_equal [], unresolved_names
+ end
+ end
+
+ # TODO: move these to specification
+ def test_require_already_activated_indirect_conflict
+ save_loaded_features do
+ a1 = new_spec "a", "1", "b" => "> 0"
+ a2 = new_spec "a", "2", "b" => "> 0"
+ b1 = new_spec "b", "1", "c" => ">= 1"
+ b2 = new_spec "b", "2", "c" => ">= 2"
+ c1 = new_spec "c", "1", nil, "lib/d.rb"
+ c2 = new_spec("c", "2", { "a" => "1" }, "lib/d.rb") # conflicts with a-2
+
+ install_specs a1, a2, b1, b2, c1, c2
+
+ a1.activate
+ c1.activate
+ assert_equal %w(a-1 c-1), loaded_spec_names
+ assert_equal ["b (> 0)"], unresolved_names
+
+ assert require "d"
+
+ assert_equal %w(a-1 c-1), loaded_spec_names
+ assert_equal ["b (> 0)"], unresolved_names
+ end
+ end
+
def test_require_missing
save_loaded_features do
assert_raises ::LoadError do
@@ -96,6 +321,221 @@ class TestGem < Gem::TestCase
end
end
+ # TODO: move these to specification
+ def test_self_activate_loaded
+ foo = util_spec 'foo', '1'
+
+ assert foo.activate
+ refute foo.activate
+ end
+
+ ##
+ # [A] depends on
+ # [B] >= 1.0 (satisfied by 2.0)
+ # [C] depends on nothing
+
+ def test_self_activate_unrelated
+ a = util_spec 'a', '1.0', 'b' => '>= 1.0'
+ util_spec 'b', '1.0'
+ c = util_spec 'c', '1.0'
+
+ assert_activate %w[b-1.0 c-1.0 a-1.0], a, c, "b"
+ 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
+ # TODO: move these to specification
+
+ def test_self_activate_over
+ a = util_spec 'a', '1.0', 'b' => '>= 1.0', 'c' => '= 1.0'
+ util_spec 'b', '1.0'
+ util_spec 'b', '1.1'
+ util_spec 'b', '2.0'
+ util_spec 'c', '1.0', 'b' => '~> 1.0'
+
+ a.activate
+
+ assert_equal %w[a-1.0 c-1.0], loaded_spec_names
+ assert_equal ["b (>= 1.0, ~> 1.0)"], unresolved_names
+ 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_self_activate_under
+ a, _ = util_spec 'a', '1.0', 'b' => '~> 1.0', 'c' => '= 1.0'
+ util_spec 'b', '1.0'
+ util_spec 'b', '1.1'
+ c, _ = util_spec 'c', '1.0', 'b' => '= 1.0'
+
+ assert_activate %w[b-1.0 c-1.0 a-1.0], a, c, "b"
+ 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_self_activate_dropped
+ a1, = util_spec 'a', '1', 'b' => nil
+ util_spec 'b', '1', 'c' => nil
+ util_spec 'b', '2'
+ util_spec 'c', '1'
+
+ assert_activate %w[b-2 a-1], a1, "b"
+ 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_self_activate_raggi_the_edgecase_generator
+ a, _ = util_spec 'a', '1.0', 'b' => '>= 1.0', 'c' => '>= 1.0'
+ util_spec 'b', '1.0'
+ util_spec 'b', '1.1', 'z' => '>= 1.0'
+ c, _ = util_spec 'c', '1.0', 'b' => '= 1.0'
+
+ assert_activate %w[b-1.0 c-1.0 a-1.0], a, c, "b"
+ end
+
+ def test_self_activate_conflict
+ util_spec 'b', '1.0'
+ util_spec 'b', '2.0'
+
+ gem "b", "= 1.0"
+
+ assert_raises Gem::LoadError do
+ gem "b", "= 2.0"
+ end
+ end
+
+ ##
+ # [A] depends on
+ # [C] = 1.0 depends on
+ # [B] = 2.0
+ # [B] ~> 1.0 (satisfied by 1.0)
+
+ def test_self_activate_checks_dependencies
+ a, _ = util_spec 'a', '1.0'
+ a.add_dependency 'c', '= 1.0'
+ a.add_dependency 'b', '~> 1.0'
+
+ util_spec 'b', '1.0'
+ util_spec 'b', '2.0'
+ c, _ = util_spec 'c', '1.0', 'b' => '= 2.0'
+
+ e = assert_raises Gem::LoadError do
+ assert_activate nil, a, c, "b"
+ end
+
+ expected = "can't satisfy 'b (~> 1.0)', already activated 'b-2.0'"
+ assert_equal expected, e.message
+ end
+
+ ##
+ # [A] depends on
+ # [B] ~> 1.0 (satisfied by 1.0)
+ # [C] = 1.0 depends on
+ # [B] = 2.0
+
+ def test_self_activate_divergent
+ a, _ = util_spec 'a', '1.0', 'b' => '~> 1.0', 'c' => '= 1.0'
+ util_spec 'b', '1.0'
+ util_spec 'b', '2.0'
+ c, _ = util_spec 'c', '1.0', 'b' => '= 2.0'
+
+ e = assert_raises Gem::LoadError do
+ assert_activate nil, a, c, "b"
+ end
+
+ assert_match(/Unable to activate c-1.0,/, e.message)
+ assert_match(/because b-1.0 conflicts with b .= 2.0/, e.message)
+ end
+
+ ##
+ # DOC
+
+ def test_self_activate_platform_alternate
+ @x1_m = util_spec 'x', '1' do |s|
+ s.platform = Gem::Platform.new %w[cpu my_platform 1]
+ end
+
+ @x1_o = util_spec 'x', '1' do |s|
+ s.platform = Gem::Platform.new %w[cpu other_platform 1]
+ end
+
+ @w1 = util_spec 'w', '1', 'x' => nil
+
+ util_set_arch 'cpu-my_platform1'
+
+ assert_activate %w[x-1-cpu-my_platform-1 w-1], @w1, @x1_m
+ end
+
+ ##
+ # DOC
+
+ def test_self_activate_platform_bump
+ @y1 = util_spec 'y', '1'
+
+ @y1_1_p = util_spec 'y', '1.1' do |s|
+ s.platform = Gem::Platform.new %w[cpu my_platform 1]
+ end
+
+ @z1 = util_spec 'z', '1', 'y' => nil
+
+ assert_activate %w[y-1 z-1], @z1, @y1
+ end
+
+ ##
+ # [C] depends on
+ # [A] = 1.a
+ # [B] = 1.0 depends on
+ # [A] >= 0 (satisfied by 1.a)
+
+ def test_self_activate_prerelease
+ @c1_pre = util_spec 'c', '1.a', "a" => "1.a", "b" => "1"
+ @a1_pre = util_spec 'a', '1.a'
+ @b1 = util_spec 'b', '1' do |s|
+ s.add_dependency 'a'
+ s.add_development_dependency 'aa'
+ end
+
+ assert_activate %w[a-1.a b-1 c-1.a], @c1_pre, @a1_pre, @b1
+ end
+
+ ##
+ # DOC
+
+ def test_self_activate_old_required
+ e1, = util_spec 'e', '1', 'd' => '= 1'
+ @d1 = util_spec 'd', '1'
+ @d2 = util_spec 'd', '2'
+
+ assert_activate %w[d-1 e-1], e1, "d"
+ end
+
def test_self_bin_path_no_exec_name
e = assert_raises ArgumentError do
Gem.bin_path 'a'
@@ -350,7 +790,9 @@ class TestGem < Gem::TestCase
spec
}
- Gem.refresh
+ # HACK should be Gem.refresh
+ Gem.searcher = nil
+ Gem::Specification.reset
expected = [
File.expand_path('test/rubygems/sff/discover.rb', @@project_dir),
@@ -364,37 +806,6 @@ class TestGem < Gem::TestCase
assert_equal cwd, $LOAD_PATH.shift
end
- def test_self_find_latest_files
- cwd = File.expand_path("test/rubygems", @@project_dir)
- $LOAD_PATH.unshift cwd
-
- discover_path = File.join 'lib', 'sff', 'discover.rb'
-
- _, foo2 = %w(1 2).map { |version|
- spec = quick_gem 'sff', version do |s|
- s.files << discover_path
- end
-
- write_file(File.join 'gems', spec.full_name, discover_path) do |fp|
- fp.puts "# #{spec.full_name}"
- end
-
- spec
- }
-
- Gem.refresh
-
- expected = [
- File.expand_path('test/rubygems/sff/discover.rb', @@project_dir),
- File.join(foo2.full_gem_path, discover_path),
- ]
-
- assert_equal expected, Gem.find_latest_files('sff/discover')
- assert_equal expected, Gem.find_latest_files('sff/**.rb'), '[ruby-core:31730]'
- ensure
- assert_equal cwd, $LOAD_PATH.shift
- end
-
def test_self_latest_spec_for
a1 = quick_spec 'a', 1
a2 = quick_spec 'a', 2
@@ -917,20 +1328,14 @@ class TestGem < Gem::TestCase
Dir.chdir @tempdir do
FileUtils.mkdir_p 'lib'
File.open plugin_path, "w" do |fp|
- fp.puts "class TestGem; PLUGINS_LOADED << 'plugin'; end"
- end
-
- foo1 = quick_spec 'foo', '1' do |s|
- s.files << plugin_path
+ fp.puts "class TestGem; TEST_SPEC_PLUGIN_LOAD = :loaded; end"
end
- install_gem foo1
-
- foo2 = quick_spec 'foo', '2' do |s|
+ foo = quick_spec 'foo', '1' do |s|
s.files << plugin_path
end
- install_gem foo2
+ install_gem foo
end
Gem.searcher = nil
@@ -940,7 +1345,7 @@ class TestGem < Gem::TestCase
Gem.load_plugins
- assert_equal %w[plugin], PLUGINS_LOADED
+ assert_equal :loaded, TEST_SPEC_PLUGIN_LOAD
end
def test_load_env_plugins
@@ -1153,61 +1558,6 @@ class TestGem < Gem::TestCase
assert_equal '["a-1", "b-1", "c-1"]', out.strip
end
- def test_register_default_spec
- Gem.clear_default_specs
-
- old_style = Gem::Specification.new do |spec|
- spec.files = ["foo.rb", "bar.rb"]
- end
-
- Gem.register_default_spec old_style
-
- assert_equal old_style, Gem.find_unresolved_default_spec("foo.rb")
- assert_equal old_style, Gem.find_unresolved_default_spec("bar.rb")
- assert_equal nil, Gem.find_unresolved_default_spec("baz.rb")
-
- Gem.clear_default_specs
-
- new_style = Gem::Specification.new do |spec|
- spec.files = ["lib/foo.rb", "ext/bar.rb", "bin/exec", "README"]
- spec.require_paths = ["lib", "ext"]
- end
-
- Gem.register_default_spec new_style
-
- assert_equal new_style, Gem.find_unresolved_default_spec("foo.rb")
- assert_equal new_style, Gem.find_unresolved_default_spec("bar.rb")
- assert_equal nil, Gem.find_unresolved_default_spec("exec")
- assert_equal nil, Gem.find_unresolved_default_spec("README")
- end
-
- def test_default_gems_use_full_paths
- begin
- if defined?(RUBY_ENGINE) then
- engine = RUBY_ENGINE
- Object.send :remove_const, :RUBY_ENGINE
- end
- Object.const_set :RUBY_ENGINE, 'ruby'
-
- refute Gem.default_gems_use_full_paths?
- ensure
- Object.send :remove_const, :RUBY_ENGINE
- Object.const_set :RUBY_ENGINE, engine if engine
- end
-
- begin
- if defined?(RUBY_ENGINE) then
- engine = RUBY_ENGINE
- Object.send :remove_const, :RUBY_ENGINE
- end
- Object.const_set :RUBY_ENGINE, 'jruby'
- assert Gem.default_gems_use_full_paths?
- ensure
- Object.send :remove_const, :RUBY_ENGINE
- Object.const_set :RUBY_ENGINE, engine if engine
- end
- end
-
def with_plugin(path)
test_plugin_path = File.expand_path("test/rubygems/plugin/#{path}",
@@project_dir)
@@ -1284,3 +1634,4 @@ class TestGem < Gem::TestCase
File.join Gem.dir, "cache"
end
end
+