Merge branch '5.2' into 5.x
* 5.2: [Messenger] StopWorkersCommand improve doc helper Added compatibility with PHPunit 9.5 do not apply the Valid constraint on scalar form data [Test] Reproduce issue with cascading validation [SecurityBundle] Don't use the container as resource type in fixtures. Fix bug with whitespace in Kernel::stripComments()
This commit is contained in:
commit
7dcaf98373
2
phpunit
2
phpunit
@ -13,7 +13,7 @@ if (!getenv('SYMFONY_PHPUNIT_VERSION')) {
|
|||||||
} elseif (\PHP_VERSION_ID < 70300) {
|
} elseif (\PHP_VERSION_ID < 70300) {
|
||||||
putenv('SYMFONY_PHPUNIT_VERSION=8.5');
|
putenv('SYMFONY_PHPUNIT_VERSION=8.5');
|
||||||
} else {
|
} else {
|
||||||
putenv('SYMFONY_PHPUNIT_VERSION=9.4');
|
putenv('SYMFONY_PHPUNIT_VERSION=9.5');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!getenv('SYMFONY_PATCH_TYPE_DECLARATIONS')) {
|
if (!getenv('SYMFONY_PATCH_TYPE_DECLARATIONS')) {
|
||||||
|
@ -42,7 +42,7 @@ class CoverageListenerTrait
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$annotations = $test->getAnnotations();
|
$annotations = Test::parseTestMethodAnnotations(\get_class($test), $test->getName(false));
|
||||||
|
|
||||||
$ignoredAnnotations = ['covers', 'coversDefaultClass', 'coversNothing'];
|
$ignoredAnnotations = ['covers', 'coversDefaultClass', 'coversNothing'];
|
||||||
|
|
||||||
|
@ -110,7 +110,9 @@ class FormValidator extends ConstraintValidator
|
|||||||
foreach ($constraints as $constraint) {
|
foreach ($constraints as $constraint) {
|
||||||
// For the "Valid" constraint, validate the data in all groups
|
// For the "Valid" constraint, validate the data in all groups
|
||||||
if ($constraint instanceof Valid) {
|
if ($constraint instanceof Valid) {
|
||||||
|
if (\is_object($data)) {
|
||||||
$validator->atPath('data')->validate($data, $constraint, $groups);
|
$validator->atPath('data')->validate($data, $constraint, $groups);
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ use Symfony\Component\Form\CallbackTransformer;
|
|||||||
use Symfony\Component\Form\Exception\TransformationFailedException;
|
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
|
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
@ -27,6 +28,7 @@ use Symfony\Component\Validator\Constraints\Expression;
|
|||||||
use Symfony\Component\Validator\Constraints\GroupSequence;
|
use Symfony\Component\Validator\Constraints\GroupSequence;
|
||||||
use Symfony\Component\Validator\Constraints\Length;
|
use Symfony\Component\Validator\Constraints\Length;
|
||||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||||
|
use Symfony\Component\Validator\Constraints\Valid;
|
||||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
|
use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
|
||||||
use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
|
use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
|
||||||
@ -286,6 +288,39 @@ class FormValidatorFunctionalTest extends TestCase
|
|||||||
$this->assertSame('children[field2].data', $violations[1]->getPropertyPath());
|
$this->assertSame('children[field2].data', $violations[1]->getPropertyPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCascadeValidationToChildFormsWithTwoValidConstraints()
|
||||||
|
{
|
||||||
|
$form = $this->formFactory->create(ReviewType::class);
|
||||||
|
|
||||||
|
$form->submit([
|
||||||
|
'rating' => 1,
|
||||||
|
'title' => 'Sample Title',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$violations = $this->validator->validate($form);
|
||||||
|
|
||||||
|
$this->assertCount(1, $violations);
|
||||||
|
$this->assertSame('This value should not be blank.', $violations[0]->getMessage());
|
||||||
|
$this->assertSame('children[author].data.email', $violations[0]->getPropertyPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCascadeValidationToChildFormsWithTwoValidConstraints2()
|
||||||
|
{
|
||||||
|
$form = $this->formFactory->create(ReviewType::class);
|
||||||
|
|
||||||
|
$form->submit([
|
||||||
|
'title' => 'Sample Title',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$violations = $this->validator->validate($form);
|
||||||
|
|
||||||
|
$this->assertCount(2, $violations);
|
||||||
|
$this->assertSame('This value should not be blank.', $violations[0]->getMessage());
|
||||||
|
$this->assertSame('data.rating', $violations[0]->getPropertyPath());
|
||||||
|
$this->assertSame('This value should not be blank.', $violations[1]->getMessage());
|
||||||
|
$this->assertSame('children[author].data.email', $violations[1]->getPropertyPath());
|
||||||
|
}
|
||||||
|
|
||||||
public function testCascadeValidationToChildFormsUsingPropertyPathsValidatedInSequence()
|
public function testCascadeValidationToChildFormsUsingPropertyPathsValidatedInSequence()
|
||||||
{
|
{
|
||||||
$form = $this->formFactory->create(FormType::class, null, [
|
$form = $this->formFactory->create(FormType::class, null, [
|
||||||
@ -444,3 +479,62 @@ class FooType extends AbstractType
|
|||||||
$resolver->setDefault('data_class', Foo::class);
|
$resolver->setDefault('data_class', Foo::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Review
|
||||||
|
{
|
||||||
|
public $rating;
|
||||||
|
public $title;
|
||||||
|
public $author;
|
||||||
|
|
||||||
|
public static function loadValidatorMetadata(ClassMetadata $metadata)
|
||||||
|
{
|
||||||
|
$metadata->addPropertyConstraint('title', new NotBlank());
|
||||||
|
$metadata->addPropertyConstraint('rating', new NotBlank());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ReviewType extends AbstractType
|
||||||
|
{
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('rating', IntegerType::class, [
|
||||||
|
'constraints' => [new Valid()],
|
||||||
|
])
|
||||||
|
->add('title')
|
||||||
|
->add('author', CustomerType::class, [
|
||||||
|
'constraints' => [new Valid()],
|
||||||
|
])
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setDefault('data_class', Review::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Customer
|
||||||
|
{
|
||||||
|
public $email;
|
||||||
|
|
||||||
|
public static function loadValidatorMetadata(ClassMetadata $metadata)
|
||||||
|
{
|
||||||
|
$metadata->addPropertyConstraint('email', new NotBlank());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomerType extends AbstractType
|
||||||
|
{
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('email')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setDefault('data_class', Customer::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -831,6 +831,9 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
|
|||||||
// replace multiple new lines with a single newline
|
// replace multiple new lines with a single newline
|
||||||
$rawChunk .= preg_replace(['/\n{2,}/S'], "\n", $token[1]);
|
$rawChunk .= preg_replace(['/\n{2,}/S'], "\n", $token[1]);
|
||||||
} elseif (\in_array($token[0], [\T_COMMENT, \T_DOC_COMMENT])) {
|
} elseif (\in_array($token[0], [\T_COMMENT, \T_DOC_COMMENT])) {
|
||||||
|
if (!\in_array($rawChunk[\strlen($rawChunk) - 1], [' ', "\n", "\r", "\t"], true)) {
|
||||||
|
$rawChunk .= ' ';
|
||||||
|
}
|
||||||
$ignoreSpace = true;
|
$ignoreSpace = true;
|
||||||
} else {
|
} else {
|
||||||
$rawChunk .= $token[1];
|
$rawChunk .= $token[1];
|
||||||
@ -838,6 +841,8 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
|
|||||||
// The PHP-open tag already has a new-line
|
// The PHP-open tag already has a new-line
|
||||||
if (\T_OPEN_TAG === $token[0]) {
|
if (\T_OPEN_TAG === $token[0]) {
|
||||||
$ignoreSpace = true;
|
$ignoreSpace = true;
|
||||||
|
} else {
|
||||||
|
$ignoreSpace = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,10 +226,37 @@ class KernelTest extends TestCase
|
|||||||
$kernel->handle($request, $type, $catch);
|
$kernel->handle($request, $type, $catch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testStripComments()
|
/**
|
||||||
|
* @dataProvider getStripCommentsCodes
|
||||||
|
*/
|
||||||
|
public function testStripComments(string $source, string $expected)
|
||||||
{
|
{
|
||||||
$source = <<<'EOF'
|
$output = Kernel::stripComments($source);
|
||||||
|
|
||||||
|
// Heredocs are preserved, making the output mixing Unix and Windows line
|
||||||
|
// endings, switching to "\n" everywhere on Windows to avoid failure.
|
||||||
|
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||||
|
$expected = str_replace("\r\n", "\n", $expected);
|
||||||
|
$output = str_replace("\r\n", "\n", $output);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $output);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getStripCommentsCodes(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['<?php echo foo();', '<?php echo foo();'],
|
||||||
|
['<?php echo/**/foo();', '<?php echo foo();'],
|
||||||
|
['<?php echo/** bar */foo();', '<?php echo foo();'],
|
||||||
|
['<?php /**/echo foo();', '<?php echo foo();'],
|
||||||
|
['<?php echo \foo();', '<?php echo \foo();'],
|
||||||
|
['<?php echo/**/\foo();', '<?php echo \foo();'],
|
||||||
|
['<?php echo/** bar */\foo();', '<?php echo \foo();'],
|
||||||
|
['<?php /**/echo \foo();', '<?php echo \foo();'],
|
||||||
|
[<<<'EOF'
|
||||||
<?php
|
<?php
|
||||||
|
include_once \dirname(__DIR__).'/foo.php';
|
||||||
|
|
||||||
$string = 'string should not be modified';
|
$string = 'string should not be modified';
|
||||||
|
|
||||||
@ -267,9 +294,10 @@ class TestClass
|
|||||||
// inline comment
|
// inline comment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EOF;
|
EOF
|
||||||
$expected = <<<'EOF'
|
, <<<'EOF'
|
||||||
<?php
|
<?php
|
||||||
|
include_once \dirname(__DIR__).'/foo.php';
|
||||||
$string = 'string should not be modified';
|
$string = 'string should not be modified';
|
||||||
$string = 'string should not be
|
$string = 'string should not be
|
||||||
|
|
||||||
@ -294,18 +322,9 @@ class TestClass
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EOF;
|
EOF
|
||||||
|
],
|
||||||
$output = Kernel::stripComments($source);
|
];
|
||||||
|
|
||||||
// Heredocs are preserved, making the output mixing Unix and Windows line
|
|
||||||
// endings, switching to "\n" everywhere on Windows to avoid failure.
|
|
||||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
|
||||||
$expected = str_replace("\r\n", "\n", $expected);
|
|
||||||
$output = str_replace("\r\n", "\n", $output);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->assertEquals($expected, $output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSerialize()
|
public function testSerialize()
|
||||||
|
@ -50,7 +50,7 @@ The <info>%command.name%</info> command sends a signal to stop any <info>messeng
|
|||||||
|
|
||||||
Each worker command will finish the message they are currently processing
|
Each worker command will finish the message they are currently processing
|
||||||
and then exit. Worker commands are *not* automatically restarted: that
|
and then exit. Worker commands are *not* automatically restarted: that
|
||||||
should be handled by something like supervisord.
|
should be handled by a process control system.
|
||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
|
Reference in New Issue
Block a user