diff --git a/src/Enum.php b/src/Enum.php index 92a42a4..3790f6e 100644 --- a/src/Enum.php +++ b/src/Enum.php @@ -61,14 +61,24 @@ public function __construct($value) $value = $value->getValue(); } - if (!$this->isValid($value)) { - throw new \UnexpectedValueException("Value '$value' is not part of the enum " . static::class); - } + static::assertValidValue($value); /** @psalm-var T */ $this->value = $value; } + /** + * @param mixed $value + * @return static + * @psalm-return static + */ + public static function from($value): self + { + static::assertValidValue($value); + + return new static($value); + } + /** * @psalm-pure * @return mixed @@ -175,6 +185,7 @@ public static function toArray() * @param $value * @psalm-param mixed $value * @psalm-pure + * @psalm-assert-if-true T $value * @return bool */ public static function isValid($value) @@ -182,6 +193,19 @@ public static function isValid($value) return \in_array($value, static::toArray(), true); } + /** + * Asserts valid enum value + * + * @psalm-pure + * @psalm-assert T $value + */ + public static function assertValidValue($value): void + { + if (!static::isValid($value)) { + throw new \UnexpectedValueException("Value '$value' is not part of the enum " . static::class); + } + } + /** * Check if is valid enum key * diff --git a/tests/EnumTest.php b/tests/EnumTest.php index cb08d29..674b977 100755 --- a/tests/EnumTest.php +++ b/tests/EnumTest.php @@ -48,6 +48,18 @@ public function testCreatingEnumWithInvalidValue($value) new EnumFixture($value); } + /** + * @dataProvider invalidValueProvider + * @param mixed $value + */ + public function testFailToCreateEnumWithInvalidValueThroughNamedConstructor($value): void + { + $this->expectException(\UnexpectedValueException::class); + $this->expectExceptionMessage('is not part of the enum MyCLabs\Tests\Enum\EnumFixture'); + + EnumFixture::from($value); + } + /** * Contains values not existing in EnumFixture * @return array @@ -332,4 +344,19 @@ public function testEnumValuesInheritance() $inheritedEnumFixture = InheritedEnumFixture::VALUE(); new EnumFixture($inheritedEnumFixture); } + + /** + * @dataProvider isValidProvider + */ + public function testAssertValidValue($value, $isValid): void + { + if (!$isValid) { + $this->expectException(\UnexpectedValueException::class); + $this->expectExceptionMessage("Value '$value' is not part of the enum " . EnumFixture::class); + } + + EnumFixture::assertValidValue($value); + + self::assertTrue(EnumFixture::isValid($value)); + } }