diff options
author | Raphaël Barrois <raphael.barrois@polytechnique.org> | 2019-08-23 23:24:50 +0200 |
---|---|---|
committer | Raphaël Barrois <raphael.barrois@polytechnique.org> | 2019-08-26 21:34:10 +0200 |
commit | c4c6ab0e925d8cfabb68d34a10a783cb854b63a0 (patch) | |
tree | 84895b9dd586594c380668875ede00ba4b8a928a /tests | |
parent | 5b9174aedaf9843ee5b3b6358461910e328e74d1 (diff) | |
download | semantic-version-c4c6ab0e925d8cfabb68d34a10a783cb854b63a0.tar.gz |
Add support for NPM-style version ranges.
The code follows closely the specification available at
https://docs.npmjs.com/misc/semver.html.
Despite similarities, the matching logic is fully separate from the
`native` code, since both might evolve at their own scales.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/django_test_app/models.py | 1 | ||||
-rw-r--r-- | tests/test_django.py | 19 | ||||
-rw-r--r-- | tests/test_npm.py | 88 |
3 files changed, 105 insertions, 3 deletions
diff --git a/tests/django_test_app/models.py b/tests/django_test_app/models.py index 3a43cfc..5f790b4 100644 --- a/tests/django_test_app/models.py +++ b/tests/django_test_app/models.py @@ -14,6 +14,7 @@ if django_loaded: class VersionModel(models.Model): version = semver_fields.VersionField(verbose_name='my version') spec = semver_fields.SpecField(verbose_name='my spec') + npm_spec = semver_fields.SpecField(syntax='npm', blank=True, verbose_name='npm spec') class PartialVersionModel(models.Model): partial = semver_fields.VersionField(partial=True, verbose_name='partial version') diff --git a/tests/test_django.py b/tests/test_django.py index b5c4a9c..5fff8a9 100644 --- a/tests/test_django.py +++ b/tests/test_django.py @@ -4,7 +4,7 @@ import unittest -from semantic_version import Version, NativeSpec +from semantic_version import Version, SimpleSpec, NpmSpec from .setup_django import django_loaded @@ -64,25 +64,29 @@ class DjangoFieldTestCase(unittest.TestCase): obj = models.VersionModel( version=Version('0.1.1'), spec=SimpleSpec('==0.1.1,!=0.1.1-alpha'), + npm_spec=NpmSpec('1.2 - 2.3'), ) self.assertEqual(Version('0.1.1'), obj.version) self.assertEqual(SimpleSpec('==0.1.1,!=0.1.1-alpha'), obj.spec) + self.assertEqual(NpmSpec('1.2 - 2.3'), obj.npm_spec) - alt_obj = models.VersionModel(version=obj.version, spec=obj.spec) + alt_obj = models.VersionModel(version=obj.version, spec=obj.spec, npm_spec=obj.npm_spec) self.assertEqual(Version('0.1.1'), alt_obj.version) self.assertEqual(SimpleSpec('==0.1.1,!=0.1.1-alpha'), alt_obj.spec) self.assertEqual(obj.spec, alt_obj.spec) + self.assertEqual(obj.npm_spec, alt_obj.npm_spec) self.assertEqual(obj.version, alt_obj.version) def test_version_clean(self): """Calling .full_clean() should convert str to Version/Spec objects.""" - obj = models.VersionModel(version='0.1.1', spec='==0.1.1,!=0.1.1-alpha') + obj = models.VersionModel(version='0.1.1', spec='==0.1.1,!=0.1.1-alpha', npm_spec='1.x') obj.full_clean() self.assertEqual(Version('0.1.1'), obj.version) self.assertEqual(SimpleSpec('==0.1.1,!=0.1.1-alpha'), obj.spec) + self.assertEqual(NpmSpec('1.x'), obj.npm_spec) def test_version_save(self): """Test saving object with a VersionField.""" @@ -166,10 +170,12 @@ class DjangoFieldTestCase(unittest.TestCase): o1 = models.VersionModel( version=Version('0.1.1'), spec=SimpleSpec('==0.1.1,!=0.1.1-alpha'), + npm_spec=NpmSpec('1.2 - 2.3'), ) o2 = models.VersionModel( version=Version('0.4.3-rc3+build3'), spec=SimpleSpec('<=0.1.1-rc2,!=0.1.1-rc1'), + npm_spec=NpmSpec('1.2 - 2.3'), ) data = serializers.serialize('json', [o1, o2]) @@ -177,8 +183,10 @@ class DjangoFieldTestCase(unittest.TestCase): obj1, obj2 = serializers.deserialize('json', data) self.assertEqual(o1.version, obj1.object.version) self.assertEqual(o1.spec, obj1.object.spec) + self.assertEqual(o1.npm_spec, obj1.object.npm_spec) self.assertEqual(o2.version, obj2.object.version) self.assertEqual(o2.spec, obj2.object.spec) + self.assertEqual(o2.npm_spec, obj2.object.npm_spec) def test_serialization_partial(self): o1 = models.PartialVersionModel( @@ -220,6 +228,11 @@ class FieldMigrationTests(DjangoTestCase): expected = {'max_length': 200} self.assertEqual(field.deconstruct()[3], expected) + def test_nondefault_spec_field(self): + field = django_fields.SpecField(syntax='npm') + expected = {'max_length': 200, 'syntax': 'npm'} + self.assertEqual(field.deconstruct()[3], expected) + @unittest.skipIf(not django_loaded, "Django not installed") class FullMigrateTests(TransactionTestCase): diff --git a/tests/test_npm.py b/tests/test_npm.py new file mode 100644 index 0000000..76cb6e2 --- /dev/null +++ b/tests/test_npm.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) The python-semanticversion project +# This code is distributed under the two-clause BSD License. + +"""Test NPM-style specifications.""" + +import unittest + +from semantic_version import base + + +class NpmSpecTests(unittest.TestCase): + examples = { + # range: [matchings], [failings] + '>=1.2.7': ( + ['1.2.7', '1.2.8', '1.3.9'], + ['1.2.6', '1.1.0'], + ), + '>=1.2.7 <1.3.0': ( + ['1.2.7', '1.2.8', '1.2.99'], + ['1.2.6', '1.3.0', '1.1.0'], + ), + '1.2.7 || >=1.2.9 <2.0.0': ( + ['1.2.7', '1.2.9', '1.4.6'], + ['1.2.8', '2.0.0'], + ), + '>1.2.3-alpha.3': ( + ['1.2.3-alpha.7', '3.4.5'], + ['1.2.3-alpha.3', '3.4.5-alpha.9'], + ), + '>=1.2.3-alpha.3': ( + ['1.2.3-alpha.3', '1.2.3-alpha.7', '3.4.5'], + ['1.2.3-alpha.2', '3.4.5-alpha.9'], + ), + '1.2.3 - 2.3.4': ( + ['1.2.3', '1.2.99', '2.2.0', '2.3.4', '2.3.4+b42'], + ['1.2.0', '1.2.3-alpha.1', '2.3.5'], + ), + '~1.2.3-beta.2': ( + ['1.2.3-beta.2', '1.2.3-beta.4', '1.2.4'], + ['1.2.4-beta.2', '1.3.0'], + ), + } + + def test_spec(self): + for spec, lists in self.examples.items(): + matching, failing = lists + for version in matching: + with self.subTest(spec=spec, version=version): + self.assertIn(base.Version(version), base.NpmSpec(spec)) + for version in failing: + with self.subTest(spec=spec, version=version): + self.assertNotIn(base.Version(version), base.NpmSpec(spec)) + + expansions = { + # Hyphen ranges + '1.2.3 - 2.3.4': '>=1.2.3 <=2.3.4', + '1.2 - 2.3.4': '>=1.2.0 <=2.3.4', + '1.2.3 - 2.3': '>=1.2.3 <2.4.0', + '1.2.3 - 2': '>=1.2.3 <3', + + # X-Ranges + '*': '>=0.0.0', + '1.x': '>=1.0.0 <2.0.0', + '1.2.x': '>=1.2.0 <1.3.0', + '': '*', + '1': '1.x.x', + '1.x.x': '>=1.0.0 <2.0.0', + '1.2': '1.2.x', + + # Tilde ranges + '~1.2.3': '>=1.2.3 <1.3.0', + '~1.2': '>=1.2.0 <1.3.0', + '~1': '>=1.0.0 <2.0.0', + '~0.2.3': '>=0.2.3 <0.3.0', + '~0.2': '>=0.2.0 <0.3.0', + '~0': '>=0.0.0 <1.0.0', + '~1.2.3-beta.2': '>=1.2.3-beta.2 <1.3.0', + } + + def test_expand(self): + for source, expanded in self.expansions.items(): + with self.subTest(source=source): + self.assertEqual( + base.NpmSpec(source).clause, + base.NpmSpec(expanded).clause, + ) |