summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaphaël Barrois <raphael.barrois@polytechnique.org>2012-05-17 16:38:14 +0200
committerRaphaël Barrois <raphael.barrois@polytechnique.org>2012-05-17 16:38:14 +0200
commita42ddd7467425ab76a0ebecd85ed1d6f7aa5ec7e (patch)
tree997a43065c93098fc52a1beb65322397eb26c21f
parent1d515998cb6ce4c56b587faa12d5b5317d65121c (diff)
downloadsemantic-version-a42ddd7467425ab76a0ebecd85ed1d6f7aa5ec7e.tar.gz
Add SpecList.
Signed-off-by: Raphaël Barrois <raphael.barrois@polytechnique.org>
-rw-r--r--src/semantic_version/base.py35
-rwxr-xr-xtests/test_base.py62
2 files changed, 97 insertions, 0 deletions
diff --git a/src/semantic_version/base.py b/src/semantic_version/base.py
index c927305..05755e6 100644
--- a/src/semantic_version/base.py
+++ b/src/semantic_version/base.py
@@ -300,6 +300,41 @@ class Spec(object):
return hash((self.kind, self.spec))
+class SpecList(object):
+ def __init__(self, specs_string):
+ self.specs = self.parse(specs_string)
+
+ @classmethod
+ def parse(self, specs_string):
+ spec_texts = specs_string.split(',')
+ return tuple(Spec(spec_text) for spec_text in spec_texts)
+
+ def match(self, version):
+ return all(spec.match(version) for spec in self.specs)
+
+ def __contains__(self, version):
+ if isinstance(version, Version):
+ return self.match(version)
+ return False
+
+ def __iter__(self):
+ return iter(self.specs)
+
+ def __str__(self):
+ return ','.join(str(spec) for spec in self.specs)
+
+ def __repr__(self):
+ return '<SpecList: %r>' % (self.specs,)
+
+ def __eq__(self, other):
+ if not isinstance(other, SpecList):
+ return NotImplemented
+
+ return set(self.specs) == set(other.specs)
+
+ def __hash__(self):
+ return hash(self.specs)
+
def compare(v1, v2):
return cmp(Version(v1), Version(v2))
diff --git a/tests/test_base.py b/tests/test_base.py
index 38c7924..54089dc 100755
--- a/tests/test_base.py
+++ b/tests/test_base.py
@@ -264,5 +264,67 @@ class SpecTestCase(unittest.TestCase):
len(set([base.Spec('==0.1.0'), base.Spec('==0.1.0')])))
+class SpecListTestCase(unittest.TestCase):
+ examples = {
+ '>=0.1.1,<0.1.2': ['>=0.1.1', '<0.1.2'],
+ '>~0.1,!=0.1.3-rc1,<0.1.3': ['>~0.1', '!=0.1.3-rc1', '<0.1.3'],
+ }
+
+ def test_parsing(self):
+ for spec_list_text, specs in self.examples.items():
+ spec_list = base.SpecList(spec_list_text)
+
+ self.assertEqual(spec_list_text, str(spec_list))
+ self.assertNotEqual(spec_list_text, spec_list)
+ self.assertEqual(specs, [str(spec) for spec in spec_list])
+
+ for spec_text in specs:
+ self.assertTrue(repr(base.Spec(spec_text)) in repr(spec_list))
+
+ matches = {
+ '>=0.1.1,<0.1.2': (
+ ['0.1.1', '0.1.2-alpha', '0.1.1+4'],
+ ['0.1.1-alpha', '0.1.2', '1.3.4'],
+ ),
+ '>~0.1,!=0.1.3-rc1,<0.1.3': (
+ ['0.1.1', '0.1.3-rc1+4', '0.1.3-alpha'],
+ ['0.0.1', '0.1.3', '0.2.2', '0.1.3-rc1'],
+ ),
+ }
+
+ def test_matches(self):
+ for spec_list_text, versions in self.matches.items():
+ spec_list = base.SpecList(spec_list_text)
+ matching, failing = versions
+
+ for version_text in matching:
+ version = base.Version(version_text)
+ self.assertTrue(version in spec_list,
+ "%r should be in %r" % (version, spec_list))
+ self.assertTrue(spec_list.match(version),
+ "%r should match %r" % (version, spec_list))
+
+ for version_text in failing:
+ version = base.Version(version_text)
+ self.assertFalse(version in spec_list,
+ "%r should not be in %r" % (version, spec_list))
+ self.assertFalse(spec_list.match(version),
+ "%r should not match %r" % (version, spec_list))
+
+ def test_equality(self):
+ for spec_list_text in self.examples:
+ slist1 = base.SpecList(spec_list_text)
+ slist2 = base.SpecList(spec_list_text)
+ self.assertEqual(slist1, slist2)
+ self.assertFalse(slist1 == spec_list_text)
+
+ def test_contains(self):
+ self.assertFalse('ii' in base.SpecList('>=0.1.1'))
+
+ def test_hash(self):
+ self.assertEqual(1,
+ len(set([base.SpecList('>=0.1.1'), base.SpecList('>=0.1.1')])))
+
+
if __name__ == '__main__': # pragma: no cover
unittest.main()