test_version.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. # Copyright 2012 Red Hat, Inc.
  2. # Copyright 2012-2013 Hewlett-Packard Development Company, L.P.
  3. #
  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
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  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
  14. # under the License.
  15. import itertools
  16. from testtools import matchers
  17. from pbr.tests import base
  18. from pbr import version
  19. from_pip_string = version.SemanticVersion.from_pip_string
  20. class TestSemanticVersion(base.BaseTestCase):
  21. def test_ordering(self):
  22. ordered_versions = [
  23. "1.2.3.dev6",
  24. "1.2.3.dev7",
  25. "1.2.3.a4.dev12",
  26. "1.2.3.a4.dev13",
  27. "1.2.3.a4",
  28. "1.2.3.a5.dev1",
  29. "1.2.3.a5",
  30. "1.2.3.b3.dev1",
  31. "1.2.3.b3",
  32. "1.2.3.rc2.dev1",
  33. "1.2.3.rc2",
  34. "1.2.3.rc3.dev1",
  35. "1.2.3",
  36. "1.2.4",
  37. "1.3.3",
  38. "2.2.3",
  39. ]
  40. for v in ordered_versions:
  41. sv = version.SemanticVersion.from_pip_string(v)
  42. self.expectThat(sv, matchers.Equals(sv))
  43. for left, right in itertools.combinations(ordered_versions, 2):
  44. l_pos = ordered_versions.index(left)
  45. r_pos = ordered_versions.index(right)
  46. if l_pos < r_pos:
  47. m1 = matchers.LessThan
  48. m2 = matchers.GreaterThan
  49. else:
  50. m1 = matchers.GreaterThan
  51. m2 = matchers.LessThan
  52. left_sv = version.SemanticVersion.from_pip_string(left)
  53. right_sv = version.SemanticVersion.from_pip_string(right)
  54. self.expectThat(left_sv, m1(right_sv))
  55. self.expectThat(right_sv, m2(left_sv))
  56. def test_from_pip_string_legacy_alpha(self):
  57. expected = version.SemanticVersion(
  58. 1, 2, 0, prerelease_type='rc', prerelease=1)
  59. parsed = from_pip_string('1.2.0rc1')
  60. self.assertEqual(expected, parsed)
  61. def test_from_pip_string_legacy_postN(self):
  62. # When pbr trunk was incompatible with PEP-440, a stable release was
  63. # made that used postN versions to represent developer builds. As
  64. # we expect only to be parsing versions of our own, we map those
  65. # into dev builds of the next version.
  66. expected = version.SemanticVersion(1, 2, 4, dev_count=5)
  67. parsed = from_pip_string('1.2.3.post5')
  68. self.expectThat(expected, matchers.Equals(parsed))
  69. expected = version.SemanticVersion(1, 2, 3, 'a', 5, dev_count=6)
  70. parsed = from_pip_string('1.2.3.0a4.post6')
  71. self.expectThat(expected, matchers.Equals(parsed))
  72. # We can't define a mapping for .postN.devM, so it should raise.
  73. self.expectThat(
  74. lambda: from_pip_string('1.2.3.post5.dev6'),
  75. matchers.raises(ValueError))
  76. def test_from_pip_string_v_version(self):
  77. parsed = from_pip_string('v1.2.3')
  78. expected = version.SemanticVersion(1, 2, 3)
  79. self.expectThat(expected, matchers.Equals(parsed))
  80. expected = version.SemanticVersion(1, 2, 3, 'a', 5, dev_count=6)
  81. parsed = from_pip_string('V1.2.3.0a4.post6')
  82. self.expectThat(expected, matchers.Equals(parsed))
  83. self.expectThat(
  84. lambda: from_pip_string('x1.2.3'),
  85. matchers.raises(ValueError))
  86. def test_from_pip_string_legacy_nonzero_lead_in(self):
  87. # reported in bug 1361251
  88. expected = version.SemanticVersion(
  89. 0, 0, 1, prerelease_type='a', prerelease=2)
  90. parsed = from_pip_string('0.0.1a2')
  91. self.assertEqual(expected, parsed)
  92. def test_from_pip_string_legacy_short_nonzero_lead_in(self):
  93. expected = version.SemanticVersion(
  94. 0, 1, 0, prerelease_type='a', prerelease=2)
  95. parsed = from_pip_string('0.1a2')
  96. self.assertEqual(expected, parsed)
  97. def test_from_pip_string_legacy_no_0_prerelease(self):
  98. expected = version.SemanticVersion(
  99. 2, 1, 0, prerelease_type='rc', prerelease=1)
  100. parsed = from_pip_string('2.1.0.rc1')
  101. self.assertEqual(expected, parsed)
  102. def test_from_pip_string_legacy_no_0_prerelease_2(self):
  103. expected = version.SemanticVersion(
  104. 2, 0, 0, prerelease_type='rc', prerelease=1)
  105. parsed = from_pip_string('2.0.0.rc1')
  106. self.assertEqual(expected, parsed)
  107. def test_from_pip_string_legacy_non_440_beta(self):
  108. expected = version.SemanticVersion(
  109. 2014, 2, prerelease_type='b', prerelease=2)
  110. parsed = from_pip_string('2014.2.b2')
  111. self.assertEqual(expected, parsed)
  112. def test_from_pip_string_pure_git_hash(self):
  113. self.assertRaises(ValueError, from_pip_string, '6eed5ae')
  114. def test_from_pip_string_non_digit_start(self):
  115. self.assertRaises(ValueError, from_pip_string,
  116. 'non-release-tag/2014.12.16-1')
  117. def test_final_version(self):
  118. semver = version.SemanticVersion(1, 2, 3)
  119. self.assertEqual((1, 2, 3, 'final', 0), semver.version_tuple())
  120. self.assertEqual("1.2.3", semver.brief_string())
  121. self.assertEqual("1.2.3", semver.debian_string())
  122. self.assertEqual("1.2.3", semver.release_string())
  123. self.assertEqual("1.2.3", semver.rpm_string())
  124. self.assertEqual(semver, from_pip_string("1.2.3"))
  125. def test_parsing_short_forms(self):
  126. semver = version.SemanticVersion(1, 0, 0)
  127. self.assertEqual(semver, from_pip_string("1"))
  128. self.assertEqual(semver, from_pip_string("1.0"))
  129. self.assertEqual(semver, from_pip_string("1.0.0"))
  130. def test_dev_version(self):
  131. semver = version.SemanticVersion(1, 2, 4, dev_count=5)
  132. self.assertEqual((1, 2, 4, 'dev', 4), semver.version_tuple())
  133. self.assertEqual("1.2.4", semver.brief_string())
  134. self.assertEqual("1.2.4~dev5", semver.debian_string())
  135. self.assertEqual("1.2.4.dev5", semver.release_string())
  136. self.assertEqual("1.2.3.dev5", semver.rpm_string())
  137. self.assertEqual(semver, from_pip_string("1.2.4.dev5"))
  138. def test_dev_no_git_version(self):
  139. semver = version.SemanticVersion(1, 2, 4, dev_count=5)
  140. self.assertEqual((1, 2, 4, 'dev', 4), semver.version_tuple())
  141. self.assertEqual("1.2.4", semver.brief_string())
  142. self.assertEqual("1.2.4~dev5", semver.debian_string())
  143. self.assertEqual("1.2.4.dev5", semver.release_string())
  144. self.assertEqual("1.2.3.dev5", semver.rpm_string())
  145. self.assertEqual(semver, from_pip_string("1.2.4.dev5"))
  146. def test_dev_zero_version(self):
  147. semver = version.SemanticVersion(1, 2, 0, dev_count=5)
  148. self.assertEqual((1, 2, 0, 'dev', 4), semver.version_tuple())
  149. self.assertEqual("1.2.0", semver.brief_string())
  150. self.assertEqual("1.2.0~dev5", semver.debian_string())
  151. self.assertEqual("1.2.0.dev5", semver.release_string())
  152. self.assertEqual("1.1.9999.dev5", semver.rpm_string())
  153. self.assertEqual(semver, from_pip_string("1.2.0.dev5"))
  154. def test_alpha_dev_version(self):
  155. semver = version.SemanticVersion(1, 2, 4, 'a', 1, 12)
  156. self.assertEqual((1, 2, 4, 'alphadev', 12), semver.version_tuple())
  157. self.assertEqual("1.2.4", semver.brief_string())
  158. self.assertEqual("1.2.4~a1.dev12", semver.debian_string())
  159. self.assertEqual("1.2.4.0a1.dev12", semver.release_string())
  160. self.assertEqual("1.2.3.a1.dev12", semver.rpm_string())
  161. self.assertEqual(semver, from_pip_string("1.2.4.0a1.dev12"))
  162. def test_alpha_version(self):
  163. semver = version.SemanticVersion(1, 2, 4, 'a', 1)
  164. self.assertEqual((1, 2, 4, 'alpha', 1), semver.version_tuple())
  165. self.assertEqual("1.2.4", semver.brief_string())
  166. self.assertEqual("1.2.4~a1", semver.debian_string())
  167. self.assertEqual("1.2.4.0a1", semver.release_string())
  168. self.assertEqual("1.2.3.a1", semver.rpm_string())
  169. self.assertEqual(semver, from_pip_string("1.2.4.0a1"))
  170. def test_alpha_zero_version(self):
  171. semver = version.SemanticVersion(1, 2, 0, 'a', 1)
  172. self.assertEqual((1, 2, 0, 'alpha', 1), semver.version_tuple())
  173. self.assertEqual("1.2.0", semver.brief_string())
  174. self.assertEqual("1.2.0~a1", semver.debian_string())
  175. self.assertEqual("1.2.0.0a1", semver.release_string())
  176. self.assertEqual("1.1.9999.a1", semver.rpm_string())
  177. self.assertEqual(semver, from_pip_string("1.2.0.0a1"))
  178. def test_alpha_major_zero_version(self):
  179. semver = version.SemanticVersion(1, 0, 0, 'a', 1)
  180. self.assertEqual((1, 0, 0, 'alpha', 1), semver.version_tuple())
  181. self.assertEqual("1.0.0", semver.brief_string())
  182. self.assertEqual("1.0.0~a1", semver.debian_string())
  183. self.assertEqual("1.0.0.0a1", semver.release_string())
  184. self.assertEqual("0.9999.9999.a1", semver.rpm_string())
  185. self.assertEqual(semver, from_pip_string("1.0.0.0a1"))
  186. def test_alpha_default_version(self):
  187. semver = version.SemanticVersion(1, 2, 4, 'a')
  188. self.assertEqual((1, 2, 4, 'alpha', 0), semver.version_tuple())
  189. self.assertEqual("1.2.4", semver.brief_string())
  190. self.assertEqual("1.2.4~a0", semver.debian_string())
  191. self.assertEqual("1.2.4.0a0", semver.release_string())
  192. self.assertEqual("1.2.3.a0", semver.rpm_string())
  193. self.assertEqual(semver, from_pip_string("1.2.4.0a0"))
  194. def test_beta_dev_version(self):
  195. semver = version.SemanticVersion(1, 2, 4, 'b', 1, 12)
  196. self.assertEqual((1, 2, 4, 'betadev', 12), semver.version_tuple())
  197. self.assertEqual("1.2.4", semver.brief_string())
  198. self.assertEqual("1.2.4~b1.dev12", semver.debian_string())
  199. self.assertEqual("1.2.4.0b1.dev12", semver.release_string())
  200. self.assertEqual("1.2.3.b1.dev12", semver.rpm_string())
  201. self.assertEqual(semver, from_pip_string("1.2.4.0b1.dev12"))
  202. def test_beta_version(self):
  203. semver = version.SemanticVersion(1, 2, 4, 'b', 1)
  204. self.assertEqual((1, 2, 4, 'beta', 1), semver.version_tuple())
  205. self.assertEqual("1.2.4", semver.brief_string())
  206. self.assertEqual("1.2.4~b1", semver.debian_string())
  207. self.assertEqual("1.2.4.0b1", semver.release_string())
  208. self.assertEqual("1.2.3.b1", semver.rpm_string())
  209. self.assertEqual(semver, from_pip_string("1.2.4.0b1"))
  210. def test_decrement_nonrelease(self):
  211. # The prior version of any non-release is a release
  212. semver = version.SemanticVersion(1, 2, 4, 'b', 1)
  213. self.assertEqual(
  214. version.SemanticVersion(1, 2, 3), semver.decrement())
  215. def test_decrement_nonrelease_zero(self):
  216. # We set an arbitrary max version of 9999 when decrementing versions
  217. # - this is part of handling rpm support.
  218. semver = version.SemanticVersion(1, 0, 0)
  219. self.assertEqual(
  220. version.SemanticVersion(0, 9999, 9999), semver.decrement())
  221. def test_decrement_release(self):
  222. # The next patch version of a release version requires a change to the
  223. # patch level.
  224. semver = version.SemanticVersion(2, 2, 5)
  225. self.assertEqual(
  226. version.SemanticVersion(2, 2, 4), semver.decrement())
  227. def test_increment_nonrelease(self):
  228. # The next patch version of a non-release version is another
  229. # non-release version as the next release doesn't need to be
  230. # incremented.
  231. semver = version.SemanticVersion(1, 2, 4, 'b', 1)
  232. self.assertEqual(
  233. version.SemanticVersion(1, 2, 4, 'b', 2), semver.increment())
  234. # Major and minor increments however need to bump things.
  235. self.assertEqual(
  236. version.SemanticVersion(1, 3, 0), semver.increment(minor=True))
  237. self.assertEqual(
  238. version.SemanticVersion(2, 0, 0), semver.increment(major=True))
  239. def test_increment_release(self):
  240. # The next patch version of a release version requires a change to the
  241. # patch level.
  242. semver = version.SemanticVersion(1, 2, 5)
  243. self.assertEqual(
  244. version.SemanticVersion(1, 2, 6), semver.increment())
  245. self.assertEqual(
  246. version.SemanticVersion(1, 3, 0), semver.increment(minor=True))
  247. self.assertEqual(
  248. version.SemanticVersion(2, 0, 0), semver.increment(major=True))
  249. def test_rc_dev_version(self):
  250. semver = version.SemanticVersion(1, 2, 4, 'rc', 1, 12)
  251. self.assertEqual((1, 2, 4, 'candidatedev', 12), semver.version_tuple())
  252. self.assertEqual("1.2.4", semver.brief_string())
  253. self.assertEqual("1.2.4~rc1.dev12", semver.debian_string())
  254. self.assertEqual("1.2.4.0rc1.dev12", semver.release_string())
  255. self.assertEqual("1.2.3.rc1.dev12", semver.rpm_string())
  256. self.assertEqual(semver, from_pip_string("1.2.4.0rc1.dev12"))
  257. def test_rc_version(self):
  258. semver = version.SemanticVersion(1, 2, 4, 'rc', 1)
  259. self.assertEqual((1, 2, 4, 'candidate', 1), semver.version_tuple())
  260. self.assertEqual("1.2.4", semver.brief_string())
  261. self.assertEqual("1.2.4~rc1", semver.debian_string())
  262. self.assertEqual("1.2.4.0rc1", semver.release_string())
  263. self.assertEqual("1.2.3.rc1", semver.rpm_string())
  264. self.assertEqual(semver, from_pip_string("1.2.4.0rc1"))
  265. def test_to_dev(self):
  266. self.assertEqual(
  267. version.SemanticVersion(1, 2, 3, dev_count=1),
  268. version.SemanticVersion(1, 2, 3).to_dev(1))
  269. self.assertEqual(
  270. version.SemanticVersion(1, 2, 3, 'rc', 1, dev_count=1),
  271. version.SemanticVersion(1, 2, 3, 'rc', 1).to_dev(1))