Skip to content

Commit 1cc462f

Browse files
author
Bilal Al
committed
added version property
1 parent ff885c8 commit 1cc462f

File tree

7 files changed

+152
-92
lines changed

7 files changed

+152
-92
lines changed

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
TESTS_REQUIRES = [
88
'flake8',
99
'pytest==7.0.1',
10-
'pytest-mock>=3.5.1',
10+
'pytest-mock==3.13.0',
1111
'coverage==6.2',
1212
'pytest-cov',
1313
'importlib-metadata==4.2',

splitio/models/grammar/matchers/semver.py

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
"""Semver matcher classes."""
2-
import abc
2+
import logging
33

4-
class Semver(object, metaclass=abc.ABCMeta):
4+
_LOGGER = logging.getLogger(__name__)
5+
6+
class Semver(object):
57
"""Semver class."""
68

79
_METADATA_DELIMITER = "+"
@@ -20,14 +22,25 @@ def __init__(self, version):
2022
self._patch = 0
2123
self._pre_release = []
2224
self._is_stable = False
23-
self._old_version = version
24-
self._parse()
25+
self.version = ""
26+
self._metadata = ""
27+
self._parse(version)
28+
29+
@classmethod
30+
def build(cls, version):
31+
try:
32+
self = cls(version)
33+
except RuntimeError as e:
34+
_LOGGER.error("Failed to parse Semver data, incorrect data type: %s", e)
35+
return None
2536

26-
def _parse(self):
37+
return self
38+
39+
def _parse(self, version):
2740
"""
28-
Parse the string in self._old_version to update the other internal variables
41+
Parse the string in self.version to update the other internal variables
2942
"""
30-
without_metadata = self.remove_metadata_if_exists()
43+
without_metadata = self.remove_metadata_if_exists(version)
3144

3245
index = without_metadata.find(self._PRE_RELEASE_DELIMITER)
3346
if index == -1:
@@ -39,18 +52,19 @@ def _parse(self):
3952

4053
self.set_major_minor_and_patch(without_metadata)
4154

42-
def remove_metadata_if_exists(self):
55+
def remove_metadata_if_exists(self, version):
4356
"""
44-
Check if there is any metadata characters in self._old_version.
57+
Check if there is any metadata characters in self.version.
4558
4659
:returns: The semver string without the metadata
4760
:rtype: str
4861
"""
49-
index = self._old_version.find(self._METADATA_DELIMITER)
62+
index = version.find(self._METADATA_DELIMITER)
5063
if index == -1:
51-
return self._old_version
64+
return version
5265

53-
return self._old_version[:index]
66+
self._metadata = version[index:]
67+
return version[:index]
5468

5569
def set_major_minor_and_patch(self, version):
5670
"""
@@ -68,6 +82,12 @@ def set_major_minor_and_patch(self, version):
6882
self._minor = int(parts[1])
6983
self._patch = int(parts[2])
7084

85+
self.version = "{major}{DELIMITER}{minor}{DELIMITER}{patch}".format(major = self._major, DELIMITER = self._VALUE_DELIMITER,
86+
minor = self._minor, patch = self._patch)
87+
self.version += "{DELIMITER}{pre_release}".format(DELIMITER=self._PRE_RELEASE_DELIMITER,
88+
pre_release = '.'.join(self._pre_release)) if len(self._pre_release) > 0 else ""
89+
self.version += "{DELIMITER}{metadata}".format(DELIMITER=self._METADATA_DELIMITER, metadata = self._metadata) if self._metadata != "" else ""
90+
7191
def compare(self, to_compare):
7292
"""
7393
Compare the current Semver object to a given Semver object, return:
@@ -81,7 +101,7 @@ def compare(self, to_compare):
81101
:returns: integer based on comparison
82102
:rtype: int
83103
"""
84-
if self._old_version == to_compare._old_version:
104+
if self.version == to_compare.version:
85105
return 0
86106

87107
# Compare major, minor, and patch versions numerically
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
version1,version2,version3,expected
2+
1.1.1,2.2.2,3.3.3,true
3+
1.1.1-rc.1,1.1.1-rc.2,1.1.1-rc.3,true
4+
1.0.0-alpha,1.0.0-alpha.1,1.0.0-alpha.beta,true
5+
1.0.0-alpha.1,1.0.0-alpha.beta,1.0.0-beta,true
6+
1.0.0-alpha.beta,1.0.0-beta,1.0.0-beta.2,true
7+
1.0.0-beta,1.0.0-beta.2,1.0.0-beta.11,true
8+
1.0.0-beta.2,1.0.0-beta.11,1.0.0-rc.1,true
9+
1.0.0-beta.11,1.0.0-rc.1,1.0.0,true
10+
1.1.2,1.1.3,1.1.4,true
11+
1.2.1,1.3.1,1.4.1,true
12+
2.0.0,3.0.0,4.0.0,true
13+
2.2.2,2.2.3-rc1,2.2.3,true
14+
2.2.2,2.3.2-rc100,2.3.3,true
15+
1.0.0-rc.1+build.1,1.2.3-beta,1.2.3-rc.1+build.123,true
16+
3.3.3,3.3.3-alpha,3.3.4,false
17+
2.2.2-rc.1,2.2.2+metadata,2.2.2-rc.10,false
18+
1.1.1-rc.1,1.1.1-rc.3,1.1.1-rc.2,false
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
version1,version2,equals
2+
1.1.1,1.1.1,true
3+
1.1.1,1.1.1+metadata,false
4+
1.1.1,1.1.1-rc.1,false
5+
88.88.88,88.88.88,true
6+
1.2.3----RC-SNAPSHOT.12.9.1--.12,1.2.3----RC-SNAPSHOT.12.9.1--.12,true
7+
10.2.3-DEV-SNAPSHOT,10.2.3-SNAPSHOT-123,false
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
invalid
2+
1
3+
1.2
4+
1.alpha.2
5+
+invalid
6+
-invalid
7+
-invalid+invalid
8+
-invalid.01
9+
alpha
10+
alpha.beta
11+
alpha.beta.1
12+
alpha.1
13+
alpha+beta
14+
alpha_beta
15+
alpha.
16+
alpha..
17+
beta
18+
-alpha.
19+
1.2
20+
1.2.3.DEV
21+
1.2-SNAPSHOT
22+
1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788
23+
1.2-RC-SNAPSHOT
24+
-1.0.3-gamma+b7718
25+
+justmeta
26+
#99999999999999999999999.999999999999999999.99999999999999999----RC-SNAPSHOT.12.09.1--------------------------------..12
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
higher,lower
2+
1.1.2,1.1.1
3+
1.0.0,1.0.0-rc.1
4+
1.1.0-rc.1,1.0.0-beta.11
5+
1.0.0-beta.11,1.0.0-beta.2
6+
1.0.0-beta.2,1.0.0-beta
7+
1.0.0-beta,1.0.0-alpha.beta
8+
1.0.0-alpha.beta,1.0.0-alpha.1
9+
1.0.0-alpha.1,1.0.0-alpha
10+
2.2.2-rc.2+metadata-lalala,2.2.2-rc.1.2
11+
1.2.3,0.0.4
12+
1.1.2+meta,1.1.2-prerelease+meta
13+
1.0.0-beta,1.0.0-alpha
14+
1.0.0-alpha0.valid,1.0.0-alpha.0valid
15+
1.0.0-rc.1+build.1,1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay
16+
10.2.3-DEV-SNAPSHOT,1.2.3-SNAPSHOT-123
17+
1.1.1-rc2,1.0.0-0A.is.legal
18+
1.2.3----RC-SNAPSHOT.12.9.1--.12+788,1.2.3----R-S.12.9.1--.12+meta
19+
1.2.3----RC-SNAPSHOT.12.9.1--.12.88,1.2.3----RC-SNAPSHOT.12.9.1--.12
20+
9223372036854775807.9223372036854775807.9223372036854775807,9223372036854775807.9223372036854775807.9223372036854775806
21+
1.1.1-alpha.beta.rc.build.java.pr.support.10,1.1.1-alpha.beta.rc.build.java.pr.support
22+
1.1.2,1.1.1
23+
1.2.1,1.1.1
24+
2.1.1,1.1.1
25+
1.1.1-rc.1,1.1.1-rc.0
Lines changed: 42 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,55 @@
11
"""Condition model tests module."""
22
import pytest
3+
import csv
4+
import os
35

46
from splitio.models.grammar.matchers.semver import Semver
57

8+
valid_versions = os.path.join(os.path.dirname(__file__), 'files', 'valid-semantic-versions.csv')
9+
invalid_versions = os.path.join(os.path.dirname(__file__), 'files', 'invalid-semantic-versions.csv')
10+
equalto_versions = os.path.join(os.path.dirname(__file__), 'files', 'equal-to-semver.csv')
11+
between_versions = os.path.join(os.path.dirname(__file__), 'files', 'between-semver.csv')
12+
613
class SemverTests(object):
714
"""Test the semver object model."""
815

9-
valid_versions = ["1.1.2", "1.1.1", "1.0.0", "1.0.0-rc.1", "1.0.0-beta.11", "1.0.0-beta.2",
10-
"1.0.0-beta", "1.0.0-alpha.beta", "1.0.0-alpha.1", "1.0.0-alpha", "2.2.2-rc.2+metadata-lalala", "2.2.2-rc.1.2",
11-
"1.2.3", "0.0.4", "1.1.2+meta", "1.1.2-prerelease+meta", "1.0.0-beta", "1.0.0-alpha", "1.0.0-alpha0.valid",
12-
"1.0.0-alpha.0valid", "1.0.0-rc.1+build.1", "1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay",
13-
"10.2.3-DEV-SNAPSHOT", "1.2.3-SNAPSHOT-123", "1.1.1-rc2", "1.0.0-0A.is.legal", "1.2.3----RC-SNAPSHOT.12.9.1--.12+788",
14-
"1.2.3----R-S.12.9.1--.12+meta", "1.2.3----RC-SNAPSHOT.12.9.1--.12.88", "1.2.3----RC-SNAPSHOT.12.9.1--.12",
15-
"9223372036854775807.9223372036854775807.9223372036854775807", "9223372036854775807.9223372036854775807.9223372036854775806",
16-
"1.1.1-alpha.beta.rc.build.java.pr.support.10", "1.1.1-alpha.beta.rc.build.java.pr.support"]
17-
1816
def test_valid_versions(self):
19-
major = [1, 1, 1, 1, 1, 1,
20-
1, 1, 1, 1, 2, 2,
21-
1, 0, 1, 1, 1, 1, 1,
22-
1, 1, 1,
23-
10, 1, 1, 1, 1,
24-
1, 1, 1,
25-
9223372036854775807, 9223372036854775807,
26-
1,1]
27-
minor = [1, 1, 0, 0, 0, 0,
28-
0, 0, 0, 0, 2, 2,
29-
2, 0, 1, 1, 0, 0, 0,
30-
0, 0, 0,
31-
2, 2, 1, 0, 2,
32-
2, 2, 2,
33-
9223372036854775807, 9223372036854775807,
34-
1, 1]
35-
patch = [2, 1, 0, 0, 0, 0,
36-
0, 0, 0, 0, 2, 2,
37-
3, 4, 2, 2, 0, 0, 0,
38-
0, 0, 0,
39-
3, 3, 1, 0, 3,
40-
3, 3, 3,
41-
9223372036854775807, 9223372036854775806,
42-
1, 1]
43-
pre_release = [[], [], [], ["rc","1"], ["beta","11"],["beta","2"],
44-
["beta"], ["alpha","beta"], ["alpha","1"], ["alpha"], ["rc","2"], ["rc","1","2"],
45-
[], [], [], ["prerelease"], ["beta"], ["alpha"], ["alpha0","valid"],
46-
["alpha","0valid"], ["rc","1"], ["alpha-a","b-c-somethinglong"],
47-
["DEV-SNAPSHOT"], ["SNAPSHOT-123"], ["rc2"], ["0A","is","legal"], ["---RC-SNAPSHOT","12","9","1--","12"],
48-
["---R-S","12","9","1--","12"], ["---RC-SNAPSHOT","12","9","1--","12","88"], ["---RC-SNAPSHOT","12","9","1--","12"],
49-
[], [],
50-
["alpha","beta","rc","build","java","pr","support","10"], ["alpha","beta","rc","build","java","pr","support"]]
51-
52-
for i in range(len(major)-1):
53-
semver = Semver(self.valid_versions[i])
54-
self._verify_version(semver, major[i], minor[i], patch[i], pre_release[i], pre_release[i]==[])
17+
with open(valid_versions) as csvfile:
18+
reader = csv.DictReader(csvfile)
19+
for row in reader:
20+
assert Semver.build(row['higher']) is not None
21+
assert Semver.build(row['lower']) is not None
5522

5623
def test_invalid_versions(self):
57-
"""Test parsing invalid versions."""
58-
invalid_versions = [
59-
"1", "1.2", "1.alpha.2", "+invalid", "-invalid", "-invalid+invalid", "+justmeta",
60-
"-invalid.01", "alpha", "alpha.beta", "alpha.beta.1", "alpha.1", "alpha+beta",
61-
"alpha_beta", "alpha.", "alpha..", "beta", "-alpha.", "1.2", "1.2.3.DEV", "-1.0.3-gamma+b7718",
62-
"1.2-SNAPSHOT", "1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788", "1.2-RC-SNAPSHOT"]
63-
# "99999999999999999999999.999999999999999999.99999999999999999----RC-SNAPSHOT.12.09.1--------------------------------..12"]
64-
65-
for version in invalid_versions:
66-
with pytest.raises(RuntimeError):
67-
semver = Semver(version)
68-
pass
24+
with open(invalid_versions) as csvfile:
25+
reader = csv.DictReader(csvfile)
26+
for row in reader:
27+
assert Semver.build(row['invalid']) is None
6928

7029
def test_compare(self):
71-
cnt = 0
72-
for i in range(int(len(self.valid_versions)/2)):
73-
assert Semver(self.valid_versions[cnt]).compare(Semver(self.valid_versions[cnt+1])) == 1
74-
assert Semver(self.valid_versions[cnt+1]).compare(Semver(self.valid_versions[cnt])) == -1
75-
assert Semver(self.valid_versions[cnt]).compare(Semver(self.valid_versions[cnt])) == 0
76-
assert Semver(self.valid_versions[cnt+1]).compare(Semver(self.valid_versions[cnt+1])) == 0
77-
cnt = cnt + 2
78-
79-
assert Semver("1.1.1").compare(Semver("1.1.1")) == 0
80-
assert Semver("1.1.1").compare(Semver("1.1.1+metadata")) == 0
81-
assert Semver("1.1.1").compare(Semver("1.1.1-rc.1")) == 1
82-
assert Semver("88.88.88").compare(Semver("88.88.88")) == 0
83-
assert Semver("1.2.3----RC-SNAPSHOT.12.9.1--.12").compare(Semver("1.2.3----RC-SNAPSHOT.12.9.1--.12")) == 0
84-
assert Semver("10.2.3-DEV-SNAPSHOT").compare(Semver("10.2.3-SNAPSHOT-123")) == -1
85-
86-
def _verify_version(self, semver, major, minor, patch, pre_release="", is_stable=True):
87-
assert semver._major == major
88-
assert semver._minor == minor
89-
assert semver._patch == patch
90-
assert semver._pre_release == pre_release
91-
assert semver._is_stable == is_stable
30+
with open(valid_versions) as csvfile:
31+
reader = csv.DictReader(csvfile)
32+
for row in reader:
33+
assert Semver.build(row['higher']).compare(Semver.build(row['lower'])) == 1
34+
assert Semver.build(row['lower']).compare(Semver.build(row['higher'])) == -1
35+
36+
with open(equalto_versions) as csvfile:
37+
reader = csv.DictReader(csvfile)
38+
for row in reader:
39+
version1 = Semver.build(row['version1'])
40+
version2 = Semver.build(row['version2'])
41+
if row['equals'] == "true":
42+
assert version1.version == version2.version
43+
else:
44+
assert version1.version != version2.version
45+
46+
with open(between_versions) as csvfile:
47+
reader = csv.DictReader(csvfile)
48+
for row in reader:
49+
version1 = Semver.build(row['version1'])
50+
version2 = Semver.build(row['version2'])
51+
version3 = Semver.build(row['version3'])
52+
if row['expected'] == "true":
53+
assert version2.compare(version1) >= 0 and version3.compare(version2) >= 0
54+
else:
55+
assert version2.compare(version1) < 0 or version3.compare(version2) < 0

0 commit comments

Comments
 (0)