1 # Copyright 2012 Red Hat, Inc.
2 # Copyright 2012-2013 Hewlett-Packard Development Company, L.P.
4 # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 # not use this file except in compliance with the License. You may obtain
6 # a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 # License for the specific language governing permissions and limitations
18 from testtools import matchers
20 from pbr.tests import base
21 from pbr import version
24 from_pip_string = version.SemanticVersion.from_pip_string
27 class TestSemanticVersion(base.BaseTestCase):
29 def test_ordering(self):
48 for v in ordered_versions:
49 sv = version.SemanticVersion.from_pip_string(v)
50 self.expectThat(sv, matchers.Equals(sv))
51 for left, right in itertools.combinations(ordered_versions, 2):
52 l_pos = ordered_versions.index(left)
53 r_pos = ordered_versions.index(right)
55 m1 = matchers.LessThan
56 m2 = matchers.GreaterThan
58 m1 = matchers.GreaterThan
59 m2 = matchers.LessThan
60 left_sv = version.SemanticVersion.from_pip_string(left)
61 right_sv = version.SemanticVersion.from_pip_string(right)
62 self.expectThat(left_sv, m1(right_sv))
63 self.expectThat(right_sv, m2(left_sv))
65 def test_from_pip_string_legacy_alpha(self):
66 expected = version.SemanticVersion(
67 1, 2, 0, prerelease_type='rc', prerelease=1)
68 parsed = from_pip_string('1.2.0rc1')
69 self.assertEqual(expected, parsed)
71 def test_from_pip_string_legacy_postN(self):
72 # When pbr trunk was incompatible with PEP-440, a stable release was
73 # made that used postN versions to represent developer builds. As
74 # we expect only to be parsing versions of our own, we map those
75 # into dev builds of the next version.
76 expected = version.SemanticVersion(1, 2, 4, dev_count=5)
77 parsed = from_pip_string('1.2.3.post5')
78 self.expectThat(expected, matchers.Equals(parsed))
79 expected = version.SemanticVersion(1, 2, 3, 'a', 5, dev_count=6)
80 parsed = from_pip_string('1.2.3.0a4.post6')
81 self.expectThat(expected, matchers.Equals(parsed))
82 # We can't define a mapping for .postN.devM, so it should raise.
84 lambda: from_pip_string('1.2.3.post5.dev6'),
85 matchers.raises(ValueError))
87 def test_from_pip_string_v_version(self):
88 parsed = from_pip_string('v1.2.3')
89 expected = version.SemanticVersion(1, 2, 3)
90 self.expectThat(expected, matchers.Equals(parsed))
92 expected = version.SemanticVersion(1, 2, 3, 'a', 5, dev_count=6)
93 parsed = from_pip_string('V1.2.3.0a4.post6')
94 self.expectThat(expected, matchers.Equals(parsed))
97 lambda: from_pip_string('x1.2.3'),
98 matchers.raises(ValueError))
100 def test_from_pip_string_legacy_nonzero_lead_in(self):
101 # reported in bug 1361251
102 expected = version.SemanticVersion(
103 0, 0, 1, prerelease_type='a', prerelease=2)
104 parsed = from_pip_string('0.0.1a2')
105 self.assertEqual(expected, parsed)
107 def test_from_pip_string_legacy_short_nonzero_lead_in(self):
108 expected = version.SemanticVersion(
109 0, 1, 0, prerelease_type='a', prerelease=2)
110 parsed = from_pip_string('0.1a2')
111 self.assertEqual(expected, parsed)
113 def test_from_pip_string_legacy_no_0_prerelease(self):
114 expected = version.SemanticVersion(
115 2, 1, 0, prerelease_type='rc', prerelease=1)
116 parsed = from_pip_string('2.1.0.rc1')
117 self.assertEqual(expected, parsed)
119 def test_from_pip_string_legacy_no_0_prerelease_2(self):
120 expected = version.SemanticVersion(
121 2, 0, 0, prerelease_type='rc', prerelease=1)
122 parsed = from_pip_string('2.0.0.rc1')
123 self.assertEqual(expected, parsed)
125 def test_from_pip_string_legacy_non_440_beta(self):
126 expected = version.SemanticVersion(
127 2014, 2, prerelease_type='b', prerelease=2)
128 parsed = from_pip_string('2014.2.b2')
129 self.assertEqual(expected, parsed)
131 def test_from_pip_string_pure_git_hash(self):
132 self.assertRaises(ValueError, from_pip_string, '6eed5ae')
134 def test_from_pip_string_non_digit_start(self):
135 self.assertRaises(ValueError, from_pip_string,
136 'non-release-tag/2014.12.16-1')
138 def test_final_version(self):
139 semver = version.SemanticVersion(1, 2, 3)
140 self.assertEqual((1, 2, 3, 'final', 0), semver.version_tuple())
141 self.assertEqual("1.2.3", semver.brief_string())
142 self.assertEqual("1.2.3", semver.debian_string())
143 self.assertEqual("1.2.3", semver.release_string())
144 self.assertEqual("1.2.3", semver.rpm_string())
145 self.assertEqual(semver, from_pip_string("1.2.3"))
147 def test_parsing_short_forms(self):
148 semver = version.SemanticVersion(1, 0, 0)
149 self.assertEqual(semver, from_pip_string("1"))
150 self.assertEqual(semver, from_pip_string("1.0"))
151 self.assertEqual(semver, from_pip_string("1.0.0"))
153 def test_dev_version(self):
154 semver = version.SemanticVersion(1, 2, 4, dev_count=5)
155 self.assertEqual((1, 2, 4, 'dev', 4), semver.version_tuple())
156 self.assertEqual("1.2.4", semver.brief_string())
157 self.assertEqual("1.2.4~dev5", semver.debian_string())
158 self.assertEqual("1.2.4.dev5", semver.release_string())
159 self.assertEqual("1.2.3.dev5", semver.rpm_string())
160 self.assertEqual(semver, from_pip_string("1.2.4.dev5"))
162 def test_dev_no_git_version(self):
163 semver = version.SemanticVersion(1, 2, 4, dev_count=5)
164 self.assertEqual((1, 2, 4, 'dev', 4), semver.version_tuple())
165 self.assertEqual("1.2.4", semver.brief_string())
166 self.assertEqual("1.2.4~dev5", semver.debian_string())
167 self.assertEqual("1.2.4.dev5", semver.release_string())
168 self.assertEqual("1.2.3.dev5", semver.rpm_string())
169 self.assertEqual(semver, from_pip_string("1.2.4.dev5"))
171 def test_dev_zero_version(self):
172 semver = version.SemanticVersion(1, 2, 0, dev_count=5)
173 self.assertEqual((1, 2, 0, 'dev', 4), semver.version_tuple())
174 self.assertEqual("1.2.0", semver.brief_string())
175 self.assertEqual("1.2.0~dev5", semver.debian_string())
176 self.assertEqual("1.2.0.dev5", semver.release_string())
177 self.assertEqual("1.1.9999.dev5", semver.rpm_string())
178 self.assertEqual(semver, from_pip_string("1.2.0.dev5"))
180 def test_alpha_dev_version(self):
181 semver = version.SemanticVersion(1, 2, 4, 'a', 1, 12)
182 self.assertEqual((1, 2, 4, 'alphadev', 12), semver.version_tuple())
183 self.assertEqual("1.2.4", semver.brief_string())
184 self.assertEqual("1.2.4~a1.dev12", semver.debian_string())
185 self.assertEqual("1.2.4.0a1.dev12", semver.release_string())
186 self.assertEqual("1.2.3.a1.dev12", semver.rpm_string())
187 self.assertEqual(semver, from_pip_string("1.2.4.0a1.dev12"))
189 def test_alpha_version(self):
190 semver = version.SemanticVersion(1, 2, 4, 'a', 1)
191 self.assertEqual((1, 2, 4, 'alpha', 1), semver.version_tuple())
192 self.assertEqual("1.2.4", semver.brief_string())
193 self.assertEqual("1.2.4~a1", semver.debian_string())
194 self.assertEqual("1.2.4.0a1", semver.release_string())
195 self.assertEqual("1.2.3.a1", semver.rpm_string())
196 self.assertEqual(semver, from_pip_string("1.2.4.0a1"))
198 def test_alpha_zero_version(self):
199 semver = version.SemanticVersion(1, 2, 0, 'a', 1)
200 self.assertEqual((1, 2, 0, 'alpha', 1), semver.version_tuple())
201 self.assertEqual("1.2.0", semver.brief_string())
202 self.assertEqual("1.2.0~a1", semver.debian_string())
203 self.assertEqual("1.2.0.0a1", semver.release_string())
204 self.assertEqual("1.1.9999.a1", semver.rpm_string())
205 self.assertEqual(semver, from_pip_string("1.2.0.0a1"))
207 def test_alpha_major_zero_version(self):
208 semver = version.SemanticVersion(1, 0, 0, 'a', 1)
209 self.assertEqual((1, 0, 0, 'alpha', 1), semver.version_tuple())
210 self.assertEqual("1.0.0", semver.brief_string())
211 self.assertEqual("1.0.0~a1", semver.debian_string())
212 self.assertEqual("1.0.0.0a1", semver.release_string())
213 self.assertEqual("0.9999.9999.a1", semver.rpm_string())
214 self.assertEqual(semver, from_pip_string("1.0.0.0a1"))
216 def test_alpha_default_version(self):
217 semver = version.SemanticVersion(1, 2, 4, 'a')
218 self.assertEqual((1, 2, 4, 'alpha', 0), semver.version_tuple())
219 self.assertEqual("1.2.4", semver.brief_string())
220 self.assertEqual("1.2.4~a0", semver.debian_string())
221 self.assertEqual("1.2.4.0a0", semver.release_string())
222 self.assertEqual("1.2.3.a0", semver.rpm_string())
223 self.assertEqual(semver, from_pip_string("1.2.4.0a0"))
225 def test_beta_dev_version(self):
226 semver = version.SemanticVersion(1, 2, 4, 'b', 1, 12)
227 self.assertEqual((1, 2, 4, 'betadev', 12), semver.version_tuple())
228 self.assertEqual("1.2.4", semver.brief_string())
229 self.assertEqual("1.2.4~b1.dev12", semver.debian_string())
230 self.assertEqual("1.2.4.0b1.dev12", semver.release_string())
231 self.assertEqual("1.2.3.b1.dev12", semver.rpm_string())
232 self.assertEqual(semver, from_pip_string("1.2.4.0b1.dev12"))
234 def test_beta_version(self):
235 semver = version.SemanticVersion(1, 2, 4, 'b', 1)
236 self.assertEqual((1, 2, 4, 'beta', 1), semver.version_tuple())
237 self.assertEqual("1.2.4", semver.brief_string())
238 self.assertEqual("1.2.4~b1", semver.debian_string())
239 self.assertEqual("1.2.4.0b1", semver.release_string())
240 self.assertEqual("1.2.3.b1", semver.rpm_string())
241 self.assertEqual(semver, from_pip_string("1.2.4.0b1"))
243 def test_decrement_nonrelease(self):
244 # The prior version of any non-release is a release
245 semver = version.SemanticVersion(1, 2, 4, 'b', 1)
247 version.SemanticVersion(1, 2, 3), semver.decrement())
249 def test_decrement_nonrelease_zero(self):
250 # We set an arbitrary max version of 9999 when decrementing versions
251 # - this is part of handling rpm support.
252 semver = version.SemanticVersion(1, 0, 0)
254 version.SemanticVersion(0, 9999, 9999), semver.decrement())
256 def test_decrement_release(self):
257 # The next patch version of a release version requires a change to the
259 semver = version.SemanticVersion(2, 2, 5)
261 version.SemanticVersion(2, 2, 4), semver.decrement())
263 def test_increment_nonrelease(self):
264 # The next patch version of a non-release version is another
265 # non-release version as the next release doesn't need to be
267 semver = version.SemanticVersion(1, 2, 4, 'b', 1)
269 version.SemanticVersion(1, 2, 4, 'b', 2), semver.increment())
270 # Major and minor increments however need to bump things.
272 version.SemanticVersion(1, 3, 0), semver.increment(minor=True))
274 version.SemanticVersion(2, 0, 0), semver.increment(major=True))
276 def test_increment_release(self):
277 # The next patch version of a release version requires a change to the
279 semver = version.SemanticVersion(1, 2, 5)
281 version.SemanticVersion(1, 2, 6), semver.increment())
283 version.SemanticVersion(1, 3, 0), semver.increment(minor=True))
285 version.SemanticVersion(2, 0, 0), semver.increment(major=True))
287 def test_rc_dev_version(self):
288 semver = version.SemanticVersion(1, 2, 4, 'rc', 1, 12)
289 self.assertEqual((1, 2, 4, 'candidatedev', 12), semver.version_tuple())
290 self.assertEqual("1.2.4", semver.brief_string())
291 self.assertEqual("1.2.4~rc1.dev12", semver.debian_string())
292 self.assertEqual("1.2.4.0rc1.dev12", semver.release_string())
293 self.assertEqual("1.2.3.rc1.dev12", semver.rpm_string())
294 self.assertEqual(semver, from_pip_string("1.2.4.0rc1.dev12"))
296 def test_rc_version(self):
297 semver = version.SemanticVersion(1, 2, 4, 'rc', 1)
298 self.assertEqual((1, 2, 4, 'candidate', 1), semver.version_tuple())
299 self.assertEqual("1.2.4", semver.brief_string())
300 self.assertEqual("1.2.4~rc1", semver.debian_string())
301 self.assertEqual("1.2.4.0rc1", semver.release_string())
302 self.assertEqual("1.2.3.rc1", semver.rpm_string())
303 self.assertEqual(semver, from_pip_string("1.2.4.0rc1"))
305 def test_to_dev(self):
307 version.SemanticVersion(1, 2, 3, dev_count=1),
308 version.SemanticVersion(1, 2, 3).to_dev(1))
310 version.SemanticVersion(1, 2, 3, 'rc', 1, dev_count=1),
311 version.SemanticVersion(1, 2, 3, 'rc', 1).to_dev(1))