summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Spataro <tony@rightscale.com>2015-06-19 12:08:39 -0700
committerAndre Arko <andre@arko.net>2015-06-19 18:02:53 -0500
commite5d936e7c6265f8f8dcdd7fcc4b93aeb013acbd1 (patch)
tree52ebecbb7c3efca5a39fd4053cda3d6f2d97d9a0
parent3f4f6286c56765e8c4968631643106cfd534b789 (diff)
downloadbundler-e5d936e7c6265f8f8dcdd7fcc4b93aeb013acbd1.tar.gz
Make Bundler::RemoteSpecification comparable.
Uses a comparison strategy borrowed from RubyGems 2.23 for maximum compatibility with Gem::Specification et. al.
-rw-r--r--CHANGELOG.md6
-rw-r--r--lib/bundler/remote_specification.rb20
-rw-r--r--spec/bundler/remote_specification_spec.rb61
3 files changed, 76 insertions, 11 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a5634ef473..4a0424f13a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 1.10.5 (Unreleased)
+
+Bugfixes:
+
+ - fix sorting of mixed DependencyLists with RubyGems >= 2.23 (@tony-spataro-rs)
+
## 1.10.4 (2015-06-16)
Workarounds:
diff --git a/lib/bundler/remote_specification.rb b/lib/bundler/remote_specification.rb
index d8bd5c331f..36f62af7e4 100644
--- a/lib/bundler/remote_specification.rb
+++ b/lib/bundler/remote_specification.rb
@@ -34,9 +34,12 @@ module Bundler
end
end
+ # Compare this specification against another object. Using sort_obj
+ # is compatible with Gem::Specification and other Bundler or RubyGems
+ # objects. Otherwise, use the default Object comparison.
def <=>(other)
- if other.respond_to?(:full_name)
- full_name <=> other.full_name
+ if other.respond_to?(:sort_obj)
+ sort_obj <=> other.sort_obj
else
super
end
@@ -51,6 +54,19 @@ module Bundler
private
+ # Create a delegate used for sorting. This strategy is copied from
+ # RubyGems 2.23 and ensures that Bundler's specifications can be
+ # compared and sorted with RubyGems' own specifications.
+ #
+ # @see #<=>
+ # @see Gem::Specification#sort_obj
+ #
+ # @return [Array] an object you can use to compare and sort this
+ # specification against other specifications
+ def sort_obj
+ [@name, @version, @platform == Gem::Platform::RUBY ? -1 : 1]
+ end
+
def _remote_specification
@_remote_specification ||= @spec_fetcher.fetch_spec([@name, @version, @platform])
end
diff --git a/spec/bundler/remote_specification_spec.rb b/spec/bundler/remote_specification_spec.rb
index 250c48c124..c93d6f908b 100644
--- a/spec/bundler/remote_specification_spec.rb
+++ b/spec/bundler/remote_specification_spec.rb
@@ -1,14 +1,57 @@
require "spec_helper"
describe Bundler::RemoteSpecification do
- subject(:spec) { Bundler::RemoteSpecification.new("foo", "1.2", "ruby", fetcher) }
- let(:fetcher) { double("SpecFetcher", :fetch_spec => rubygems_spec)}
- let(:rubygems_spec) { Gem::Specification.new("foo", "1.2") }
-
- describe "<=>" do
- let(:other_spec) { Gem::Specification.new("bar", "1.0") }
- it "sorts with Gem::Specification" do
- expect(spec <=> other_spec).to eq(1)
+ it "is Comparable" do
+ expect(described_class.ancestors).to include(Comparable)
+ end
+
+ describe "#<=>" do
+ let(:name) { "foo" }
+ let(:version) { Gem::Version.new("1.0.0") }
+ let(:newer_version) { Gem::Version.new("1.1.0") }
+ let(:older_version) { Gem::Version.new("0.9.0") }
+ let(:platform) { Gem::Platform::RUBY }
+
+ subject do
+ Bundler::RemoteSpecification.new(name, version, platform, nil)
+ end
+
+ context "given a Gem::Specification" do
+ let(:same_gem) do
+ Gem::Specification.new(name, version)
+ end
+
+ let(:different_name) do
+ Gem::Specification.new("bar", version)
+ end
+
+ let(:newer_gem) do
+ Gem::Specification.new(name, newer_version)
+ end
+
+ let(:older_gem) do
+ Gem::Specification.new(name, older_version)
+ end
+
+ let(:different_platform) do
+ s = Gem::Specification.new(name, version)
+ s.platform = Gem::Platform.new "x86-mswin32"
+ s
+ end
+
+ it "compares based on name" do
+ expect(subject <=> different_name).not_to eq(0)
+ end
+
+ it "compares based on version" do
+ expect(subject <=> same_gem).to eq(0)
+ expect(subject).to be < newer_gem
+ expect(subject).to be > older_gem
+ end
+
+ it "compares based on platform" do
+ expect(subject <=> different_platform).not_to eq(0)
+ end
end
end
-end \ No newline at end of file
+end