Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion lib/rubygems/requirement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class Gem::Requirement
">=" => lambda {|v, r| v >= r },
"<=" => lambda {|v, r| v <= r },
"~>" => lambda {|v, r| v >= r && v.release < r.bump },
"^>" => lambda {|v, r| v >= r && v.release < r.bump_major },
}.freeze

SOURCE_SET_REQUIREMENT = Struct.new(:for_lockfile).new "!" # :nodoc:
Expand Down Expand Up @@ -191,7 +192,14 @@ def as_list # :nodoc:
end

def hash # :nodoc:
requirements.map {|r| r.first == "~>" ? [r[0], r[1].to_s] : r }.sort.hash
requirements.map do |r|
case r.first
when "~>", "^>"
[r[0], r[1].to_s]
else
r
end
end.sort.hash
end

def marshal_dump # :nodoc:
Expand Down
16 changes: 16 additions & 0 deletions lib/rubygems/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ def self.create(input)

@@all = {}
@@bump = {}
@@bump_major = {}
@@release = {}

def self.new(version) # :nodoc:
Expand Down Expand Up @@ -255,6 +256,21 @@ def bump
end
end

##
# Return a new version object where the major version number
# is one greater and all non-major version components are zeroed out -
# e.g., 5.3.1 => 6.0.0.

def bump_major
@@bump_major[self] ||= begin
segments = self.segments
segments.pop while segments.any? {|s| String === s }
segments[0] = segments[0].succ
segments[1..-1] = Array.new(segments.length - 1, 0)
self.class.new segments.join(".")
end
end

##
# A Version is only eql? to another version if it's specified to the
# same precision. Version "1.0" is not the same as version "1".
Expand Down
89 changes: 89 additions & 0 deletions test/rubygems/test_gem_requirement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,15 @@ def test_equals2

refute_requirement_equal "~> 1.3", "~> 1.3.0"
refute_requirement_equal "~> 1.3.0", "~> 1.3"
refute_requirement_equal "~> 1.3.1", "^> 1.3"

assert_requirement_equal ["> 2", "~> 1.3", "~> 1.3.1"], ["~> 1.3.1", "~> 1.3", "> 2"]
assert_requirement_equal ["> 2", "^> 1.3", "^> 1.3.1"], ["^> 1.3.1", "^> 1.3", "> 2"]
assert_requirement_equal ["> 2", "^> 1.3", "^> 1.3.1"], ["^> 1.3.1", "^> 1.3", "> 2"]

assert_requirement_equal ["> 2", "~> 1.3"], ["> 2.0", "~> 1.3"]
assert_requirement_equal ["> 2.0", "~> 1.3"], ["> 2", "~> 1.3"]
assert_requirement_equal ["> 2.0", "^> 1.3"], ["> 2", "^> 1.3"]

refute_equal Object.new, req("= 1.2")
refute_equal req("= 1.2"), Object.new
Expand Down Expand Up @@ -70,8 +74,10 @@ def test_basic_non_none

def test_for_lockfile
assert_equal " (~> 1.0)", req("~> 1.0").for_lockfile
assert_equal " (^> 1.0)", req("^> 1.0").for_lockfile

assert_equal " (~> 1.0, >= 1.0.1)", req(">= 1.0.1", "~> 1.0").for_lockfile
assert_equal " (^> 1.0, >= 1.0.1)", req(">= 1.0.1", "^> 1.0").for_lockfile

duped = req "= 1.0"
duped.requirements << ["=", v("1.0")]
Expand Down Expand Up @@ -252,6 +258,50 @@ def test_satisfied_by_eh_tilde_gt_v0
assert_satisfied_by "0.0.1", r
end

def test_satisfied_by_eh_caret_gt
r = req "^> 1.2"

refute_satisfied_by "1.1", r
assert_satisfied_by "1.2", r
assert_satisfied_by "1.2.1", r
assert_satisfied_by "1.3", r

assert_raise ArgumentError do
r.satisfied_by? nil
end
end

def test_satisfied_by_eh_caret_gt_v0
r = req "^> 0.0.1"

assert_satisfied_by "0.1.1", r
assert_satisfied_by "0.0.2", r
assert_satisfied_by "0.0.1", r
refute_satisfied_by "1.0.1", r
end

def test_satisfied_by_eh_caret_gt_v1
r = req "^> 1"

assert_satisfied_by "1", r
assert_satisfied_by "1.1", r
assert_satisfied_by "1.1.1", r
assert_satisfied_by "1.0.2", r
assert_satisfied_by "1.0.1", r
refute_satisfied_by "2.0.1", r
refute_satisfied_by "2.1.1", r
end

def test_satisfied_by_eh_caret_gt_v10
r = req "^> 1.0"

assert_satisfied_by "1.1.1", r
assert_satisfied_by "1.0.2", r
assert_satisfied_by "1.0.1", r
refute_satisfied_by "2.0.0", r
refute_satisfied_by "2.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"
Expand Down Expand Up @@ -287,11 +337,22 @@ def test_satisfied_by_eh_good

assert_satisfied_by "3.0.rc2", "> 0"

assert_satisfied_by "5.0.0.rc2", "~> 5.a"
refute_satisfied_by "5.0.0.rc2", "~> 5.x"
assert_satisfied_by "5.0.0.rc2", "~> 5.a"
refute_satisfied_by "5.0.0.rc2", "~> 5.x"

assert_satisfied_by "5.0.0", "~> 5.a"
assert_satisfied_by "5.0.0", "~> 5.x"

assert_satisfied_by "5.0.0.rc2", "^> 5.a"
refute_satisfied_by "5.0.0.rc2", "^> 5.x"

assert_satisfied_by "5.0.0.rc2", "^> 5.a"
refute_satisfied_by "5.0.0.rc2", "^> 5.x"

assert_satisfied_by "5.0.0", "^> 5.a"
assert_satisfied_by "5.0.0", "^> 5.x"
end

def test_illformed_requirements
Expand Down Expand Up @@ -336,6 +397,30 @@ def test_satisfied_by_eh_boxed
refute_satisfied_by "2.0", "~> 1"
end

def test_satisfied_by_eh_boxed_caret
refute_satisfied_by "1.3", "^> 1.4"
assert_satisfied_by "1.4", "^> 1.4"
assert_satisfied_by "1.5", "^> 1.4"
refute_satisfied_by "2.0", "^> 1.4"

refute_satisfied_by "1.3", "^> 1.4.4"
refute_satisfied_by "1.4", "^> 1.4.4"
assert_satisfied_by "1.4.4", "^> 1.4.4"
assert_satisfied_by "1.4.5", "^> 1.4.4"
assert_satisfied_by "1.5", "^> 1.4.4"
refute_satisfied_by "2.0", "^> 1.4.4"

assert_satisfied_by "1.1.pre", "^> 1.0.0"
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
req = [">= 1.4", "<= 1.6", "!= 1.5"]

Expand Down Expand Up @@ -385,6 +470,7 @@ def test_specific
assert req("<= 1").specific?
assert req("= 1") .specific?
assert req("~> 1").specific?
assert req("^> 1").specific?

assert req("> 1", "> 2").specific? # GIGO
end
Expand Down Expand Up @@ -422,11 +508,14 @@ def test_hash_returns_equal_hashes_for_equivalent_requirements

refute_requirement_hash_equal "~> 1.3", "~> 1.3.0"
refute_requirement_hash_equal "~> 1.3.0", "~> 1.3"
refute_requirement_hash_equal "^> 1.3.0", "^> 1.3"

assert_requirement_hash_equal ["> 2", "~> 1.3", "~> 1.3.1"], ["~> 1.3.1", "~> 1.3", "> 2"]
assert_requirement_hash_equal ["> 2", "^> 1.3", "^> 1.3.1"], ["^> 1.3.1", "^> 1.3", "> 2"]

assert_requirement_hash_equal ["> 2", "~> 1.3"], ["> 2.0", "~> 1.3"]
assert_requirement_hash_equal ["> 2.0", "~> 1.3"], ["> 2", "~> 1.3"]
assert_requirement_hash_equal ["> 2.0", "^> 1.3"], ["> 2", "^> 1.3"]

assert_requirement_hash_equal "= 1.0", "= 1.0.0"
assert_requirement_hash_equal "= 1.1", "= 1.1.0"
Expand Down