Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
178 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
class Version: | ||
|
||
def __init__(self, version): | ||
self.version = version | ||
|
||
def __repr__(self): | ||
return self.version | ||
|
||
def __eq__(self, other): | ||
return Comparator().compare(self.version, other.version) == 0 | ||
|
||
def __ne__(self, other): | ||
return not self == other | ||
|
||
def __lt__(self, other): | ||
return Comparator().compare(self.version, other.version) < 0 | ||
|
||
def __le__(self, other): | ||
return Comparator().compare(self.version, other.version) <= 0 | ||
|
||
def __gt__(self, other): | ||
return Comparator().compare(self.version, other.version) > 0 | ||
|
||
def __ge__(self, other): | ||
return Comparator().compare(self.version, other.version) >= 0 | ||
|
||
|
||
class Comparator: | ||
|
||
''' | ||
A comparator that semantically sorts versions. This comparator considers, | ||
e.g., "10" to be greater than "9", in contrast to a lexical comparison. | ||
Return: | ||
0 if version a == version b | ||
<0 if version a < version b | ||
>0 if version a > version b | ||
Rules: | ||
* version strings are broken into nodes delimited by '.' | ||
* comparison is initially on the first node of each version | ||
* if each node can both be converted to an integer, they are compared as such | ||
* otherwise, the nodes are compared as strings | ||
* if the comparison result of the first nodes is not 0, that result is returned | ||
* else, the first nodes are equal | ||
* if neither version has addition nodes, 0 is returned | ||
* if each version has additional nodes, those nodes are compared as above | ||
* else the version with the no more nodes remaining is considered the lesser version | ||
''' | ||
def compare(self, a, b): | ||
if a is None or b is None: | ||
raise ValueError('version string cannot be None') | ||
if not(isinstance(a, Version) or isinstance(a, str)) or not(isinstance(b, Version) or isinstance(b, str)): | ||
raise TypeError('version must be an instance of a Version or str') | ||
if not a or not b: | ||
raise ValueError('version string cannot be empty') | ||
def compareNodes(anodes, bnodes): | ||
if len(anodes) == 0 and len(bnodes) == 0: | ||
return 0 | ||
if len(anodes) == 0: | ||
return -1 | ||
if len(bnodes) == 0: | ||
return 1 | ||
anode, bnode = anodes[0], bnodes[0] | ||
try: | ||
anode, bnode = int(anode), int(bnode) | ||
except ValueError: | ||
pass | ||
if anode > bnode: | ||
return 1 | ||
elif anode < bnode: | ||
return -1 | ||
else: | ||
return compareNodes(anodes[1:], bnodes[1:]) | ||
return compareNodes(a.split('.'), b.split('.')) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import sure | ||
import unittest | ||
import version | ||
|
||
class VersionTest(unittest.TestCase): | ||
|
||
def testStringRepresentation(self): | ||
myversion = version.Version('1.2.3') | ||
repr(myversion).should.equal('1.2.3') | ||
|
||
def testEqual(self): | ||
a = version.Version('1.2.3') | ||
b = version.Version('1.2.3') | ||
a.should.equal(b) | ||
|
||
def testNotEqual(self): | ||
a = version.Version('1.2.3') | ||
b = version.Version('1.2.4') | ||
a.should_not.equal(b) | ||
|
||
def testGreaterThan(self): | ||
a = version.Version('10') | ||
b = version.Version('9') | ||
(a > b).should.be.true | ||
|
||
def testGreaterThanOrEquals(self): | ||
a = version.Version('10') | ||
b = version.Version('9') | ||
c = version.Version('10') | ||
(a >= b).should.be.true | ||
(a >= c).should.be.true | ||
|
||
def testLessThan(self): | ||
a = version.Version('9') | ||
b = version.Version('10') | ||
(a < b).should.be.true | ||
|
||
def testLessThanOrEqual(self): | ||
a = version.Version('9') | ||
b = version.Version('10') | ||
c = version.Version('9') | ||
(a <= b).should.be.true | ||
(a <= c).should.be.true | ||
|
||
class ComparatorTest(unittest.TestCase): | ||
|
||
def setUp(self): | ||
self.comparator = version.Comparator() | ||
|
||
def testEqual(self): | ||
(self.comparator.compare('1.2.3', '1.2.3') == 0).should.be.true | ||
|
||
def testNumericComparison(self): | ||
(self.comparator.compare('10', '9') > 0).should.be.true | ||
(self.comparator.compare('9', '10') < 0).should.be.true | ||
|
||
def testAlphaComparsion(self): | ||
(self.comparator.compare('z', 'a') > 0).should.be.true | ||
(self.comparator.compare('a', 'z') < 0).should.be.true | ||
|
||
def testAlphaNumberComparison(self): | ||
(self.comparator.compare('a', '1') > 0).should.be.true | ||
(self.comparator.compare('1', 'a') < 0).should.be.true | ||
|
||
def testDifferentNodeLengths(self): | ||
(self.comparator.compare('1.2.3', '1.2') > 0).should.be.true | ||
(self.comparator.compare('1.2', '1.2.3') < 0).should.be.true | ||
|
||
def testValueError(self): | ||
self.assertRaises(ValueError, self.comparator.compare, '1.2.3', '') | ||
self.assertRaises(ValueError, self.comparator.compare, '', '1.2.3') | ||
self.assertRaises(ValueError, self.comparator.compare, '1.2.3', None) | ||
self.assertRaises(ValueError, self.comparator.compare, None, '1.2.3') | ||
|
||
def testTypeError(self): | ||
self.assertRaises(TypeError, self.comparator.compare, '1.2.3', 0) | ||
self.assertRaises(TypeError, self.comparator.compare, 0, '1.2.3') | ||
|
||
if __name__ == '__main__': | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters