diff options
Diffstat (limited to 'spec/bundler/bundler/definition_spec.rb')
-rw-r--r-- | spec/bundler/bundler/definition_spec.rb | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/spec/bundler/bundler/definition_spec.rb b/spec/bundler/bundler/definition_spec.rb new file mode 100644 index 0000000000..73d44a93ab --- /dev/null +++ b/spec/bundler/bundler/definition_spec.rb @@ -0,0 +1,277 @@ +# frozen_string_literal: true +require "spec_helper" +require "bundler/definition" + +RSpec.describe Bundler::Definition do + describe "#lock" do + before do + allow(Bundler).to receive(:settings) { Bundler::Settings.new(".") } + allow(Bundler).to receive(:default_gemfile) { Pathname.new("Gemfile") } + allow(Bundler).to receive(:ui) { double("UI", :info => "", :debug => "") } + end + context "when it's not possible to write to the file" do + subject { Bundler::Definition.new(nil, [], Bundler::SourceList.new, []) } + + it "raises an PermissionError with explanation" do + expect(File).to receive(:open).with("Gemfile.lock", "wb"). + and_raise(Errno::EACCES) + expect { subject.lock("Gemfile.lock") }. + to raise_error(Bundler::PermissionError, /Gemfile\.lock/) + end + end + context "when a temporary resource access issue occurs" do + subject { Bundler::Definition.new(nil, [], Bundler::SourceList.new, []) } + + it "raises a TemporaryResourceError with explanation" do + expect(File).to receive(:open).with("Gemfile.lock", "wb"). + and_raise(Errno::EAGAIN) + expect { subject.lock("Gemfile.lock") }. + to raise_error(Bundler::TemporaryResourceError, /temporarily unavailable/) + end + end + end + + describe "detects changes" do + it "for a path gem with changes" do + build_lib "foo", "1.0", :path => lib_path("foo") + + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "foo", :path => "#{lib_path("foo")}" + G + + build_lib "foo", "1.0", :path => lib_path("foo") do |s| + s.add_dependency "rack", "1.0" + end + + bundle :install, :env => { "DEBUG" => 1 } + + expect(out).to match(/re-resolving dependencies/) + lockfile_should_be <<-G + PATH + remote: #{lib_path("foo")} + specs: + foo (1.0) + rack (= 1.0) + + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + ruby + + DEPENDENCIES + foo! + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "for a path gem with deps and no changes" do + build_lib "foo", "1.0", :path => lib_path("foo") do |s| + s.add_dependency "rack", "1.0" + s.add_development_dependency "net-ssh", "1.0" + end + + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "foo", :path => "#{lib_path("foo")}" + G + + bundle :check, :env => { "DEBUG" => 1 } + + expect(out).to match(/using resolution from the lockfile/) + lockfile_should_be <<-G + PATH + remote: #{lib_path("foo")} + specs: + foo (1.0) + rack (= 1.0) + + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + ruby + + DEPENDENCIES + foo! + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "for a rubygems gem" do + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "foo" + G + + bundle :check, :env => { "DEBUG" => 1 } + + expect(out).to match(/using resolution from the lockfile/) + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + foo (1.0) + + PLATFORMS + ruby + + DEPENDENCIES + foo + + BUNDLED WITH + #{Bundler::VERSION} + G + end + end + + describe "initialize" do + context "gem version promoter" do + context "with lockfile" do + before do + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "foo" + G + end + + it "should get a locked specs list when updating all" do + definition = Bundler::Definition.new(bundled_app("Gemfile.lock"), [], Bundler::SourceList.new, true) + locked_specs = definition.gem_version_promoter.locked_specs + expect(locked_specs.to_a.map(&:name)).to eq ["foo"] + expect(definition.instance_variable_get("@locked_specs").empty?).to eq true + end + end + + context "without gemfile or lockfile" do + it "should not attempt to parse empty lockfile contents" do + definition = Bundler::Definition.new(nil, [], mock_source_list, true) + expect(definition.gem_version_promoter.locked_specs.to_a).to eq [] + end + end + + context "eager unlock" do + before do + gemfile <<-G + source "file://#{gem_repo4}" + gem 'isolated_owner' + + gem 'shared_owner_a' + gem 'shared_owner_b' + G + + lockfile <<-L + GEM + remote: file://#{gem_repo4} + specs: + isolated_dep (2.0.1) + isolated_owner (1.0.1) + isolated_dep (~> 2.0) + shared_dep (5.0.1) + shared_owner_a (3.0.1) + shared_dep (~> 5.0) + shared_owner_b (4.0.1) + shared_dep (~> 5.0) + + PLATFORMS + ruby + + DEPENDENCIES + shared_owner_a + shared_owner_b + isolated_owner + + BUNDLED WITH + 1.13.0 + L + end + + it "should not eagerly unlock shared dependency with bundle install conservative updating behavior" do + updated_deps_in_gemfile = [Bundler::Dependency.new("isolated_owner", ">= 0"), + Bundler::Dependency.new("shared_owner_a", "3.0.2"), + Bundler::Dependency.new("shared_owner_b", ">= 0")] + unlock_hash_for_bundle_install = {} + definition = Bundler::Definition.new( + bundled_app("Gemfile.lock"), + updated_deps_in_gemfile, + Bundler::SourceList.new, + unlock_hash_for_bundle_install + ) + locked = definition.send(:converge_locked_specs).map(&:name) + expect(locked.include?("shared_dep")).to be_truthy + end + + it "should not eagerly unlock shared dependency with bundle update conservative updating behavior" do + updated_deps_in_gemfile = [Bundler::Dependency.new("isolated_owner", ">= 0"), + Bundler::Dependency.new("shared_owner_a", ">= 0"), + Bundler::Dependency.new("shared_owner_b", ">= 0")] + definition = Bundler::Definition.new( + bundled_app("Gemfile.lock"), + updated_deps_in_gemfile, + Bundler::SourceList.new, + :gems => ["shared_owner_a"], :lock_shared_dependencies => true + ) + locked = definition.send(:converge_locked_specs).map(&:name) + expect(locked).to eq %w(isolated_dep isolated_owner shared_dep shared_owner_b) + expect(locked.include?("shared_dep")).to be_truthy + end + end + end + end + + describe "find_resolved_spec" do + it "with no platform set in SpecSet" do + ss = Bundler::SpecSet.new([build_stub_spec("a", "1.0"), build_stub_spec("b", "1.0")]) + dfn = Bundler::Definition.new(nil, [], mock_source_list, true) + dfn.instance_variable_set("@specs", ss) + found = dfn.find_resolved_spec(build_spec("a", "0.9", "ruby").first) + expect(found.name).to eq "a" + expect(found.version.to_s).to eq "1.0" + end + end + + describe "find_indexed_specs" do + it "with no platform set in indexed specs" do + index = Bundler::Index.new + %w(1.0.0 1.0.1 1.1.0).each {|v| index << build_stub_spec("foo", v) } + + dfn = Bundler::Definition.new(nil, [], mock_source_list, true) + dfn.instance_variable_set("@index", index) + found = dfn.find_indexed_specs(build_spec("foo", "0.9", "ruby").first) + expect(found.length).to eq 3 + end + end + + def build_stub_spec(name, version) + Bundler::StubSpecification.new(name, version, nil, nil) + end + + def mock_source_list + Class.new do + def all_sources + [] + end + + def path_sources + [] + end + + def rubygems_remotes + [] + end + + def replace_sources!(arg) + nil + end + end.new + end +end |