diff options
Diffstat (limited to 'spec/bundler/resolver/basic_spec.rb')
| -rw-r--r-- | spec/bundler/resolver/basic_spec.rb | 210 |
1 files changed, 175 insertions, 35 deletions
diff --git a/spec/bundler/resolver/basic_spec.rb b/spec/bundler/resolver/basic_spec.rb index d5658824ba..185df1b1c7 100644 --- a/spec/bundler/resolver/basic_spec.rb +++ b/spec/bundler/resolver/basic_spec.rb @@ -6,15 +6,15 @@ RSpec.describe "Resolving" do end it "resolves a single gem" do - dep "rack" + dep "myrack" - should_resolve_as %w[rack-1.1] + should_resolve_as %w[myrack-1.1] end it "resolves a gem with dependencies" do dep "actionpack" - should_resolve_as %w[actionpack-2.3.5 activesupport-2.3.5 rack-1.0] + should_resolve_as %w[actionpack-2.3.5 activesupport-2.3.5 myrack-1.0] end it "resolves a conflicting index" do @@ -35,13 +35,20 @@ RSpec.describe "Resolving" do should_resolve_as %w[berkshelf-2.0.7 chef-10.26 chef_app-1.0.0 json-1.7.7] end - it "prefers expicitly requested dependencies when resolving an index which would otherwise be ambiguous" do + it "prefers explicitly requested dependencies when resolving an index which would otherwise be ambiguous" do @index = an_ambiguous_index dep "a" dep "b" should_resolve_as %w[a-1.0.0 b-2.0.0 c-1.0.0 d-1.0.0] end + it "prefers non-prerelease resolutions in sort order" do + @index = optional_prereleases_index + dep "a" + dep "b" + should_resolve_as %w[a-1.0.0 b-1.5.0] + end + it "resolves a index with root level conflict on child" do @index = a_index_with_root_conflict_on_child dep "i18n", "~> 0.4" @@ -73,12 +80,40 @@ RSpec.describe "Resolving" do should_resolve_as %w[need-pre-1.0.0 activesupport-3.0.0.beta1] end + it "selects a pre-release if it's specified in the Gemfile" do + dep "activesupport", "= 3.0.0.beta" + dep "actionpack" + + should_resolve_as %w[activesupport-3.0.0.beta actionpack-3.0.0.beta myrack-1.1 myrack-mount-0.6] + end + + it "prefers non-pre-releases when doing conservative updates" do + @index = build_index do + gem "mail", "2.7.0" + gem "mail", "2.7.1.rc1" + gem "RubyGems\0", Gem::VERSION + end + dep "mail" + @locked = locked ["mail", "2.7.0"] + @base = locked + should_conservative_resolve_and_include [:patch], [], ["mail-2.7.0"] + end + it "raises an exception if a child dependency is not resolved" do - @index = a_unresovable_child_index + @index = a_unresolvable_child_index dep "chef_app_error" expect do resolve - end.to raise_error(Bundler::VersionConflict) + end.to raise_error(Bundler::SolveFailure) + end + + it "does not try to re-resolve including prereleases if gems involved don't have prereleases" do + @index = a_unresolvable_child_index + dep "chef_app_error" + expect(Bundler.ui).not_to receive(:debug).with("Retrying resolution...", any_args) + expect do + resolve + end.to raise_error(Bundler::SolveFailure) end it "raises an exception with the minimal set of conflicting dependencies" do @@ -92,14 +127,15 @@ RSpec.describe "Resolving" do dep "c" expect do resolve - end.to raise_error(Bundler::VersionConflict, <<-E.strip) -Bundler could not find compatible versions for gem "a": - In Gemfile: - b was resolved to 1.0, which depends on - a (>= 2) - - c was resolved to 1.0, which depends on - a (< 1) + end.to raise_error(Bundler::SolveFailure, <<~E.strip) + Could not find compatible versions + + Because every version of c depends on a < 1 + and every version of b depends on a >= 2, + every version of c is incompatible with b >= 0. + So, because Gemfile depends on b >= 0 + and Gemfile depends on c >= 0, + version solving has failed. E end @@ -108,7 +144,7 @@ Bundler could not find compatible versions for gem "a": dep "circular_app" expect do - resolve + Bundler::SpecSet.new(resolve).sort end.to raise_error(Bundler::CyclicDependencyError, /please remove either gem 'bar' or gem 'foo'/i) end @@ -143,17 +179,12 @@ Bundler could not find compatible versions for gem "a": s.required_ruby_version = "~> 2.0.0" end - gem "ruby\0", "1.8.7" + gem "Ruby\0", "1.8.7" end dep "foo" - dep "ruby\0", "1.8.7" - - deps = [] - @deps.each do |d| - deps << Bundler::DepProxy.new(d, "ruby") - end + dep "Ruby\0", "1.8.7" - should_resolve_and_include %w[foo-1.0.0 bar-1.0.0], [[]] + should_resolve_and_include %w[foo-1.0.0 bar-1.0.0] end context "conservative" do @@ -180,12 +211,12 @@ Bundler could not find compatible versions for gem "a": it "resolves all gems to latest patch" do # strict is not set, so bar goes up a minor version due to dependency from foo 1.4.5 - should_conservative_resolve_and_include :patch, [], %w[foo-1.4.5 bar-2.1.1] + should_conservative_resolve_and_include :patch, true, %w[foo-1.4.5 bar-2.1.1] end it "resolves all gems to latest patch strict" do # strict is set, so foo can only go up to 1.4.4 to avoid bar going up a minor version, and bar can go up to 2.0.5 - should_conservative_resolve_and_include [:patch, :strict], [], %w[foo-1.4.4 bar-2.0.5] + should_conservative_resolve_and_include [:patch, :strict], true, %w[foo-1.4.4 bar-2.0.5] end it "resolves foo only to latest patch - same dependency case" do @@ -200,14 +231,14 @@ Bundler could not find compatible versions for gem "a": # dependencies and since the dependency of the selected foo gem changes, the latest matching # dependency of "bar", "~> 2.1" -- bar-2.1.1 -- is selected. This is not a bug and follows # the long-standing documented Conservative Updating behavior of bundle install. - # http://bundler.io/v1.12/man/bundle-install.1.html#CONSERVATIVE-UPDATING + # https://bundler.io/v1.12/man/bundle-install.1.html#CONSERVATIVE-UPDATING should_conservative_resolve_and_include :patch, ["foo"], %w[foo-1.4.5 bar-2.1.1] end it "resolves foo only to latest patch - changing dependency declared case" do # bar is locked AND a declared dependency in the Gemfile, so it will not move, and therefore # foo can only move up to 1.4.4. - @base << build_spec("bar", "2.0.3").first + @base = Bundler::SpecSet.new([Bundler::LazySpecification.new("bar", Gem::Version.new("2.0.3"), nil)]) should_conservative_resolve_and_include :patch, ["foo"], %w[foo-1.4.4 bar-2.0.3] end @@ -225,20 +256,20 @@ Bundler could not find compatible versions for gem "a": it "resolves all gems to latest minor" do # strict is not set, so bar goes up a major version due to dependency from foo 1.4.5 - should_conservative_resolve_and_include :minor, [], %w[foo-1.5.1 bar-3.0.0] + should_conservative_resolve_and_include :minor, true, %w[foo-1.5.1 bar-3.0.0] end it "resolves all gems to latest minor strict" do # strict is set, so foo can only go up to 1.5.0 to avoid bar going up a major version - should_conservative_resolve_and_include [:minor, :strict], [], %w[foo-1.5.0 bar-2.1.1] + should_conservative_resolve_and_include [:minor, :strict], true, %w[foo-1.5.0 bar-2.1.1] end it "resolves all gems to latest major" do - should_conservative_resolve_and_include :major, [], %w[foo-2.0.0 bar-3.0.0] + should_conservative_resolve_and_include :major, true, %w[foo-2.0.0 bar-3.0.0] end it "resolves all gems to latest major strict" do - should_conservative_resolve_and_include [:major, :strict], [], %w[foo-2.0.0 bar-3.0.0] + should_conservative_resolve_and_include [:major, :strict], true, %w[foo-2.0.0 bar-3.0.0] end # Why would this happen in real life? If bar 2.2 has a bug that the author of foo wants to bypass @@ -261,22 +292,131 @@ Bundler could not find compatible versions for gem "a": end it "could revert to a previous version level patch" do - should_conservative_resolve_and_include :patch, [], %w[foo-1.4.4 bar-2.1.1] + should_conservative_resolve_and_include :patch, true, %w[foo-1.4.4 bar-2.1.1] end it "cannot revert to a previous version in strict mode level patch" do # fall back to the locked resolution since strict means we can't regress either version - should_conservative_resolve_and_include [:patch, :strict], [], %w[foo-1.4.3 bar-2.2.3] + should_conservative_resolve_and_include [:patch, :strict], true, %w[foo-1.4.3 bar-2.2.3] end it "could revert to a previous version level minor" do - should_conservative_resolve_and_include :minor, [], %w[foo-1.5.0 bar-2.0.5] + should_conservative_resolve_and_include :minor, true, %w[foo-1.5.0 bar-2.0.5] end it "cannot revert to a previous version in strict mode level minor" do # fall back to the locked resolution since strict means we can't regress either version - should_conservative_resolve_and_include [:minor, :strict], [], %w[foo-1.4.3 bar-2.2.3] + should_conservative_resolve_and_include [:minor, :strict], true, %w[foo-1.4.3 bar-2.2.3] + end + end + end + + it "handles versions that redundantly depend on themselves" do + @index = build_index do + gem "myrack", "3.0.0" + + gem "standalone_migrations", "7.1.0" do + dep "myrack", "~> 2.0" + end + + gem "standalone_migrations", "2.0.4" do + dep "standalone_migrations", ">= 0" + end + + gem "standalone_migrations", "1.0.13" do + dep "myrack", ">= 0" + end + end + + dep "myrack", "~> 3.0" + dep "standalone_migrations" + + should_resolve_as %w[myrack-3.0.0 standalone_migrations-2.0.4] + end + + it "ignores versions that incorrectly depend on themselves" do + @index = build_index do + gem "myrack", "3.0.0" + + gem "standalone_migrations", "7.1.0" do + dep "myrack", "~> 2.0" + end + + gem "standalone_migrations", "2.0.4" do + dep "standalone_migrations", ">= 2.0.5" + end + + gem "standalone_migrations", "1.0.13" do + dep "myrack", ">= 0" + end + end + + dep "myrack", "~> 3.0" + dep "standalone_migrations" + + should_resolve_as %w[myrack-3.0.0 standalone_migrations-1.0.13] + end + + it "does not ignore versions that incorrectly depend on themselves when dependency_api is not available" do + @index = build_index do + gem "myrack", "3.0.0" + + gem "standalone_migrations", "7.1.0" do + dep "myrack", "~> 2.0" + end + + gem "standalone_migrations", "2.0.4" do + dep "standalone_migrations", ">= 2.0.5" + end + + gem "standalone_migrations", "1.0.13" do + dep "myrack", ">= 0" + end + end + + dep "myrack", "~> 3.0" + dep "standalone_migrations" + + should_resolve_without_dependency_api %w[myrack-3.0.0 standalone_migrations-2.0.4] + end + + it "resolves fine cases that need joining unbounded disjoint ranges" do + @index = build_index do + gem "inspec", "5.22.3" do + dep "ruby", ">= 3.2.2" + dep "train-kubernetes", ">= 0.1.7" + end + + gem "ruby", "3.2.2" + + gem "train-kubernetes", "0.1.12" do + dep "k8s-ruby", ">= 0.14.0" + end + + gem "train-kubernetes", "0.1.10" do + dep "k8s-ruby", "= 0.10.5" + end + + gem "train-kubernetes", "0.1.7" do + dep "k8s-ruby", ">= 0.10.5" + end + + gem "k8s-ruby", "0.10.5" do + dep "ruby","< 3.2.2" + end + + gem "k8s-ruby", "0.11.0" do + dep "ruby", ">= 3.2.2" + end + + gem "k8s-ruby", "0.14.0" do + dep "ruby", "< 3.2.2" end end + + dep "inspec", "5.22.3" + dep "ruby", "3.2.2" + + should_resolve_as %w[inspec-5.22.3 ruby-3.2.2 train-kubernetes-0.1.7 k8s-ruby-0.11.0] end end |
