diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c90d13..8d0c284 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,10 +12,12 @@ For a full diff see [`64ced12...main`][64ced12...main]. - Added `Version` as a value object ([#1]), by [@localheinz] - Added `Major` as a value object ([#3]), by [@localheinz] +- Added `Minor` as a value object ([#4]), by [@localheinz] [64ced12...main]: https://github.com/ergebnis/version/compare/64ced12...main [#1]: https://github.com/ergebnis/version/pull/1 [#3]: https://github.com/ergebnis/version/pull/3 +[#4]: https://github.com/ergebnis/version/pull/4 [@localheinz]: https://github.com/localheinz diff --git a/README.md b/README.md index b0a2de9..f8007c2 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ $version = Version\Version::fromString('1.2.3'); echo $version->toString(); // 1.2.3 echo $version->major()->toString(); // 1 +echo $version->minor()->toString(); // 2 ``` ### Compare a `Version` with another `Version` @@ -90,6 +91,39 @@ $one->equals($three); // false $one->equals($two); // true ``` +### Create a `Minor` from a `string` + +```php +toString(); // 1 +``` + +### Compare a `Minor` with another `Minor` + +```php +equals($two); // true +$one->equals($three); // false + +$one->equals($two); // true +``` + ## Changelog The maintainers of this project record notable changes to this project in a [changelog](CHANGELOG.md). diff --git a/psalm-baseline.xml b/psalm-baseline.xml index b132131..441f0f0 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -6,6 +6,12 @@ provideValidValue + + + provideInvalidValue + provideValidValue + + provideInvalidValue diff --git a/src/Exception/InvalidMinor.php b/src/Exception/InvalidMinor.php new file mode 100644 index 0000000..a5cac14 --- /dev/null +++ b/src/Exception/InvalidMinor.php @@ -0,0 +1,25 @@ +0|[1-9]\d*)$/'; + + private function __construct(private readonly string $value) + { + } + + /** + * @throws Exception\InvalidMinor + */ + public static function fromString(string $value): self + { + if (1 !== \preg_match(self::REGEX, $value)) { + throw Exception\InvalidMinor::fromString($value); + } + + return new self($value); + } + + public function toString(): string + { + return $this->value; + } + + public function equals(self $other): bool + { + return $this->value === $other->value; + } +} diff --git a/src/Version.php b/src/Version.php index 9bdc4d3..3b124e4 100644 --- a/src/Version.php +++ b/src/Version.php @@ -24,6 +24,7 @@ final class Version private function __construct( private readonly string $value, private readonly Major $major, + private readonly Minor $minor, ) { } @@ -39,6 +40,7 @@ public static function fromString(string $value): self return new self( $value, Major::fromString($matches['major']), + Minor::fromString($matches['minor']), ); } @@ -56,4 +58,9 @@ public function major(): Major { return $this->major; } + + public function minor(): Minor + { + return $this->minor; + } } diff --git a/test/Unit/Exception/InvalidMinorTest.php b/test/Unit/Exception/InvalidMinorTest.php new file mode 100644 index 0000000..9c1b85e --- /dev/null +++ b/test/Unit/Exception/InvalidMinorTest.php @@ -0,0 +1,38 @@ +word(); + + $exception = Exception\InvalidMinor::fromString($value); + + $message = \sprintf( + 'Value "%s" does not appear to be valid.', + $value, + ); + + self::assertSame($message, $exception->getMessage()); + } +} diff --git a/test/Unit/MinorTest.php b/test/Unit/MinorTest.php new file mode 100644 index 0000000..e010d3c --- /dev/null +++ b/test/Unit/MinorTest.php @@ -0,0 +1,107 @@ +expectException(Exception\InvalidMinor::class); + + Minor::fromString($value); + } + + /** + * @see https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string + * @see https://regex101.com/r/Ly7O1x/3/ + * + * @return Generator + */ + public static function provideInvalidValue(): Generator + { + $faker = self::faker(); + + $values = [ + 'leading-zero' => \sprintf( + '0%d', + $faker->numberBetween(1), + ), + 'word' => $faker->word(), + ]; + + foreach ($values as $value) { + yield $value => [ + $value, + ]; + } + } + + #[Framework\Attributes\DataProvider('provideValidValue')] + public function testFromStringReturnsMinor(string $value): void + { + $minor = Minor::fromString($value); + + self::assertSame($value, $minor->toString()); + } + + /** + * @see https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string + * @see https://regex101.com/r/Ly7O1x/3/ + * + * @return Generator + */ + public static function provideValidValue(): Generator + { + $values = [ + 'zero' => '0', + 'one' => '1', + 'greater-than-one' => (string) self::faker()->numberBetween(2), + ]; + + foreach ($values as $key => $value) { + yield $key => [ + $value, + ]; + } + } + + public function testEqualsReturnsFalseWhenValuesAreDifferent(): void + { + $faker = self::faker()->unique(); + + $one = Minor::fromString((string) $faker->numberBetween(0)); + $two = Minor::fromString((string) $faker->numberBetween(0)); + + self::assertFalse($one->equals($two)); + } + + public function testEqualsReturnsTrueWhenValueIsSame(): void + { + $value = (string) self::faker()->numberBetween(0); + + $one = Minor::fromString($value); + $two = Minor::fromString($value); + + self::assertTrue($one->equals($two)); + } +} diff --git a/test/Unit/VersionTest.php b/test/Unit/VersionTest.php index 970d351..04eb50a 100644 --- a/test/Unit/VersionTest.php +++ b/test/Unit/VersionTest.php @@ -15,6 +15,7 @@ use Ergebnis\Version\Exception; use Ergebnis\Version\Major; +use Ergebnis\Version\Minor; use Ergebnis\Version\Test; use Ergebnis\Version\Version; use PHPUnit\Framework; @@ -22,6 +23,7 @@ #[Framework\Attributes\CoversClass(Version::class)] #[Framework\Attributes\UsesClass(Exception\InvalidVersion::class)] #[Framework\Attributes\UsesClass(Major::class)] +#[Framework\Attributes\UsesClass(Minor::class)] final class VersionTest extends Framework\TestCase { use Test\Util\Helper; @@ -95,122 +97,156 @@ public static function provideInvalidValue(): \Generator public function testFromStringReturnsVersion( string $value, Major $major, + Minor $minor, ): void { $version = Version::fromString($value); self::assertSame($value, $version->toString()); self::assertEquals($major, $version->major()); + self::assertEquals($minor, $version->minor()); } /** * @see https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string * @see https://regex101.com/r/Ly7O1x/3/ * - * @return \Generator + * @return \Generator */ public static function provideValidValue(): \Generator { $values = [ '0.0.4' => [ Major::fromString('0'), + Minor::fromString('0'), ], '1.2.3' => [ Major::fromString('1'), + Minor::fromString('2'), ], '10.20.30' => [ Major::fromString('10'), + Minor::fromString('20'), ], '1.1.2-prerelease+meta' => [ Major::fromString('1'), + Minor::fromString('1'), ], '1.1.2+meta' => [ Major::fromString('1'), + Minor::fromString('1'), ], '1.1.2+meta-valid' => [ Major::fromString('1'), + Minor::fromString('1'), ], '1.0.0-alpha' => [ Major::fromString('1'), + Minor::fromString('0'), ], '1.0.0-beta' => [ Major::fromString('1'), + Minor::fromString('0'), ], '1.0.0-alpha.beta' => [ Major::fromString('1'), + Minor::fromString('0'), ], '1.0.0-alpha.beta.1' => [ Major::fromString('1'), + Minor::fromString('0'), ], '1.0.0-alpha.1' => [ Major::fromString('1'), + Minor::fromString('0'), ], '1.0.0-alpha0.valid' => [ Major::fromString('1'), + Minor::fromString('0'), ], '1.0.0-alpha.0valid' => [ Major::fromString('1'), + Minor::fromString('0'), ], '1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay' => [ Major::fromString('1'), + Minor::fromString('0'), ], '1.0.0-rc.1+build.1' => [ Major::fromString('1'), + Minor::fromString('0'), ], '2.0.0-rc.1+build.123' => [ Major::fromString('2'), + Minor::fromString('0'), ], '1.2.3-beta' => [ Major::fromString('1'), + Minor::fromString('2'), ], '10.2.3-DEV-SNAPSHOT' => [ Major::fromString('10'), + Minor::fromString('2'), ], '1.2.3-SNAPSHOT-123' => [ Major::fromString('1'), + Minor::fromString('2'), ], '1.0.0' => [ Major::fromString('1'), + Minor::fromString('0'), ], '2.0.0' => [ Major::fromString('2'), + Minor::fromString('0'), ], '1.1.7' => [ Major::fromString('1'), + Minor::fromString('1'), ], '2.0.0+build.1848' => [ Major::fromString('2'), + Minor::fromString('0'), ], '2.0.1-alpha.1227' => [ Major::fromString('2'), + Minor::fromString('0'), ], '1.0.0-alpha+beta' => [ Major::fromString('1'), + Minor::fromString('0'), ], '1.2.3----RC-SNAPSHOT.12.9.1--.12+788' => [ Major::fromString('1'), + Minor::fromString('2'), ], '1.2.3----R-S.12.9.1--.12+meta' => [ Major::fromString('1'), + Minor::fromString('2'), ], '1.2.3----RC-SNAPSHOT.12.9.1--.12' => [ Major::fromString('1'), + Minor::fromString('2'), ], '1.0.0+0.build.1-rc.10000aaa-kk-0.1' => [ Major::fromString('1'), + Minor::fromString('0'), ], '99999999999999999999999.999999999999999999.99999999999999999' => [ Major::fromString('99999999999999999999999'), + Minor::fromString('999999999999999999'), ], '1.0.0-0A.is.legal' => [ Major::fromString('1'), + Minor::fromString('0'), ], ]; - foreach ($values as $value => [$major]) { + foreach ($values as $value => [$major, $minor]) { yield $value => [ $value, $major, + $minor, ]; } }