forked from GNUsocial/gnu-social
		
	
		
			
	
	
		
			442 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
		
		
			
		
	
	
			442 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
|   | <?php | ||
|  | 
 | ||
|  | /* | ||
|  |  * This file is part of the Symfony package. | ||
|  |  * | ||
|  |  * (c) Fabien Potencier <fabien@symfony.com> | ||
|  |  * | ||
|  |  * For the full copyright and license information, please view the LICENSE | ||
|  |  * file that was distributed with this source code. | ||
|  |  */ | ||
|  | 
 | ||
|  | namespace Symfony\Component\Validator\Tests\Constraints; | ||
|  | 
 | ||
|  | use PHPUnit\Framework\Assert; | ||
|  | use PHPUnit\Framework\TestCase; | ||
|  | use Symfony\Component\Validator\Constraint; | ||
|  | use Symfony\Component\Validator\Constraints\NotNull; | ||
|  | use Symfony\Component\Validator\ConstraintValidatorInterface; | ||
|  | use Symfony\Component\Validator\ConstraintViolation; | ||
|  | use Symfony\Component\Validator\Context\ExecutionContext; | ||
|  | use Symfony\Component\Validator\Context\ExecutionContextInterface; | ||
|  | use Symfony\Component\Validator\Context\LegacyExecutionContext; | ||
|  | use Symfony\Component\Validator\ExecutionContextInterface as LegacyExecutionContextInterface; | ||
|  | use Symfony\Component\Validator\Mapping\ClassMetadata; | ||
|  | use Symfony\Component\Validator\Mapping\PropertyMetadata; | ||
|  | use Symfony\Component\Validator\Validation; | ||
|  | 
 | ||
|  | /** | ||
|  |  * @author Bernhard Schussek <bschussek@gmail.com> | ||
|  |  */ | ||
|  | abstract class AbstractConstraintValidatorTest extends TestCase | ||
|  | { | ||
|  |     /** | ||
|  |      * @var ExecutionContextInterface | ||
|  |      */ | ||
|  |     protected $context; | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @var ConstraintValidatorInterface | ||
|  |      */ | ||
|  |     protected $validator; | ||
|  | 
 | ||
|  |     protected $group; | ||
|  |     protected $metadata; | ||
|  |     protected $object; | ||
|  |     protected $value; | ||
|  |     protected $root; | ||
|  |     protected $propertyPath; | ||
|  |     protected $constraint; | ||
|  |     protected $defaultTimezone; | ||
|  | 
 | ||
|  |     protected function setUp() | ||
|  |     { | ||
|  |         $this->group = 'MyGroup'; | ||
|  |         $this->metadata = null; | ||
|  |         $this->object = null; | ||
|  |         $this->value = 'InvalidValue'; | ||
|  |         $this->root = 'root'; | ||
|  |         $this->propertyPath = 'property.path'; | ||
|  | 
 | ||
|  |         // Initialize the context with some constraint so that we can
 | ||
|  |         // successfully build a violation.
 | ||
|  |         $this->constraint = new NotNull(); | ||
|  | 
 | ||
|  |         $this->context = $this->createContext(); | ||
|  |         $this->validator = $this->createValidator(); | ||
|  |         $this->validator->initialize($this->context); | ||
|  | 
 | ||
|  |         \Locale::setDefault('en'); | ||
|  | 
 | ||
|  |         $this->setDefaultTimezone('UTC'); | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function tearDown() | ||
|  |     { | ||
|  |         $this->restoreDefaultTimezone(); | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function setDefaultTimezone($defaultTimezone) | ||
|  |     { | ||
|  |         // Make sure this method can not be called twice before calling
 | ||
|  |         // also restoreDefaultTimezone()
 | ||
|  |         if (null === $this->defaultTimezone) { | ||
|  |             $this->defaultTimezone = date_default_timezone_get(); | ||
|  |             date_default_timezone_set($defaultTimezone); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function restoreDefaultTimezone() | ||
|  |     { | ||
|  |         if (null !== $this->defaultTimezone) { | ||
|  |             date_default_timezone_set($this->defaultTimezone); | ||
|  |             $this->defaultTimezone = null; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function createContext() | ||
|  |     { | ||
|  |         $translator = $this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface')->getMock(); | ||
|  |         $validator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ValidatorInterface')->getMock(); | ||
|  |         $contextualValidator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ContextualValidatorInterface')->getMock(); | ||
|  | 
 | ||
|  |         switch ($this->getApiVersion()) { | ||
|  |             case Validation::API_VERSION_2_5: | ||
|  |                 $context = new ExecutionContext( | ||
|  |                     $validator, | ||
|  |                     $this->root, | ||
|  |                     $translator | ||
|  |                 ); | ||
|  |                 break; | ||
|  |             case Validation::API_VERSION_2_4: | ||
|  |             case Validation::API_VERSION_2_5_BC: | ||
|  |                 $context = new LegacyExecutionContext( | ||
|  |                     $validator, | ||
|  |                     $this->root, | ||
|  |                     $this->getMockBuilder('Symfony\Component\Validator\MetadataFactoryInterface')->getMock(), | ||
|  |                     $translator | ||
|  |                 ); | ||
|  |                 break; | ||
|  |             default: | ||
|  |                 throw new \RuntimeException('Invalid API version'); | ||
|  |         } | ||
|  | 
 | ||
|  |         $context->setGroup($this->group); | ||
|  |         $context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath); | ||
|  |         $context->setConstraint($this->constraint); | ||
|  | 
 | ||
|  |         $validator->expects($this->any()) | ||
|  |             ->method('inContext') | ||
|  |             ->with($context) | ||
|  |             ->will($this->returnValue($contextualValidator)); | ||
|  | 
 | ||
|  |         return $context; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @param mixed  $message | ||
|  |      * @param array  $parameters | ||
|  |      * @param string $propertyPath | ||
|  |      * @param string $invalidValue | ||
|  |      * @param null   $plural | ||
|  |      * @param null   $code | ||
|  |      * | ||
|  |      * @return ConstraintViolation | ||
|  |      * | ||
|  |      * @deprecated to be removed in Symfony 3.0. Use {@link buildViolation()} instead. | ||
|  |      */ | ||
|  |     protected function createViolation($message, array $parameters = array(), $propertyPath = 'property.path', $invalidValue = 'InvalidValue', $plural = null, $code = null) | ||
|  |     { | ||
|  |         return new ConstraintViolation( | ||
|  |             null, | ||
|  |             $message, | ||
|  |             $parameters, | ||
|  |             $this->root, | ||
|  |             $propertyPath, | ||
|  |             $invalidValue, | ||
|  |             $plural, | ||
|  |             $code, | ||
|  |             $this->constraint | ||
|  |         ); | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function setGroup($group) | ||
|  |     { | ||
|  |         $this->group = $group; | ||
|  |         $this->context->setGroup($group); | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function setObject($object) | ||
|  |     { | ||
|  |         $this->object = $object; | ||
|  |         $this->metadata = \is_object($object) | ||
|  |             ? new ClassMetadata(\get_class($object)) | ||
|  |             : null; | ||
|  | 
 | ||
|  |         $this->context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath); | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function setProperty($object, $property) | ||
|  |     { | ||
|  |         $this->object = $object; | ||
|  |         $this->metadata = \is_object($object) | ||
|  |             ? new PropertyMetadata(\get_class($object), $property) | ||
|  |             : null; | ||
|  | 
 | ||
|  |         $this->context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath); | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function setValue($value) | ||
|  |     { | ||
|  |         $this->value = $value; | ||
|  |         $this->context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath); | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function setRoot($root) | ||
|  |     { | ||
|  |         $this->root = $root; | ||
|  |         $this->context = $this->createContext(); | ||
|  |         $this->validator->initialize($this->context); | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function setPropertyPath($propertyPath) | ||
|  |     { | ||
|  |         $this->propertyPath = $propertyPath; | ||
|  |         $this->context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath); | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function expectNoValidate() | ||
|  |     { | ||
|  |         $validator = $this->context->getValidator()->inContext($this->context); | ||
|  |         $validator->expects($this->never()) | ||
|  |             ->method('atPath'); | ||
|  |         $validator->expects($this->never()) | ||
|  |             ->method('validate'); | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function expectValidateAt($i, $propertyPath, $value, $group) | ||
|  |     { | ||
|  |         $validator = $this->context->getValidator()->inContext($this->context); | ||
|  |         $validator->expects($this->at(2 * $i)) | ||
|  |             ->method('atPath') | ||
|  |             ->with($propertyPath) | ||
|  |             ->will($this->returnValue($validator)); | ||
|  |         $validator->expects($this->at(2 * $i + 1)) | ||
|  |             ->method('validate') | ||
|  |             ->with($value, $this->logicalOr(null, array(), $this->isInstanceOf('\Symfony\Component\Validator\Constraints\Valid')), $group); | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function expectValidateValueAt($i, $propertyPath, $value, $constraints, $group = null) | ||
|  |     { | ||
|  |         $contextualValidator = $this->context->getValidator()->inContext($this->context); | ||
|  |         $contextualValidator->expects($this->at(2 * $i)) | ||
|  |             ->method('atPath') | ||
|  |             ->with($propertyPath) | ||
|  |             ->will($this->returnValue($contextualValidator)); | ||
|  |         $contextualValidator->expects($this->at(2 * $i + 1)) | ||
|  |             ->method('validate') | ||
|  |             ->with($value, $constraints, $group); | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function assertNoViolation() | ||
|  |     { | ||
|  |         $this->assertSame(0, $violationsCount = \count($this->context->getViolations()), sprintf('0 violation expected. Got %u.', $violationsCount)); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @param mixed  $message | ||
|  |      * @param array  $parameters | ||
|  |      * @param string $propertyPath | ||
|  |      * @param string $invalidValue | ||
|  |      * @param null   $plural | ||
|  |      * @param null   $code | ||
|  |      * | ||
|  |      * @deprecated To be removed in Symfony 3.0. Use | ||
|  |      *             {@link buildViolation()} instead. | ||
|  |      */ | ||
|  |     protected function assertViolation($message, array $parameters = array(), $propertyPath = 'property.path', $invalidValue = 'InvalidValue', $plural = null, $code = null) | ||
|  |     { | ||
|  |         @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.3 and will be removed in 3.0. Use the buildViolation() method instead.', E_USER_DEPRECATED); | ||
|  | 
 | ||
|  |         $this->buildViolation($message) | ||
|  |             ->setParameters($parameters) | ||
|  |             ->atPath($propertyPath) | ||
|  |             ->setInvalidValue($invalidValue) | ||
|  |             ->setCode($code) | ||
|  |             ->setPlural($plural) | ||
|  |             ->assertRaised(); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @param array $expected | ||
|  |      * | ||
|  |      * @deprecated To be removed in Symfony 3.0. Use | ||
|  |      *             {@link buildViolation()} instead. | ||
|  |      */ | ||
|  |     protected function assertViolations(array $expected) | ||
|  |     { | ||
|  |         @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.3 and will be removed in 3.0. Use the buildViolation() method instead.', E_USER_DEPRECATED); | ||
|  | 
 | ||
|  |         $violations = $this->context->getViolations(); | ||
|  | 
 | ||
|  |         $this->assertCount(\count($expected), $violations); | ||
|  | 
 | ||
|  |         $i = 0; | ||
|  | 
 | ||
|  |         foreach ($expected as $violation) { | ||
|  |             $this->assertEquals($violation, $violations[$i++]); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @param $message | ||
|  |      * | ||
|  |      * @return ConstraintViolationAssertion | ||
|  |      */ | ||
|  |     protected function buildViolation($message) | ||
|  |     { | ||
|  |         return new ConstraintViolationAssertion($this->context, $message, $this->constraint); | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function getApiVersion() | ||
|  |     { | ||
|  |         return Validation::API_VERSION_2_5; | ||
|  |     } | ||
|  | 
 | ||
|  |     abstract protected function createValidator(); | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * @internal | ||
|  |  */ | ||
|  | class ConstraintViolationAssertion | ||
|  | { | ||
|  |     /** | ||
|  |      * @var LegacyExecutionContextInterface | ||
|  |      */ | ||
|  |     private $context; | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @var ConstraintViolationAssertion[] | ||
|  |      */ | ||
|  |     private $assertions; | ||
|  | 
 | ||
|  |     private $message; | ||
|  |     private $parameters = array(); | ||
|  |     private $invalidValue = 'InvalidValue'; | ||
|  |     private $propertyPath = 'property.path'; | ||
|  |     private $translationDomain; | ||
|  |     private $plural; | ||
|  |     private $code; | ||
|  |     private $constraint; | ||
|  |     private $cause; | ||
|  | 
 | ||
|  |     public function __construct(LegacyExecutionContextInterface $context, $message, Constraint $constraint = null, array $assertions = array()) | ||
|  |     { | ||
|  |         $this->context = $context; | ||
|  |         $this->message = $message; | ||
|  |         $this->constraint = $constraint; | ||
|  |         $this->assertions = $assertions; | ||
|  |     } | ||
|  | 
 | ||
|  |     public function atPath($path) | ||
|  |     { | ||
|  |         $this->propertyPath = $path; | ||
|  | 
 | ||
|  |         return $this; | ||
|  |     } | ||
|  | 
 | ||
|  |     public function setParameter($key, $value) | ||
|  |     { | ||
|  |         $this->parameters[$key] = $value; | ||
|  | 
 | ||
|  |         return $this; | ||
|  |     } | ||
|  | 
 | ||
|  |     public function setParameters(array $parameters) | ||
|  |     { | ||
|  |         $this->parameters = $parameters; | ||
|  | 
 | ||
|  |         return $this; | ||
|  |     } | ||
|  | 
 | ||
|  |     public function setTranslationDomain($translationDomain) | ||
|  |     { | ||
|  |         $this->translationDomain = $translationDomain; | ||
|  | 
 | ||
|  |         return $this; | ||
|  |     } | ||
|  | 
 | ||
|  |     public function setInvalidValue($invalidValue) | ||
|  |     { | ||
|  |         $this->invalidValue = $invalidValue; | ||
|  | 
 | ||
|  |         return $this; | ||
|  |     } | ||
|  | 
 | ||
|  |     public function setPlural($number) | ||
|  |     { | ||
|  |         $this->plural = $number; | ||
|  | 
 | ||
|  |         return $this; | ||
|  |     } | ||
|  | 
 | ||
|  |     public function setCode($code) | ||
|  |     { | ||
|  |         $this->code = $code; | ||
|  | 
 | ||
|  |         return $this; | ||
|  |     } | ||
|  | 
 | ||
|  |     public function setCause($cause) | ||
|  |     { | ||
|  |         $this->cause = $cause; | ||
|  | 
 | ||
|  |         return $this; | ||
|  |     } | ||
|  | 
 | ||
|  |     public function buildNextViolation($message) | ||
|  |     { | ||
|  |         $assertions = $this->assertions; | ||
|  |         $assertions[] = $this; | ||
|  | 
 | ||
|  |         return new self($this->context, $message, $this->constraint, $assertions); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function assertRaised() | ||
|  |     { | ||
|  |         $expected = array(); | ||
|  |         foreach ($this->assertions as $assertion) { | ||
|  |             $expected[] = $assertion->getViolation(); | ||
|  |         } | ||
|  |         $expected[] = $this->getViolation(); | ||
|  | 
 | ||
|  |         $violations = iterator_to_array($this->context->getViolations()); | ||
|  | 
 | ||
|  |         Assert::assertSame($expectedCount = \count($expected), $violationsCount = \count($violations), sprintf('%u violation(s) expected. Got %u.', $expectedCount, $violationsCount)); | ||
|  | 
 | ||
|  |         reset($violations); | ||
|  | 
 | ||
|  |         foreach ($expected as $violation) { | ||
|  |             Assert::assertEquals($violation, current($violations)); | ||
|  |             next($violations); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     private function getViolation() | ||
|  |     { | ||
|  |         return new ConstraintViolation( | ||
|  |             null, | ||
|  |             $this->message, | ||
|  |             $this->parameters, | ||
|  |             $this->context->getRoot(), | ||
|  |             $this->propertyPath, | ||
|  |             $this->invalidValue, | ||
|  |             $this->plural, | ||
|  |             $this->code, | ||
|  |             $this->constraint, | ||
|  |             $this->cause | ||
|  |         ); | ||
|  |     } | ||
|  | } |