summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorRaphaël Barrois <raphael.barrois@polytechnique.org>2019-08-23 23:24:50 +0200
committerRaphaël Barrois <raphael.barrois@polytechnique.org>2019-08-26 21:34:10 +0200
commitc4c6ab0e925d8cfabb68d34a10a783cb854b63a0 (patch)
tree84895b9dd586594c380668875ede00ba4b8a928a /tests
parent5b9174aedaf9843ee5b3b6358461910e328e74d1 (diff)
downloadsemantic-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.py1
-rw-r--r--tests/test_django.py19
-rw-r--r--tests/test_npm.py88
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,
+ )