Repository: PHLAK/SemVer Branch: master Commit: bf9c3ca45511 Files: 21 Total size: 48.9 KB Directory structure: gitextract_fljnwk0f/ ├── .editorconfig ├── .gitattributes ├── .github/ │ ├── FUNDING.yml │ ├── dependabot.yml │ └── workflows/ │ └── test-suite.yaml ├── .gitignore ├── .php-cs-fixer.dist.php ├── LICENSE ├── Makefile ├── README.md ├── composer.json ├── phpstan-ignores.neon ├── phpstan.neon.dist ├── phpunit.xml ├── src/ │ ├── Enums/ │ │ └── Compare.php │ ├── Exceptions/ │ │ └── InvalidVersionException.php │ ├── Support/ │ │ └── helpers.php │ ├── Traits/ │ │ ├── Comparable.php │ │ └── Incrementable.php │ └── Version.php └── tests/ └── VersionTest.php ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] charset = utf-8 end_of_line = lf indent_size = 4 indent_style = space insert_final_newline = true trim_trailing_whitespace = true [*.json] indent_style = space indent_size = 4 [*.md] trim_trailing_whitespace = false indent_size = 4 [*.{yml,yaml}] indent_size = 2 indent_style = space ================================================ FILE: .gitattributes ================================================ tests export-ignore .gitattributes export-ignore .gitignore export-ignore .php_cs.dist export-ignore .travis.yml export-ignore phpunit.xml export-ignore ================================================ FILE: .github/FUNDING.yml ================================================ github: PHLAK patreon: PHLAK custom: https://paypal.me/ChrisKankiewicz ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: - package-ecosystem: composer directory: "/" schedule: interval: monthly timezone: US/Arizona open-pull-requests-limit: 10 assignees: - PHLAK - package-ecosystem: github-actions directory: "/" schedule: interval: monthly timezone: US/Arizona assignees: - PHLAK ================================================ FILE: .github/workflows/test-suite.yaml ================================================ name: SemVer Test Suite on: [push, pull_request, workflow_dispatch] jobs: coding-standards: name: Coding Standards runs-on: 'ubuntu-latest' env: PHP_CS_FIXER_IGNORE_ENV: 1 steps: - name: Checkout Repository uses: actions/checkout@v5 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: '8.4' - name: Install PHP Dependencies run: composer install --no-interaction --no-progress --no-scripts --prefer-dist - name: Verify Coding Standards run: vendor/bin/php-cs-fixer fix --diff --dry-run static-analysis: name: Static Analysis runs-on: 'ubuntu-latest' steps: - name: Checkout Repository uses: actions/checkout@v5 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: '8.4' - name: Install PHP Dependencies run: composer install --no-interaction --no-progress --no-scripts --prefer-dist - name: Run Static Analysis run: vendor/bin/phpstan analyze tests: name: Tests runs-on: 'ubuntu-latest' strategy: matrix: php-versions: ['8.1', '8.2', '8.3', '8.4'] steps: - name: Checkout Repository uses: actions/checkout@v5 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-versions }} coverage: xdebug - name: Install PHP Dependencies run: composer install --no-interaction --no-progress --no-scripts --prefer-dist - name: Run Tests run: vendor/bin/phpunit --coverage-text ================================================ FILE: .gitignore ================================================ /.php-cs-fixer.cache /.phpunit.cache /composer.lock /vendor/ ================================================ FILE: .php-cs-fixer.dist.php ================================================ in([ __DIR__ . DIRECTORY_SEPARATOR . 'src', __DIR__ . DIRECTORY_SEPARATOR . 'tests', ]); return PHLAK\CodingStandards\ConfigFactory::make($finder); ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2024 Chris Kankiewicz Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Makefile ================================================ dev development: # Build application for development @composer install --no-interaction prod production: # Build application for production @composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader test: # Run coding standards/static analysis checks and tests @vendor/bin/php-cs-fixer fix --diff --dry-run \ && vendor/bin/phpstan analyze \ && vendor/bin/phpunit --coverage-text coverage: # Generate an HTML coverage report @vendor/bin/phpunit --coverage-html .coverage ================================================ FILE: README.md ================================================ SemVer ======

SemVer

Semantic versioning helper library • Created by Chris Kankiewicz (@phlak.dev)

Join our Community Become a Sponsor One-time Donation
Latest Stable Version Total Downloads License Tests Status

--- Requirements ------------ - [PHP](https://php.net) >= 8.1 Installation ------------ ```bash composer require phlak/semver ``` Initializing ------------ ```php use PHLAK\SemVer; $version = new SemVer\Version(); // Initilializes to '0.1.0' ``` Or initialize with a custom version by passing a version string on creation. Accepts any valid semantic version string with or without a preceding `v`. ```php $version = new SemVer\Version('v1.2.3-alpha.5+sha.8d31ff4'); ``` Or parse an incomple version string with the static `Version::parse()` constructor. ```php $version = SemVer\Version::parse('v1') // Initializes to '1.0.0' $version = SemVer\Version::parse('v1.2') // Initializes to '1.2.0' ``` Usage ----- #### Retrieve the version or individual values ```php $version = new SemVer\Version('v1.2.3-beta.4+007'); echo $version; // '1.2.3-beta.4+007' echo $version->major; // 1 echo $version->minor; // 2 echo $version->patch; // 3 echo $version->preRelease; // 'beta.4' echo $version->build; // '007' ``` #### Increment the version ```php $version = new SemVer\Version('v1.2.3'); $version->incrementMajor(); // v1.2.3 -> v2.0.0 $version->incrementMinor(); // v1.2.3 -> v1.3.0 $version->incrementPatch(); // v1.2.3 -> v1.2.4 $version->incrementPreRelease(); // v1.2.3-alpha.5 -> v1.2.3-alpha.6 ``` #### Set (override) the version or individual values ```php $version = new SemVer\Version(); $version->setVersion('v1.2.3'); // v1.2.3 $version->setMajor(3); // v1.2.3 -> v3.0.0 $version->setMinor(5); // v1.2.3 -> v1.5.0 $version->setPatch(7); // v1.2.3 -> 1.2.7 $version->setPreRelease('rc.2'); // v1.2.3 -> v1.2.3-rc.2 $version->setBuild('007'); // v1.2.3 -> v1.2.3+007 ``` #### Clear pre-release / build values ```php $version->setPreRelease(null); // v1.2.3-rc.2 -> v1.2.3 $version->setBuild(null); // v1.2.3+007 -> v1.2.3 ``` #### Check for pre-release / build values ```php $version->isPreRelease(); $version->hasBuild(); ``` #### Compare two SemVer objects ```php $version1 = new SemVer\Version('v1.2.3'); $version2 = new SemVer\Version('v3.2.1'); $version1->gt($version2); // false $version1->lt($version2); // true $version1->eq($version2); // false $version1->neq($version2); // true $version1->gte($version2); // false $version1->lte($version2); // true ``` ##### Limit comparison to the major version only Ignores the minor, patch and pre-release versions completely ```php $version1 = new SemVer\Version('v1.2.3-alpha.4'); $version2 = new SemVer\Version('v1.3.4-alpha.5'); $version1->gt($version2, Compare::MAJOR); // false $version1->lt($version2, Compare::MAJOR); // false $version1->eq($version2, Compare::MAJOR); // true $version1->neq($version2, Compare::MAJOR); // false $version1->gte($version2, Compare::MAJOR); // true $version1->lte($version2, Compare::MAJOR); // true ``` ##### Limit comparison to the major and minor versions only Ignores the patch and pre-release versions completely ```php $version1 = new SemVer\Version('v1.2.3-alpha.4'); $version2 = new SemVer\Version('v1.2.4-alpha.5'); $version1->gt($version2, Compare::MINOR); // false $version1->lt($version2, Compare::MINOR); // false $version1->eq($version2, Compare::MINOR); // true $version1->neq($version2, Compare::MINOR); // false $version1->gte($version2, Compare::MINOR); // true $version1->lte($version2, Compare::MINOR); // true ``` ##### Limit comparison to the major, minor and patch versions only Ignores the pre-release version completely ```php $version1 = new SemVer\Version('v1.2.3-alpha.4'); $version2 = new SemVer\Version('v1.2.3-alpha.5'); $version1->gt($version2, Compare::PATCH); // false $version1->lt($version2, Compare::PATCH); // false $version1->eq($version2, Compare::PATCH); // true $version1->neq($version2, Compare::PATCH); // false $version1->gte($version2, Compare::PATCH); // true $version1->lte($version2, Compare::PATCH); // true ``` Troubleshooting --------------- For general help and support join our [GitHub Discussions](https://github.com/PHLAK/SemVer/discussions) or reach out on [Bluesky](https://bsky.app/profile/phlak.dev). Please report bugs to the [GitHub Issue Tracker](https://github.com/PHLAK/SemVer/issues). Copyright --------- This project is liscensed under the [MIT License](https://github.com/PHLAK/SemVer/blob/master/LICENSE). ================================================ FILE: composer.json ================================================ { "name": "phlak/semver", "description": "Semantic versioning helper library", "type": "library", "license": "MIT", "authors": [ { "name": "Chris Kankiewicz", "email": "Chris@ChrisKankiewicz.com" } ], "funding": [ { "type": "github", "url": "https://github.com/sponsors/PHLAK" }, { "type": "paypal", "url": "https://paypal.me/ChrisKankiewicz" } ], "support": { "issues": "https://github.com/PHLAK/SemVer/issues" }, "require": { "php": "^8.1 || ^8.2 || ^8.3 || ^8.4" }, "require-dev": { "phlak/coding-standards": "^4.0", "phpstan/phpstan": "^2.0", "yoast/phpunit-polyfills": "^4.0" }, "autoload": { "psr-4": { "PHLAK\\SemVer\\": "src/" }, "files": ["src/Support/helpers.php"] }, "autoload-dev": { "psr-4": { "PHLAK\\Semver\\Tests\\": "tests/" } }, "config": { "sort-packages": true, "optimize-autoloader": true, "allow-plugins": { "composer/package-versions-deprecated": true } } } ================================================ FILE: phpstan-ignores.neon ================================================ parameters: ignoreErrors: - message: "/^Method .+ throws checked exception .+ but it's missing from the PHPDoc @throws tag.$/" path: tests/* ================================================ FILE: phpstan.neon.dist ================================================ parameters: paths: - src - tests level: max checkFunctionNameCase: true exceptions: implicitThrows: false check: missingCheckedExceptionInThrows: true tooWideThrowType: true uncheckedExceptionClasses: - 'RuntimeException' - 'PHPUnit\Framework\Exception' includes: - phpstan-ignores.neon ================================================ FILE: phpunit.xml ================================================ tests/ src/ ================================================ FILE: src/Enums/Compare.php ================================================ [[$version1->major], [$version2->major]], Compare::MINOR => [[$version1->major, $version1->minor], [$version2->major, $version2->minor]], default => [[$version1->major, $version1->minor, $version1->patch], [$version2->major, $version2->minor, $version2->patch]] }; $baseComparison = $v1 <=> $v2; if ($baseComparison !== 0 || $comparison !== Compare::FULL) { return $baseComparison; } if ($version1->preRelease !== null && $version2->preRelease === null) { return -1; } if ($version1->preRelease === null && $version2->preRelease !== null) { return 1; } $v1preReleaseParts = explode('.', $version1->preRelease ?? ''); $v2preReleaseParts = explode('.', $version2->preRelease ?? ''); $preReleases1 = array_pad($v1preReleaseParts, count($v2preReleaseParts), null); $preReleases2 = array_pad($v2preReleaseParts, count($v1preReleaseParts), null); return $preReleases1 <=> $preReleases2; } /** * Check if this Version object is greater than another. * * @param Version $version An instance of SemVer/Version * * @return bool True if this Version object is greater than the comparing * object, otherwise false */ public function gt(Version $version, Compare $comparison = Compare::FULL): bool { return self::compare($this, $version, $comparison) > 0; } /** * Check if this Version object is less than another. * * @param Version $version An instance of SemVer/Version * * @return bool True if this Version object is less than the comparing * object, otherwise false */ public function lt(Version $version, Compare $comparison = Compare::FULL): bool { return self::compare($this, $version, $comparison) < 0; } /** * Check if this Version object is equal to than another. * * @param Version $version An instance of SemVer/Version * * @return bool True if this Version object is equal to the comparing * object, otherwise false */ public function eq(Version $version, Compare $comparison = Compare::FULL): bool { return self::compare($this, $version, $comparison) === 0; } /** * Check if this Version object is not equal to another. * * @param Version $version An instance of SemVer/Version * * @return bool True if this Version object is not equal to the comparing * object, otherwise false */ public function neq(Version $version, Compare $comparison = Compare::FULL): bool { return self::compare($this, $version, $comparison) !== 0; } /** * Check if this Version object is greater than or equal to another. * * @param Version $version An instance of SemVer/Version * * @return bool True if this Version object is greater than or equal to the * comparing object, otherwise false */ public function gte(Version $version, Compare $comparison = Compare::FULL): bool { return self::compare($this, $version, $comparison) >= 0; } /** * Check if this Version object is less than or equal to another. * * @param Version $version An instance of SemVer/Version * * @return bool True if this Version object is less than or equal to the * comparing object, otherwise false */ public function lte(Version $version, Compare $comparison = Compare::FULL): bool { return self::compare($this, $version, $comparison) <= 0; } } ================================================ FILE: src/Traits/Incrementable.php ================================================ setMajor($this->major + 1); return $this; } /** * Increment the minor version value by one. * * @return static This Version object */ public function incrementMinor(): static { $this->setMinor($this->minor + 1); return $this; } /** * Increment the patch version value by one. * * @return static This Version object */ public function incrementPatch(): static { $this->setPatch($this->patch + 1); return $this; } /** * Increment the pre-release version value by one. * * @return static This Version object */ public function incrementPreRelease(): static { if (empty($this->preRelease)) { $this->incrementPatch(); $this->setPreRelease('1'); return $this; } $identifiers = explode('.', $this->preRelease); if (! is_numeric(end($identifiers))) { $this->setPreRelease(implode('.', [$this->preRelease, '1'])); return $this; } array_push($identifiers, (string) ((int) array_pop($identifiers) + 1)); $this->setPreRelease(implode('.', $identifiers)); return $this; } } ================================================ FILE: src/Version.php ================================================ setVersion($version); } /** * Magic get method; provides access to version properties. * * @param string $property Version property * * @return mixed Version property value */ public function __get(string $property) { return $this->$property; } /** * Magic toString method; allows object interaction as if it were a string. * * @return string Current version string */ public function __toString(): string { $version = implode('.', [$this->major, $this->minor, $this->patch]); if (! empty($this->preRelease)) { $version .= '-' . $this->preRelease; } if (! empty($this->build)) { $version .= '+' . $this->build; } return $version; } /** * Attempt to parse an incomplete version string. * * Examples: 'v1', 'v1.2', 'v1-beta.4', 'v1.3+007' * * @param string $version Version string * * @throws \PHLAK\SemVer\Exceptions\InvalidVersionException * * @return static This Version object */ public static function parse(string $version): static { $semverRegex = '/^v?(?\d+)(?:\.(?\d+)(?:\.(?\d+))?)?(?:-(?[0-9A-Za-z-.]+))?(?:\+(?[0-9A-Za-z-.]+)?)?$/'; if (! preg_match($semverRegex, $version, $matches, PREG_UNMATCHED_AS_NULL)) { throw new InvalidVersionException('Invalid semantic version string provided'); } $version = sprintf('%s.%s.%s', $matches['major'], $matches['minor'] ?? 0, $matches['patch'] ?? 0); if (! empty($matches['pre_release'])) { $version .= '-' . $matches['pre_release']; } if (! empty($matches['build'])) { $version .= '+' . $matches['build']; } return new static($version); } /** Serialize version to JSON. */ public function jsonSerialize(): mixed { return (string) $this; } /** * Set (override) the entire version value. * * @param string $version Version string * * @throws \PHLAK\SemVer\Exceptions\InvalidVersionException * * @return static This Version object */ public function setVersion(string $version): static { $semverRegex = '/^v?(?\d+)\.(?\d+)\.(?\d+)(?:-(?[0-9A-Za-z-.]+))?(?:\+(?[0-9A-Za-z-.]+)?)?$/'; if (! preg_match($semverRegex, $version, $matches, PREG_UNMATCHED_AS_NULL)) { throw new InvalidVersionException('Invalid semantic version string provided'); } $this->major = (int) $matches['major']; $this->minor = (int) $matches['minor']; $this->patch = (int) $matches['patch']; $this->preRelease = $matches['pre_release'] ?? null; $this->build = $matches['build'] ?? null; return $this; } /** * Set the major version to a custom value. * * @param int $value Positive integer value * * @return static This Version object */ public function setMajor(int $value): static { $this->major = $value; $this->setMinor(0); return $this; } /** * Set the minor version to a custom value. * * @param int $value Positive integer value * * @return static This Version object */ public function setMinor(int $value): static { $this->minor = $value; $this->setPatch(0); return $this; } /** * Set the patch version to a custom value. * * @param int $value Positive integer value * * @return static This Version object */ public function setPatch(int $value): static { $this->patch = $value; $this->setPreRelease(null); $this->setBuild(null); return $this; } /** * Set the pre-release string to a custom value. * * @param string|null $value A new pre-release value * * @return static This Version object */ public function setPreRelease($value): static { $this->preRelease = $value; return $this; } /** * Set the build string to a custom value. * * @param string|null $value A new build value * * @return static This Version object */ public function setBuild($value): static { $this->build = $value; return $this; } /** * Get the version string prefixed with a custom string. * * @param string $prefix String to prepend to the version string * (default: 'v') * * @return string Prefixed version string */ public function prefix(string $prefix = 'v'): string { return $prefix . (string) $this; } /** * Determine if the version is a pre-release. * * @return bool Returns true if the version is a pre-release, false otherwise */ public function isPreRelease(): bool { return ! empty($this->preRelease); } /** * Determine if the version has a build string. * * @return bool Returns true if the version has a build string, false otherwise */ public function hasBuild(): bool { return ! empty($this->build); } } ================================================ FILE: tests/VersionTest.php ================================================ > */ public static function pre_release_comparison_provider(): array { return [ ['v1.3.37', 'v1.3.37-alpha'], ['v1.3.37', 'v1.3.37-alpha.5+007'], ['v1.3.0', 'v1.3.0-beta'], ['v1.0.0', 'v1.0.0-rc1'], // Test cases from http://semver.org ['1.0.0', '1.0.0-rc.1'], ['1.0.0-rc.1', '1.0.0-beta.11'], ['1.0.0-beta.11', '1.0.0-beta.2'], ['1.0.0-beta.2', '1.0.0-beta'], ['1.0.0-beta', '1.0.0-alpha.beta'], ['1.0.0-alpha.beta', '1.0.0-alpha.1'], ['1.0.0-alpha.1', '1.0.0-alpha'], ]; } #[Test] public function it_can_be_initialized(): void { $version = new SemVer\Version('v1.3.37'); $this->assertInstanceOf(SemVer\Version::class, $version); } #[Test] public function it_can_be_initialized_with_the_helper_function(): void { $version = semver('v1.3.37'); $this->assertInstanceOf(SemVer\Version::class, $version); } #[Test] public function it_throws_a_runtime_exception_for_an_invalid_version(): void { $this->expectException(InvalidVersionException::class); new SemVer\Version('not.a.version'); } #[Test] public function it_can_parse_an_incomplete_version_string(): void { $this->assertEquals('1.0.0', (string) SemVer\Version::parse('v1')); $this->assertEquals('1.3.0', (string) SemVer\Version::parse('v1.3')); $this->assertEquals('1.3.37', (string) SemVer\Version::parse('v1.3.37')); $this->assertEquals('1.0.0-alpha.5', (string) SemVer\Version::parse('v1-alpha.5')); $this->assertEquals('1.3.0-alpha.5', (string) SemVer\Version::parse('v1.3-alpha.5')); $this->assertEquals('1.3.37-alpha.5', (string) SemVer\Version::parse('v1.3.37-alpha.5')); $this->assertEquals('1.0.0+007', (string) SemVer\Version::parse('v1+007')); $this->assertEquals('1.3.0+007', (string) SemVer\Version::parse('v1.3+007')); $this->assertEquals('1.3.37+007', (string) SemVer\Version::parse('v1.3.37+007')); } #[Test] public function it_throws_a_runtime_exception_when_parsing_an_invalid_version(): void { $this->expectException(InvalidVersionException::class); SemVer\Version::parse('not.a.version'); } #[Test] public function it_can_set_and_retrieve_a_version(): void { $version = new SemVer\Version('v1.3.37'); $version->setVersion('v2.4.48'); $this->assertEquals('2.4.48', (string) $version); } #[Test] public function it_can_return_a_prefixed_version_string(): void { $version = new SemVer\Version('v1.3.37'); $this->assertEquals('v1.3.37', $version->prefix()); $this->assertEquals('x1.3.37', $version->prefix('x')); } #[Test] public function it_can_be_cast_to_a_string(): void { $this->assertEquals('1.3.37', (string) new SemVer\Version('v1.3.37')); $this->assertEquals('1.3.37-alpha.5', (string) new SemVer\Version('v1.3.37-alpha.5')); $this->assertEquals('1.3.37+007', (string) new SemVer\Version('v1.3.37+007')); $this->assertEquals('1.3.37-alpha.5+007', (string) new SemVer\Version('v1.3.37-alpha.5+007')); } #[Test] public function it_can_get_individual_properties(): void { $version = new SemVer\Version('v1.3.37-alpha.5+007'); $this->assertEquals(1, $version->major); $this->assertEquals(3, $version->minor); $this->assertEquals(37, $version->patch); $this->assertEquals('alpha.5', $version->preRelease); $this->assertEquals('007', $version->build); } #[Test] public function it_can_increment_major(): void { $version = new SemVer\Version('v1.3.37'); $version->incrementMajor(); $this->assertEquals('2.0.0', (string) $version); } #[Test] public function it_can_set_major(): void { $version = new SemVer\Version('v1.3.37'); $version->setMajor(7); $this->assertEquals('7.0.0', (string) $version); } #[Test] public function it_can_increment_minor(): void { $version = new SemVer\Version('v1.3.37'); $version->incrementMinor(); $this->assertEquals('1.4.0', (string) $version); } #[Test] public function it_can_set_minor(): void { $version = new SemVer\Version('v1.3.37'); $version->setMinor(5); $this->assertEquals('1.5.0', (string) $version); } #[Test] public function it_can_increment_patch(): void { $version = new SemVer\Version('v1.3.37'); $version->incrementPatch(); $this->assertEquals('1.3.38', (string) $version); } #[Test] public function it_can_increment_prerelease(): void { $version = new SemVer\Version('v1.3.37'); $version->setPreRelease('alpha.5'); $version->incrementPreRelease(); $this->assertEquals('1.3.37-alpha.6', (string) $version); } #[Test] public function it_can_increment_prerelease_without_number(): void { $version = new SemVer\Version('v1.3.37'); $version->setPreRelease('alpha'); $version->incrementPreRelease(); $this->assertEquals('1.3.37-alpha.1', (string) $version); } #[Test] public function it_can_increment_prerelease_without_prefix_for_prerelease(): void { $version = new SemVer\Version('v1.3.37'); $version->setPreRelease('5'); $version->incrementPreRelease(); $this->assertEquals('1.3.37-6', (string) $version); } #[Test] public function it_can_increment_prerelease_containing_multiple_dots(): void { $version = new SemVer\Version('v1.3.37'); $version->setPreRelease('alpha.a.b.5'); $version->incrementPreRelease(); $this->assertEquals('1.3.37-alpha.a.b.6', (string) $version); } #[Test] public function it_can_increment_prerelease_containing_multiple_dots_and_without_number(): void { $version = new SemVer\Version('v1.3.37'); $version->setPreRelease('alpha.a.b'); $version->incrementPreRelease(); $this->assertEquals('1.3.37-alpha.a.b.1', (string) $version); } #[Test] public function it_can_increment_prerelease_and_patch_when_prerelease_is_null(): void { $version = new SemVer\Version('v1.3.37'); $version->incrementPreRelease(); $this->assertEquals('1.3.38-1', (string) $version); } #[Test] public function it_can_set_patch(): void { $version = new SemVer\Version('v1.3.37'); $version->setPatch(12); $this->assertEquals('1.3.12', (string) $version); } #[Test] public function it_can_set_pre_release(): void { $version = new SemVer\Version('v1.3.37'); $version->setPreRelease('alpha.5'); $this->assertEquals('1.3.37-alpha.5', (string) $version); } #[Test] public function it_can_unset_pre_release(): void { $version = (new SemVer\Version('v1.3.37-alpha.5'))->setPreRelease(null); $this->assertNull($version->preRelease); } #[Test] public function it_can_set_build(): void { $version = new SemVer\Version('v1.3.37'); $version->setBuild('007'); $this->assertEquals('1.3.37+007', (string) $version); } #[Test] public function it_can_unset_build(): void { $version = (new SemVer\Version('v1.3.37+007'))->setBuild(null); $this->assertNull($version->build); } #[Test] public function it_can_be_greater_than_another_semver_object(): void { $version = new SemVer\Version('v1.3.37'); $this->assertTrue($version->gt(new SemVer\Version('v0.5.0'))); $this->assertTrue($version->gt(new SemVer\Version('v1.3.36'))); $this->assertFalse($version->gt(new SemVer\Version('v1.3.38'))); $this->assertFalse($version->gt(new SemVer\Version('v1.3.37'))); } #[Test] public function it_can_be_less_than_another_semver_object(): void { $version = new SemVer\Version('v1.3.37'); $this->assertTrue($version->lt(new SemVer\Version('v1.3.38'))); $this->assertTrue($version->lt(new SemVer\Version('v1.4.0'))); $this->assertFalse($version->lt(new SemVer\Version('v1.3.36'))); $this->assertFalse($version->lt(new SemVer\Version('v1.3.37'))); } #[Test] public function it_can_be_equal_to_another_semver_object(): void { $version = new SemVer\Version('v1.3.37'); $this->assertTrue($version->eq(new SemVer\Version('v1.3.37'))); $this->assertFalse($version->eq(new SemVer\Version('v1.2.3'))); } #[Test] public function it_can_be_not_equal_to_another_semver_object(): void { $version = new SemVer\Version('v1.3.37'); $this->assertTrue($version->neq(new SemVer\Version('v1.2.3'))); $this->assertFalse($version->neq(new SemVer\Version('v1.3.37'))); } #[Test] public function it_can_be_greater_than_or_equal_to_another_semver_object(): void { $version = new SemVer\Version('v1.3.37'); $this->assertTrue($version->gte(new SemVer\Version('v1.2.3'))); $this->assertTrue($version->gte(new SemVer\Version('v1.3.37'))); $this->assertFalse($version->gte(new SemVer\Version('v2.3.4'))); } #[Test] public function it_can_be_less_than_or_equal_to_another_semver_object(): void { $version = new SemVer\Version('v1.3.37'); $this->assertTrue($version->lte(new SemVer\Version('v2.3.4'))); $this->assertTrue($version->lte(new SemVer\Version('v1.3.37'))); $this->assertFalse($version->lte(new SemVer\Version('v1.2.3'))); } #[Test] public function it_can_be_greater_than_another_semver_object_using_major(): void { $version = new SemVer\Version('v2.3.37'); $this->assertTrue($version->gt(new SemVer\Version('v0.5.0'), Compare::MAJOR)); $this->assertTrue($version->gt(new SemVer\Version('v1.3.38'), Compare::MAJOR)); $this->assertFalse($version->gt(new SemVer\Version('v2.3.36'), Compare::MAJOR)); $this->assertFalse($version->gt(new SemVer\Version('v3.3.36'), Compare::MAJOR)); } #[Test] public function it_can_be_less_than_another_semver_object_using_major(): void { $version = new SemVer\Version('v2.3.37'); $this->assertTrue($version->lt(new SemVer\Version('v3.3.38'), Compare::MAJOR)); $this->assertFalse($version->lt(new SemVer\Version('v2.3.36'), Compare::MAJOR)); $this->assertFalse($version->lt(new SemVer\Version('v1.3.37'), Compare::MAJOR)); } #[Test] public function it_can_be_equal_to_another_semver_object_using_major(): void { $version = new SemVer\Version('v1.3.37-alpha.5'); $this->assertTrue($version->eq(new SemVer\Version('v1.3.37-alpha.4'), Compare::MAJOR)); $this->assertTrue($version->eq(new SemVer\Version('v1.2.3'), Compare::MAJOR)); } #[Test] public function it_can_be_not_equal_to_another_semver_object_using_major(): void { $version = new SemVer\Version('v2.3.37'); $this->assertTrue($version->neq(new SemVer\Version('v3.2.3'), Compare::MAJOR)); $this->assertFalse($version->neq(new SemVer\Version('v2.2.3'), Compare::MAJOR)); $this->assertTrue($version->neq(new SemVer\Version('v1.3.37'), Compare::MAJOR)); } #[Test] public function it_can_be_greater_than_or_equal_to_another_semver_object_using_major(): void { $version = new SemVer\Version('v3.3.37-alpha.5'); $this->assertTrue($version->gte(new SemVer\Version('v1.3.4'), Compare::MAJOR)); $this->assertTrue($version->gte(new SemVer\Version('v2.3.37-alpha.6'), Compare::MAJOR)); $this->assertTrue($version->gte(new SemVer\Version('v3.2.3'), Compare::MAJOR)); $this->assertFalse($version->gte(new SemVer\Version('v4.2.3'), Compare::MAJOR)); } #[Test] public function it_can_be_less_than_or_equal_to_another_semver_object_using_major(): void { $version = new SemVer\Version('v2.3.37-alpha.5'); $this->assertTrue($version->lte(new SemVer\Version('v3.2.3'), Compare::MAJOR)); $this->assertTrue($version->lte(new SemVer\Version('v2.3.37-alpha.4'), Compare::MAJOR)); $this->assertFalse($version->lte(new SemVer\Version('v1.3.4'), Compare::MAJOR)); } #[Test] public function it_can_be_greater_than_another_semver_object_using_minor(): void { $version = new SemVer\Version('v1.3.37-alpha.5'); $this->assertTrue($version->gt(new SemVer\Version('v0.5.0'), Compare::MINOR)); $this->assertTrue($version->gt(new SemVer\Version('v1.2.40'), Compare::MINOR)); $this->assertFalse($version->gt(new SemVer\Version('v1.3.38-alpha.5'), Compare::MINOR)); $this->assertFalse($version->gt(new SemVer\Version('v1.4.0'), Compare::MINOR)); } #[Test] public function it_can_be_less_than_another_semver_object_using_minor(): void { $version = new SemVer\Version('v1.3.37-alpha.5'); $this->assertTrue($version->lt(new SemVer\Version('v1.4.38'), Compare::MINOR)); $this->assertTrue($version->lt(new SemVer\Version('v1.4.0'), Compare::MINOR)); $this->assertFalse($version->lt(new SemVer\Version('v1.2.36'), Compare::MINOR)); $this->assertFalse($version->lt(new SemVer\Version('v1.3.37-alpha.6'), Compare::MINOR)); } #[Test] public function it_can_be_equal_to_another_semver_object_using_minor(): void { $version = new SemVer\Version('v1.3.37-alpha.5'); $this->assertFalse($version->eq(new SemVer\Version('v1.4.3'), Compare::MINOR)); $this->assertTrue($version->eq(new SemVer\Version('v1.3.37-alpha.4'), Compare::MINOR)); $this->assertFalse($version->eq(new SemVer\Version('v1.2.3'), Compare::MINOR)); } #[Test] public function it_can_be_not_equal_to_another_semver_object_using_minor(): void { $version = new SemVer\Version('v1.3.37-alpha.5'); $this->assertTrue($version->neq(new SemVer\Version('v1.2.37-alpha.5'), Compare::MINOR)); $this->assertFalse($version->neq(new SemVer\Version('v1.3.37-alpha.6'), Compare::MINOR)); $this->assertTrue($version->neq(new SemVer\Version('v1.4.37'), Compare::MINOR)); } #[Test] public function it_can_be_greater_than_or_equal_to_another_semver_object_using_minor(): void { $version = new SemVer\Version('v1.3.37-alpha.5'); $this->assertTrue($version->gte(new SemVer\Version('v1.3.38-alpha.4'), Compare::MINOR)); $this->assertTrue($version->gte(new SemVer\Version('v1.2.3'), Compare::MINOR)); $this->assertFalse($version->gte(new SemVer\Version('v1.4.4'), Compare::MINOR)); $this->assertFalse($version->gte(new SemVer\Version('v2.3.4'), Compare::MINOR)); } #[Test] public function it_can_be_less_than_or_equal_to_another_semver_object_using_minor(): void { $version = new SemVer\Version('v1.3.37-alpha.5'); $this->assertTrue($version->lte(new SemVer\Version('v2.3.4'), Compare::MINOR)); $this->assertTrue($version->lte(new SemVer\Version('v1.3.37'), Compare::MINOR)); $this->assertTrue($version->lte(new SemVer\Version('v1.3.36'), Compare::MINOR)); $this->assertFalse($version->lte(new SemVer\Version('v1.2.37-alpha.5'), Compare::MINOR)); } #[Test] public function it_can_be_greater_than_another_semver_object_using_patch(): void { $version = new SemVer\Version('v1.3.37-alpha.5'); $this->assertTrue($version->gt(new SemVer\Version('v0.5.0'), Compare::PATCH)); $this->assertTrue($version->gt(new SemVer\Version('v1.3.36'), Compare::PATCH)); $this->assertFalse($version->gt(new SemVer\Version('v1.3.38'), Compare::PATCH)); $this->assertFalse($version->gt(new SemVer\Version('v1.3.37-alpha.4'), Compare::PATCH)); } #[Test] public function it_can_be_less_than_another_semver_object_using_patch(): void { $version = new SemVer\Version('v1.3.37-alpha.5'); $this->assertTrue($version->lt(new SemVer\Version('v1.3.38'), Compare::PATCH)); $this->assertTrue($version->lt(new SemVer\Version('v1.4.0'), Compare::PATCH)); $this->assertFalse($version->lt(new SemVer\Version('v1.3.36'), Compare::PATCH)); $this->assertFalse($version->lt(new SemVer\Version('v1.3.37-alpha.6'), Compare::PATCH)); } #[Test] public function it_can_be_equal_to_another_semver_object_using_patch(): void { $version = new SemVer\Version('v1.3.37-alpha.5'); $this->assertTrue($version->eq(new SemVer\Version('v1.3.37-alpha.6'), Compare::PATCH)); $this->assertFalse($version->eq(new SemVer\Version('v1.2.3'), Compare::PATCH)); } #[Test] public function it_can_be_not_equal_to_another_semver_object_using_patch(): void { $version = new SemVer\Version('v1.3.37-alpha.5'); $this->assertTrue($version->neq(new SemVer\Version('v1.2.3'), Compare::PATCH)); $this->assertFalse($version->neq(new SemVer\Version('v1.3.37-alpha.6'), Compare::PATCH)); } #[Test] public function it_can_be_greater_than_or_equal_to_another_semver_object_using_patch(): void { $version = new SemVer\Version('v1.3.37-alpha.5'); $this->assertTrue($version->gte(new SemVer\Version('v1.2.3'), Compare::PATCH)); $this->assertTrue($version->gte(new SemVer\Version('v1.3.37-alpha.6'), Compare::PATCH)); $this->assertFalse($version->gte(new SemVer\Version('v2.3.4'), Compare::PATCH)); } #[Test] public function it_can_be_less_than_or_equal_to_another_semver_object_using_patch(): void { $version = new SemVer\Version('v1.3.37-alpha.5'); $this->assertTrue($version->lte(new SemVer\Version('v2.3.4'), Compare::PATCH)); $this->assertTrue($version->lte(new SemVer\Version('v1.3.37-alpha.4'), Compare::PATCH)); $this->assertFalse($version->lte(new SemVer\Version('v1.2.3'), Compare::PATCH)); } #[Test] public function setting_the_major_version_resets_appropriate_properties(): void { $version = new SemVer\Version('v1.3.37-alpha.5+007'); $version->setMajor(2); $this->assertEquals(2, $version->major); $this->assertEquals(0, $version->minor); $this->assertEquals(0, $version->patch); $this->assertNull($version->preRelease); $this->assertNull($version->build); } #[Test] public function setting_the_minor_version_resets_appropriate_properties(): void { $version = new SemVer\Version('v1.3.37-alpha.5+007'); $version->setMinor(4); $this->assertEquals(1, $version->major); $this->assertEquals(4, $version->minor); $this->assertEquals(0, $version->patch); $this->assertNull($version->preRelease); $this->assertNull($version->build); } #[Test] public function setting_the_patch_version_resets_appropriate_properties(): void { $version = new SemVer\Version('v1.3.37-alpha.5+007'); $version->setPatch(38); $this->assertEquals(1, $version->major); $this->assertEquals(3, $version->minor); $this->assertEquals(38, $version->patch); $this->assertNull($version->preRelease); $this->assertNull($version->build); } #[Test] public function it_compares_pre_release_tags(): void { $alpha = new SemVer\Version('v1.3.37-alpha'); $beta = new SemVer\Version('v1.3.37-beta'); $this->assertTrue($alpha->lt($beta)); $this->assertFalse($alpha->gt($beta)); $this->assertTrue($alpha->lte($beta)); $this->assertFalse($alpha->gte($beta)); $this->assertFalse($alpha->eq($beta)); } #[Test] public function it_ignores_the_build_version_when_comparing_versions(): void { $oldBuild = new SemVer\Version('v1.3.37-alpha.5+006'); $newBuild = new SemVer\Version('v1.3.37-alpha.5+007'); $this->assertTrue($oldBuild->eq($newBuild)); $this->assertFalse($oldBuild->neq($newBuild)); $this->assertFalse($oldBuild->gt($newBuild)); $this->assertFalse($oldBuild->lt($newBuild)); $this->assertTrue($oldBuild->gte($newBuild)); $this->assertTrue($oldBuild->lte($newBuild)); $this->assertTrue((new SemVer\Version('v1.3.37'))->eq(new SemVer\Version('v1.3.37+007'))); } #[Test] #[\PHPUnit\Framework\Attributes\DataProvider('pre_release_comparison_provider')] public function it_compares_pre_release_tags_vs_release(string $release, string $prerelease): void { $release = new SemVer\Version($release); $prerelease = new SemVer\Version($prerelease); $this->assertFalse($release->eq($prerelease)); $this->assertFalse($release->lt($prerelease)); $this->assertFalse($release->lte($prerelease)); $this->assertTrue($release->gt($prerelease)); $this->assertTrue($release->gte($prerelease)); $this->assertFalse($prerelease->gt($release)); $this->assertFalse($prerelease->eq($release)); $this->assertFalse($prerelease->gte($release)); $this->assertTrue($prerelease->lt($release)); $this->assertTrue($prerelease->lte($release)); } #[Test] public function it_can_compare_two_versions(): void { $version1 = new SemVer\Version('v1.3.37'); $version2 = new SemVer\Version('v3.2.1'); // Major Comparisons $this->assertEquals(-1, SemVer\Version::compare(new SemVer\Version('v1.2.3'), new SemVer\Version('v3.2.1'))); $this->assertEquals(0, SemVer\Version::compare(new SemVer\Version('v1.2.3'), new SemVer\Version('v1.2.3'))); $this->assertEquals(1, SemVer\Version::compare(new SemVer\Version('v3.2.1'), new SemVer\Version('v1.2.3'))); // Minor Comparisons $this->assertEquals(-1, SemVer\Version::compare(new SemVer\Version('v0.1.2'), new SemVer\Version('v0.2.1'))); $this->assertEquals(0, SemVer\Version::compare(new SemVer\Version('v0.1.2'), new SemVer\Version('v0.1.2'))); $this->assertEquals(1, SemVer\Version::compare(new SemVer\Version('v0.2.1'), new SemVer\Version('v0.1.2'))); // Patch Comparisons $this->assertEquals(-1, SemVer\Version::compare(new SemVer\Version('v1.0.1'), new SemVer\Version('v1.0.2'))); $this->assertEquals(0, SemVer\Version::compare(new SemVer\Version('v1.0.0'), new SemVer\Version('v1.0.0'))); $this->assertEquals(1, SemVer\Version::compare(new SemVer\Version('v1.0.2'), new SemVer\Version('v1.0.1'))); } #[Test] public function it_can_be_serialized_to_json(): void { $version = new SemVer\Version('v1.3.37'); $this->assertInstanceOf(JsonSerializable::class, $version); $this->assertEquals('1.3.37', $version->jsonSerialize()); } #[Test] public function it_can_determine_if_it_is_a_pre_release(): void { $version = new SemVer\Version('v1.3.37-alpha.5+007'); $this->assertTrue($version->isPreRelease()); } #[Test] public function can_determine_if_it_is_not_a_pre_release(): void { $version = new SemVer\Version('v1.3.37+007'); $this->assertFalse($version->isPreRelease()); } #[Test] public function can_determine_if_it_has_a_build_string(): void { $version = new SemVer\Version('v1.3.37-alpha.5+007'); $this->assertTrue($version->hasBuild()); } #[Test] public function it_can_determine_if_it_has_a_build_string(): void { $version = new SemVer\Version('v1.3.37-alpha'); $this->assertFalse($version->hasBuild()); } }