PageRenderTime 55ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php

https://github.com/hhamon/symfony
PHP | 223 lines | 162 code | 32 blank | 29 comment | 1 complexity | 8f4fcb1681aaaed5ead354104ba590b2 MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Validator\Tests\Mapping\Loader;
  11. use Doctrine\Common\Annotations\AnnotationReader;
  12. use PHPUnit\Framework\TestCase;
  13. use Symfony\Component\Validator\Constraints\All;
  14. use Symfony\Component\Validator\Constraints\AtLeastOneOf;
  15. use Symfony\Component\Validator\Constraints\Callback;
  16. use Symfony\Component\Validator\Constraints\Choice;
  17. use Symfony\Component\Validator\Constraints\Collection;
  18. use Symfony\Component\Validator\Constraints\Email;
  19. use Symfony\Component\Validator\Constraints\Expression;
  20. use Symfony\Component\Validator\Constraints\IsTrue;
  21. use Symfony\Component\Validator\Constraints\NotBlank;
  22. use Symfony\Component\Validator\Constraints\NotNull;
  23. use Symfony\Component\Validator\Constraints\Optional;
  24. use Symfony\Component\Validator\Constraints\Range;
  25. use Symfony\Component\Validator\Constraints\Required;
  26. use Symfony\Component\Validator\Constraints\Sequentially;
  27. use Symfony\Component\Validator\Constraints\Valid;
  28. use Symfony\Component\Validator\Mapping\ClassMetadata;
  29. use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
  30. use Symfony\Component\Validator\Tests\Fixtures\Annotation\Entity;
  31. use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
  32. class AnnotationLoaderTest extends TestCase
  33. {
  34. public function testLoadClassMetadataReturnsTrueIfSuccessful()
  35. {
  36. $reader = new AnnotationReader();
  37. $loader = new AnnotationLoader($reader);
  38. $metadata = new ClassMetadata(Entity::class);
  39. $this->assertTrue($loader->loadClassMetadata($metadata));
  40. }
  41. public function testLoadClassMetadataReturnsFalseIfNotSuccessful()
  42. {
  43. $loader = new AnnotationLoader(new AnnotationReader());
  44. $metadata = new ClassMetadata('\stdClass');
  45. $this->assertFalse($loader->loadClassMetadata($metadata));
  46. }
  47. /**
  48. * @dataProvider provideNamespaces
  49. */
  50. public function testLoadClassMetadata(string $namespace)
  51. {
  52. $loader = new AnnotationLoader(new AnnotationReader());
  53. $metadata = new ClassMetadata($namespace.'\Entity');
  54. $loader->loadClassMetadata($metadata);
  55. $expected = new ClassMetadata($namespace.'\Entity');
  56. $expected->setGroupSequence(['Foo', 'Entity']);
  57. $expected->addConstraint(new ConstraintA());
  58. $expected->addConstraint(new Callback(['Symfony\Component\Validator\Tests\Fixtures\CallbackClass', 'callback']));
  59. $expected->addConstraint(new Sequentially([
  60. new Expression('this.getFirstName() != null'),
  61. ]));
  62. $expected->addConstraint(new Callback(['callback' => 'validateMe', 'payload' => 'foo']));
  63. $expected->addConstraint(new Callback('validateMeStatic'));
  64. $expected->addPropertyConstraint('firstName', new NotNull());
  65. $expected->addPropertyConstraint('firstName', new Range(['min' => 3]));
  66. $expected->addPropertyConstraint('firstName', new All([new NotNull(), new Range(['min' => 3])]));
  67. $expected->addPropertyConstraint('firstName', new All(['constraints' => [new NotNull(), new Range(['min' => 3])]]));
  68. $expected->addPropertyConstraint('firstName', new Collection([
  69. 'foo' => [new NotNull(), new Range(['min' => 3])],
  70. 'bar' => new Range(['min' => 5]),
  71. 'baz' => new Required([new Email()]),
  72. 'qux' => new Optional([new NotBlank()]),
  73. ], null, null, true));
  74. $expected->addPropertyConstraint('firstName', new Choice([
  75. 'message' => 'Must be one of %choices%',
  76. 'choices' => ['A', 'B'],
  77. ]));
  78. $expected->addPropertyConstraint('firstName', new AtLeastOneOf([
  79. new NotNull(),
  80. new Range(['min' => 3]),
  81. ], null, null, 'foo', null, false));
  82. $expected->addPropertyConstraint('firstName', new Sequentially([
  83. new NotBlank(),
  84. new Range(['min' => 5]),
  85. ]));
  86. $expected->addPropertyConstraint('childA', new Valid());
  87. $expected->addPropertyConstraint('childB', new Valid());
  88. $expected->addGetterConstraint('lastName', new NotNull());
  89. $expected->addGetterMethodConstraint('valid', 'isValid', new IsTrue());
  90. $expected->addGetterConstraint('permissions', new IsTrue());
  91. // load reflection class so that the comparison passes
  92. $expected->getReflectionClass();
  93. $this->assertEquals($expected, $metadata);
  94. }
  95. /**
  96. * Test MetaData merge with parent annotation.
  97. *
  98. * @dataProvider provideNamespaces
  99. */
  100. public function testLoadParentClassMetadata(string $namespace)
  101. {
  102. $loader = new AnnotationLoader(new AnnotationReader());
  103. // Load Parent MetaData
  104. $parent_metadata = new ClassMetadata($namespace.'\EntityParent');
  105. $loader->loadClassMetadata($parent_metadata);
  106. $expected_parent = new ClassMetadata($namespace.'\EntityParent');
  107. $expected_parent->addPropertyConstraint('other', new NotNull());
  108. $expected_parent->getReflectionClass();
  109. $this->assertEquals($expected_parent, $parent_metadata);
  110. }
  111. /**
  112. * Test MetaData merge with parent annotation.
  113. *
  114. * @dataProvider provideNamespaces
  115. */
  116. public function testLoadClassMetadataAndMerge(string $namespace)
  117. {
  118. $loader = new AnnotationLoader(new AnnotationReader());
  119. // Load Parent MetaData
  120. $parent_metadata = new ClassMetadata($namespace.'\EntityParent');
  121. $loader->loadClassMetadata($parent_metadata);
  122. $metadata = new ClassMetadata($namespace.'\Entity');
  123. // Merge parent metaData.
  124. $metadata->mergeConstraints($parent_metadata);
  125. $loader->loadClassMetadata($metadata);
  126. $expected_parent = new ClassMetadata($namespace.'\EntityParent');
  127. $expected_parent->addPropertyConstraint('other', new NotNull());
  128. $expected_parent->getReflectionClass();
  129. $expected = new ClassMetadata($namespace.'\Entity');
  130. $expected->mergeConstraints($expected_parent);
  131. $expected->setGroupSequence(['Foo', 'Entity']);
  132. $expected->addConstraint(new ConstraintA());
  133. $expected->addConstraint(new Callback(['Symfony\Component\Validator\Tests\Fixtures\CallbackClass', 'callback']));
  134. $expected->addConstraint(new Sequentially([
  135. new Expression('this.getFirstName() != null'),
  136. ]));
  137. $expected->addConstraint(new Callback(['callback' => 'validateMe', 'payload' => 'foo']));
  138. $expected->addConstraint(new Callback('validateMeStatic'));
  139. $expected->addPropertyConstraint('firstName', new NotNull());
  140. $expected->addPropertyConstraint('firstName', new Range(['min' => 3]));
  141. $expected->addPropertyConstraint('firstName', new All([new NotNull(), new Range(['min' => 3])]));
  142. $expected->addPropertyConstraint('firstName', new All(['constraints' => [new NotNull(), new Range(['min' => 3])]]));
  143. $expected->addPropertyConstraint('firstName', new Collection([
  144. 'foo' => [new NotNull(), new Range(['min' => 3])],
  145. 'bar' => new Range(['min' => 5]),
  146. 'baz' => new Required([new Email()]),
  147. 'qux' => new Optional([new NotBlank()]),
  148. ], null, null, true));
  149. $expected->addPropertyConstraint('firstName', new Choice([
  150. 'message' => 'Must be one of %choices%',
  151. 'choices' => ['A', 'B'],
  152. ]));
  153. $expected->addPropertyConstraint('firstName', new AtLeastOneOf([
  154. new NotNull(),
  155. new Range(['min' => 3]),
  156. ], null, null, 'foo', null, false));
  157. $expected->addPropertyConstraint('firstName', new Sequentially([
  158. new NotBlank(),
  159. new Range(['min' => 5]),
  160. ]));
  161. $expected->addPropertyConstraint('childA', new Valid());
  162. $expected->addPropertyConstraint('childB', new Valid());
  163. $expected->addGetterConstraint('lastName', new NotNull());
  164. $expected->addGetterMethodConstraint('valid', 'isValid', new IsTrue());
  165. $expected->addGetterConstraint('permissions', new IsTrue());
  166. // load reflection class so that the comparison passes
  167. $expected->getReflectionClass();
  168. $this->assertEquals($expected, $metadata);
  169. }
  170. /**
  171. * @dataProvider provideNamespaces
  172. */
  173. public function testLoadGroupSequenceProviderAnnotation(string $namespace)
  174. {
  175. $loader = new AnnotationLoader(new AnnotationReader());
  176. $metadata = new ClassMetadata($namespace.'\GroupSequenceProviderEntity');
  177. $loader->loadClassMetadata($metadata);
  178. $expected = new ClassMetadata($namespace.'\GroupSequenceProviderEntity');
  179. $expected->setGroupSequenceProvider(true);
  180. $expected->getReflectionClass();
  181. $this->assertEquals($expected, $metadata);
  182. }
  183. public function provideNamespaces(): iterable
  184. {
  185. yield 'annotations' => ['Symfony\Component\Validator\Tests\Fixtures\Annotation'];
  186. yield 'attributes' => ['Symfony\Component\Validator\Tests\Fixtures\Attribute'];
  187. if (\PHP_VERSION_ID >= 80100) {
  188. yield 'nested_attributes' => ['Symfony\Component\Validator\Tests\Fixtures\NestedAttribute'];
  189. }
  190. }
  191. }