semantic 1.0.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
[](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:
|