-
-
Notifications
You must be signed in to change notification settings - Fork 76
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Restore annotation constraint in 8.1 (#216)
- Loading branch information
Showing
10 changed files
with
321 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<?php | ||
/* | ||
* This file is part of the FreshDoctrineEnumBundle. | ||
* | ||
* (c) Artem Henvald <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Fresh\DoctrineEnumBundle\Tests\Validator; | ||
|
||
use Fresh\DoctrineEnumBundle\Exception\InvalidArgumentException; | ||
use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\BasketballPositionType; | ||
use Fresh\DoctrineEnumBundle\Validator\Constraints\EnumType; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
/** | ||
* EnumTypeTest. | ||
* | ||
* @author Artem Henvald <[email protected]> | ||
*/ | ||
final class EnumTypeTest extends TestCase | ||
{ | ||
public function testConstructorWithRequiredArguments(): void | ||
{ | ||
$constraint = new EnumType(entity: BasketballPositionType::class); | ||
|
||
self::assertEquals(BasketballPositionType::getValues(), $constraint->choices); | ||
self::assertTrue($constraint->strict); | ||
} | ||
|
||
public function testConstructorWithAllArguments(): void | ||
{ | ||
$constraint = new EnumType(entity: BasketballPositionType::class, message: 'test', groups: ['foo'], payload: ['bar' => 'baz']); | ||
|
||
self::assertEquals(BasketballPositionType::getValues(), $constraint->choices); | ||
self::assertTrue($constraint->strict); | ||
self::assertEquals(BasketballPositionType::class, $constraint->entity); | ||
self::assertEquals('test', $constraint->message); | ||
self::assertEquals(['foo'], $constraint->groups); | ||
self::assertEquals(['bar' => 'baz'], $constraint->payload); | ||
self::assertNull($constraint->callback); | ||
self::assertFalse($constraint->multiple); | ||
self::assertNull($constraint->min); | ||
self::assertNull($constraint->max); | ||
} | ||
|
||
public function testNotEnumType(): void | ||
{ | ||
$this->expectException(InvalidArgumentException::class); | ||
$this->expectExceptionMessage('stdClass is not instance of Fresh\DoctrineEnumBundle\DBAL\Types\AbstractEnumType'); | ||
|
||
new EnumType(entity: \stdClass::class); | ||
} | ||
|
||
public function testGetDefaultOption(): void | ||
{ | ||
$constraint = new EnumType(entity: BasketballPositionType::class); | ||
|
||
self::assertEquals('choices', $constraint->getDefaultOption()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<?php | ||
/* | ||
* This file is part of the FreshDoctrineEnumBundle. | ||
* | ||
* (c) Artem Henvald <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Fresh\DoctrineEnumBundle\Tests\Validator; | ||
|
||
use Fresh\DoctrineEnumBundle\Exception\RuntimeException; | ||
use Fresh\DoctrineEnumBundle\Tests\Fixtures\DBAL\Types\BasketballPositionType; | ||
use Fresh\DoctrineEnumBundle\Validator\Constraints\EnumType; | ||
use Fresh\DoctrineEnumBundle\Validator\Constraints\EnumTypeValidator; | ||
use PHPUnit\Framework\MockObject\MockObject; | ||
use PHPUnit\Framework\TestCase; | ||
use Symfony\Component\Validator\Context\ExecutionContext; | ||
use Symfony\Component\Validator\Violation\ConstraintViolationBuilder; | ||
|
||
/** | ||
* EnumValidatorTest. | ||
* | ||
* @author Artem Henvald <[email protected]> | ||
*/ | ||
final class EnumTypeValidatorTest extends TestCase | ||
{ | ||
/** @var ExecutionContext|MockObject */ | ||
private $context; | ||
|
||
private EnumTypeValidator $enumValidator; | ||
|
||
protected function setUp(): void | ||
{ | ||
$this->enumValidator = new EnumTypeValidator(); | ||
$this->context = $this->createMock(ExecutionContext::class); | ||
} | ||
|
||
protected function tearDown(): void | ||
{ | ||
unset( | ||
$this->enumValidator, | ||
$this->context | ||
); | ||
} | ||
|
||
public function testValidateIncorrectConstraintClass(): void | ||
{ | ||
$this->expectException(RuntimeException::class); | ||
$this->expectExceptionMessageMatches('/^Object of class .* is not instance of .*$/'); | ||
|
||
$this->enumValidator->validate(BasketballPositionType::POINT_GUARD, new DummyConstraint()); | ||
} | ||
|
||
public function testValidBasketballPositionType(): void | ||
{ | ||
$constraint = new EnumType(entity: BasketballPositionType::class); | ||
|
||
$this->context | ||
->expects(self::never()) | ||
->method('buildViolation') | ||
; | ||
|
||
$this->enumValidator->initialize($this->context); | ||
$this->enumValidator->validate(BasketballPositionType::SMALL_FORWARD, $constraint); | ||
} | ||
|
||
public function testInvalidBasketballPositionType(): void | ||
{ | ||
$constraint = new EnumType(entity: BasketballPositionType::class); | ||
$constraintValidationBuilder = $this->createMock(ConstraintViolationBuilder::class); | ||
|
||
$constraintValidationBuilder | ||
->expects(self::exactly(2)) | ||
->method('setParameter') | ||
->withConsecutive( | ||
[self::equalTo('{{ value }}'), self::equalTo('"Pitcher"')], | ||
[self::equalTo('{{ choices }}'), self::equalTo('"PG", "SG", "SF", "PF", "C"')] | ||
) | ||
->willReturn($constraintValidationBuilder, $constraintValidationBuilder) | ||
; | ||
|
||
$constraintValidationBuilder | ||
->expects(self::once()) | ||
->method('setCode') | ||
->willReturnSelf() | ||
; | ||
|
||
$this->context | ||
->expects(self::once()) | ||
->method('buildViolation') | ||
->with(self::equalTo('The value you selected is not a valid choice.')) | ||
->willReturn($constraintValidationBuilder) | ||
; | ||
|
||
$this->enumValidator->initialize($this->context); | ||
$this->enumValidator->validate('Pitcher', $constraint); // It's not a baseball =) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,37 +12,47 @@ | |
|
||
namespace Fresh\DoctrineEnumBundle\Validator\Constraints; | ||
|
||
use Attribute; | ||
use Fresh\DoctrineEnumBundle\DBAL\Types\AbstractEnumType; | ||
use Fresh\DoctrineEnumBundle\Exception\InvalidArgumentException; | ||
use Symfony\Component\Validator\Constraints\Choice; | ||
|
||
/** | ||
* ENUM Constraint. | ||
* | ||
* @deprecated Support for Enum annotation will be dropped in 9.0. Please switch to using \Fresh\DoctrineEnumBundle\Validator\Constraints\EnumType attribute instead. | ||
* | ||
* @author Artem Henvald <[email protected]> | ||
* | ||
* @Annotation | ||
*/ | ||
#[Attribute(Attribute::TARGET_PROPERTY)] | ||
class Enum extends Choice | ||
{ | ||
/** @var string|AbstractEnumType<int|string, int|string> */ | ||
public $entity; | ||
|
||
/** | ||
* @param string $entity | ||
* @param string|null $message | ||
* @param string[]|null $groups | ||
* @param mixed $payload | ||
* @param array<string, array<string, string>> $options | ||
*/ | ||
public function __construct(public string $entity, ?string $message = null, ?array $groups = null, mixed $payload = null) | ||
public function __construct($options = null) | ||
{ | ||
if (!\is_subclass_of($entity, AbstractEnumType::class)) { | ||
throw new InvalidArgumentException(\sprintf('%s is not instance of %s', $entity, AbstractEnumType::class)); | ||
$this->strict = true; | ||
|
||
if (isset($options['entity'])) { | ||
/** @var AbstractEnumType<int|string, int|string> $entity */ | ||
$entity = $options['entity']; | ||
|
||
if (\is_subclass_of($entity, AbstractEnumType::class)) { | ||
$this->choices = $entity::getValues(); | ||
} | ||
} | ||
|
||
parent::__construct( | ||
choices: $entity::getValues(), | ||
strict: true, | ||
message: $message, | ||
groups: $groups, | ||
payload: $payload | ||
); | ||
parent::__construct($options); | ||
} | ||
|
||
/** | ||
* @return string[] | ||
*/ | ||
public function getRequiredOptions(): array | ||
{ | ||
return ['entity']; | ||
} | ||
} |
Oops, something went wrong.