Skip to content

Commit 84c4397

Browse files
authored
fix: check pre-release and build (#269)
1 parent bc09647 commit 84c4397

File tree

2 files changed

+61
-15
lines changed

2 files changed

+61
-15
lines changed

lib/optimizely/semantic_version.rb

+51-11
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,43 @@ module SemanticVersion
2727
module_function
2828

2929
def pre_release?(target)
30-
# Method to check if the given version contains "-"
30+
# Method to check if the given version is a prerelease
3131
#
3232
# target - String representing semantic version
3333
#
34-
# Returns true if the given version does contain "-"
34+
# Returns true if the given version is a prerelease
3535
# false if it doesn't
3636

37-
target.include? SEMVER_PRE_RELEASE
37+
raise unless target.is_a? String
38+
39+
prerelease_index = target.index(SEMVER_PRE_RELEASE)
40+
build_index = target.index(SEMVER_BUILD)
41+
42+
return false if prerelease_index.nil?
43+
return true if build_index.nil?
44+
45+
# when both operators are present prerelease should precede the build operator
46+
prerelease_index < build_index
47+
end
48+
49+
def build?(target)
50+
# Method to check if the given version is a build
51+
#
52+
# target - String representing semantic version
53+
#
54+
# Returns true if the given version is a build
55+
# false if it doesn't
56+
57+
raise unless target.is_a? String
58+
59+
prerelease_index = target.index(SEMVER_PRE_RELEASE)
60+
build_index = target.index(SEMVER_BUILD)
61+
62+
return false if build_index.nil?
63+
return true if prerelease_index.nil?
64+
65+
# when both operators are present build should precede the prerelease operator
66+
build_index < prerelease_index
3867
end
3968

4069
def split_semantic_version(target)
@@ -52,9 +81,9 @@ def split_semantic_version(target)
5281
raise InvalidSemanticVersion if target.include? ' '
5382

5483
if pre_release?(target)
55-
target_parts = target.split(SEMVER_PRE_RELEASE)
56-
elsif target.include? SEMVER_BUILD
57-
target_parts = target.split(SEMVER_BUILD)
84+
target_parts = target.split(SEMVER_PRE_RELEASE, 2)
85+
elsif build? target
86+
target_parts = target.split(SEMVER_BUILD, 2)
5887
end
5988

6089
unless target_parts.empty?
@@ -91,6 +120,9 @@ def compare_user_version_with_target_version(target_version, user_version)
91120
raise InvalidAttributeType unless target_version.is_a? String
92121
raise InvalidAttributeType unless user_version.is_a? String
93122

123+
is_target_version_prerelease = pre_release?(target_version)
124+
is_user_version_prerelease = pre_release?(user_version)
125+
94126
target_version_parts = split_semantic_version(target_version)
95127
user_version_parts = split_semantic_version(user_version)
96128
user_version_parts_len = user_version_parts.length if user_version_parts
@@ -99,15 +131,23 @@ def compare_user_version_with_target_version(target_version, user_version)
99131
target_version_parts.each_with_index do |_item, idx|
100132
if user_version_parts_len <= idx
101133
# even if they are equal at this point. if the target is a prerelease
102-
# then it must be greater than the pre release.
103-
return 1 if pre_release?(target_version)
134+
# then user version must be greater than the pre release.
135+
return 1 if is_target_version_prerelease
104136

105137
return -1
106138

107139
elsif !Helpers::Validator.string_numeric? user_version_parts[idx]
108140
# compare strings
109-
return -1 if user_version_parts[idx] < target_version_parts[idx]
110-
return 1 if user_version_parts[idx] > target_version_parts[idx]
141+
if user_version_parts[idx] < target_version_parts[idx]
142+
return 1 if is_target_version_prerelease && !is_user_version_prerelease
143+
144+
return -1
145+
146+
elsif user_version_parts[idx] > target_version_parts[idx]
147+
return -1 if is_user_version_prerelease && !is_target_version_prerelease
148+
149+
return 1
150+
end
111151

112152
else
113153
user_version_part = user_version_parts[idx].to_i
@@ -118,7 +158,7 @@ def compare_user_version_with_target_version(target_version, user_version)
118158
end
119159
end
120160

121-
return -1 if pre_release?(user_version) && !pre_release?(target_version)
161+
return -1 if is_user_version_prerelease && !is_target_version_prerelease
122162

123163
0
124164
end

spec/semantic_version_spec.rb

+10-4
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
['2.1', '2.1.0'],
3030
['2.1', '2.1.215'],
3131
['2', '2.12'],
32-
['2', '2.785.13']
32+
['2', '2.785.13'],
33+
['3.7.0', '3.7.0+build']
3334
]
3435

3536
versions.each do |target_version, user_version|
@@ -49,7 +50,10 @@
4950
['2.9.0', '2.9.1'],
5051
['2.1.2', '2.1.3-beta'],
5152
['2.1.2-beta', '2.1.2-release'],
52-
['2.1.3-beta', '2.1.3']
53+
['2.1.3-beta', '2.1.3'],
54+
['2.1.3-beta+1', '2.1.3-beta+1.2.3'],
55+
['3.7.0-prerelease', '3.7.0+build'],
56+
['3.7.0-prerelease+build', '3.7.0-prerelease-prelrease+rc']
5357
]
5458

5559
versions.each do |target_version, user_version|
@@ -69,7 +73,9 @@
6973
['2.3.5', '2.3.1'],
7074
['2.9.8', '2.9'],
7175
['2.1.2-release', '2.1.2-beta'],
72-
['2.1.3', '2.1.3-beta']
76+
['2.1.3', '2.1.3-beta'],
77+
['2.1.3+build-1.2.3', '2.1.3+build-1'],
78+
['3.7.0', '3.7.0-prerelease']
7379
]
7480

7581
versions.each do |target_version, user_version|
@@ -83,7 +89,7 @@
8389

8490
# invalid semantic version
8591
versions = [
86-
'-', '.', '..', '+', '+test', ' ', '2 .3. 0', '2.', '.2.2', '3.7.2.2', '3.x', ',', '+build-prerelease'
92+
'-', '.', '..', '+', '+test', ' ', '2 .3. 0', '2.', '.2.2', '3.7.2.2', '3.x', ',', '+build-prerelease', '2..2'
8793
]
8894

8995
versions.each do |user_version|

0 commit comments

Comments
 (0)