summaryrefslogtreecommitdiff
path: root/tests/test_spec.py
blob: 43c9d6a5dcb255be85fda8724f4adbbc1d991ff3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) The python-semanticversion project
# This code is distributed under the two-clause BSD License.

"""Test conformance to the specs."""

from .compat import unittest, is_python2

import semantic_version

# shortcut
Version = semantic_version.Version


class FormatTests(unittest.TestCase):
    """Tests proper version validation."""

    def test_major_minor_patch(self):
        ### SPEC:
        # A normal version number MUST take the form X.Y.Z

        with self.assertRaises(ValueError):
            Version('1')
        with self.assertRaises(ValueError):
            Version('1.1')
        # Doesn't raise
        Version('1.2.3')
        with self.assertRaises(ValueError):
            Version('1.2.3.4')

        ### SPEC:
        # Where X, Y, and Z are non-negative integers,

        with self.assertRaises(ValueError):
            Version('1.2.A')
        with self.assertRaises(ValueError):
            Version('1.-2.3')
        # Valid
        v = Version('1.2.3')
        self.assertEqual(1, v.major)
        self.assertEqual(2, v.minor)
        self.assertEqual(3, v.patch)


        ### Spec:
        # And MUST NOT contain leading zeroes
        with self.assertRaises(ValueError):
            Version('1.2.01')
        with self.assertRaises(ValueError):
            Version('1.02.1')
        with self.assertRaises(ValueError):
            Version('01.2.1')
        # Valid
        v = Version('0.0.0')
        self.assertEqual(0, v.major)
        self.assertEqual(0, v.minor)
        self.assertEqual(0, v.patch)

    def test_prerelease(self):
        ### SPEC:
        # A pre-release version MAY be denoted by appending a hyphen and a
        # series of dot separated identifiers immediately following the patch
        # version.

        with self.assertRaises(ValueError):
            Version('1.2.3 -23')
        # Valid
        v = Version('1.2.3-23')
        self.assertEqual(('23',), v.prerelease)

        ### SPEC:
        # Identifiers MUST comprise only ASCII alphanumerics and hyphen.
        # Identifiers MUST NOT be empty
        with self.assertRaises(ValueError):
            Version('1.2.3-a,')
        with self.assertRaises(ValueError):
            Version('1.2.3-..')

        ### SPEC:
        # Numeric identifiers MUST NOT include leading zeroes.

        with self.assertRaises(ValueError):
            Version('1.2.3-a0.01')
        with self.assertRaises(ValueError):
            Version('1.2.3-00')
        # Valid
        v = Version('1.2.3-0a.0.000zz')
        self.assertEqual(('0a', '0', '000zz'), v.prerelease)

    def test_build(self):
        ### SPEC:
        # Build metadata MAY be denoted by appending a plus sign and a series of
        # dot separated identifiers immediately following the patch or
        # pre-release version

        v = Version('1.2.3')
        self.assertEqual((), v.build)
        with self.assertRaises(ValueError):
            Version('1.2.3 +4')

        ### SPEC:
        # Identifiers MUST comprise only ASCII alphanumerics and hyphen.
        # Identifiers MUST NOT be empty
        with self.assertRaises(ValueError):
            Version('1.2.3+a,')
        with self.assertRaises(ValueError):
            Version('1.2.3+..')

        # Leading zeroes allowed
        v = Version('1.2.3+0.0a.01')
        self.assertEqual(('0', '0a', '01'), v.build)

    def test_precedence(self):
        ### SPEC:
        # Precedence is determined by the first difference when comparing from
        # left to right as follows: Major, minor, and patch versions are always
        # compared numerically.
        # Example: 1.0.0 < 2.0.0 < 2.1.0 < 2.1.1
        self.assertLess(Version('1.0.0'), Version('2.0.0'))
        self.assertLess(Version('2.0.0'), Version('2.1.0'))
        self.assertLess(Version('2.1.0'), Version('2.1.1'))

        ### SPEC:
        # When major, minor, and patch are equal, a pre-release version has
        # lower precedence than a normal version.
        # Example: 1.0.0-alpha < 1.0.0
        self.assertLess(Version('1.0.0-alpha'), Version('1.0.0'))

        ### SPEC:
        # Precedence for two pre-release versions with the same major, minor,
        # and patch version MUST be determined by comparing each dot separated
        # identifier from left to right until a difference is found as follows:
        # identifiers consisting of only digits are compared numerically
        self.assertLess(Version('1.0.0-1'), Version('1.0.0-2'))

        # and identifiers with letters or hyphens are compared lexically in
        # ASCII sort order.
        self.assertLess(Version('1.0.0-aa'), Version('1.0.0-ab'))

        # Numeric identifiers always have lower precedence than
        # non-numeric identifiers.
        self.assertLess(Version('1.0.0-9'), Version('1.0.0-a'))

        # A larger set of pre-release fields has a higher precedence than a
        # smaller set, if all of the preceding identifiers are equal.
        self.assertLess(Version('1.0.0-a.b.c'), Version('1.0.0-a.b.c.0'))

        # Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.
        self.assertLess(Version('1.0.0-alpha'), Version('1.0.0-alpha.1'))
        self.assertLess(Version('1.0.0-alpha.1'), Version('1.0.0-alpha.beta'))
        self.assertLess(Version('1.0.0-alpha.beta'), Version('1.0.0-beta'))
        self.assertLess(Version('1.0.0-beta'), Version('1.0.0-beta.2'))
        self.assertLess(Version('1.0.0-beta.2'), Version('1.0.0-beta.11'))
        self.assertLess(Version('1.0.0-beta.11'), Version('1.0.0-rc.1'))
        self.assertLess(Version('1.0.0-rc.1'), Version('1.0.0'))