From eda1816d04b1cfe2feba376c8c527d0ed6d63843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Mon, 25 Dec 2023 16:16:15 +0100 Subject: [PATCH] Enhancement: Allow creating Major, Minor, and Patch from int --- README.md | 42 ++++++++++++++++++++++++ psalm-baseline.xml | 12 +++---- src/Exception/InvalidMajor.php | 8 +++++ src/Exception/InvalidMinor.php | 8 +++++ src/Exception/InvalidPatch.php | 8 +++++ src/Major.php | 23 +++++++++++-- src/Minor.php | 23 +++++++++++-- src/Patch.php | 23 +++++++++++-- test/Unit/Exception/InvalidMajorTest.php | 14 ++++++++ test/Unit/Exception/InvalidMinorTest.php | 14 ++++++++ test/Unit/Exception/InvalidPatchTest.php | 14 ++++++++ test/Unit/MajorTest.php | 28 +++++++++++++--- test/Unit/MinorTest.php | 28 +++++++++++++--- test/Unit/PatchTest.php | 28 +++++++++++++--- 14 files changed, 243 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 29d21df..201b7a3 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,20 @@ $one->equals($two); // true $one->equals($three); // false ``` +### Create a `Major` from an `int` + +```php +toInt(); // 1 +``` + ### Create a `Major` from a `string` ```php @@ -94,6 +108,20 @@ $one->equals($three); // false $one->equals($two); // true ``` +### Create a `Minor` from an `int` + +```php +toInt(); // 1 +``` + ### Create a `Minor` from a `string` ```php @@ -127,6 +155,20 @@ $one->equals($three); // false $one->equals($two); // true ``` +### Create a `Patch` from an `int` + +```php +toInt(); // 1 +``` + ### Create a `Patch` from a `string` ```php diff --git a/psalm-baseline.xml b/psalm-baseline.xml index f1962e5..11a25e4 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -8,20 +8,20 @@ - provideInvalidValue - provideValidValue + provideInvalidStringValue + provideValidStringValue - provideInvalidValue - provideValidValue + provideInvalidStringValue + provideValidStringValue - provideInvalidValue - provideValidValue + provideInvalidStringValue + provideValidStringValue diff --git a/src/Exception/InvalidMajor.php b/src/Exception/InvalidMajor.php index 5d00a78..ab99092 100644 --- a/src/Exception/InvalidMajor.php +++ b/src/Exception/InvalidMajor.php @@ -15,6 +15,14 @@ final class InvalidMajor extends \InvalidArgumentException { + public static function fromInt(int $value): self + { + return new self(\sprintf( + 'Value "%d" does not appear to be valid.', + $value, + )); + } + public static function fromString(string $value): self { return new self(\sprintf( diff --git a/src/Exception/InvalidMinor.php b/src/Exception/InvalidMinor.php index a5cac14..0d4d703 100644 --- a/src/Exception/InvalidMinor.php +++ b/src/Exception/InvalidMinor.php @@ -15,6 +15,14 @@ final class InvalidMinor extends \InvalidArgumentException { + public static function fromInt(int $value): self + { + return new self(\sprintf( + 'Value "%d" does not appear to be valid.', + $value, + )); + } + public static function fromString(string $value): self { return new self(\sprintf( diff --git a/src/Exception/InvalidPatch.php b/src/Exception/InvalidPatch.php index 90cb5a4..8af237c 100644 --- a/src/Exception/InvalidPatch.php +++ b/src/Exception/InvalidPatch.php @@ -15,6 +15,14 @@ final class InvalidPatch extends \InvalidArgumentException { + public static function fromInt(int $value): self + { + return new self(\sprintf( + 'Value "%d" does not appear to be valid.', + $value, + )); + } + public static function fromString(string $value): self { return new self(\sprintf( diff --git a/src/Major.php b/src/Major.php index c375084..4eb86bf 100644 --- a/src/Major.php +++ b/src/Major.php @@ -21,10 +21,22 @@ final class Major */ private const REGEX = '/^(?P0|[1-9]\d*)$/'; - private function __construct(private readonly string $value) + private function __construct(private readonly int $value) { } + /** + * @throws Exception\InvalidMajor + */ + public static function fromInt(int $value): self + { + if (0 > $value) { + throw Exception\InvalidMajor::fromInt($value); + } + + return new self($value); + } + /** * @throws Exception\InvalidMajor */ @@ -34,14 +46,19 @@ public static function fromString(string $value): self throw Exception\InvalidMajor::fromString($value); } - return new self($value); + return new self((int) $value); } - public function toString(): string + public function toInt(): int { return $this->value; } + public function toString(): string + { + return (string) $this->value; + } + public function equals(self $other): bool { return $this->value === $other->value; diff --git a/src/Minor.php b/src/Minor.php index e7dd0a7..7240a31 100644 --- a/src/Minor.php +++ b/src/Minor.php @@ -21,10 +21,22 @@ final class Minor */ private const REGEX = '/^(?P0|[1-9]\d*)$/'; - private function __construct(private readonly string $value) + private function __construct(private readonly int $value) { } + /** + * @throws Exception\InvalidMinor + */ + public static function fromInt(int $value): self + { + if (0 > $value) { + throw Exception\InvalidMinor::fromInt($value); + } + + return new self($value); + } + /** * @throws Exception\InvalidMinor */ @@ -34,14 +46,19 @@ public static function fromString(string $value): self throw Exception\InvalidMinor::fromString($value); } - return new self($value); + return new self((int) $value); } - public function toString(): string + public function toInt(): int { return $this->value; } + public function toString(): string + { + return (string) $this->value; + } + public function equals(self $other): bool { return $this->value === $other->value; diff --git a/src/Patch.php b/src/Patch.php index ddfc2ae..7835daf 100644 --- a/src/Patch.php +++ b/src/Patch.php @@ -21,10 +21,22 @@ final class Patch */ private const REGEX = '/^(?P0|[1-9]\d*)$/'; - private function __construct(private readonly string $value) + private function __construct(private readonly int $value) { } + /** + * @throws Exception\InvalidPatch + */ + public static function fromInt(int $value): self + { + if (0 > $value) { + throw Exception\InvalidPatch::fromInt($value); + } + + return new self($value); + } + /** * @throws Exception\InvalidPatch */ @@ -34,14 +46,19 @@ public static function fromString(string $value): self throw Exception\InvalidPatch::fromString($value); } - return new self($value); + return new self((int) $value); } - public function toString(): string + public function toInt(): int { return $this->value; } + public function toString(): string + { + return (string) $this->value; + } + public function equals(self $other): bool { return $this->value === $other->value; diff --git a/test/Unit/Exception/InvalidMajorTest.php b/test/Unit/Exception/InvalidMajorTest.php index a5ecc28..388aea7 100644 --- a/test/Unit/Exception/InvalidMajorTest.php +++ b/test/Unit/Exception/InvalidMajorTest.php @@ -22,6 +22,20 @@ final class InvalidMajorTest extends Framework\TestCase { use Test\Util\Helper; + public function testFromIntReturnsException(): void + { + $value = self::faker()->numberBetween(0); + + $exception = Exception\InvalidMajor::fromInt($value); + + $message = \sprintf( + 'Value "%d" does not appear to be valid.', + $value, + ); + + self::assertSame($message, $exception->getMessage()); + } + public function testFromStringReturnsException(): void { $value = self::faker()->word(); diff --git a/test/Unit/Exception/InvalidMinorTest.php b/test/Unit/Exception/InvalidMinorTest.php index 9c1b85e..0b6035a 100644 --- a/test/Unit/Exception/InvalidMinorTest.php +++ b/test/Unit/Exception/InvalidMinorTest.php @@ -22,6 +22,20 @@ final class InvalidMinorTest extends Framework\TestCase { use Test\Util\Helper; + public function testFromIntReturnsException(): void + { + $value = self::faker()->numberBetween(0); + + $exception = Exception\InvalidMinor::fromInt($value); + + $message = \sprintf( + 'Value "%d" does not appear to be valid.', + $value, + ); + + self::assertSame($message, $exception->getMessage()); + } + public function testFromStringReturnsException(): void { $value = self::faker()->word(); diff --git a/test/Unit/Exception/InvalidPatchTest.php b/test/Unit/Exception/InvalidPatchTest.php index 3ace47d..c46a9e7 100644 --- a/test/Unit/Exception/InvalidPatchTest.php +++ b/test/Unit/Exception/InvalidPatchTest.php @@ -22,6 +22,20 @@ final class InvalidPatchTest extends Framework\TestCase { use Test\Util\Helper; + public function testFromIntReturnsException(): void + { + $value = self::faker()->numberBetween(0); + + $exception = Exception\InvalidPatch::fromInt($value); + + $message = \sprintf( + 'Value "%d" does not appear to be valid.', + $value, + ); + + self::assertSame($message, $exception->getMessage()); + } + public function testFromStringReturnsException(): void { $value = self::faker()->word(); diff --git a/test/Unit/MajorTest.php b/test/Unit/MajorTest.php index 11ed5b2..4114cb3 100644 --- a/test/Unit/MajorTest.php +++ b/test/Unit/MajorTest.php @@ -13,6 +13,7 @@ namespace Ergebnis\Version\Test\Unit; +use Ergebnis\DataProvider; use Ergebnis\Version\Exception; use Ergebnis\Version\Major; use Ergebnis\Version\Test; @@ -24,8 +25,25 @@ final class MajorTest extends Framework\TestCase { use Test\Util\Helper; - #[Framework\Attributes\DataProvider('provideInvalidValue')] - public function testFromStringRejectsInvalidValue(string $value): void + #[Framework\Attributes\DataProviderExternal(DataProvider\IntProvider::class, 'lessThanZero')] + public function testFromIntRejectsInvalidIntValue(int $value): void + { + $this->expectException(Exception\InvalidMajor::class); + + Major::fromInt($value); + } + + #[Framework\Attributes\DataProviderExternal(DataProvider\IntProvider::class, 'zero')] + #[Framework\Attributes\DataProviderExternal(DataProvider\IntProvider::class, 'greaterThanZero')] + public function testFromIntReturnsMajor(int $value): void + { + $major = Major::fromInt($value); + + self::assertSame($value, $major->toInt()); + } + + #[Framework\Attributes\DataProvider('provideInvalidStringValue')] + public function testFromStringRejectsInvalidStringValue(string $value): void { $this->expectException(Exception\InvalidMajor::class); @@ -38,7 +56,7 @@ public function testFromStringRejectsInvalidValue(string $value): void * * @return \Generator */ - public static function provideInvalidValue(): \Generator + public static function provideInvalidStringValue(): \Generator { $faker = self::faker(); @@ -57,7 +75,7 @@ public static function provideInvalidValue(): \Generator } } - #[Framework\Attributes\DataProvider('provideValidValue')] + #[Framework\Attributes\DataProvider('provideValidStringValue')] public function testFromStringReturnsMajor(string $value): void { $major = Major::fromString($value); @@ -71,7 +89,7 @@ public function testFromStringReturnsMajor(string $value): void * * @return \Generator */ - public static function provideValidValue(): \Generator + public static function provideValidStringValue(): \Generator { $values = [ 'zero' => '0', diff --git a/test/Unit/MinorTest.php b/test/Unit/MinorTest.php index d67f9b9..c25bdd5 100644 --- a/test/Unit/MinorTest.php +++ b/test/Unit/MinorTest.php @@ -13,6 +13,7 @@ namespace Ergebnis\Version\Test\Unit; +use Ergebnis\DataProvider; use Ergebnis\Version\Exception; use Ergebnis\Version\Minor; use Ergebnis\Version\Test; @@ -24,8 +25,25 @@ final class MinorTest extends Framework\TestCase { use Test\Util\Helper; - #[Framework\Attributes\DataProvider('provideInvalidValue')] - public function testFromStringRejectsInvalidValue(string $value): void + #[Framework\Attributes\DataProviderExternal(DataProvider\IntProvider::class, 'lessThanZero')] + public function testFromIntRejectsInvalidIntValue(int $value): void + { + $this->expectException(Exception\InvalidMinor::class); + + Minor::fromInt($value); + } + + #[Framework\Attributes\DataProviderExternal(DataProvider\IntProvider::class, 'zero')] + #[Framework\Attributes\DataProviderExternal(DataProvider\IntProvider::class, 'greaterThanZero')] + public function testFromIntReturnsMinor(int $value): void + { + $minor = Minor::fromInt($value); + + self::assertSame($value, $minor->toInt()); + } + + #[Framework\Attributes\DataProvider('provideInvalidStringValue')] + public function testFromStringRejectsInvalidStringValue(string $value): void { $this->expectException(Exception\InvalidMinor::class); @@ -38,7 +56,7 @@ public function testFromStringRejectsInvalidValue(string $value): void * * @return \Generator */ - public static function provideInvalidValue(): \Generator + public static function provideInvalidStringValue(): \Generator { $faker = self::faker(); @@ -57,7 +75,7 @@ public static function provideInvalidValue(): \Generator } } - #[Framework\Attributes\DataProvider('provideValidValue')] + #[Framework\Attributes\DataProvider('provideValidStringValue')] public function testFromStringReturnsMinor(string $value): void { $minor = Minor::fromString($value); @@ -71,7 +89,7 @@ public function testFromStringReturnsMinor(string $value): void * * @return \Generator */ - public static function provideValidValue(): \Generator + public static function provideValidStringValue(): \Generator { $values = [ 'zero' => '0', diff --git a/test/Unit/PatchTest.php b/test/Unit/PatchTest.php index e80625d..d5d67d7 100644 --- a/test/Unit/PatchTest.php +++ b/test/Unit/PatchTest.php @@ -13,6 +13,7 @@ namespace Ergebnis\Version\Test\Unit; +use Ergebnis\DataProvider; use Ergebnis\Version\Exception; use Ergebnis\Version\Patch; use Ergebnis\Version\Test; @@ -24,8 +25,25 @@ final class PatchTest extends Framework\TestCase { use Test\Util\Helper; - #[Framework\Attributes\DataProvider('provideInvalidValue')] - public function testFromStringRejectsInvalidValue(string $value): void + #[Framework\Attributes\DataProviderExternal(DataProvider\IntProvider::class, 'lessThanZero')] + public function testFromIntRejectsInvalidIntValue(int $value): void + { + $this->expectException(Exception\InvalidPatch::class); + + Patch::fromInt($value); + } + + #[Framework\Attributes\DataProviderExternal(DataProvider\IntProvider::class, 'zero')] + #[Framework\Attributes\DataProviderExternal(DataProvider\IntProvider::class, 'greaterThanZero')] + public function testFromIntReturnsPatch(int $value): void + { + $patch = Patch::fromInt($value); + + self::assertSame($value, $patch->toInt()); + } + + #[Framework\Attributes\DataProvider('provideInvalidStringValue')] + public function testFromStringRejectsInvalidStringValue(string $value): void { $this->expectException(Exception\InvalidPatch::class); @@ -38,7 +56,7 @@ public function testFromStringRejectsInvalidValue(string $value): void * * @return \Generator */ - public static function provideInvalidValue(): \Generator + public static function provideInvalidStringValue(): \Generator { $faker = self::faker(); @@ -57,7 +75,7 @@ public static function provideInvalidValue(): \Generator } } - #[Framework\Attributes\DataProvider('provideValidValue')] + #[Framework\Attributes\DataProvider('provideValidStringValue')] public function testFromStringReturnsPatch(string $value): void { $patch = Patch::fromString($value); @@ -71,7 +89,7 @@ public function testFromStringReturnsPatch(string $value): void * * @return \Generator */ - public static function provideValidValue(): \Generator + public static function provideValidStringValue(): \Generator { $values = [ 'zero' => '0',