VersionParserTest.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. <?php
  2. /*
  3. * This file is part of Composer.
  4. *
  5. * (c) Nils Adermann <naderman@naderman.de>
  6. * Jordi Boggiano <j.boggiano@seld.be>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Composer\Test\Package\Version;
  12. use Composer\Package\Link;
  13. use Composer\Package\Version\VersionParser;
  14. use Composer\Package\LinkConstraint\MultiConstraint;
  15. use Composer\Package\LinkConstraint\VersionConstraint;
  16. use Composer\Package\LinkConstraint\EmptyConstraint;
  17. use Composer\Package\PackageInterface;
  18. class VersionParserTest extends \PHPUnit_Framework_TestCase
  19. {
  20. /**
  21. * @dataProvider numericAliasVersions
  22. */
  23. public function testParseNumericAliasPrefix($input, $expected)
  24. {
  25. $parser = new VersionParser;
  26. $this->assertSame($expected, $parser->parseNumericAliasPrefix($input));
  27. }
  28. public function numericAliasVersions()
  29. {
  30. return array(
  31. array('0.x-dev', '0.'),
  32. array('1.0.x-dev', '1.0.'),
  33. array('1.x-dev', '1.'),
  34. array('1.2.x-dev', '1.2.'),
  35. array('1.2-dev', '1.2.'),
  36. array('1-dev', '1.'),
  37. array('dev-develop', false),
  38. array('dev-master', false),
  39. );
  40. }
  41. /**
  42. * @dataProvider successfulNormalizedVersions
  43. */
  44. public function testNormalizeSucceeds($input, $expected)
  45. {
  46. $parser = new VersionParser;
  47. $this->assertSame($expected, $parser->normalize($input));
  48. }
  49. public function successfulNormalizedVersions()
  50. {
  51. return array(
  52. 'none' => array('1.0.0', '1.0.0.0'),
  53. 'none/2' => array('1.2.3.4', '1.2.3.4'),
  54. 'parses state' => array('1.0.0RC1dev', '1.0.0.0-RC1-dev'),
  55. 'CI parsing' => array('1.0.0-rC15-dev', '1.0.0.0-RC15-dev'),
  56. 'delimiters' => array('1.0.0.RC.15-dev', '1.0.0.0-RC15-dev'),
  57. 'RC uppercase' => array('1.0.0-rc1', '1.0.0.0-RC1'),
  58. 'patch replace' => array('1.0.0.pl3-dev', '1.0.0.0-patch3-dev'),
  59. 'forces w.x.y.z' => array('1.0-dev', '1.0.0.0-dev'),
  60. 'forces w.x.y.z/2' => array('0', '0.0.0.0'),
  61. 'parses long' => array('10.4.13-beta', '10.4.13.0-beta'),
  62. 'parses long/2' => array('10.4.13beta2', '10.4.13.0-beta2'),
  63. 'parses long/semver' => array('10.4.13beta.2', '10.4.13.0-beta2'),
  64. 'expand shorthand' => array('10.4.13-b', '10.4.13.0-beta'),
  65. 'expand shorthand2' => array('10.4.13-b5', '10.4.13.0-beta5'),
  66. 'strips leading v' => array('v1.0.0', '1.0.0.0'),
  67. 'strips v/datetime' => array('v20100102', '20100102'),
  68. 'parses dates y-m' => array('2010.01', '2010-01'),
  69. 'parses dates w/ .' => array('2010.01.02', '2010-01-02'),
  70. 'parses dates w/ -' => array('2010-01-02', '2010-01-02'),
  71. 'parses numbers' => array('2010-01-02.5', '2010-01-02-5'),
  72. 'parses dates y.m.Y' => array('2010.1.555', '2010.1.555.0'),
  73. 'parses datetime' => array('20100102-203040', '20100102-203040'),
  74. 'parses dt+number' => array('20100102203040-10', '20100102203040-10'),
  75. 'parses dt+patch' => array('20100102-203040-p1', '20100102-203040-patch1'),
  76. 'parses master' => array('dev-master', '9999999-dev'),
  77. 'parses trunk' => array('dev-trunk', '9999999-dev'),
  78. 'parses branches' => array('1.x-dev', '1.9999999.9999999.9999999-dev'),
  79. 'parses arbitrary' => array('dev-feature-foo', 'dev-feature-foo'),
  80. 'parses arbitrary2' => array('DEV-FOOBAR', 'dev-FOOBAR'),
  81. 'parses arbitrary3' => array('dev-feature/foo', 'dev-feature/foo'),
  82. 'ignores aliases' => array('dev-master as 1.0.0', '9999999-dev'),
  83. 'semver metadata' => array('dev-master+foo.bar', '9999999-dev'),
  84. 'semver metadata/2' => array('1.0.0-beta.5+foo', '1.0.0.0-beta5'),
  85. 'semver metadata/3' => array('1.0.0+foo', '1.0.0.0'),
  86. 'metadata w/ alias' => array('1.0.0+foo as 2.0', '1.0.0.0'),
  87. );
  88. }
  89. /**
  90. * @dataProvider failingNormalizedVersions
  91. * @expectedException UnexpectedValueException
  92. */
  93. public function testNormalizeFails($input)
  94. {
  95. $parser = new VersionParser;
  96. $parser->normalize($input);
  97. }
  98. public function failingNormalizedVersions()
  99. {
  100. return array(
  101. 'empty ' => array(''),
  102. 'invalid chars' => array('a'),
  103. 'invalid type' => array('1.0.0-meh'),
  104. 'too many bits' => array('1.0.0.0.0'),
  105. 'non-dev arbitrary' => array('feature-foo'),
  106. 'metadata w/ space' => array('1.0.0+foo bar'),
  107. );
  108. }
  109. /**
  110. * @dataProvider successfulNormalizedBranches
  111. */
  112. public function testNormalizeBranch($input, $expected)
  113. {
  114. $parser = new VersionParser;
  115. $this->assertSame((string) $expected, (string) $parser->normalizeBranch($input));
  116. }
  117. public function successfulNormalizedBranches()
  118. {
  119. return array(
  120. 'parses x' => array('v1.x', '1.9999999.9999999.9999999-dev'),
  121. 'parses *' => array('v1.*', '1.9999999.9999999.9999999-dev'),
  122. 'parses digits' => array('v1.0', '1.0.9999999.9999999-dev'),
  123. 'parses digits/2' => array('2.0', '2.0.9999999.9999999-dev'),
  124. 'parses long x' => array('v1.0.x', '1.0.9999999.9999999-dev'),
  125. 'parses long *' => array('v1.0.3.*', '1.0.3.9999999-dev'),
  126. 'parses long digits' => array('v2.4.0', '2.4.0.9999999-dev'),
  127. 'parses long digits/2' => array('2.4.4', '2.4.4.9999999-dev'),
  128. 'parses master' => array('master', '9999999-dev'),
  129. 'parses trunk' => array('trunk', '9999999-dev'),
  130. 'parses arbitrary' => array('feature-a', 'dev-feature-a'),
  131. 'parses arbitrary/2' => array('FOOBAR', 'dev-FOOBAR'),
  132. );
  133. }
  134. public function testParseConstraintsIgnoresStabilityFlag()
  135. {
  136. $parser = new VersionParser;
  137. $this->assertSame((string) new VersionConstraint('=', '1.0.0.0'), (string) $parser->parseConstraints('1.0@dev'));
  138. }
  139. public function testParseConstraintsIgnoresReferenceOnDevVersion()
  140. {
  141. $parser = new VersionParser;
  142. $this->assertSame((string) new VersionConstraint('=', '1.0.9999999.9999999-dev'), (string) $parser->parseConstraints('1.0.x-dev#abcd123'));
  143. $this->assertSame((string) new VersionConstraint('=', '1.0.9999999.9999999-dev'), (string) $parser->parseConstraints('1.0.x-dev#trunk/@123'));
  144. }
  145. /**
  146. * @expectedException UnexpectedValueException
  147. */
  148. public function testParseConstraintsFailsOnBadReference()
  149. {
  150. $parser = new VersionParser;
  151. $this->assertSame((string) new VersionConstraint('=', '1.0.0.0'), (string) $parser->parseConstraints('1.0#abcd123'));
  152. $this->assertSame((string) new VersionConstraint('=', '1.0.0.0'), (string) $parser->parseConstraints('1.0#trunk/@123'));
  153. }
  154. /**
  155. * @expectedException UnexpectedValueException
  156. * @expectedExceptionMessage Invalid operator "~>", you probably meant to use the "~" operator
  157. */
  158. public function testParseConstraintsNudgesRubyDevsTowardsThePathOfRighteousness()
  159. {
  160. $parser = new VersionParser;
  161. $parser->parseConstraints('~>1.2');
  162. }
  163. /**
  164. * @dataProvider simpleConstraints
  165. */
  166. public function testParseConstraintsSimple($input, $expected)
  167. {
  168. $parser = new VersionParser;
  169. $this->assertSame((string) $expected, (string) $parser->parseConstraints($input));
  170. }
  171. public function simpleConstraints()
  172. {
  173. return array(
  174. 'match any' => array('*', new EmptyConstraint()),
  175. 'match any/2' => array('*.*', new EmptyConstraint()),
  176. 'match any/3' => array('*.x.*', new EmptyConstraint()),
  177. 'match any/4' => array('x.X.x.*', new EmptyConstraint()),
  178. 'not equal' => array('<>1.0.0', new VersionConstraint('<>', '1.0.0.0')),
  179. 'not equal/2' => array('!=1.0.0', new VersionConstraint('!=', '1.0.0.0')),
  180. 'greater than' => array('>1.0.0', new VersionConstraint('>', '1.0.0.0')),
  181. 'lesser than' => array('<1.2.3.4', new VersionConstraint('<', '1.2.3.4-dev')),
  182. 'less/eq than' => array('<=1.2.3', new VersionConstraint('<=', '1.2.3.0')),
  183. 'great/eq than' => array('>=1.2.3', new VersionConstraint('>=', '1.2.3.0-dev')),
  184. 'equals' => array('=1.2.3', new VersionConstraint('=', '1.2.3.0')),
  185. 'double equals' => array('==1.2.3', new VersionConstraint('=', '1.2.3.0')),
  186. 'no op means eq' => array('1.2.3', new VersionConstraint('=', '1.2.3.0')),
  187. 'completes version' => array('=1.0', new VersionConstraint('=', '1.0.0.0')),
  188. 'shorthand beta' => array('1.2.3b5', new VersionConstraint('=', '1.2.3.0-beta5')),
  189. 'accepts spaces' => array('>= 1.2.3', new VersionConstraint('>=', '1.2.3.0-dev')),
  190. 'accepts spaces/2' => array('< 1.2.3', new VersionConstraint('<', '1.2.3.0-dev')),
  191. 'accepts spaces/3' => array('> 1.2.3', new VersionConstraint('>', '1.2.3.0')),
  192. 'accepts master' => array('>=dev-master', new VersionConstraint('>=', '9999999-dev')),
  193. 'accepts master/2' => array('dev-master', new VersionConstraint('=', '9999999-dev')),
  194. 'accepts arbitrary' => array('dev-feature-a', new VersionConstraint('=', 'dev-feature-a')),
  195. 'regression #550' => array('dev-some-fix', new VersionConstraint('=', 'dev-some-fix')),
  196. 'regression #935' => array('dev-CAPS', new VersionConstraint('=', 'dev-CAPS')),
  197. 'ignores aliases' => array('dev-master as 1.0.0', new VersionConstraint('=', '9999999-dev')),
  198. 'lesser than override' => array('<1.2.3.4-stable', new VersionConstraint('<', '1.2.3.4')),
  199. 'great/eq than override' => array('>=1.2.3.4-stable', new VersionConstraint('>=', '1.2.3.4')),
  200. );
  201. }
  202. /**
  203. * @dataProvider wildcardConstraints
  204. */
  205. public function testParseConstraintsWildcard($input, $min, $max)
  206. {
  207. $parser = new VersionParser;
  208. if ($min) {
  209. $expected = new MultiConstraint(array($min, $max));
  210. } else {
  211. $expected = $max;
  212. }
  213. $this->assertSame((string) $expected, (string) $parser->parseConstraints($input));
  214. }
  215. public function wildcardConstraints()
  216. {
  217. return array(
  218. array('2.*', new VersionConstraint('>=', '2.0.0.0-dev'), new VersionConstraint('<', '3.0.0.0-dev')),
  219. array('20.*', new VersionConstraint('>=', '20.0.0.0-dev'), new VersionConstraint('<', '21.0.0.0-dev')),
  220. array('2.0.*', new VersionConstraint('>=', '2.0.0.0-dev'), new VersionConstraint('<', '2.1.0.0-dev')),
  221. array('2.2.x', new VersionConstraint('>=', '2.2.0.0-dev'), new VersionConstraint('<', '2.3.0.0-dev')),
  222. array('2.10.X', new VersionConstraint('>=', '2.10.0.0-dev'), new VersionConstraint('<', '2.11.0.0-dev')),
  223. array('2.1.3.*', new VersionConstraint('>=', '2.1.3.0-dev'), new VersionConstraint('<', '2.1.4.0-dev')),
  224. array('0.*', null, new VersionConstraint('<', '1.0.0.0-dev')),
  225. );
  226. }
  227. /**
  228. * @dataProvider tildeConstraints
  229. */
  230. public function testParseTildeWildcard($input, $min, $max)
  231. {
  232. $parser = new VersionParser;
  233. if ($min) {
  234. $expected = new MultiConstraint(array($min, $max));
  235. } else {
  236. $expected = $max;
  237. }
  238. $this->assertSame((string) $expected, (string) $parser->parseConstraints($input));
  239. }
  240. public function tildeConstraints()
  241. {
  242. return array(
  243. array('~1', new VersionConstraint('>=', '1.0.0.0-dev'), new VersionConstraint('<', '2.0.0.0-dev')),
  244. array('~1.0', new VersionConstraint('>=', '1.0.0.0-dev'), new VersionConstraint('<', '2.0.0.0-dev')),
  245. array('~1.0.0', new VersionConstraint('>=', '1.0.0.0-dev'), new VersionConstraint('<', '1.1.0.0-dev')),
  246. array('~1.2', new VersionConstraint('>=', '1.2.0.0-dev'), new VersionConstraint('<', '2.0.0.0-dev')),
  247. array('~1.2.3', new VersionConstraint('>=', '1.2.3.0-dev'), new VersionConstraint('<', '1.3.0.0-dev')),
  248. array('~1.2.3.4', new VersionConstraint('>=', '1.2.3.4-dev'), new VersionConstraint('<', '1.2.4.0-dev')),
  249. array('~1.2-beta',new VersionConstraint('>=', '1.2.0.0-beta'), new VersionConstraint('<', '2.0.0.0-dev')),
  250. array('~1.2-b2', new VersionConstraint('>=', '1.2.0.0-beta2'), new VersionConstraint('<', '2.0.0.0-dev')),
  251. array('~1.2-BETA2', new VersionConstraint('>=', '1.2.0.0-beta2'), new VersionConstraint('<', '2.0.0.0-dev')),
  252. array('~1.2.2-dev', new VersionConstraint('>=', '1.2.2.0-dev'), new VersionConstraint('<', '1.3.0.0-dev')),
  253. array('~1.2.2-stable', new VersionConstraint('>=', '1.2.2.0-stable'), new VersionConstraint('<', '1.3.0.0-dev')),
  254. );
  255. }
  256. /**
  257. * @dataProvider caretConstraints
  258. */
  259. public function testParseCaretWildcard($input, $min, $max)
  260. {
  261. $parser = new VersionParser;
  262. if ($min) {
  263. $expected = new MultiConstraint(array($min, $max));
  264. } else {
  265. $expected = $max;
  266. }
  267. $this->assertSame((string) $expected, (string) $parser->parseConstraints($input));
  268. }
  269. public function caretConstraints()
  270. {
  271. return array(
  272. array('^1', new VersionConstraint('>=', '1.0.0.0-dev'), new VersionConstraint('<', '2.0.0.0-dev')),
  273. array('^0', new VersionConstraint('>=', '0.0.0.0-dev'), new VersionConstraint('<', '1.0.0.0-dev')),
  274. array('^0.0', new VersionConstraint('>=', '0.0.0.0-dev'), new VersionConstraint('<', '0.1.0.0-dev')),
  275. array('^1.2', new VersionConstraint('>=', '1.2.0.0-dev'), new VersionConstraint('<', '2.0.0.0-dev')),
  276. array('^1.2.3-beta.2', new VersionConstraint('>=', '1.2.3.0-beta2'), new VersionConstraint('<', '2.0.0.0-dev')),
  277. array('^1.2.3.4', new VersionConstraint('>=', '1.2.3.4-dev'), new VersionConstraint('<', '2.0.0.0-dev')),
  278. array('^1.2.3', new VersionConstraint('>=', '1.2.3.0-dev'), new VersionConstraint('<', '2.0.0.0-dev')),
  279. array('^0.2.3', new VersionConstraint('>=', '0.2.3.0-dev'), new VersionConstraint('<', '0.3.0.0-dev')),
  280. array('^0.2', new VersionConstraint('>=', '0.2.0.0-dev'), new VersionConstraint('<', '0.3.0.0-dev')),
  281. array('^0.2.0', new VersionConstraint('>=', '0.2.0.0-dev'), new VersionConstraint('<', '0.3.0.0-dev')),
  282. array('^0.0.3', new VersionConstraint('>=', '0.0.3.0-dev'), new VersionConstraint('<', '0.0.4.0-dev')),
  283. array('^0.0.3-alpha', new VersionConstraint('>=', '0.0.3.0-alpha'), new VersionConstraint('<', '0.0.4.0-dev')),
  284. array('^0.0.3-dev', new VersionConstraint('>=', '0.0.3.0-dev'), new VersionConstraint('<', '0.0.4.0-dev')),
  285. );
  286. }
  287. /**
  288. * @dataProvider hyphenConstraints
  289. */
  290. public function testParseHyphen($input, $min, $max)
  291. {
  292. $parser = new VersionParser;
  293. if ($min) {
  294. $expected = new MultiConstraint(array($min, $max));
  295. } else {
  296. $expected = $max;
  297. }
  298. $this->assertSame((string) $expected, (string) $parser->parseConstraints($input));
  299. }
  300. public function hyphenConstraints()
  301. {
  302. return array(
  303. array('1 - 2', new VersionConstraint('>=', '1.0.0.0-dev'), new VersionConstraint('<', '3.0.0.0-dev')),
  304. array('1.2.3 - 2.3.4.5', new VersionConstraint('>=', '1.2.3.0-dev'), new VersionConstraint('<=', '2.3.4.5')),
  305. array('1.2-beta - 2.3', new VersionConstraint('>=', '1.2.0.0-beta'), new VersionConstraint('<', '2.4.0.0-dev')),
  306. array('1.2-beta - 2.3-dev', new VersionConstraint('>=', '1.2.0.0-beta'), new VersionConstraint('<=', '2.3.0.0-dev')),
  307. array('1.2-RC - 2.3.1', new VersionConstraint('>=', '1.2.0.0-RC'), new VersionConstraint('<=', '2.3.1.0')),
  308. array('1.2.3-alpha - 2.3-RC', new VersionConstraint('>=', '1.2.3.0-alpha'), new VersionConstraint('<=', '2.3.0.0-RC')),
  309. array('1 - 2.0', new VersionConstraint('>=', '1.0.0.0-dev'), new VersionConstraint('<', '2.1.0.0-dev')),
  310. array('1 - 2.1', new VersionConstraint('>=', '1.0.0.0-dev'), new VersionConstraint('<', '2.2.0.0-dev')),
  311. array('1.2 - 2.1.0', new VersionConstraint('>=', '1.2.0.0-dev'), new VersionConstraint('<=', '2.1.0.0')),
  312. array('1.3 - 2.1.3', new VersionConstraint('>=', '1.3.0.0-dev'), new VersionConstraint('<=', '2.1.3.0')),
  313. );
  314. }
  315. /**
  316. * @dataProvider multiConstraintProvider
  317. */
  318. public function testParseConstraintsMulti($constraint)
  319. {
  320. $parser = new VersionParser;
  321. $first = new VersionConstraint('>', '2.0.0.0');
  322. $second = new VersionConstraint('<=', '3.0.0.0');
  323. $multi = new MultiConstraint(array($first, $second));
  324. $this->assertSame((string) $multi, (string) $parser->parseConstraints($constraint));
  325. }
  326. public function multiConstraintProvider()
  327. {
  328. return array(
  329. array('>2.0,<=3.0'),
  330. array('>2.0 <=3.0'),
  331. array('>2.0 <=3.0'),
  332. array('>2.0, <=3.0'),
  333. array('>2.0 ,<=3.0'),
  334. array('>2.0 , <=3.0'),
  335. array('>2.0 , <=3.0'),
  336. array('> 2.0 <= 3.0'),
  337. array('> 2.0 , <= 3.0'),
  338. array(' > 2.0 , <= 3.0 '),
  339. );
  340. }
  341. public function testParseConstraintsMultiWithStabilitySuffix()
  342. {
  343. $parser = new VersionParser;
  344. $first = new VersionConstraint('>=', '1.1.0.0-alpha4');
  345. $second = new VersionConstraint('<', '1.2.9999999.9999999-dev');
  346. $multi = new MultiConstraint(array($first, $second));
  347. $this->assertSame((string) $multi, (string) $parser->parseConstraints('>=1.1.0-alpha4,<1.2.x-dev'));
  348. $first = new VersionConstraint('>=', '1.1.0.0-alpha4');
  349. $second = new VersionConstraint('<', '1.2.0.0-beta2');
  350. $multi = new MultiConstraint(array($first, $second));
  351. $this->assertSame((string) $multi, (string) $parser->parseConstraints('>=1.1.0-alpha4,<1.2-beta2'));
  352. }
  353. /**
  354. * @dataProvider multiConstraintProvider2
  355. */
  356. public function testParseConstraintsMultiDisjunctiveHasPrioOverConjuctive($constraint)
  357. {
  358. $parser = new VersionParser;
  359. $first = new VersionConstraint('>', '2.0.0.0');
  360. $second = new VersionConstraint('<', '2.0.5.0-dev');
  361. $third = new VersionConstraint('>', '2.0.6.0');
  362. $multi1 = new MultiConstraint(array($first, $second));
  363. $multi2 = new MultiConstraint(array($multi1, $third), false);
  364. $this->assertSame((string) $multi2, (string) $parser->parseConstraints($constraint));
  365. }
  366. public function multiConstraintProvider2()
  367. {
  368. return array(
  369. array('>2.0,<2.0.5 | >2.0.6'),
  370. array('>2.0,<2.0.5 || >2.0.6'),
  371. array('> 2.0 , <2.0.5 | > 2.0.6'),
  372. );
  373. }
  374. public function testParseConstraintsMultiWithStabilities()
  375. {
  376. $parser = new VersionParser;
  377. $first = new VersionConstraint('>', '2.0.0.0');
  378. $second = new VersionConstraint('<=', '3.0.0.0-dev');
  379. $multi = new MultiConstraint(array($first, $second));
  380. $this->assertSame((string) $multi, (string) $parser->parseConstraints('>2.0@stable,<=3.0@dev'));
  381. }
  382. /**
  383. * @dataProvider failingConstraints
  384. * @expectedException UnexpectedValueException
  385. */
  386. public function testParseConstraintsFails($input)
  387. {
  388. $parser = new VersionParser;
  389. $parser->parseConstraints($input);
  390. }
  391. public function failingConstraints()
  392. {
  393. return array(
  394. 'empty ' => array(''),
  395. 'invalid version' => array('1.0.0-meh'),
  396. 'operator abuse' => array('>2.0,,<=3.0'),
  397. 'operator abuse/2' => array('>2.0 ,, <=3.0'),
  398. 'operator abuse/3' => array('>2.0 ||| <=3.0'),
  399. );
  400. }
  401. /**
  402. * @dataProvider stabilityProvider
  403. */
  404. public function testParseStability($expected, $version)
  405. {
  406. $this->assertSame($expected, VersionParser::parseStability($version));
  407. }
  408. public function stabilityProvider()
  409. {
  410. return array(
  411. array('stable', '1'),
  412. array('stable', '1.0'),
  413. array('stable', '3.2.1'),
  414. array('stable', 'v3.2.1'),
  415. array('dev', 'v2.0.x-dev'),
  416. array('dev', 'v2.0.x-dev#abc123'),
  417. array('dev', 'v2.0.x-dev#trunk/@123'),
  418. array('RC', '3.0-RC2'),
  419. array('dev', 'dev-master'),
  420. array('dev', '3.1.2-dev'),
  421. array('stable', '3.1.2-pl2'),
  422. array('stable', '3.1.2-patch'),
  423. array('alpha', '3.1.2-alpha5'),
  424. array('beta', '3.1.2-beta'),
  425. array('beta', '2.0B1'),
  426. array('alpha', '1.2.0a1'),
  427. array('alpha', '1.2_a1'),
  428. array('RC', '2.0.0rc1')
  429. );
  430. }
  431. }