semantic 1.0.0 → 1.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +17 -1
- data/lib/semantic/core_ext.rb +4 -0
- data/lib/semantic/version.rb +155 -60
- data/lib/semantic.rb +1 -2
- data/spec/core_ext_spec.rb +28 -8
- data/spec/spec_helper.rb +0 -1
- data/spec/version_spec.rb +296 -65
- metadata +21 -28
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 49f4f8185e5b08f5e55c52e84b9e97514734e773
|
4
|
+
data.tar.gz: d0348d4f5c518868f35a68fc17730e65b6b19a41
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e8b5397c167716fec08c08c156cd83adc8feaf97865311cd761bc344dfbeac4dc88aad60c2b4b771e4e69ffae217bdefd875715d05222ea6a486f01fb516419e
|
7
|
+
data.tar.gz: 4ac7c975674f02f07cbffbd5829532305f998ce74922866a413d6182041cf2cad3e0b8272d3546cab7793752657b1a60d026db175408f69a91411e70a290c7e3
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
Semantic
|
2
2
|
========
|
3
|
+
[![BuildStatus](https://travis-ci.org/jlindsey/semantic.svg?branch=master)](https://travis-ci.org/jlindsey/semantic)
|
3
4
|
|
4
5
|
A small Ruby utility class to aid in the storage, parsing, and comparison of SemVer-style Version strings.
|
5
6
|
|
@@ -26,6 +27,21 @@ newer_version <=> version # => 1
|
|
26
27
|
complex_version = Semantic::Version.new '3.7.9-pre.1+revision.15723'
|
27
28
|
complex_version.pre # => "pre.1"
|
28
29
|
complex_version.build # => "revision.15623"
|
30
|
+
|
31
|
+
# semantic supports Pessimistic Operator
|
32
|
+
version.satisfies? '~> 1.5' # => true
|
33
|
+
version.satisfies? '~> 1.6.0' # => true
|
34
|
+
|
35
|
+
# incrementing version numbers
|
36
|
+
version = Semantic::Version.new('0.1.0')
|
37
|
+
new_version = version.increment!(:major) # 1.1.0
|
38
|
+
new_version = version.increment!(:minor) # 0.2.0
|
39
|
+
new_version = version.increment!(:patch) # 0.1.1
|
40
|
+
|
41
|
+
new_version = verstion.major! # 1.1.0
|
42
|
+
new_version = verstion.minor! # 0.2.0
|
43
|
+
new_version = verstion.patch! # 0.1.1
|
44
|
+
# (note: increment! & friends return a copy and leave the original unchanged)
|
29
45
|
```
|
30
46
|
|
31
47
|
There is also a set of core extensions as an optional require:
|
@@ -39,5 +55,5 @@ require 'semantic/core_ext'
|
|
39
55
|
|
40
56
|
License
|
41
57
|
-------
|
42
|
-
Copyright (c) 2012 Josh Lindsey. See LICENSE for details.
|
58
|
+
Copyright (c) 2012 Josh Lindsey. See [LICENSE](LICENSE) for details.
|
43
59
|
|
data/lib/semantic/core_ext.rb
CHANGED
data/lib/semantic/version.rb
CHANGED
@@ -1,85 +1,180 @@
|
|
1
1
|
# See: http://semver.org
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
module Semantic
|
3
|
+
class Version
|
4
|
+
include Comparable
|
5
5
|
|
6
|
-
|
7
|
-
raise ArgumentError.new("Not a valid SemVer Version (http://semver.org)") unless version_str =~ SemVerRegexp
|
6
|
+
SemVerRegexp = /\A(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][a-zA-Z0-9-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][a-zA-Z0-9-]*))*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?\Z/
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
8
|
+
|
9
|
+
attr_accessor :major, :minor, :patch, :pre
|
10
|
+
attr_reader :build
|
11
|
+
|
12
|
+
def initialize version_str
|
13
|
+
v = version_str.match(SemVerRegexp)
|
14
|
+
|
15
|
+
raise ArgumentError.new("#{version_str} is not a valid SemVer Version (http://semver.org)") if v.nil?
|
16
|
+
@major = v[1].to_i
|
17
|
+
@minor = v[2].to_i
|
18
|
+
@patch = v[3].to_i
|
19
|
+
@pre = v[4]
|
20
|
+
@build = v[5]
|
21
|
+
@version = version_str
|
16
22
|
end
|
17
23
|
|
18
24
|
|
19
|
-
|
20
|
-
|
25
|
+
def build=(b)
|
26
|
+
@build = (!b.nil? && b.empty?) ? nil : b
|
27
|
+
end
|
21
28
|
|
22
|
-
|
23
|
-
|
24
|
-
|
29
|
+
def identifiers(pre)
|
30
|
+
array = pre.split(/[\.\-]/)
|
31
|
+
array.each_with_index {|e,i| array[i] = Integer(e) if /\A\d+\z/.match(e)}
|
32
|
+
return array
|
33
|
+
end
|
25
34
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
35
|
+
def compare_pre(prea, preb)
|
36
|
+
if prea.nil? || preb.nil?
|
37
|
+
return 0 if prea.nil? && preb.nil?
|
38
|
+
return 1 if prea.nil?
|
39
|
+
return -1 if preb.nil?
|
40
|
+
end
|
41
|
+
a = identifiers(prea)
|
42
|
+
b = identifiers(preb)
|
43
|
+
smallest = a.size < b.size ? a : b
|
44
|
+
smallest.each_with_index do |e, i|
|
45
|
+
c = a[i] <=> b[i]
|
46
|
+
if c.nil?
|
47
|
+
return a[i].is_a?(Integer) ? -1 : 1
|
48
|
+
elsif c != 0
|
49
|
+
return c
|
50
|
+
end
|
51
|
+
end
|
52
|
+
return a.size <=> b.size
|
53
|
+
end
|
30
54
|
|
31
|
-
|
32
|
-
|
55
|
+
def to_a
|
56
|
+
[@major, @minor, @patch, @pre, @build]
|
57
|
+
end
|
33
58
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
59
|
+
def to_s
|
60
|
+
str = [@major, @minor, @patch].join '.'
|
61
|
+
str << '-' << @pre unless @pre.nil?
|
62
|
+
str << '+' << @build unless @build.nil?
|
63
|
+
str
|
64
|
+
end
|
38
65
|
|
39
|
-
|
40
|
-
|
41
|
-
|
66
|
+
def to_h
|
67
|
+
keys = [:major, :minor, :patch, :pre, :build]
|
68
|
+
Hash[keys.zip(self.to_a)]
|
69
|
+
end
|
42
70
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
71
|
+
alias to_hash to_h
|
72
|
+
alias to_array to_a
|
73
|
+
alias to_string to_s
|
47
74
|
|
48
|
-
|
49
|
-
|
50
|
-
|
75
|
+
def hash
|
76
|
+
to_a.hash
|
77
|
+
end
|
51
78
|
|
52
|
-
|
53
|
-
|
54
|
-
|
79
|
+
def eql? other_version
|
80
|
+
self.hash == other_version.hash
|
81
|
+
end
|
55
82
|
|
56
|
-
|
83
|
+
def <=> other_version
|
84
|
+
other_version = Version.new(other_version) if other_version.is_a? String
|
85
|
+
[:major, :minor, :patch].each do |part|
|
86
|
+
c = (self.send(part) <=> other_version.send(part))
|
87
|
+
if c != 0
|
88
|
+
return c
|
89
|
+
end
|
90
|
+
end
|
91
|
+
return compare_pre(self.pre, other_version.pre)
|
92
|
+
end
|
57
93
|
|
58
|
-
|
59
|
-
|
60
|
-
|
94
|
+
def satisfies? other_version
|
95
|
+
return true if other_version.strip == '*'
|
96
|
+
parts = other_version.split(/(\d(.+)?)/, 2)
|
97
|
+
comparator, other_version_string = parts[0].strip, parts[1].strip
|
98
|
+
|
99
|
+
begin
|
100
|
+
Version.new other_version_string
|
101
|
+
comparator.empty? && comparator = '=='
|
102
|
+
satisfies_comparator? comparator, other_version_string
|
103
|
+
rescue ArgumentError
|
104
|
+
if ['<', '>', '<=', '>='].include?(comparator)
|
105
|
+
satisfies_comparator? comparator, pad_version_string(other_version_string)
|
106
|
+
elsif comparator == '~>'
|
107
|
+
pessimistic_match? other_version_string
|
108
|
+
else
|
109
|
+
tilde_matches? other_version_string
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
61
113
|
|
62
|
-
|
114
|
+
def satisfied_by? versions
|
115
|
+
raise ArgumentError.new("Versions #{versions} should be an array of versions") unless versions.is_a? Array
|
116
|
+
versions.all? { |version| satisfies?(version) }
|
117
|
+
end
|
63
118
|
|
64
|
-
|
65
|
-
|
119
|
+
[:major, :minor, :patch].each do |term|
|
120
|
+
define_method("#{term}!") { increment!(term) }
|
121
|
+
end
|
66
122
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
123
|
+
def increment!(term)
|
124
|
+
term = term.to_sym
|
125
|
+
new_version = clone
|
126
|
+
new_value = send(term) + 1
|
127
|
+
|
128
|
+
new_version.send("#{term}=", new_value)
|
129
|
+
new_version.minor = 0 if term == :major
|
130
|
+
new_version.patch = 0 if term == :major || term == :minor
|
131
|
+
new_version.build = new_version.pre = nil
|
132
|
+
|
133
|
+
new_version
|
72
134
|
end
|
73
135
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
136
|
+
private
|
137
|
+
|
138
|
+
def pad_version_string version_string
|
139
|
+
parts = version_string.split('.').reject {|x| x == '*'}
|
140
|
+
while parts.length < 3
|
141
|
+
parts << '0'
|
142
|
+
end
|
143
|
+
parts.join '.'
|
144
|
+
end
|
145
|
+
|
146
|
+
def tilde_matches? other_version_string
|
147
|
+
this_parts = to_a.collect(&:to_s)
|
148
|
+
other_parts = other_version_string.split('.').reject {|x| x == '*'}
|
149
|
+
other_parts == this_parts[0..other_parts.length-1]
|
150
|
+
end
|
151
|
+
|
152
|
+
def pessimistic_match? other_version_string
|
153
|
+
other_parts = other_version_string.split('.')
|
154
|
+
unless other_parts.size == 2 || other_parts.size == 3
|
155
|
+
raise ArgumentError.new("Version #{other_version_string} should not be applied with a pessimistic operator")
|
156
|
+
end
|
157
|
+
other_parts.pop
|
158
|
+
other_parts << (other_parts.pop.to_i + 1).to_s
|
159
|
+
satisfies_comparator?('>=', semverified(other_version_string)) && satisfies_comparator?('<', semverified(other_parts.join('.')))
|
160
|
+
end
|
161
|
+
|
162
|
+
def satisfies_comparator? comparator, other_version_string
|
163
|
+
if comparator == '~'
|
164
|
+
tilde_matches? other_version_string
|
165
|
+
elsif comparator == '~>'
|
166
|
+
pessimistic_match? other_version_string
|
167
|
+
else
|
168
|
+
self.send comparator, other_version_string
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def semverified version_string
|
173
|
+
parts = version_string.split('.')
|
174
|
+
raise ArgumentError.new("Version #{version_string} not supported by semverified") if parts.size > 3
|
175
|
+
(3 - parts.size).times { parts << '0' }
|
176
|
+
parts.join('.')
|
79
177
|
end
|
80
178
|
|
81
|
-
# Recurse down to the next part if equal
|
82
|
-
compare_recursively ary1, ary2
|
83
179
|
end
|
84
180
|
end
|
85
|
-
|
data/lib/semantic.rb
CHANGED
data/spec/core_ext_spec.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'semantic/core_ext'
|
3
3
|
|
4
|
+
# rubocop:disable Metrics/BlockLength
|
4
5
|
describe 'Core Extensions' do
|
5
|
-
context
|
6
|
+
context 'String#to_version' do
|
6
7
|
before(:each) do
|
7
8
|
@test_versions = [
|
8
9
|
'1.0.0',
|
@@ -23,20 +24,39 @@ describe 'Core Extensions' do
|
|
23
24
|
]
|
24
25
|
end
|
25
26
|
|
26
|
-
it
|
27
|
-
|
27
|
+
it 'extends String with a #to_version method' do
|
28
|
+
expect('').to respond_to(:to_version)
|
28
29
|
end
|
29
30
|
|
30
|
-
it
|
31
|
+
it 'converts the String into a Version object' do
|
31
32
|
@test_versions.each do |v|
|
32
|
-
expect { v.to_version }.to_not raise_error
|
33
|
-
v.to_version.
|
33
|
+
expect { v.to_version }.to_not raise_error
|
34
|
+
expect(v.to_version).to be_a(Semantic::Version)
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
37
|
-
it
|
38
|
+
it 'raises an error on invalid strings' do
|
38
39
|
@bad_versions.each do |v|
|
39
|
-
expect { v.to_version }.to raise_error(
|
40
|
+
expect { v.to_version }.to raise_error(
|
41
|
+
ArgumentError,
|
42
|
+
/not a valid SemVer/
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'extends String with a #is_version? method' do
|
48
|
+
expect('').to respond_to(:is_version?)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'detects valid semantic version strings' do
|
52
|
+
@test_versions.each do |v|
|
53
|
+
expect(v.is_version?).to be true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'detects invalid semantic version strings' do
|
58
|
+
@bad_versions.each do |v|
|
59
|
+
expect(v.is_version?).to be false
|
40
60
|
end
|
41
61
|
end
|
42
62
|
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/version_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
|
2
|
+
# rubocop:disable Metrics/BlockLength, Style/VariableNumber
|
3
3
|
describe Semantic::Version do
|
4
4
|
before(:each) do
|
5
5
|
@test_versions = [
|
@@ -17,111 +17,342 @@ describe Semantic::Version do
|
|
17
17
|
'1.a.3',
|
18
18
|
'a.3.4',
|
19
19
|
'5.2.a',
|
20
|
-
'pre3-1.5.3'
|
20
|
+
'pre3-1.5.3',
|
21
|
+
"I am not a valid semver\n0.0.0\nbut I still pass"
|
21
22
|
]
|
22
23
|
end
|
23
24
|
|
24
|
-
context
|
25
|
-
it
|
25
|
+
context 'parsing' do
|
26
|
+
it 'parses valid SemVer versions' do
|
26
27
|
@test_versions.each do |v|
|
27
|
-
expect { Semantic::Version.new v }.
|
28
|
+
expect { Semantic::Version.new v }.not_to raise_error
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
31
|
-
it
|
32
|
+
it 'raises an error on invalid versions' do
|
32
33
|
@bad_versions.each do |v|
|
33
|
-
expect { Semantic::Version.new v }.to raise_error(
|
34
|
+
expect { Semantic::Version.new v }.to raise_error(
|
35
|
+
ArgumentError,
|
36
|
+
/not a valid SemVer/
|
37
|
+
)
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
37
|
-
it
|
41
|
+
it 'stores parsed versions in member variables' do
|
38
42
|
v1 = Semantic::Version.new '1.5.9'
|
39
|
-
v1.major.
|
40
|
-
v1.minor.
|
41
|
-
v1.patch.
|
42
|
-
v1.pre.
|
43
|
-
v1.build.
|
43
|
+
expect(v1.major).to eq(1)
|
44
|
+
expect(v1.minor).to eq(5)
|
45
|
+
expect(v1.patch).to eq(9)
|
46
|
+
expect(v1.pre).to be_nil
|
47
|
+
expect(v1.build).to be_nil
|
44
48
|
|
45
49
|
v2 = Semantic::Version.new '0.0.1-pre.1'
|
46
|
-
v2.major.
|
47
|
-
v2.minor.
|
48
|
-
v2.patch.
|
49
|
-
v2.pre.
|
50
|
-
v2.build.
|
50
|
+
expect(v2.major).to eq(0)
|
51
|
+
expect(v2.minor).to eq(0)
|
52
|
+
expect(v2.patch).to eq(1)
|
53
|
+
expect(v2.pre).to eq('pre.1')
|
54
|
+
expect(v2.build).to be_nil
|
51
55
|
|
52
56
|
v3 = Semantic::Version.new '1.0.1-pre.5+build.123.5'
|
53
|
-
v3.major.
|
54
|
-
v3.minor.
|
55
|
-
v3.patch.
|
56
|
-
v3.pre.
|
57
|
-
v3.build.
|
57
|
+
expect(v3.major).to eq(1)
|
58
|
+
expect(v3.minor).to eq(0)
|
59
|
+
expect(v3.patch).to eq(1)
|
60
|
+
expect(v3.pre).to eq('pre.5')
|
61
|
+
expect(v3.build).to eq('build.123.5')
|
58
62
|
|
59
63
|
v4 = Semantic::Version.new '0.0.0+hello'
|
60
|
-
v4.major.
|
61
|
-
v4.minor.
|
62
|
-
v4.patch.
|
63
|
-
v4.pre.
|
64
|
-
v4.build.
|
64
|
+
expect(v4.major).to eq(0)
|
65
|
+
expect(v4.minor).to eq(0)
|
66
|
+
expect(v4.patch).to eq(0)
|
67
|
+
expect(v4.pre).to be_nil
|
68
|
+
expect(v4.build).to eq('hello')
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'provides round-trip fidelity for an empty build parameter' do
|
72
|
+
v = Semantic::Version.new('1.2.3')
|
73
|
+
v.build = ''
|
74
|
+
expect(Semantic::Version.new(v.to_s).build).to eq(v.build)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'provides round-trip fidelity for a nil build parameter' do
|
78
|
+
v = Semantic::Version.new('1.2.3+build')
|
79
|
+
v.build = nil
|
80
|
+
expect(Semantic::Version.new(v.to_s).build).to eq(v.build)
|
65
81
|
end
|
66
82
|
end
|
67
83
|
|
68
|
-
context
|
84
|
+
context 'comparisons' do
|
69
85
|
before(:each) do
|
70
|
-
|
71
|
-
@
|
72
|
-
@
|
73
|
-
@
|
86
|
+
# These three are all semantically equivalent, according to the spec.
|
87
|
+
@v1_5_9_pre_1 = Semantic::Version.new '1.5.9-pre.1'
|
88
|
+
@v1_5_9_pre_1_build_5127 = Semantic::Version.new '1.5.9-pre.1+build.5127'
|
89
|
+
@v1_5_9_pre_1_build_4352 = Semantic::Version.new '1.5.9-pre.1+build.4352'
|
90
|
+
# more pre syntax testing: "-"
|
91
|
+
@v3_13_0_75_generic = Semantic::Version.new '3.13.0-75-generic'
|
92
|
+
@v3_13_0_141_generic = Semantic::Version.new '3.13.0-141-generic'
|
93
|
+
|
94
|
+
@v1_5_9 = Semantic::Version.new '1.5.9'
|
95
|
+
@v1_6_0 = Semantic::Version.new '1.6.0'
|
96
|
+
|
97
|
+
@v1_6_0_alpha = Semantic::Version.new '1.6.0-alpha'
|
98
|
+
@v1_6_0_alpha_1 = Semantic::Version.new '1.6.0-alpha.1'
|
99
|
+
@v1_6_0_alpha_beta = Semantic::Version.new '1.6.0-alpha.beta'
|
100
|
+
@v1_6_0_beta = Semantic::Version.new '1.6.0-beta'
|
101
|
+
@v1_6_0_beta_2 = Semantic::Version.new '1.6.0-beta.2'
|
102
|
+
@v1_6_0_beta_11 = Semantic::Version.new '1.6.0-beta.11'
|
103
|
+
@v1_6_0_rc_1 = Semantic::Version.new '1.6.0-rc.1'
|
104
|
+
|
105
|
+
# expected order:
|
106
|
+
# 1.6.0-alpha < 1.6.0-alpha.1 < 1.6.0-alpha.beta < 1.6.0-beta
|
107
|
+
# < 1.6.0-beta.2 < 1.6.0-beta.11 < 1.6.0-rc.1 < 1.6.0.
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'determines sort order' do
|
111
|
+
# The second parameter here can be a string, so we want to ensure that
|
112
|
+
# this kind of comparison works also.
|
113
|
+
expect((@v1_5_9_pre_1 <=> @v1_5_9_pre_1.to_s)).to eq(0)
|
114
|
+
|
115
|
+
expect((@v1_5_9_pre_1 <=> @v1_5_9_pre_1_build_5127)).to eq(0)
|
116
|
+
expect((@v1_5_9_pre_1 <=> @v1_5_9)).to eq(-1)
|
117
|
+
expect((@v1_5_9_pre_1_build_5127 <=> @v1_5_9)).to eq(-1)
|
118
|
+
|
119
|
+
expect(@v1_5_9_pre_1_build_5127.build).to eq('build.5127')
|
120
|
+
|
121
|
+
expect((@v1_5_9 <=> @v1_6_0)).to eq(-1)
|
122
|
+
expect((@v1_6_0 <=> @v1_5_9)).to eq(1)
|
123
|
+
expect((@v1_6_0 <=> @v1_5_9_pre_1)).to eq(1)
|
124
|
+
expect((@v1_5_9_pre_1 <=> @v1_6_0)).to eq(-1)
|
125
|
+
|
126
|
+
expect([@v1_5_9_pre_1, @v1_5_9_pre_1_build_5127, @v1_5_9, @v1_6_0]
|
127
|
+
.reverse.sort).to \
|
128
|
+
eq([@v1_5_9_pre_1, @v1_5_9_pre_1_build_5127, @v1_5_9, @v1_6_0])
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'determines sort order pre' do
|
132
|
+
ary = [@v1_6_0_alpha, @v1_6_0_alpha_1, @v1_6_0_alpha_beta,
|
133
|
+
@v1_6_0_beta, @v1_6_0_beta_2, @v1_6_0_beta_11, @v1_6_0_rc_1,
|
134
|
+
@v1_6_0]
|
135
|
+
expect(ary.shuffle.sort).to eq(ary)
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'determine alternate char sep works in pre' do
|
139
|
+
expect((@v3_13_0_75_generic <=> @v3_13_0_141_generic.to_s)).to eq(-1)
|
140
|
+
expect((@v3_13_0_75_generic <=> @v3_13_0_141_generic)).to eq(-1)
|
141
|
+
expect((@v3_13_0_75_generic <=> '3.13.0-75-generic')).to eq(0)
|
142
|
+
expect((@v3_13_0_75_generic <=> '3.13.0-141-generic')).to eq(-1)
|
143
|
+
expect((@v3_13_0_141_generic <=> '3.13.0-75-generic')).to eq(1)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'determines whether it is greater than another instance' do
|
147
|
+
# These should be equal, since "Build metadata SHOULD be ignored
|
148
|
+
# when determining version precedence".
|
149
|
+
# (SemVer 2.0.0-rc.2, paragraph 10 - http://www.semver.org)
|
150
|
+
expect(@v1_5_9_pre_1).not_to be > @v1_5_9_pre_1_build_5127
|
151
|
+
expect(@v1_5_9_pre_1).not_to be < @v1_5_9_pre_1_build_5127
|
152
|
+
|
153
|
+
expect(@v1_6_0).to be > @v1_5_9
|
154
|
+
expect(@v1_5_9).not_to be > @v1_6_0
|
155
|
+
expect(@v1_5_9).to be > @v1_5_9_pre_1_build_5127
|
156
|
+
expect(@v1_5_9).to be > @v1_5_9_pre_1
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'determines whether it is less than another instance' do
|
160
|
+
expect(@v1_5_9_pre_1).not_to be < @v1_5_9_pre_1_build_5127
|
161
|
+
expect(@v1_5_9_pre_1_build_5127).not_to be < @v1_5_9_pre_1
|
162
|
+
expect(@v1_5_9_pre_1).to be < @v1_5_9
|
163
|
+
expect(@v1_5_9_pre_1).to be < @v1_6_0
|
164
|
+
expect(@v1_5_9_pre_1_build_5127).to be < @v1_6_0
|
165
|
+
expect(@v1_5_9).to be < @v1_6_0
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'determines whether it is greater than or equal to another instance' do
|
169
|
+
expect(@v1_5_9_pre_1).to be >= @v1_5_9_pre_1
|
170
|
+
expect(@v1_5_9_pre_1).to be >= @v1_5_9_pre_1_build_5127
|
171
|
+
expect(@v1_5_9_pre_1_build_5127).to be >= @v1_5_9_pre_1
|
172
|
+
expect(@v1_5_9).to be >= @v1_5_9_pre_1
|
173
|
+
expect(@v1_6_0).to be >= @v1_5_9
|
174
|
+
expect(@v1_5_9_pre_1_build_5127).not_to be >= @v1_6_0
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'determines whether it is less than or equal to another instance' do
|
178
|
+
expect(@v1_5_9_pre_1).to be <= @v1_5_9_pre_1_build_5127
|
179
|
+
expect(@v1_6_0).not_to be <= @v1_5_9
|
180
|
+
expect(@v1_5_9_pre_1_build_5127).to be <= @v1_5_9_pre_1_build_5127
|
181
|
+
expect(@v1_5_9).not_to be <= @v1_5_9_pre_1
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'determines whether it is semantically equal to another instance' do
|
185
|
+
expect(@v1_5_9_pre_1).to eq(@v1_5_9_pre_1.dup)
|
186
|
+
expect(@v1_5_9_pre_1_build_5127).to eq(@v1_5_9_pre_1_build_5127.dup)
|
187
|
+
|
188
|
+
# "Semantically equal" is the keyword here; these are by definition
|
189
|
+
# not "equal" (different build), but should be treated as
|
190
|
+
# equal according to the spec.
|
191
|
+
expect(@v1_5_9_pre_1_build_4352).to eq(@v1_5_9_pre_1_build_5127)
|
192
|
+
expect(@v1_5_9_pre_1_build_4352).to eq(@v1_5_9_pre_1)
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'determines whether it is between two others instance' do
|
196
|
+
expect(@v1_5_9).to be_between @v1_5_9_pre_1, @v1_6_0
|
197
|
+
expect(@v1_5_9).to_not be_between @v1_6_0, @v1_6_0_beta
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'determines whether it satisfies >= style specifications' do
|
201
|
+
expect(@v1_6_0.satisfies?('>=1.6.0')).to be true
|
202
|
+
expect(@v1_6_0.satisfies?('<=1.6.0')).to be true
|
203
|
+
expect(@v1_6_0.satisfies?('>=1.5.0')).to be true
|
204
|
+
expect(@v1_6_0.satisfies?('<=1.5.0')).not_to be true
|
205
|
+
|
206
|
+
# partial / non-semver numbers after comparator are extremely common in
|
207
|
+
# version specifications in the wild
|
208
|
+
|
209
|
+
expect(@v1_6_0.satisfies?('>1.5')).to be true
|
210
|
+
expect(@v1_6_0.satisfies?('<1')).not_to be true
|
74
211
|
end
|
75
212
|
|
76
|
-
it
|
77
|
-
(@
|
78
|
-
(@
|
79
|
-
(@
|
80
|
-
(@
|
81
|
-
|
213
|
+
it 'determines whether it satisfies * style specifications' do
|
214
|
+
expect(@v1_6_0.satisfies?('1.*')).to be true
|
215
|
+
expect(@v1_6_0.satisfies?('1.6.*')).to be true
|
216
|
+
expect(@v1_6_0.satisfies?('2.*')).not_to be true
|
217
|
+
expect(@v1_6_0.satisfies?('1.5.*')).not_to be true
|
218
|
+
end
|
82
219
|
|
83
|
-
|
220
|
+
it 'determines whether it satisfies ~ style specifications' do
|
221
|
+
expect(@v1_6_0.satisfies?('~1.6')).to be true
|
222
|
+
expect(@v1_5_9_pre_1.satisfies?('~1.5')).to be true
|
223
|
+
expect(@v1_6_0.satisfies?('~1.5')).not_to be true
|
84
224
|
end
|
85
225
|
|
86
|
-
it
|
87
|
-
@
|
88
|
-
@
|
89
|
-
@
|
90
|
-
|
226
|
+
it 'determines whether it satisfies ~> style specifications' do
|
227
|
+
expect(@v1_5_9_pre_1_build_5127.satisfies?('~> 1.4')).to be true
|
228
|
+
expect(@v1_5_9_pre_1_build_4352.satisfies?('~> 1.5.2')).to be true
|
229
|
+
expect(@v1_6_0_alpha_1.satisfies?('~> 1.4')).to be true
|
230
|
+
|
231
|
+
expect(@v1_5_9.satisfies?('~> 1.0')).to be true
|
232
|
+
expect(@v1_5_9.satisfies?('~> 1.4')).to be true
|
233
|
+
expect(Semantic::Version.new('1.99.1').satisfies?('~> 1.5')).to be true
|
234
|
+
expect(@v1_5_9.satisfies?('~> 1.5')).to be true
|
235
|
+
expect(@v1_5_9.satisfies?('~> 1.5.0')).to be true
|
236
|
+
expect(@v1_5_9.satisfies?('~> 1.5.8')).to be true
|
237
|
+
expect(@v1_5_9.satisfies?('~> 1.5.9')).to be true
|
238
|
+
expect(Semantic::Version.new('1.5.99').satisfies?('~> 1.5.9')).to be true
|
239
|
+
expect(@v1_5_9.satisfies?('~> 1.6.0')).to be false
|
240
|
+
expect(@v1_5_9.satisfies?('~> 1.6')).to be false
|
241
|
+
expect(@v1_5_9.satisfies?('~> 1.7')).to be false
|
91
242
|
end
|
92
243
|
|
93
|
-
it
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
244
|
+
it 'determines whether version is satisfies by range of bound versions' do
|
245
|
+
v5_2_1 = Semantic::Version.new('5.2.1')
|
246
|
+
v5_3_0 = Semantic::Version.new('5.3.0')
|
247
|
+
v6_0_1 = Semantic::Version.new('6.0.1')
|
248
|
+
range = [
|
249
|
+
">= 5.2.1",
|
250
|
+
"<= 6.0.0"
|
251
|
+
]
|
252
|
+
|
253
|
+
expect(v5_2_1.satisfied_by?(range)).to be true
|
254
|
+
expect(v5_3_0.satisfied_by?(range)).to be true
|
255
|
+
expect(v6_0_1.satisfied_by?(range)).to be false
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'raises error if the input is not an array of versions' do
|
259
|
+
v5_2_1 = Semantic::Version.new('5.2.1')
|
260
|
+
range = ">= 5.2.1 <= 6.0.0"
|
261
|
+
expect { v5_2_1.satisfied_by?(range) }.to raise_error(
|
262
|
+
ArgumentError,
|
263
|
+
/should be an array of versions/
|
264
|
+
)
|
98
265
|
end
|
99
266
|
end
|
100
267
|
|
101
|
-
context
|
102
|
-
it
|
268
|
+
context 'type coercions' do
|
269
|
+
it 'converts to a string' do
|
103
270
|
@test_versions.each do |v|
|
104
|
-
Semantic::Version.new(v).to_s.
|
271
|
+
expect(Semantic::Version.new(v).to_s).to be == v
|
105
272
|
end
|
106
273
|
end
|
107
274
|
|
108
|
-
it
|
109
|
-
Semantic::Version.new('1.0.0').to_a.
|
110
|
-
|
111
|
-
Semantic::Version.new('
|
112
|
-
|
275
|
+
it 'converts to an array' do
|
276
|
+
expect(Semantic::Version.new('1.0.0').to_a).to \
|
277
|
+
eq([1, 0, 0, nil, nil])
|
278
|
+
expect(Semantic::Version.new('6.1.4-pre.5').to_a).to \
|
279
|
+
eq([6, 1, 4, 'pre.5', nil])
|
280
|
+
expect(Semantic::Version.new('91.6.0+build.17').to_a).to \
|
281
|
+
eq([91, 6, 0, nil, 'build.17'])
|
282
|
+
expect(Semantic::Version.new('0.1.5-pre.7+build191').to_a).to \
|
283
|
+
eq([0, 1, 5, 'pre.7', 'build191'])
|
113
284
|
end
|
114
285
|
|
115
|
-
it
|
116
|
-
Semantic::Version.new('1.0.0').to_h.
|
117
|
-
|
118
|
-
Semantic::Version.new('
|
119
|
-
|
286
|
+
it 'converts to a hash' do
|
287
|
+
expect(Semantic::Version.new('1.0.0').to_h).to \
|
288
|
+
eq(major: 1, minor: 0, patch: 0, pre: nil, build: nil)
|
289
|
+
expect(Semantic::Version.new('6.1.4-pre.5').to_h).to \
|
290
|
+
eq(major: 6, minor: 1, patch: 4, pre: 'pre.5', build: nil)
|
291
|
+
expect(Semantic::Version.new('91.6.0+build.17').to_h).to \
|
292
|
+
eq(major: 91, minor: 6, patch: 0, pre: nil, build: 'build.17')
|
293
|
+
expect(Semantic::Version.new('0.1.5-pre.7+build191').to_h).to \
|
294
|
+
eq(major: 0, minor: 1, patch: 5, pre: 'pre.7', build: 'build191')
|
120
295
|
end
|
121
296
|
|
122
|
-
it
|
297
|
+
it 'aliases conversion methods' do
|
123
298
|
v = Semantic::Version.new('0.0.0')
|
124
|
-
[:to_hash, :to_array, :to_string].each
|
299
|
+
[:to_hash, :to_array, :to_string].each do |sym|
|
300
|
+
expect(v).to respond_to(sym)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
it 'as hash key' do
|
306
|
+
hash = {}
|
307
|
+
hash[Semantic::Version.new('1.2.3-pre1+build2')] = 'semantic'
|
308
|
+
expect(hash[Semantic::Version.new('1.2.3-pre1+build2')]).to eq('semantic')
|
309
|
+
end
|
310
|
+
|
311
|
+
describe '#major!' do
|
312
|
+
subject { described_class.new('1.2.3-pre1+build2') }
|
313
|
+
|
314
|
+
context 'changing the major term' do
|
315
|
+
it 'changes the major version and resets the others' do
|
316
|
+
expect(subject.major!).to eq('2.0.0')
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
describe '#minor!' do
|
322
|
+
subject { described_class.new('1.2.3-pre1+build2') }
|
323
|
+
|
324
|
+
context 'changing the minor term' do
|
325
|
+
it 'changes minor term and resets patch, pre and build' do
|
326
|
+
expect(subject.minor!).to eq('1.3.0')
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
describe '#patch!' do
|
332
|
+
subject { described_class.new('1.2.3-pre1+build2') }
|
333
|
+
|
334
|
+
context 'changing the patch term' do
|
335
|
+
it 'changes the patch term and resets the pre and build' do
|
336
|
+
expect(subject.patch!).to eq('1.2.4')
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
describe '#increment!' do
|
342
|
+
subject { described_class.new('1.2.3-pre1+build2') }
|
343
|
+
|
344
|
+
context 'changing the minor term' do
|
345
|
+
context 'with a string' do
|
346
|
+
it 'changes the minor term and resets the path, pre and build' do
|
347
|
+
expect(subject.increment!('minor')).to eq('1.3.0')
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
context 'with a symbol' do
|
352
|
+
it 'changes the minor term and resets the path, pre and build' do
|
353
|
+
expect(subject.increment!(:minor)).to eq('1.3.0')
|
354
|
+
end
|
355
|
+
end
|
125
356
|
end
|
126
357
|
end
|
127
358
|
end
|
metadata
CHANGED
@@ -1,91 +1,84 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: semantic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
5
|
-
prerelease:
|
4
|
+
version: 1.6.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Josh Lindsey
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2018-02-14 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rake
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- - ~>
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
19
|
+
version: '11'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- - ~>
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
26
|
+
version: '11'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rspec
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- - ~>
|
31
|
+
- - "~>"
|
36
32
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
33
|
+
version: '3'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- - ~>
|
38
|
+
- - "~>"
|
44
39
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
46
|
-
description:
|
47
|
-
|
40
|
+
version: '3'
|
41
|
+
description: 'Semantic Version utility class for parsing, storing, and comparing versions.
|
42
|
+
See: http://semver.org'
|
48
43
|
email:
|
49
|
-
-
|
44
|
+
- joshua.s.lindsey@gmail.com
|
50
45
|
executables: []
|
51
46
|
extensions: []
|
52
47
|
extra_rdoc_files: []
|
53
48
|
files:
|
54
|
-
- lib/semantic/core_ext.rb
|
55
|
-
- lib/semantic/version.rb
|
56
|
-
- lib/semantic.rb
|
57
49
|
- LICENSE
|
58
50
|
- README.md
|
51
|
+
- lib/semantic.rb
|
52
|
+
- lib/semantic/core_ext.rb
|
53
|
+
- lib/semantic/version.rb
|
59
54
|
- spec/core_ext_spec.rb
|
60
55
|
- spec/spec_helper.rb
|
61
56
|
- spec/version_spec.rb
|
62
57
|
homepage: https://github.com/jlindsey/semantic
|
63
58
|
licenses:
|
64
59
|
- MIT
|
60
|
+
metadata: {}
|
65
61
|
post_install_message:
|
66
62
|
rdoc_options: []
|
67
63
|
require_paths:
|
68
64
|
- lib
|
69
65
|
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
-
none: false
|
71
66
|
requirements:
|
72
|
-
- -
|
67
|
+
- - ">="
|
73
68
|
- !ruby/object:Gem::Version
|
74
69
|
version: '0'
|
75
70
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
-
none: false
|
77
71
|
requirements:
|
78
|
-
- -
|
72
|
+
- - ">="
|
79
73
|
- !ruby/object:Gem::Version
|
80
74
|
version: '0'
|
81
75
|
requirements: []
|
82
76
|
rubyforge_project:
|
83
|
-
rubygems_version:
|
77
|
+
rubygems_version: 2.6.13
|
84
78
|
signing_key:
|
85
|
-
specification_version:
|
79
|
+
specification_version: 4
|
86
80
|
summary: Semantic Version utility class
|
87
81
|
test_files:
|
88
82
|
- spec/core_ext_spec.rb
|
89
83
|
- spec/spec_helper.rb
|
90
84
|
- spec/version_spec.rb
|
91
|
-
has_rdoc:
|