/
githubmirror
/
symfony
Обзор
Документация
Войти
/
githubmirror
/
symfony
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
8.2
src/Symfony/Component/Form/Tests/DependencyInjection/FormPassTest.php
401 строка
15 KB
Nicolas Grekas
Merge branch '8.0' into 8.1
23 фев 2026, 15:14
23 фев 2026, 15:14
ff5be9a
Код
Авторство
О чём код?
<?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\Form\Tests\DependencyInjection; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ServiceLocator; use Symfony\Component\Form\AbstractTypeExtension; use Symfony\Component\Form\Command\DebugCommand; use Symfony\Component\Form\DependencyInjection\FormPass; use Symfony\Component\Form\Extension\Csrf\Type\FormTypeCsrfExtension; use Symfony\Component\Form\FormRegistry; /** * @author Bernhard Schussek <bschussek@gmail.com> */ class FormPassTest extends TestCase { public function testDoNothingIfFormExtensionNotLoaded() { $container = $this->createContainerBuilder(); $container->compile(); $this->assertFalse($container->hasDefinition('form.extension')); } public function testDoNothingIfDebugCommandNotLoaded() { $container = $this->createContainerBuilder(); $container->compile(); $this->assertFalse($container->hasDefinition('console.command.form_debug')); } public function testAddTaggedTypes() { $container = $this->createContainerBuilder(); $container->setDefinition('form.extension', $this->createExtensionDefinition()); $container->register('my.type1', __CLASS__.'_Type1')->addTag('form.type')->setPublic(true); $container->register('my.type2', __CLASS__.'_Type2')->addTag('form.type')->setPublic(true); $container->compile(); $extDefinition = $container->getDefinition('form.extension'); $locator = $extDefinition->getArgument(0); $this->assertTrue($locator->isPrivate()); $this->assertEquals( (new Definition(ServiceLocator::class, [[ __CLASS__.'_Type1' => new ServiceClosureArgument(new Reference('my.type1')), __CLASS__.'_Type2' => new ServiceClosureArgument(new Reference('my.type2')), ]]))->addTag('container.service_locator'), $locator ); } public function testAddTaggedTypesToDebugCommand() { $container = $this->createContainerBuilder(); $container->register('form.registry', FormRegistry::class); $commandDefinition = new Definition(DebugCommand::class, [new Reference('form.registry')]); $commandDefinition->setPublic(true); $container->setDefinition('form.extension', $this->createExtensionDefinition()); $container->setDefinition('console.command.form_debug', $commandDefinition); $container->register('my.type1', __CLASS__.'_Type1')->addTag('form.type')->setPublic(true); $container->register('my.type2', __CLASS__.'_Type2')->addTag('form.type')->setPublic(true); $container->compile(); $cmdDefinition = $container->getDefinition('console.command.form_debug'); $this->assertEquals( [ 'Symfony\Component\Form\Extension\Core\Type', __NAMESPACE__, ], $cmdDefinition->getArgument(1) ); } public function testAddTaggedTypesToCsrfTypeExtension() { $container = $this->createContainerBuilder(); $container->register('form.registry', FormRegistry::class); $container->register('form.type_extension.csrf', FormTypeCsrfExtension::class) ->setArguments([null, true, '_token', null, 'validator.translation_domain', null, [], null]) ->setPublic(true); $container->setDefinition('form.extension', $this->createExtensionDefinition()); $container->register('my.type1', __CLASS__.'_Type1')->addTag('form.type', ['csrf_token_id' => 'the_token_id']); $container->register('my.type2', __CLASS__.'_Type2')->addTag('form.type'); $container->compile(); $csrfDefinition = $container->getDefinition('form.type_extension.csrf'); $this->assertSame([__CLASS__.'_Type1' => 'the_token_id'], $csrfDefinition->getArgument(7)); } #[DataProvider('addTaggedTypeExtensionsDataProvider')] public function testAddTaggedTypeExtensions(array $extensions, array $expectedRegisteredExtensions, array $parameters = []) { $container = $this->createContainerBuilder(); foreach ($parameters as $name => $value) { $container->setParameter($name, $value); } $container->setDefinition('form.extension', $this->createExtensionDefinition()); foreach ($extensions as $serviceId => $config) { $container->register($serviceId, $config['class'])->addTag('form.type_extension', $config['tag']); } $container->compile(); $extDefinition = $container->getDefinition('form.extension'); $this->assertEquals($expectedRegisteredExtensions, $extDefinition->getArgument(1)); } public static function addTaggedTypeExtensionsDataProvider() { return [ [ [ Type1TypeExtension::class => [ 'class' => Type1TypeExtension::class, 'tag' => ['extended_type' => 'type1'], ], Type1Type2TypeExtension::class => [ 'class' => Type1Type2TypeExtension::class, 'tag' => ['extended_type' => 'type2'], ], ], [ 'type1' => new IteratorArgument([new Reference(Type1TypeExtension::class)]), 'type2' => new IteratorArgument([new Reference(Type1Type2TypeExtension::class)]), ], ], [ [ Type1TypeExtension::class => [ 'class' => Type1TypeExtension::class, 'tag' => [], ], Type1Type2TypeExtension::class => [ 'class' => Type1Type2TypeExtension::class, 'tag' => [], ], ], [ 'type1' => new IteratorArgument([ new Reference(Type1TypeExtension::class), new Reference(Type1Type2TypeExtension::class), ]), 'type2' => new IteratorArgument([new Reference(Type1Type2TypeExtension::class)]), ], ], [ [ 'my.type_extension1' => [ 'class' => Type1TypeExtension::class, 'tag' => ['extended_type' => 'type1', 'priority' => 1], ], 'my.type_extension2' => [ 'class' => Type1TypeExtension::class, 'tag' => ['extended_type' => 'type1', 'priority' => 2], ], 'my.type_extension3' => [ 'class' => Type1TypeExtension::class, 'tag' => ['extended_type' => 'type1', 'priority' => -1], ], 'my.type_extension4' => [ 'class' => Type2TypeExtension::class, 'tag' => ['extended_type' => 'type2', 'priority' => 2], ], 'my.type_extension5' => [ 'class' => Type2TypeExtension::class, 'tag' => ['extended_type' => 'type2', 'priority' => 1], ], 'my.type_extension6' => [ 'class' => Type2TypeExtension::class, 'tag' => ['extended_type' => 'type2', 'priority' => 1], ], ], [ 'type1' => new IteratorArgument([ new Reference('my.type_extension2'), new Reference('my.type_extension1'), new Reference('my.type_extension3'), ]), 'type2' => new IteratorArgument([ new Reference('my.type_extension4'), new Reference('my.type_extension5'), new Reference('my.type_extension6'), ]), ], ], [ [ 'my.type_extension1' => [ 'class' => '%type1_extension_class%', 'tag' => ['extended_type' => 'type1'], ], 'my.type_extension2' => [ 'class' => '%type1_extension_class%', 'tag' => [], ], ], [ 'type1' => new IteratorArgument([ new Reference('my.type_extension1'), new Reference('my.type_extension2'), ]), ], [ 'type1_extension_class' => Type1TypeExtension::class, ], ], ]; } public function testAddTaggedFormTypeExtensionWithoutExtendingAnyType() { $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage('The getExtendedTypes() method for service "my.type_extension" does not return any extended types.'); $container = $this->createContainerBuilder(); $container->setDefinition('form.extension', $this->createExtensionDefinition()); $container->register('my.type_extension', WithoutExtendedTypesTypeExtension::class) ->setPublic(true) ->addTag('form.type_extension'); $container->compile(); } public function testAddTaggedGuessers() { $container = $this->createContainerBuilder(); $definition1 = new Definition('stdClass'); $definition1->addTag('form.type_guesser'); $definition2 = new Definition('stdClass'); $definition2->addTag('form.type_guesser'); $container->setDefinition('form.extension', $this->createExtensionDefinition()); $container->setDefinition('my.guesser1', $definition1)->setPublic(true); $container->setDefinition('my.guesser2', $definition2)->setPublic(true); $container->compile(); $extDefinition = $container->getDefinition('form.extension'); $this->assertEquals( new IteratorArgument([ new Reference('my.guesser1'), new Reference('my.guesser2'), ]), $extDefinition->getArgument(2) ); } public function testTypeExtensionClassIsTrackedAsResource() { $container = $this->createContainerBuilder(); $container->setDefinition('form.extension', $this->createExtensionDefinition()); $container->register('my.type_extension', Type1TypeExtension::class) ->addTag('form.type_extension'); $container->compile(); $resources = array_map('strval', $container->getResources()); $this->assertContains('reflection.'.Type1TypeExtension::class, $resources); } #[DataProvider('privateTaggedServicesProvider')] public function testPrivateTaggedServices($id, $class, $tagName, callable $assertion, array $tagAttributes = []) { $formPass = new FormPass(); $container = new ContainerBuilder(); $container->setDefinition('form.extension', $this->createExtensionDefinition()); $container->register($id, $class)->setPublic(false)->addTag($tagName, $tagAttributes); $formPass->process($container); $assertion($container); } public static function privateTaggedServicesProvider() { return [ [ 'my.type', 'stdClass', 'form.type', static function (ContainerBuilder $container) { $formTypes = $container->getDefinition('form.extension')->getArgument(0); self::assertInstanceOf(Reference::class, $formTypes); $locator = $container->getDefinition((string) $formTypes); $expectedLocatorMap = [ 'stdClass' => new ServiceClosureArgument(new Reference('my.type')), ]; self::assertInstanceOf(Definition::class, $locator); self::assertEquals($expectedLocatorMap, $locator->getArgument(0)); }, ], [ 'my.type_extension', Type1TypeExtension::class, 'form.type_extension', static function (ContainerBuilder $container) { self::assertEquals( ['Symfony\Component\Form\Extension\Core\Type\FormType' => new IteratorArgument([new Reference('my.type_extension')])], $container->getDefinition('form.extension')->getArgument(1) ); }, ['extended_type' => 'Symfony\Component\Form\Extension\Core\Type\FormType'], ], ['my.guesser', 'stdClass', 'form.type_guesser', static function (ContainerBuilder $container) { self::assertEquals(new IteratorArgument([new Reference('my.guesser')]), $container->getDefinition('form.extension')->getArgument(2)); }], ]; } private function createExtensionDefinition() { $definition = new Definition('Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension'); $definition->setPublic(true); $definition->setArguments([ [], [], new IteratorArgument([]), ]); return $definition; } private function createContainerBuilder() { $container = new ContainerBuilder(); $container->addCompilerPass(new FormPass()); return $container; } } class Type1TypeExtension extends AbstractTypeExtension { public static function getExtendedTypes(): iterable { return ['type1']; } } class Type2TypeExtension extends AbstractTypeExtension { public static function getExtendedTypes(): iterable { return ['type2']; } } class Type1Type2TypeExtension extends AbstractTypeExtension { public static function getExtendedTypes(): iterable { yield 'type1'; yield 'type2'; } } class WithoutExtendedTypesTypeExtension extends AbstractTypeExtension { public static function getExtendedTypes(): iterable { return []; } }