diff --git a/.php_cs b/.php_cs new file mode 100644 index 0000000..4be4f3d --- /dev/null +++ b/.php_cs @@ -0,0 +1,12 @@ +in([ + __DIR__ . DIRECTORY_SEPARATOR . 'src', + __DIR__ . DIRECTORY_SEPARATOR . 'tests', + ]); + +return Symfony\CS\Config\Config::create() + ->level(\Symfony\CS\FixerInterface::PSR2_LEVEL) + ->fixers(['short_array_syntax']) + ->finder($finder); \ No newline at end of file diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 07d9fd6..043069b 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -3,37 +3,9 @@ filter: - 'tests/*' checks: php: true -coding_style: - php: - indentation: - general: - use_tabs: true - braces: - classes_functions: - class: end-of-line - function: end-of-line - closure: end-of-line - if: - opening: end-of-line - else_on_new_line: true - for: - opening: end-of-line - while: - opening: end-of-line - do_while: - opening: end-of-line - while_on_new_line: true - switch: - opening: end-of-line - try: - opening: end-of-line - catch_on_new_line: true - finally_on_new_line: true - upper_lower_casing: - keywords: - general: lower - constants: - true_false_null: lower tools: external_code_coverage: - runs: 4 \ No newline at end of file + runs: 2 + php_code_sniffer: + config: + standard: "PSR2" \ No newline at end of file diff --git a/src/NoSemanticVersionException.php b/src/NoSemanticVersionException.php index 209efc6..91c5040 100644 --- a/src/NoSemanticVersionException.php +++ b/src/NoSemanticVersionException.php @@ -16,5 +16,6 @@ * * @since 1.0.0-rc.1 */ -class NoSemanticVersionException extends RuntimeException { -} \ No newline at end of file +class NoSemanticVersionException extends RuntimeException +{ +} diff --git a/src/SemanticComparator.php b/src/SemanticComparator.php index 358e9b5..02580bd 100644 --- a/src/SemanticComparator.php +++ b/src/SemanticComparator.php @@ -15,82 +15,87 @@ * @since 1.0.0-rc.1 * @see http://semver.org */ -class SemanticComparator { - /** - * @param SemanticVersion $left - * @param SemanticVersion $right - * @return int - * @see compare() - */ - public function __invoke(SemanticVersion $left, SemanticVersion $right) { - return $this->compare($left, $right); - } - - /** - * Build metadata is ignored when determining version precedence. - * - * @param SemanticVersion $left - * @param SemanticVersion $right - * @return int `0` if both versions are equal, `< 0` if `$left` is smaller and `> 0` if `$left` is greater. - */ - public function compare(SemanticVersion $left, SemanticVersion $right) { - $result = $this->compareMajorMinorPatch($left, $right); - - if ($result === 0) { - $result = $this->comparePre($left, $right); - } - - return $result; - } - - /** - * @param SemanticVersion $left - * @param SemanticVersion $right - * @return int - */ - private function compareMajorMinorPatch(SemanticVersion $left, SemanticVersion $right) { - $result = $left->getMajor() - $right->getMajor(); - - if ($result === 0) { - $result = $left->getMinor() - $right->getMinor(); - - if ($result === 0) { - $result = $left->getPatch() - $right->getPatch(); - } - } - - return $result; - } - - /** - * @param SemanticVersion $left - * @param SemanticVersion $right - * @return int - */ - private function comparePre(SemanticVersion $left, SemanticVersion $right) { - if ($left->getPre() === '') { - return $right->getPre() === '' ? 0 : 1; - } - - if ($right->getPre() === '') { - return -1; - } - - $leftStack = $left->getPreStack(); - $rightStack = $right->getPreStack(); - - $leftCount = count($leftStack); - $rightCount = count($rightStack); - $minCount = min($leftCount, $rightCount); - - for ($i = 0; $i < $minCount; $i++) { - $result = strnatcasecmp($leftStack[$i], $rightStack[$i]); - - if ($result !== 0) { - return $result; - } - } - - return $leftCount - $rightCount; - } -} \ No newline at end of file +class SemanticComparator +{ + /** + * @param SemanticVersion $left + * @param SemanticVersion $right + * @return int + * @see compare() + */ + public function __invoke(SemanticVersion $left, SemanticVersion $right) + { + return $this->compare($left, $right); + } + + /** + * Build metadata is ignored when determining version precedence. + * + * @param SemanticVersion $left + * @param SemanticVersion $right + * @return int `0` if both versions are equal, `< 0` if `$left` is smaller and `> 0` if `$left` is greater. + */ + public function compare(SemanticVersion $left, SemanticVersion $right) + { + $result = $this->compareMajorMinorPatch($left, $right); + + if ($result === 0) { + $result = $this->comparePre($left, $right); + } + + return $result; + } + + /** + * @param SemanticVersion $left + * @param SemanticVersion $right + * @return int + */ + private function compareMajorMinorPatch(SemanticVersion $left, SemanticVersion $right) + { + $result = $left->getMajor() - $right->getMajor(); + + if ($result === 0) { + $result = $left->getMinor() - $right->getMinor(); + + if ($result === 0) { + $result = $left->getPatch() - $right->getPatch(); + } + } + + return $result; + } + + /** + * @param SemanticVersion $left + * @param SemanticVersion $right + * @return int + */ + private function comparePre(SemanticVersion $left, SemanticVersion $right) + { + if ($left->getPre() === '') { + return $right->getPre() === '' ? 0 : 1; + } + + if ($right->getPre() === '') { + return -1; + } + + $leftStack = $left->getPreStack(); + $rightStack = $right->getPreStack(); + + $leftCount = count($leftStack); + $rightCount = count($rightStack); + $minCount = min($leftCount, $rightCount); + + for ($i = 0; $i < $minCount; $i++) { + $result = strnatcasecmp($leftStack[$i], $rightStack[$i]); + + if ($result !== 0) { + return $result; + } + } + + return $leftCount - $rightCount; + } +} diff --git a/src/SemanticVersion.php b/src/SemanticVersion.php index 1284030..ae3aca1 100644 --- a/src/SemanticVersion.php +++ b/src/SemanticVersion.php @@ -16,167 +16,181 @@ * @since 1.0.0-rc.1 * @see http://semver.org */ -class SemanticVersion { - /** - * @var int - */ - private $major; - - /** - * @var int - */ - private $minor; - - /** - * @var int - */ - private $patch; - - /** - * @var string - */ - private $pre; - - /** - * @var array - */ - private $preStack; - - /** - * @var string - */ - private $meta; - - /** - * @var array - */ - private $metaStack; - - /** - * @var string - */ - private $version; - - /** - * @param string $version - * @throws NoSemanticVersionException On incompatible `$version`. - */ - public function __construct($version) { - $this->version = (string) $version; - - $matches = []; - - if (!preg_match('#^(\d|[1-9]\d+)\.(\d|[1-9]\d+)\.(\d|[1-9]\d+)(|-[\.0-9A-Za-z-]+)(|\+[\.0-9A-Za-z-]+)$#', $version, $matches)) { - throw $this->buildException(); - } - - $this->major = (int) $matches[1]; - $this->minor = (int) $matches[2]; - $this->patch = (int) $matches[3]; - - $this->setPre($matches[4] ? substr($matches[4], 1) : ''); - $this->setMeta($matches[5] ? substr($matches[5], 1) : ''); - } - - /** - * @return string - */ - public function __toString() { - return $this->getVersion(); - } - - /** - * @param string $pre - * @throws NoSemanticVersionException - */ - private function setPre($pre) { - $this->pre = $pre; - $this->preStack = $pre === '' ? [] : explode('.', $pre); - - foreach ($this->preStack as $value) { - if ($value === '' || preg_match('#^0\d+$#', $value)) { - throw $this->buildException(); - } - } - } - - /** - * @param string $meta - * @throws NoSemanticVersionException - */ - private function setMeta($meta) { - $this->meta = $meta; - $this->metaStack = $meta === '' ? [] : explode('.', $meta); - - foreach ($this->metaStack as $value) { - if ($value === '') { - throw $this->buildException(); - } - } - } - - /** - * @return NoSemanticVersionException - */ - private function buildException() { - return new NoSemanticVersionException(sprintf('Invalid semantic version `%s`.', $this->getVersion())); - } - - /** - * @return int Non-negative integer without leading zeroes. - */ - public function getMajor() { - return $this->major; - } - - /** - * @return int Non-negative integer without leading zeroes. - */ - public function getMinor() { - return $this->minor; - } - - /** - * @return int Non-negative integer without leading zeroes. - */ - public function getPatch() { - return $this->patch; - } - - /** - * @return string Optional pre-release information. - */ - public function getPre() { - return $this->pre; - } - - /** - * @return string[] - * @since 1.0.0-rc.2 - */ - public function getPreStack() { - return $this->preStack; - } - - /** - * @return string Optional metadata. - */ - public function getMeta() { - return $this->meta; - } - - /** - * @return string[] - * @since 1.0.0-rc.2 - */ - public function getMetaStack() { - return $this->metaStack; - } - - /** - * @return string - */ - public function getVersion() { - return $this->version; - } -} \ No newline at end of file +class SemanticVersion +{ + /** + * @var int + */ + private $major; + + /** + * @var int + */ + private $minor; + + /** + * @var int + */ + private $patch; + + /** + * @var string + */ + private $pre; + + /** + * @var array + */ + private $preStack; + + /** + * @var string + */ + private $meta; + + /** + * @var array + */ + private $metaStack; + + /** + * @var string + */ + private $version; + + /** + * @param string $version + * @throws NoSemanticVersionException On incompatible `$version`. + */ + public function __construct($version) + { + $this->version = (string) $version; + + $matches = []; + + if (!preg_match('#^(\d|[1-9]\d+)\.(\d|[1-9]\d+)\.(\d|[1-9]\d+)(|-[\.0-9A-Za-z-]+)(|\+[\.0-9A-Za-z-]+)$#', $version, $matches)) { + throw $this->buildException(); + } + + $this->major = (int) $matches[1]; + $this->minor = (int) $matches[2]; + $this->patch = (int) $matches[3]; + + $this->setPre($matches[4] ? substr($matches[4], 1) : ''); + $this->setMeta($matches[5] ? substr($matches[5], 1) : ''); + } + + /** + * @return string + */ + public function __toString() + { + return $this->getVersion(); + } + + /** + * @param string $pre + * @throws NoSemanticVersionException + */ + private function setPre($pre) + { + $this->pre = $pre; + $this->preStack = $pre === '' ? [] : explode('.', $pre); + + foreach ($this->preStack as $value) { + if ($value === '' || preg_match('#^0\d+$#', $value)) { + throw $this->buildException(); + } + } + } + + /** + * @param string $meta + * @throws NoSemanticVersionException + */ + private function setMeta($meta) + { + $this->meta = $meta; + $this->metaStack = $meta === '' ? [] : explode('.', $meta); + + foreach ($this->metaStack as $value) { + if ($value === '') { + throw $this->buildException(); + } + } + } + + /** + * @return NoSemanticVersionException + */ + private function buildException() + { + return new NoSemanticVersionException(sprintf('Invalid semantic version `%s`.', $this->getVersion())); + } + + /** + * @return int Non-negative integer without leading zeroes. + */ + public function getMajor() + { + return $this->major; + } + + /** + * @return int Non-negative integer without leading zeroes. + */ + public function getMinor() + { + return $this->minor; + } + + /** + * @return int Non-negative integer without leading zeroes. + */ + public function getPatch() + { + return $this->patch; + } + + /** + * @return string Optional pre-release information. + */ + public function getPre() + { + return $this->pre; + } + + /** + * @return string[] + * @since 1.0.0-rc.2 + */ + public function getPreStack() + { + return $this->preStack; + } + + /** + * @return string Optional metadata. + */ + public function getMeta() + { + return $this->meta; + } + + /** + * @return string[] + * @since 1.0.0-rc.2 + */ + public function getMetaStack() + { + return $this->metaStack; + } + + /** + * @return string + */ + public function getVersion() + { + return $this->version; + } +} diff --git a/src/autoload.php b/src/autoload.php index d341d78..8eafb8d 100644 --- a/src/autoload.php +++ b/src/autoload.php @@ -11,4 +11,4 @@ require_once __DIR__ . '/NoSemanticVersionException.php'; require_once __DIR__ . '/SemanticComparator.php'; -require_once __DIR__ . '/SemanticVersion.php'; \ No newline at end of file +require_once __DIR__ . '/SemanticVersion.php'; diff --git a/tests/AutoloadTest.php b/tests/AutoloadTest.php index 5621ab6..39cde83 100644 --- a/tests/AutoloadTest.php +++ b/tests/AutoloadTest.php @@ -14,11 +14,13 @@ /** * Tests for the `autoload.php` file. */ -class AutoloadTest extends PHPUnit_Framework_TestCase { - /** - * - */ - public function test() { - require dirname(__DIR__) . '/src/autoload.php'; - } -} \ No newline at end of file +class AutoloadTest extends PHPUnit_Framework_TestCase +{ + /** + * + */ + public function test() + { + require dirname(__DIR__) . '/src/autoload.php'; + } +} diff --git a/tests/Examples/ExamplesTest.php b/tests/Examples/ExamplesTest.php new file mode 100644 index 0000000..933569d --- /dev/null +++ b/tests/Examples/ExamplesTest.php @@ -0,0 +1,74 @@ +getMajor()); + assert(0 === $version->getMinor()); + assert(0 === $version->getPatch()); + assert('beta' === $version->getPre()); + assert('exp.sha.5114f85' === $version->getMeta()); + assert('1.0.0-beta+exp.sha.5114f85' === $version->getVersion()); + } + + public function testCompare() + { + $comparator = new SemanticComparator(); + + $alpha = new SemanticVersion('1.0.0-alpha'); + $candidate = new SemanticVersion('1.0.0-rc.1'); + $candidate_meta = new SemanticVersion('1.0.0-rc.1+ci'); + $release = new SemanticVersion('1.0.0'); + + // $alpha < $candidate + assert($comparator($alpha, $candidate) < 0); + assert($comparator->compare($alpha, $candidate) < 0); + + // $candidate == $candidate_meta + assert($comparator($candidate, $candidate_meta) == 0); + assert($comparator->compare($candidate, $candidate_meta) == 0); + + // $release > $candidate + assert($comparator($release, $candidate) > 0); + assert($comparator->compare($release, $candidate) > 0); + } + + public function testSort() + { + $versions = [ + $candidate = new SemanticVersion('1.0.0-rc.1'), + $release = new SemanticVersion('1.0.0'), + $alpha = new SemanticVersion('1.0.0-alpha'), + ]; + + // Sort by semantic precedence. + usort($versions, new SemanticComparator()); + + assert($versions[0] === $alpha); + assert($versions[1] === $candidate); + assert($versions[2] === $release); + } +} diff --git a/tests/SemanticComparatorTest.php b/tests/SemanticComparatorTest.php index 24acffd..e6ee7bc 100644 --- a/tests/SemanticComparatorTest.php +++ b/tests/SemanticComparatorTest.php @@ -14,99 +14,105 @@ /** * @see http://semver.org/ */ -class SemanticComparatorTest extends PHPUnit_Framework_TestCase { - /** - * @param array[] $sets Replaces strings with `SemanticVersion` objects. - */ - private function replaceStringsWithSemanticVersionObjects(&$sets) { - array_walk($sets, function(&$sets){ - array_walk($sets, function(&$version){ - $version = new SemanticVersion($version); - }); - }); - } - - /** - * @return array[] - */ - public function provideSmallerGreaterVersions() { - $sets = [ - [ - '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', - ], - [ - '1.0.0', - '2.0.0', - '2.1.0', - '2.1.1', - ], - ]; - - $this->replaceStringsWithSemanticVersionObjects($sets); - - $result = []; - - foreach ($sets as $set) { - for ($i = 0; $i < count($set); $i++) { - for ($j = $i + 1; $j < count($set); $j++) { - $result[] = [$set[$i], $set[$j]]; - } - } - } - - return $result; - } - - /** - * @return array[] - */ - public function provideEqualVersions() { - $result = [ - ['0.6.0', '0.6.0'], - ['1.0.0-alpha+001', '1.0.0-alpha+002'], - ['1.0.0+20130313144700', '1.0.0+20151219222700'], - ['1.0.0-beta+exp.sha.5114f85', '1.0.0-beta+exp.md5.e07910a'], - ]; - - $this->replaceStringsWithSemanticVersionObjects($result); - - return $result; - } - - /** - * @dataProvider provideEqualVersions - * @param SemanticVersion $left - * @param SemanticVersion $right - */ - public function testEqualComparison(SemanticVersion $left, SemanticVersion $right) { - $comparator = new SemanticComparator(); - - $this->assertSame(0, $comparator->compare($left, $right), "$left == $right"); - $this->assertSame(0, $comparator->compare($right, $left), "$right == $left"); - - $this->assertSame(0, $comparator($left, $right), "$left == $right"); - $this->assertSame(0, $comparator($right, $left), "$right == $left"); - } - - /** - * @dataProvider provideSmallerGreaterVersions - * @param SemanticVersion $smaller - * @param SemanticVersion $greater - */ - public function testNotEqualComparison(SemanticVersion $smaller, SemanticVersion $greater) { - $comparator = new SemanticComparator(); - - $this->assertTrue($comparator->compare($smaller, $greater) < 0, "$smaller < $greater"); - $this->assertTrue($comparator->compare($greater, $smaller) > 0, "$greater > $smaller"); - - $this->assertTrue($comparator($smaller, $greater) < 0, "$smaller < $greater"); - $this->assertTrue($comparator($greater, $smaller) > 0, "$greater > $smaller"); - } -} \ No newline at end of file +class SemanticComparatorTest extends PHPUnit_Framework_TestCase +{ + /** + * @param array[] $sets Replaces strings with `SemanticVersion` objects. + */ + private function replaceStringsWithSemanticVersionObjects(&$sets) + { + array_walk($sets, function (&$sets) { + array_walk($sets, function (&$version) { + $version = new SemanticVersion($version); + }); + }); + } + + /** + * @return array[] + */ + public function provideSmallerGreaterVersions() + { + $sets = [ + [ + '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', + ], + [ + '1.0.0', + '2.0.0', + '2.1.0', + '2.1.1', + ], + ]; + + $this->replaceStringsWithSemanticVersionObjects($sets); + + $result = []; + + foreach ($sets as $set) { + for ($i = 0; $i < count($set); $i++) { + for ($j = $i + 1; $j < count($set); $j++) { + $result[] = [$set[$i], $set[$j]]; + } + } + } + + return $result; + } + + /** + * @return array[] + */ + public function provideEqualVersions() + { + $result = [ + ['0.6.0', '0.6.0'], + ['1.0.0-alpha+001', '1.0.0-alpha+002'], + ['1.0.0+20130313144700', '1.0.0+20151219222700'], + ['1.0.0-beta+exp.sha.5114f85', '1.0.0-beta+exp.md5.e07910a'], + ]; + + $this->replaceStringsWithSemanticVersionObjects($result); + + return $result; + } + + /** + * @dataProvider provideEqualVersions + * @param SemanticVersion $left + * @param SemanticVersion $right + */ + public function testEqualComparison(SemanticVersion $left, SemanticVersion $right) + { + $comparator = new SemanticComparator(); + + $this->assertSame(0, $comparator->compare($left, $right), "$left == $right"); + $this->assertSame(0, $comparator->compare($right, $left), "$right == $left"); + + $this->assertSame(0, $comparator($left, $right), "$left == $right"); + $this->assertSame(0, $comparator($right, $left), "$right == $left"); + } + + /** + * @dataProvider provideSmallerGreaterVersions + * @param SemanticVersion $smaller + * @param SemanticVersion $greater + */ + public function testNotEqualComparison(SemanticVersion $smaller, SemanticVersion $greater) + { + $comparator = new SemanticComparator(); + + $this->assertTrue($comparator->compare($smaller, $greater) < 0, "$smaller < $greater"); + $this->assertTrue($comparator->compare($greater, $smaller) > 0, "$greater > $smaller"); + + $this->assertTrue($comparator($smaller, $greater) < 0, "$smaller < $greater"); + $this->assertTrue($comparator($greater, $smaller) > 0, "$greater > $smaller"); + } +} diff --git a/tests/SemanticVersionTest.php b/tests/SemanticVersionTest.php index a3c4324..a178c15 100644 --- a/tests/SemanticVersionTest.php +++ b/tests/SemanticVersionTest.php @@ -14,134 +14,139 @@ /** * @see http://semver.org/ */ -class SemanticVersionTest extends PHPUnit_Framework_TestCase { - /** - * @return array[] - */ - public function provideValidVersions() { - return [ - ['1.2.3', 1, 2, 3, '', '', [], []], - ['1.2.3-4', 1, 2, 3, '4', '', ['4'], []], - ['1.2.3+5', 1, 2, 3, '', '5', [], ['5']], - ['1.2.3-4+5', 1, 2, 3, '4', '5', ['4'], ['5']], - - // Pre-release - ['1.2.3-pre', 1, 2, 3, 'pre', '', ['pre'], []], - ['1.2.3-pre.pre', 1, 2, 3, 'pre.pre', '', ['pre', 'pre'], []], - ['1.2.3-pre-pre', 1, 2, 3, 'pre-pre', '', ['pre-pre'], []], - - // Leading zeroes aren't forbidden for non-numeric pre-releases. - // This fact isn't quite clear in Semantic Versioning 2.0.0, - // but the Backus–Naur Form Grammar of Semantic Versioning 2.1.0 (Draft) - // allows leading zeroes for non-numeric pre-releases. - ['0.0.0-0FF', 0, 0, 0, '0FF', '', ['0FF'], []], - ['0.0.0-0FF+0', 0, 0, 0, '0FF', '0', ['0FF'], ['0']], - - // Metadata - ['1.2.3+meta', 1, 2, 3, '', 'meta', [], ['meta']], - ['1.2.3+meta.meta', 1, 2, 3, '', 'meta.meta', [], ['meta', 'meta']], - ['1.2.3+meta-meta', 1, 2, 3, '', 'meta-meta', [], ['meta-meta']], - - // Leading zeroes aren't forbidden for metadata - ['0.0.0+00', 0, 0, 0, '', '00', [], ['00']], - ['0.0.0-0+00', 0, 0, 0, '0', '00', ['0'], ['00']], - - // Pre-release and metadata - ['1.2.3-pre+meta', 1, 2, 3, 'pre', 'meta', ['pre'], ['meta']], - ['1.2.3-pre.pre+meta.meta', 1, 2, 3, 'pre.pre', 'meta.meta', ['pre', 'pre'], ['meta', 'meta']], - ['1.2.3-pre-pre+meta-meta', 1, 2, 3, 'pre-pre', 'meta-meta', ['pre-pre'], ['meta-meta']], - - ['1.0.0-alpha', 1, 0, 0, 'alpha', '', ['alpha'], []], - ['1.0.0-alpha.1', 1, 0, 0, 'alpha.1', '', ['alpha', '1'], []], - ['1.0.0-0.3.7', 1, 0, 0, '0.3.7', '', ['0', '3', '7'], []], - ['1.0.0-x.7.z.92', 1, 0, 0, 'x.7.z.92', '', ['x', '7', 'z', '92'], []], - - ['1.0.0-alpha+001', 1, 0, 0, 'alpha', '001', ['alpha'], ['001']], - ['1.0.0+20130313144700', 1, 0, 0, '', '20130313144700', [], ['20130313144700']], - ['1.0.0-beta+exp.sha.5114f85', 1, 0, 0, 'beta', 'exp.sha.5114f85', ['beta'], ['exp', 'sha', '5114f85']], - ]; - } - - /** - * @return array[] - */ - public function provideInvalidVersions() { - return [ - [null], - [''], - ['0'], - ['T.X.T'], - - // Negative integers - ['-0.0.0'], - ['0.-0.0'], - ['0.0.-0'], - - // Leading zeroes - ['01.0.0'], - ['0.01.1'], - ['0.0.01'], - - // Empty pre-release - ['0.6.0-'], - ['0.6.0-.'], - ['0.6.0-a.'], - ['0.6.0-.b'], - ['0.6.0-a..b'], - - // Pre-release numbers with leading zeroes - ['0.0.0-00'], - ['0.0.0-00+0'], - - // Empty metadata - ['0.6.0+'], - ['0.6.0+.'], - ['0.6.0+a.'], - ['0.6.0+.b'], - ['0.6.0+a..b'], - - // Invalid pre-release and metadata - ['0.6.0+meta+meta'], - ['0.6.0-pre+meta+meta'], - - // Invalid characters - ['0.0.0-❤'], - ['0.0.0+❤'], - ['0.0.0-Präzisionsmessgerät'], - ]; - } - - /** - * @dataProvider provideValidVersions - * @param string $version - * @param int $major - * @param int $minor - * @param int $patch - * @param string $pre - * @param string $meta - * @param string[] $preStack - * @param string[] $metaStack - */ - public function testValidVersion($version, $major, $minor, $patch, $pre, $meta, array $preStack, array $metaStack) { - $object = new SemanticVersion($version); - - $this->assertSame($version, (string) $object); - $this->assertSame($version, $object->getVersion()); - $this->assertSame($major, $object->getMajor()); - $this->assertSame($minor, $object->getMinor()); - $this->assertSame($patch, $object->getPatch()); - $this->assertSame($pre, $object->getPre()); - $this->assertSame($preStack, $object->getPreStack()); - $this->assertSame($meta, $object->getMeta()); - $this->assertSame($metaStack, $object->getMetaStack()); - } - - /** - * @dataProvider provideInvalidVersions - * @expectedException \Rayne\SemanticVersioning\NoSemanticVersionException - * @param mixed $version - */ - public function testInvalidVersion($version) { - new SemanticVersion($version); - } -} \ No newline at end of file +class SemanticVersionTest extends PHPUnit_Framework_TestCase +{ + /** + * @return array[] + */ + public function provideValidVersions() + { + return [ + ['1.2.3', 1, 2, 3, '', '', [], []], + ['1.2.3-4', 1, 2, 3, '4', '', ['4'], []], + ['1.2.3+5', 1, 2, 3, '', '5', [], ['5']], + ['1.2.3-4+5', 1, 2, 3, '4', '5', ['4'], ['5']], + + // Pre-release + ['1.2.3-pre', 1, 2, 3, 'pre', '', ['pre'], []], + ['1.2.3-pre.pre', 1, 2, 3, 'pre.pre', '', ['pre', 'pre'], []], + ['1.2.3-pre-pre', 1, 2, 3, 'pre-pre', '', ['pre-pre'], []], + + // Leading zeroes aren't forbidden for non-numeric pre-releases. + // This fact isn't quite clear in Semantic Versioning 2.0.0, + // but the Backus–Naur Form Grammar of Semantic Versioning 2.1.0 (Draft) + // allows leading zeroes for non-numeric pre-releases. + ['0.0.0-0FF', 0, 0, 0, '0FF', '', ['0FF'], []], + ['0.0.0-0FF+0', 0, 0, 0, '0FF', '0', ['0FF'], ['0']], + + // Metadata + ['1.2.3+meta', 1, 2, 3, '', 'meta', [], ['meta']], + ['1.2.3+meta.meta', 1, 2, 3, '', 'meta.meta', [], ['meta', 'meta']], + ['1.2.3+meta-meta', 1, 2, 3, '', 'meta-meta', [], ['meta-meta']], + + // Leading zeroes aren't forbidden for metadata + ['0.0.0+00', 0, 0, 0, '', '00', [], ['00']], + ['0.0.0-0+00', 0, 0, 0, '0', '00', ['0'], ['00']], + + // Pre-release and metadata + ['1.2.3-pre+meta', 1, 2, 3, 'pre', 'meta', ['pre'], ['meta']], + ['1.2.3-pre.pre+meta.meta', 1, 2, 3, 'pre.pre', 'meta.meta', ['pre', 'pre'], ['meta', 'meta']], + ['1.2.3-pre-pre+meta-meta', 1, 2, 3, 'pre-pre', 'meta-meta', ['pre-pre'], ['meta-meta']], + + ['1.0.0-alpha', 1, 0, 0, 'alpha', '', ['alpha'], []], + ['1.0.0-alpha.1', 1, 0, 0, 'alpha.1', '', ['alpha', '1'], []], + ['1.0.0-0.3.7', 1, 0, 0, '0.3.7', '', ['0', '3', '7'], []], + ['1.0.0-x.7.z.92', 1, 0, 0, 'x.7.z.92', '', ['x', '7', 'z', '92'], []], + + ['1.0.0-alpha+001', 1, 0, 0, 'alpha', '001', ['alpha'], ['001']], + ['1.0.0+20130313144700', 1, 0, 0, '', '20130313144700', [], ['20130313144700']], + ['1.0.0-beta+exp.sha.5114f85', 1, 0, 0, 'beta', 'exp.sha.5114f85', ['beta'], ['exp', 'sha', '5114f85']], + ]; + } + + /** + * @return array[] + */ + public function provideInvalidVersions() + { + return [ + [null], + [''], + ['0'], + ['T.X.T'], + + // Negative integers + ['-0.0.0'], + ['0.-0.0'], + ['0.0.-0'], + + // Leading zeroes + ['01.0.0'], + ['0.01.1'], + ['0.0.01'], + + // Empty pre-release + ['0.6.0-'], + ['0.6.0-.'], + ['0.6.0-a.'], + ['0.6.0-.b'], + ['0.6.0-a..b'], + + // Pre-release numbers with leading zeroes + ['0.0.0-00'], + ['0.0.0-00+0'], + + // Empty metadata + ['0.6.0+'], + ['0.6.0+.'], + ['0.6.0+a.'], + ['0.6.0+.b'], + ['0.6.0+a..b'], + + // Invalid pre-release and metadata + ['0.6.0+meta+meta'], + ['0.6.0-pre+meta+meta'], + + // Invalid characters + ['0.0.0-❤'], + ['0.0.0+❤'], + ['0.0.0-Präzisionsmessgerät'], + ]; + } + + /** + * @dataProvider provideValidVersions + * @param string $version + * @param int $major + * @param int $minor + * @param int $patch + * @param string $pre + * @param string $meta + * @param string[] $preStack + * @param string[] $metaStack + */ + public function testValidVersion($version, $major, $minor, $patch, $pre, $meta, array $preStack, array $metaStack) + { + $object = new SemanticVersion($version); + + $this->assertSame($version, (string) $object); + $this->assertSame($version, $object->getVersion()); + $this->assertSame($major, $object->getMajor()); + $this->assertSame($minor, $object->getMinor()); + $this->assertSame($patch, $object->getPatch()); + $this->assertSame($pre, $object->getPre()); + $this->assertSame($preStack, $object->getPreStack()); + $this->assertSame($meta, $object->getMeta()); + $this->assertSame($metaStack, $object->getMetaStack()); + } + + /** + * @dataProvider provideInvalidVersions + * @expectedException \Rayne\SemanticVersioning\NoSemanticVersionException + * @param mixed $version + */ + public function testInvalidVersion($version) + { + new SemanticVersion($version); + } +} diff --git a/tests/examples/ExamplesTest.php b/tests/examples/ExamplesTest.php deleted file mode 100644 index 8fec2b5..0000000 --- a/tests/examples/ExamplesTest.php +++ /dev/null @@ -1,70 +0,0 @@ -getMajor()); - assert( 0 === $version->getMinor()); - assert( 0 === $version->getPatch()); - assert( 'beta' === $version->getPre()); - assert( 'exp.sha.5114f85' === $version->getMeta()); - assert('1.0.0-beta+exp.sha.5114f85' === $version->getVersion()); - } - - public function testCompare() { - $comparator = new SemanticComparator(); - - $alpha = new SemanticVersion('1.0.0-alpha'); - $candidate = new SemanticVersion('1.0.0-rc.1'); - $candidate_meta = new SemanticVersion('1.0.0-rc.1+ci'); - $release = new SemanticVersion('1.0.0'); - - // $alpha < $candidate - assert($comparator($alpha, $candidate) < 0); - assert($comparator->compare($alpha, $candidate) < 0); - - // $candidate == $candidate_meta - assert($comparator($candidate, $candidate_meta) == 0); - assert($comparator->compare($candidate, $candidate_meta) == 0); - - // $release > $candidate - assert($comparator($release, $candidate) > 0); - assert($comparator->compare($release, $candidate) > 0); - } - - public function testSort() { - $versions = [ - $candidate = new SemanticVersion('1.0.0-rc.1'), - $release = new SemanticVersion('1.0.0'), - $alpha = new SemanticVersion('1.0.0-alpha'), - ]; - - // Sort by semantic precedence. - usort($versions, new SemanticComparator()); - - assert($versions[0] === $alpha); - assert($versions[1] === $candidate); - assert($versions[2] === $release); - } -} \ No newline at end of file