diff options
-rw-r--r-- | CREDITS | 4 | ||||
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | LICENSE | 2 | ||||
-rw-r--r-- | README.rst | 4 | ||||
-rw-r--r-- | semantic_version/__init__.py | 2 | ||||
-rw-r--r-- | semantic_version/base.py | 21 | ||||
-rw-r--r-- | semantic_version/compat.py | 2 | ||||
-rw-r--r-- | semantic_version/django_fields.py | 4 | ||||
-rwxr-xr-x | setup.py | 2 | ||||
-rw-r--r-- | tests/compat.py | 2 | ||||
-rw-r--r-- | tests/django_test_app/__init__.py | 2 | ||||
-rw-r--r-- | tests/django_test_app/models.py | 2 | ||||
-rwxr-xr-x | tests/test_base.py | 130 | ||||
-rw-r--r-- | tests/test_django.py | 41 | ||||
-rwxr-xr-x | tests/test_match.py | 2 | ||||
-rwxr-xr-x | tests/test_parsing.py | 2 | ||||
-rw-r--r-- | tests/test_spec.py | 2 |
17 files changed, 201 insertions, 25 deletions
@@ -18,8 +18,10 @@ Contributors The project has received contributions from (in alphabetical order): * Raphaƫl Barrois <raphael.barrois+semver@polytechnique.org> (https://github.com/rbarrois) -* Michael Hrivnak <mhrivnak@hrivnak.org> (https://github.com/mhrivnak) * Rick Eyre <rick.eyre@outlook.com> (https://github.com/rickeyre) +* Hugo Rodger-Brown <hugo@yunojuno.com> (https://github.com/yunojuno) +* Michael Hrivnak <mhrivnak@hrivnak.org> (https://github.com/mhrivnak) +* William Minchin <w_minchin@hotmail.com> (https://github.com/minchinweb) * Dave Hall <skwadhd@gmail.com> (https://github.com/skwashd) @@ -31,6 +31,8 @@ ChangeLog parameters differ only by build metadata * ``Spec('<=1.3.0')`` now matches ``Version('1.3.0+abde24fe883')`` + * `#24 <https://github.com/rbarrois/python-semanticversion/issues/24>`_: Fix handling of bumping pre-release versions, thanks to @minchinweb. + 2.4.2 (2015-07-02) ------------------ @@ -1,4 +1,4 @@ -Copyright (c) 2012-2014 The python-semanticversion project +Copyright (c) The python-semanticversion project All rights reserved. Redistribution and use in source and binary forms, with or without @@ -7,7 +7,7 @@ It follows strictly the 2.0.0 version of the SemVer scheme. .. image:: https://secure.travis-ci.org/rbarrois/python-semanticversion.png?branch=master :target: http://travis-ci.org/rbarrois/python-semanticversion/ -semantic_version supports Python 2.6, 2.7, 3.2, 3.3, 3.4; and is distributed under the two-clause BSD licence. +semantic_version supports Python 2.6, 2.7, 3.2, 3.3, 3.4; and is distributed under the two-clause BSD license. Links ----- @@ -293,7 +293,7 @@ When submitting patches or pull requests, you should respect the following rules .. note:: All files should contain the following header:: # -*- encoding: utf-8 -*- - # Copyright (c) 2012-2014 The python-semanticversion project + # Copyright (c) The python-semanticversion project Contents diff --git a/semantic_version/__init__.py b/semantic_version/__init__.py index 07de3a5..94e0a8d 100644 --- a/semantic_version/__init__.py +++ b/semantic_version/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2012-2014 The python-semanticversion project +# Copyright (c) The python-semanticversion project # This code is distributed under the two-clause BSD License. diff --git a/semantic_version/base.py b/semantic_version/base.py index d0f5db8..7451e14 100644 --- a/semantic_version/base.py +++ b/semantic_version/base.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2012-2014 The python-semanticversion project +# Copyright (c) The python-semanticversion project # This code is distributed under the two-clause BSD License. from __future__ import unicode_literals @@ -89,15 +89,24 @@ class Version(object): return int(value) def next_major(self): - return Version('.'.join(str(x) for x in [self.major + 1, 0, 0])) + if self.prerelease and self.minor is 0 and self.patch is 0: + return Version('.'.join(str(x) for x in [self.major, self.minor, self.patch])) + else: + return Version('.'.join(str(x) for x in [self.major + 1, 0, 0])) def next_minor(self): - return Version( - '.'.join(str(x) for x in [self.major, self.minor + 1, 0])) + if self.prerelease and self.patch is 0: + return Version('.'.join(str(x) for x in [self.major, self.minor, self.patch])) + else: + return Version( + '.'.join(str(x) for x in [self.major, self.minor + 1, 0])) def next_patch(self): - return Version( - '.'.join(str(x) for x in [self.major, self.minor, self.patch + 1])) + if self.prerelease: + return Version('.'.join(str(x) for x in [self.major, self.minor, self.patch])) + else: + return Version( + '.'.join(str(x) for x in [self.major, self.minor, self.patch + 1])) @classmethod def coerce(cls, version_string, partial=False): diff --git a/semantic_version/compat.py b/semantic_version/compat.py index 4dd60fe..b17468f 100644 --- a/semantic_version/compat.py +++ b/semantic_version/compat.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2012-2014 The python-semanticversion project +# Copyright (c) The python-semanticversion project # This code is distributed under the two-clause BSD License. diff --git a/semantic_version/django_fields.py b/semantic_version/django_fields.py index a0c6979..eba8658 100644 --- a/semantic_version/django_fields.py +++ b/semantic_version/django_fields.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2012-2014 The python-semanticversion project +# Copyright (c) The python-semanticversion project # This code is distributed under the two-clause BSD License. from __future__ import unicode_literals @@ -18,7 +18,7 @@ class BaseSemVerField(models.CharField): super(BaseSemVerField, self).__init__(*args, **kwargs) def get_prep_value(self, obj): - return str(obj) + return None if obj is None else str(obj) def get_db_prep_value(self, value, connection, prepared=False): if not prepared: @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (c) 2012-2014 The python-semanticversion project +# Copyright (c) The python-semanticversion project import codecs diff --git a/tests/compat.py b/tests/compat.py index f3617ee..f3ef508 100644 --- a/tests/compat.py +++ b/tests/compat.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2012-2014 The python-semanticversion project +# Copyright (c) The python-semanticversion project # This code is distributed under the two-clause BSD License. import sys diff --git a/tests/django_test_app/__init__.py b/tests/django_test_app/__init__.py index 72ebf68..0f94470 100644 --- a/tests/django_test_app/__init__.py +++ b/tests/django_test_app/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2012-2014 The python-semanticversion project +# Copyright (c) The python-semanticversion project # This code is distributed under the two-clause BSD License. try: # pragma: no cover diff --git a/tests/django_test_app/models.py b/tests/django_test_app/models.py index 06d0096..5313e89 100644 --- a/tests/django_test_app/models.py +++ b/tests/django_test_app/models.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2012-2014 The python-semanticversion project +# Copyright (c) The python-semanticversion project try: from django.db import models diff --git a/tests/test_base.py b/tests/test_base.py index ae23d86..6b64073 100755 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (c) 2012-2014 The python-semanticversion project +# Copyright (c) The python-semanticversion project # This code is distributed under the two-clause BSD License. """Test the various functions from 'base'.""" @@ -241,19 +241,119 @@ class VersionTestCase(unittest.TestCase): self.assertTrue(v != '0.1.0') self.assertFalse(v == '0.1.0') - def test_bump_versions(self): + def test_bump_clean_versions(self): + # We Test each property explicitly as the == comparator for versions + # does not distinguish between prerelease or builds for equality. + + v = base.Version('1.0.0+build') + v = v.next_major() + self.assertEqual(v.major, 2) + self.assertEqual(v.minor, 0) + self.assertEqual(v.patch, 0) + self.assertEqual(v.prerelease, ()) + self.assertEqual(v.build, ()) + + v = base.Version('1.0.0+build') + v = v.next_minor() + self.assertEqual(v.major, 1) + self.assertEqual(v.minor, 1) + self.assertEqual(v.patch, 0) + self.assertEqual(v.prerelease, ()) + self.assertEqual(v.build, ()) + + v = base.Version('1.0.0+build') + v = v.next_patch() + self.assertEqual(v.major, 1) + self.assertEqual(v.minor, 0) + self.assertEqual(v.patch, 1) + self.assertEqual(v.prerelease, ()) + self.assertEqual(v.build, ()) + + v = base.Version('1.1.0+build') + v = v.next_major() + self.assertEqual(v.major, 2) + self.assertEqual(v.minor, 0) + self.assertEqual(v.patch, 0) + self.assertEqual(v.prerelease, ()) + self.assertEqual(v.build, ()) + + v = base.Version('1.1.0+build') + v = v.next_minor() + self.assertEqual(v.major, 1) + self.assertEqual(v.minor, 2) + self.assertEqual(v.patch, 0) + self.assertEqual(v.prerelease, ()) + self.assertEqual(v.build, ()) + + v = base.Version('1.1.0+build') + v = v.next_patch() + self.assertEqual(v.major, 1) + self.assertEqual(v.minor, 1) + self.assertEqual(v.patch, 1) + self.assertEqual(v.prerelease, ()) + self.assertEqual(v.build, ()) + + v = base.Version('1.0.1+build') + v = v.next_major() + self.assertEqual(v.major, 2) + self.assertEqual(v.minor, 0) + self.assertEqual(v.patch, 0) + self.assertEqual(v.prerelease, ()) + self.assertEqual(v.build, ()) + + v = base.Version('1.0.1+build') + v = v.next_minor() + self.assertEqual(v.major, 1) + self.assertEqual(v.minor, 1) + self.assertEqual(v.patch, 0) + self.assertEqual(v.prerelease, ()) + self.assertEqual(v.build, ()) + + v = base.Version('1.0.1+build') + v = v.next_patch() + self.assertEqual(v.major, 1) + self.assertEqual(v.minor, 0) + self.assertEqual(v.patch, 2) + self.assertEqual(v.prerelease, ()) + self.assertEqual(v.build, ()) + + def test_bump_prerelease_versions(self): # We Test each property explicitly as the == comparator for versions # does not distinguish between prerelease or builds for equality. v = base.Version('1.0.0-pre+build') v = v.next_major() + self.assertEqual(v.major, 1) + self.assertEqual(v.minor, 0) + self.assertEqual(v.patch, 0) + self.assertEqual(v.prerelease, ()) + self.assertEqual(v.build, ()) + + v = base.Version('1.0.0-pre+build') + v = v.next_minor() + self.assertEqual(v.major, 1) + self.assertEqual(v.minor, 0) + self.assertEqual(v.patch, 0) + self.assertEqual(v.prerelease, ()) + self.assertEqual(v.build, ()) + + v = base.Version('1.0.0-pre+build') + v = v.next_patch() + self.assertEqual(v.major, 1) + self.assertEqual(v.minor, 0) + self.assertEqual(v.patch, 0) + self.assertEqual(v.prerelease, ()) + self.assertEqual(v.build, ()) + + v = base.Version('1.1.0-pre+build') + v = v.next_major() self.assertEqual(v.major, 2) self.assertEqual(v.minor, 0) self.assertEqual(v.patch, 0) self.assertEqual(v.prerelease, ()) self.assertEqual(v.build, ()) - v = base.Version('1.0.1-pre+build') + v = base.Version('1.1.0-pre+build') v = v.next_minor() self.assertEqual(v.major, 1) self.assertEqual(v.minor, 1) @@ -265,6 +365,30 @@ class VersionTestCase(unittest.TestCase): v = v.next_patch() self.assertEqual(v.major, 1) self.assertEqual(v.minor, 1) + self.assertEqual(v.patch, 0) + self.assertEqual(v.prerelease, ()) + self.assertEqual(v.build, ()) + + v = base.Version('1.0.1-pre+build') + v = v.next_major() + self.assertEqual(v.major, 2) + self.assertEqual(v.minor, 0) + self.assertEqual(v.patch, 0) + self.assertEqual(v.prerelease, ()) + self.assertEqual(v.build, ()) + + v = base.Version('1.0.1-pre+build') + v = v.next_minor() + self.assertEqual(v.major, 1) + self.assertEqual(v.minor, 1) + self.assertEqual(v.patch, 0) + self.assertEqual(v.prerelease, ()) + self.assertEqual(v.build, ()) + + v = base.Version('1.0.1-pre+build') + v = v.next_patch() + self.assertEqual(v.major, 1) + self.assertEqual(v.minor, 0) self.assertEqual(v.patch, 1) self.assertEqual(v.prerelease, ()) self.assertEqual(v.build, ()) diff --git a/tests/test_django.py b/tests/test_django.py index 94e2420..c93dde7 100644 --- a/tests/test_django.py +++ b/tests/test_django.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2012-2014 The python-semanticversion project +# Copyright (c) The python-semanticversion project # This code is distributed under the two-clause BSD License. from __future__ import unicode_literals @@ -30,6 +30,13 @@ if django_loaded and django.VERSION < (1, 7): # pragma: no cover except ImportError: pass +# the refresh_from_db method only came in with 1.8, so in order to make this +# work will all supported versions we have our own function. +def save_and_refresh(obj): + """Saves an object, and refreshes from the database.""" + obj.save() + obj = obj.__class__.objects.get(id=obj.id) + @unittest.skipIf(not django_loaded, "Django not installed") class DjangoFieldTestCase(unittest.TestCase): @@ -48,6 +55,38 @@ class DjangoFieldTestCase(unittest.TestCase): obj.full_clean() + def test_version_save(self): + """Test saving object with a VersionField.""" + # first test with a null value + obj = models.PartialVersionModel() + self.assertIsNone(obj.id) + self.assertIsNone(obj.optional) + save_and_refresh(obj) + self.assertIsNotNone(obj.id) + self.assertIsNone(obj.optional_spec) + + # now set to something that is not null + spec = semantic_version.Spec('==0,!=0.2') + obj.optional_spec = spec + save_and_refresh(obj) + self.assertEqual(obj.optional_spec, spec) + + def test_spec_save(self): + """Test saving object with a SpecField.""" + # first test with a null value + obj = models.PartialVersionModel() + self.assertIsNone(obj.id) + self.assertIsNone(obj.optional_spec) + save_and_refresh(obj) + self.assertIsNotNone(obj.id) + self.assertIsNone(obj.optional_spec) + + # now set to something that is not null + spec = semantic_version.Spec('==0,!=0.2') + obj.optional_spec = spec + save_and_refresh(obj) + self.assertEqual(obj.optional_spec, spec) + def test_partial_spec(self): obj = models.VersionModel(version='0.1.1', spec='==0,!=0.2') self.assertEqual(semantic_version.Version('0.1.1'), obj.version) diff --git a/tests/test_match.py b/tests/test_match.py index 473abfc..9955b9f 100755 --- a/tests/test_match.py +++ b/tests/test_match.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (c) 2012-2014 The python-semanticversion project +# Copyright (c) The python-semanticversion project # This code is distributed under the two-clause BSD License. import unittest diff --git a/tests/test_parsing.py b/tests/test_parsing.py index c7651d2..8fd22da 100755 --- a/tests/test_parsing.py +++ b/tests/test_parsing.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (c) 2012-2014 The python-semanticversion project +# Copyright (c) The python-semanticversion project # This code is distributed under the two-clause BSD License. import itertools diff --git a/tests/test_spec.py b/tests/test_spec.py index a13cb0b..43c9d6a 100644 --- a/tests/test_spec.py +++ b/tests/test_spec.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (c) 2012-2014 The python-semanticversion project +# Copyright (c) The python-semanticversion project # This code is distributed under the two-clause BSD License. """Test conformance to the specs.""" |