diff options
author | Raphaël Barrois <raphael.barrois@polytechnique.org> | 2012-05-17 16:38:14 +0200 |
---|---|---|
committer | Raphaël Barrois <raphael.barrois@polytechnique.org> | 2012-05-17 16:38:14 +0200 |
commit | a42ddd7467425ab76a0ebecd85ed1d6f7aa5ec7e (patch) | |
tree | 997a43065c93098fc52a1beb65322397eb26c21f | |
parent | 1d515998cb6ce4c56b587faa12d5b5317d65121c (diff) | |
download | semantic-version-a42ddd7467425ab76a0ebecd85ed1d6f7aa5ec7e.tar.gz |
Add SpecList.
Signed-off-by: Raphaël Barrois <raphael.barrois@polytechnique.org>
-rw-r--r-- | src/semantic_version/base.py | 35 | ||||
-rwxr-xr-x | tests/test_base.py | 62 |
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() |