[Form] Fixed ResolvedFormType to really be replaceable
This commit is contained in:
parent
6b39ebc4f8
commit
8070e6997e
@ -247,11 +247,10 @@
|
||||
reasons. It is now not possible anymore to use custom implementations of
|
||||
`FormBuilderInterface` for specific form types.
|
||||
|
||||
If you are in such a situation, you can subclass `FormRegistry` instead and override
|
||||
`resolveType` to return a custom `ResolvedFormTypeInterface` implementation, within
|
||||
which you can create your own `FormBuilderInterface` implementation. You should
|
||||
register this custom registry class under the service name "form.registry" in order
|
||||
to replace the default implementation.
|
||||
If you are in such a situation, you can implement a custom `ResolvedFormTypeInterface`
|
||||
where you create your own `FormBuilderInterface` implementation. You also need to
|
||||
register a custom `ResolvedFormTypeFactoryInterface` implementation under the service
|
||||
name "form.resolved_type_factory" in order to replace the default implementation.
|
||||
|
||||
* If you previously inherited from `FieldType`, you should now inherit from
|
||||
`FormType`. You should also set the option `compound` to `false` if your field
|
||||
|
@ -5,13 +5,17 @@
|
||||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
|
||||
<parameters>
|
||||
<parameter key="form.extension.class">Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension</parameter>
|
||||
<parameter key="form.resolved_type_factory.class">Symfony\Component\Form\ResolvedFormTypeFactory</parameter>
|
||||
<parameter key="form.registry.class">Symfony\Component\Form\FormRegistry</parameter>
|
||||
<parameter key="form.factory.class">Symfony\Component\Form\FormFactory</parameter>
|
||||
<parameter key="form.extension.class">Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension</parameter>
|
||||
<parameter key="form.type_guesser.validator.class">Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
<!-- ResolvedFormTypeFactory -->
|
||||
<service id="form.resolved_type_factory" class="%form.resolved_type_factory.class%" />
|
||||
|
||||
<!-- FormRegistry -->
|
||||
<service id="form.registry" class="%form.registry.class%">
|
||||
<argument type="collection">
|
||||
@ -23,11 +27,13 @@
|
||||
-->
|
||||
<argument type="service" id="form.extension" />
|
||||
</argument>
|
||||
<argument type="service" id="form.resolved_type_factory" />
|
||||
</service>
|
||||
|
||||
<!-- FormFactory -->
|
||||
<service id="form.factory" class="%form.factory.class%">
|
||||
<argument type="service" id="form.registry" />
|
||||
<argument type="service" id="form.resolved_type_factory" />
|
||||
</service>
|
||||
|
||||
<!-- DependencyInjectionExtension -->
|
||||
|
@ -152,12 +152,12 @@ CHANGELOG
|
||||
* deprecated the options "data_timezone" and "user_timezone" in DateType, DateTimeType and TimeType
|
||||
and renamed them to "model_timezone" and "view_timezone"
|
||||
* fixed: TransformationFailedExceptions thrown in the model transformer are now caught by the form
|
||||
* added FormRegistry and ResolvedFormTypeInterface
|
||||
* added FormRegistryInterface, ResolvedFormTypeInterface and ResolvedFormTypeFactoryInterface
|
||||
* deprecated FormFactory methods
|
||||
* `addType`
|
||||
* `hasType`
|
||||
* `getType`
|
||||
* [BC BREAK] FormFactory now expects a FormRegistryInterface as constructor argument
|
||||
* [BC BREAK] FormFactory now expects a FormRegistryInterface and a ResolvedFormTypeFactoryInterface as constructor argument
|
||||
* [BC BREAK] The method `createBuilder` in FormTypeInterface is not supported anymore for performance reasons
|
||||
* [BC BREAK] Removed `setTypes` from FormBuilder
|
||||
* deprecated AbstractType methods
|
||||
|
@ -23,9 +23,15 @@ class FormFactory implements FormFactoryInterface
|
||||
*/
|
||||
private $registry;
|
||||
|
||||
public function __construct(FormRegistryInterface $registry)
|
||||
/**
|
||||
* @var ResolvedFormTypeFactoryInterface
|
||||
*/
|
||||
private $resolvedTypeFactory;
|
||||
|
||||
public function __construct(FormRegistryInterface $registry, ResolvedFormTypeFactoryInterface $resolvedTypeFactory)
|
||||
{
|
||||
$this->registry = $registry;
|
||||
$this->resolvedTypeFactory = $resolvedTypeFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,14 +79,20 @@ class FormFactory implements FormFactoryInterface
|
||||
$options['data'] = $data;
|
||||
}
|
||||
|
||||
if ($type instanceof ResolvedFormTypeInterface) {
|
||||
$this->registry->addType($type);
|
||||
} elseif ($type instanceof FormTypeInterface) {
|
||||
$type = $this->registry->resolveType($type);
|
||||
$this->registry->addType($type);
|
||||
if ($type instanceof FormTypeInterface) {
|
||||
// An unresolved type instance was passed. Type extensions
|
||||
// are not supported for these. If you want to use type
|
||||
// extensions, you should create form extensions or register
|
||||
// your type in the Dependency Injection configuration instead.
|
||||
$parentType = $type->getParent();
|
||||
$type = $this->resolvedTypeFactory->createResolvedType(
|
||||
$type,
|
||||
array(),
|
||||
$parentType ? $this->registry->getType($parentType) : null
|
||||
);
|
||||
} elseif (is_string($type)) {
|
||||
$type = $this->registry->getType($type);
|
||||
} else {
|
||||
} elseif (!$type instanceof ResolvedFormTypeInterface) {
|
||||
throw new UnexpectedTypeException($type, 'string, Symfony\Component\Form\ResolvedFormTypeInterface or Symfony\Component\Form\FormTypeInterface');
|
||||
}
|
||||
|
||||
@ -152,12 +164,18 @@ class FormFactory implements FormFactoryInterface
|
||||
* @param FormTypeInterface $type The type
|
||||
*
|
||||
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
|
||||
* {@link FormRegistryInterface::resolveType()} and
|
||||
* {@link FormRegistryInterface::addType()} instead.
|
||||
* form extensions or type registration in the Dependency
|
||||
* Injection Container instead.
|
||||
*/
|
||||
public function addType(FormTypeInterface $type)
|
||||
{
|
||||
$this->registry->addType($this->registry->resolveType($type));
|
||||
$parentType = $type->getParent();
|
||||
|
||||
$this->registry->addType($this->resolvedTypeFactory->createResolvedType(
|
||||
$type,
|
||||
array(),
|
||||
$parentType ? $this->registry->getType($parentType) : null
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,14 +37,20 @@ class FormRegistry implements FormRegistryInterface
|
||||
*/
|
||||
private $guesser;
|
||||
|
||||
/**
|
||||
* @var ResolvedFormTypeFactoryInterface
|
||||
*/
|
||||
private $resolvedTypeFactory;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $extensions An array of FormExtensionInterface
|
||||
* @param array $extensions An array of FormExtensionInterface
|
||||
* @param ResolvedFormTypeFactoryInterface $resolvedTypeFactory The factory for resolved form types.
|
||||
*
|
||||
* @throws UnexpectedTypeException if any extension does not implement FormExtensionInterface
|
||||
*/
|
||||
public function __construct(array $extensions)
|
||||
public function __construct(array $extensions, ResolvedFormTypeFactoryInterface $resolvedTypeFactory)
|
||||
{
|
||||
foreach ($extensions as $extension) {
|
||||
if (!$extension instanceof FormExtensionInterface) {
|
||||
@ -53,26 +59,7 @@ class FormRegistry implements FormRegistryInterface
|
||||
}
|
||||
|
||||
$this->extensions = $extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolveType(FormTypeInterface $type)
|
||||
{
|
||||
$typeExtensions = array();
|
||||
|
||||
foreach ($this->extensions as $extension) {
|
||||
/* @var FormExtensionInterface $extension */
|
||||
$typeExtensions = array_merge(
|
||||
$typeExtensions,
|
||||
$extension->getTypeExtensions($type->getName())
|
||||
);
|
||||
}
|
||||
|
||||
$parent = $type->getParent() ? $this->getType($type->getParent()) : null;
|
||||
|
||||
return new ResolvedFormType($type, $typeExtensions, $parent);
|
||||
$this->resolvedTypeFactory = $resolvedTypeFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,6 +80,7 @@ class FormRegistry implements FormRegistryInterface
|
||||
}
|
||||
|
||||
if (!isset($this->types[$name])) {
|
||||
/** @var FormTypeInterface $type */
|
||||
$type = null;
|
||||
|
||||
foreach ($this->extensions as $extension) {
|
||||
@ -107,7 +95,22 @@ class FormRegistry implements FormRegistryInterface
|
||||
throw new FormException(sprintf('Could not load type "%s"', $name));
|
||||
}
|
||||
|
||||
$this->addType($this->resolveType($type));
|
||||
$parentType = $type->getParent();
|
||||
$typeExtensions = array();
|
||||
|
||||
foreach ($this->extensions as $extension) {
|
||||
/* @var FormExtensionInterface $extension */
|
||||
$typeExtensions = array_merge(
|
||||
$typeExtensions,
|
||||
$extension->getTypeExtensions($name)
|
||||
);
|
||||
}
|
||||
|
||||
$this->addType($this->resolvedTypeFactory->createResolvedType(
|
||||
$type,
|
||||
$typeExtensions,
|
||||
$parentType ? $this->getType($parentType) : null
|
||||
));
|
||||
}
|
||||
|
||||
return $this->types[$name];
|
||||
|
@ -22,6 +22,10 @@ interface FormRegistryInterface
|
||||
* Adds a form type.
|
||||
*
|
||||
* @param ResolvedFormTypeInterface $type The type
|
||||
*
|
||||
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
|
||||
* form extensions or type registration in the Dependency
|
||||
* Injection Container instead.
|
||||
*/
|
||||
public function addType(ResolvedFormTypeInterface $type);
|
||||
|
||||
@ -48,18 +52,6 @@ interface FormRegistryInterface
|
||||
*/
|
||||
public function hasType($name);
|
||||
|
||||
/**
|
||||
* Resolves a form type.
|
||||
*
|
||||
* @param FormTypeInterface $type
|
||||
*
|
||||
* @return ResolvedFormTypeInterface
|
||||
*
|
||||
* @throws Exception\UnexpectedTypeException if the types parent {@link FormTypeInterface::getParent()} is not a string
|
||||
* @throws Exception\FormException if the types parent can not be retrieved from any extension
|
||||
*/
|
||||
public function resolveType(FormTypeInterface $type);
|
||||
|
||||
/**
|
||||
* Returns the guesser responsible for guessing types.
|
||||
*
|
||||
|
@ -35,7 +35,7 @@ class ResolvedFormType implements ResolvedFormTypeInterface
|
||||
private $typeExtensions;
|
||||
|
||||
/**
|
||||
* @var ResolvedFormType
|
||||
* @var ResolvedFormTypeInterface
|
||||
*/
|
||||
private $parent;
|
||||
|
||||
@ -44,7 +44,7 @@ class ResolvedFormType implements ResolvedFormTypeInterface
|
||||
*/
|
||||
private $optionsResolver;
|
||||
|
||||
public function __construct(FormTypeInterface $innerType, array $typeExtensions = array(), ResolvedFormType $parent = null)
|
||||
public function __construct(FormTypeInterface $innerType, array $typeExtensions = array(), ResolvedFormTypeInterface $parent = null)
|
||||
{
|
||||
if (!preg_match('/^[a-z0-9_]*$/i', $innerType->getName())) {
|
||||
throw new FormException(sprintf(
|
||||
@ -148,7 +148,16 @@ class ResolvedFormType implements ResolvedFormTypeInterface
|
||||
return $view;
|
||||
}
|
||||
|
||||
private function buildForm(FormBuilderInterface $builder, array $options)
|
||||
/**
|
||||
* Configures a form builder for the type hierarchy.
|
||||
*
|
||||
* This method is protected in order to allow implementing classes
|
||||
* to change or call it in re-implementations of {@link createBuilder()}.
|
||||
*
|
||||
* @param FormBuilderInterface $builder The builder to configure.
|
||||
* @param array $options The options used for the configuration.
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
if (null !== $this->parent) {
|
||||
$this->parent->buildForm($builder, $options);
|
||||
@ -162,7 +171,19 @@ class ResolvedFormType implements ResolvedFormTypeInterface
|
||||
}
|
||||
}
|
||||
|
||||
private function buildView(FormView $view, FormInterface $form, array $options)
|
||||
/**
|
||||
* Configures a form view for the type hierarchy.
|
||||
*
|
||||
* This method is protected in order to allow implementing classes
|
||||
* to change or call it in re-implementations of {@link createView()}.
|
||||
*
|
||||
* It is called before the children of the view are built.
|
||||
*
|
||||
* @param FormView $view The form view to configure.
|
||||
* @param FormInterface $form The form corresponding to the view.
|
||||
* @param array $options The options used for the configuration.
|
||||
*/
|
||||
public function buildView(FormView $view, FormInterface $form, array $options)
|
||||
{
|
||||
if (null !== $this->parent) {
|
||||
$this->parent->buildView($view, $form, $options);
|
||||
@ -176,7 +197,19 @@ class ResolvedFormType implements ResolvedFormTypeInterface
|
||||
}
|
||||
}
|
||||
|
||||
private function finishView(FormView $view, FormInterface $form, array $options)
|
||||
/**
|
||||
* Finishes a form view for the type hierarchy.
|
||||
*
|
||||
* This method is protected in order to allow implementing classes
|
||||
* to change or call it in re-implementations of {@link createView()}.
|
||||
*
|
||||
* It is called after the children of the view have been built.
|
||||
*
|
||||
* @param FormView $view The form view to configure.
|
||||
* @param FormInterface $form The form corresponding to the view.
|
||||
* @param array $options The options used for the configuration.
|
||||
*/
|
||||
public function finishView(FormView $view, FormInterface $form, array $options)
|
||||
{
|
||||
if (null !== $this->parent) {
|
||||
$this->parent->finishView($view, $form, $options);
|
||||
@ -190,7 +223,15 @@ class ResolvedFormType implements ResolvedFormTypeInterface
|
||||
}
|
||||
}
|
||||
|
||||
private function getOptionsResolver()
|
||||
/**
|
||||
* Returns the configured options resolver used for this type.
|
||||
*
|
||||
* This method is protected in order to allow implementing classes
|
||||
* to change or call it in re-implementations of {@link createBuilder()}.
|
||||
*
|
||||
* @return \Symfony\Component\OptionsResolver\OptionsResolverInterface The options resolver.
|
||||
*/
|
||||
public function getOptionsResolver()
|
||||
{
|
||||
if (null === $this->optionsResolver) {
|
||||
if (null !== $this->parent) {
|
||||
|
26
src/Symfony/Component/Form/ResolvedFormTypeFactory.php
Normal file
26
src/Symfony/Component/Form/ResolvedFormTypeFactory.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class ResolvedFormTypeFactory implements ResolvedFormTypeFactoryInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createResolvedType(FormTypeInterface $type, array $typeExtensions, ResolvedFormTypeInterface $parent = null)
|
||||
{
|
||||
return new ResolvedFormType($type, $typeExtensions, $parent);
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* Creates ResolvedFormTypeInterface instances.
|
||||
*
|
||||
* This interface allows you to use your custom ResolvedFormTypeInterface
|
||||
* implementation, within which you can customize the concrete FormBuilderInterface
|
||||
* implementations or FormView subclasses that are used by the framework.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
interface ResolvedFormTypeFactoryInterface
|
||||
{
|
||||
/**
|
||||
* Resolves a form type.
|
||||
*
|
||||
* @param FormTypeInterface $type
|
||||
* @param array $typeExtensions
|
||||
* @param ResolvedFormTypeInterface $parent
|
||||
*
|
||||
* @return ResolvedFormTypeInterface
|
||||
*
|
||||
* @throws Exception\UnexpectedTypeException if the types parent {@link FormTypeInterface::getParent()} is not a string
|
||||
* @throws Exception\FormException if the types parent can not be retrieved from any extension
|
||||
*/
|
||||
public function createResolvedType(FormTypeInterface $type, array $typeExtensions, ResolvedFormTypeInterface $parent = null);
|
||||
}
|
@ -67,4 +67,41 @@ interface ResolvedFormTypeInterface
|
||||
* @return FormView The created form view.
|
||||
*/
|
||||
public function createView(FormInterface $form, FormView $parent = null);
|
||||
|
||||
/**
|
||||
* Configures a form builder for the type hierarchy.
|
||||
*
|
||||
* @param FormBuilderInterface $builder The builder to configure.
|
||||
* @param array $options The options used for the configuration.
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options);
|
||||
|
||||
/**
|
||||
* Configures a form view for the type hierarchy.
|
||||
*
|
||||
* It is called before the children of the view are built.
|
||||
*
|
||||
* @param FormView $view The form view to configure.
|
||||
* @param FormInterface $form The form corresponding to the view.
|
||||
* @param array $options The options used for the configuration.
|
||||
*/
|
||||
public function buildView(FormView $view, FormInterface $form, array $options);
|
||||
|
||||
/**
|
||||
* Finishes a form view for the type hierarchy.
|
||||
*
|
||||
* It is called after the children of the view have been built.
|
||||
*
|
||||
* @param FormView $view The form view to configure.
|
||||
* @param FormInterface $form The form corresponding to the view.
|
||||
* @param array $options The options used for the configuration.
|
||||
*/
|
||||
public function finishView(FormView $view, FormInterface $form, array $options);
|
||||
|
||||
/**
|
||||
* Returns the configured options resolver used for this type.
|
||||
*
|
||||
* @return \Symfony\Component\OptionsResolver\OptionsResolverInterface The options resolver.
|
||||
*/
|
||||
public function getOptionsResolver();
|
||||
}
|
||||
|
@ -44,6 +44,11 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
private $registry;
|
||||
|
||||
/**
|
||||
* @var \PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
private $resolvedTypeFactory;
|
||||
|
||||
/**
|
||||
* @var FormFactory
|
||||
*/
|
||||
@ -55,10 +60,11 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
$this->markTestSkipped('The "EventDispatcher" component is not available');
|
||||
}
|
||||
|
||||
$this->resolvedTypeFactory = $this->getMock('Symfony\Component\Form\ResolvedFormTypeFactoryInterface');
|
||||
$this->guesser1 = $this->getMock('Symfony\Component\Form\FormTypeGuesserInterface');
|
||||
$this->guesser2 = $this->getMock('Symfony\Component\Form\FormTypeGuesserInterface');
|
||||
$this->registry = $this->getMock('Symfony\Component\Form\FormRegistryInterface');
|
||||
$this->factory = new FormFactory($this->registry);
|
||||
$this->factory = new FormFactory($this->registry, $this->resolvedTypeFactory);
|
||||
|
||||
$this->registry->expects($this->any())
|
||||
->method('getTypeGuesser')
|
||||
@ -73,8 +79,8 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
$type = new FooType();
|
||||
$resolvedType = $this->getMockResolvedType();
|
||||
|
||||
$this->registry->expects($this->once())
|
||||
->method('resolveType')
|
||||
$this->resolvedTypeFactory->expects($this->once())
|
||||
->method('createResolvedType')
|
||||
->with($type)
|
||||
->will($this->returnValue($resolvedType));
|
||||
|
||||
@ -136,16 +142,11 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
$type = $this->getMockType();
|
||||
$resolvedType = $this->getMockResolvedType();
|
||||
|
||||
$this->registry->expects($this->once())
|
||||
->method('resolveType')
|
||||
$this->resolvedTypeFactory->expects($this->once())
|
||||
->method('createResolvedType')
|
||||
->with($type)
|
||||
->will($this->returnValue($resolvedType));
|
||||
|
||||
// The type is also implicitly added to the registry
|
||||
$this->registry->expects($this->once())
|
||||
->method('addType')
|
||||
->with($resolvedType);
|
||||
|
||||
$resolvedType->expects($this->once())
|
||||
->method('createBuilder')
|
||||
->with($this->factory, 'name', $options)
|
||||
@ -159,11 +160,6 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
$options = array('a' => '1', 'b' => '2');
|
||||
$resolvedType = $this->getMockResolvedType();
|
||||
|
||||
// The type is also implicitly added to the registry
|
||||
$this->registry->expects($this->once())
|
||||
->method('addType')
|
||||
->with($resolvedType);
|
||||
|
||||
$resolvedType->expects($this->once())
|
||||
->method('createBuilder')
|
||||
->with($this->factory, 'name', $options)
|
||||
@ -555,7 +551,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
return $this->getMockBuilder('Symfony\Component\Form\FormFactory')
|
||||
->setMethods($methods)
|
||||
->setConstructorArgs(array($this->registry))
|
||||
->setConstructorArgs(array($this->registry, $this->resolvedTypeFactory))
|
||||
->getMock();
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\Form\Tests;
|
||||
|
||||
use Symfony\Component\Form\FormFactory;
|
||||
use Symfony\Component\Form\ResolvedFormTypeFactory;
|
||||
use Symfony\Component\Form\FormRegistry;
|
||||
use Symfony\Component\Form\Extension\Core\CoreExtension;
|
||||
|
||||
@ -20,6 +21,11 @@ use Symfony\Component\Form\Extension\Core\CoreExtension;
|
||||
*/
|
||||
class FormIntegrationTestCase extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var ResolvedFormTypeFactory
|
||||
*/
|
||||
protected $resolvedTypeFactory;
|
||||
|
||||
/**
|
||||
* @var FormRegistry
|
||||
*/
|
||||
@ -36,8 +42,9 @@ class FormIntegrationTestCase extends \PHPUnit_Framework_TestCase
|
||||
$this->markTestSkipped('The "EventDispatcher" component is not available');
|
||||
}
|
||||
|
||||
$this->registry = new FormRegistry($this->getExtensions());
|
||||
$this->factory = new FormFactory($this->registry);
|
||||
$this->resolvedTypeFactory = new ResolvedFormTypeFactory();
|
||||
$this->registry = new FormRegistry($this->getExtensions(), $this->resolvedTypeFactory);
|
||||
$this->factory = new FormFactory($this->registry, $this->resolvedTypeFactory);
|
||||
}
|
||||
|
||||
protected function getExtensions()
|
||||
|
@ -27,6 +27,11 @@ class FormRegistryTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
private $registry;
|
||||
|
||||
/**
|
||||
* @var \PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
private $resolvedTypeFactory;
|
||||
|
||||
/**
|
||||
* @var \PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
@ -49,6 +54,7 @@ class FormRegistryTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->resolvedTypeFactory = $this->getMock('Symfony\Component\Form\ResolvedFormTypeFactory');
|
||||
$this->guesser1 = $this->getMock('Symfony\Component\Form\FormTypeGuesserInterface');
|
||||
$this->guesser2 = $this->getMock('Symfony\Component\Form\FormTypeGuesserInterface');
|
||||
$this->extension1 = new TestExtension($this->guesser1);
|
||||
@ -56,53 +62,16 @@ class FormRegistryTest extends \PHPUnit_Framework_TestCase
|
||||
$this->registry = new FormRegistry(array(
|
||||
$this->extension1,
|
||||
$this->extension2,
|
||||
));
|
||||
}
|
||||
|
||||
public function testResolveType()
|
||||
{
|
||||
$type = new FooType();
|
||||
$ext1 = new FooTypeBarExtension();
|
||||
$ext2 = new FooTypeBazExtension();
|
||||
|
||||
$this->extension1->addTypeExtension($ext1);
|
||||
$this->extension2->addTypeExtension($ext2);
|
||||
|
||||
$resolvedType = $this->registry->resolveType($type);
|
||||
|
||||
$this->assertEquals($type, $resolvedType->getInnerType());
|
||||
$this->assertEquals(array($ext1, $ext2), $resolvedType->getTypeExtensions());
|
||||
}
|
||||
|
||||
public function testResolveTypeConnectsParent()
|
||||
{
|
||||
$parentType = new FooType();
|
||||
$type = new FooSubType();
|
||||
|
||||
$resolvedParentType = $this->registry->resolveType($parentType);
|
||||
|
||||
$this->registry->addType($resolvedParentType);
|
||||
|
||||
$resolvedType = $this->registry->resolveType($type);
|
||||
|
||||
$this->assertSame($resolvedParentType, $resolvedType->getParent());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Symfony\Component\Form\Exception\FormException
|
||||
*/
|
||||
public function testResolveTypeThrowsExceptionIfParentNotFound()
|
||||
{
|
||||
$type = new FooSubType();
|
||||
|
||||
$this->registry->resolveType($type);
|
||||
), $this->resolvedTypeFactory);
|
||||
}
|
||||
|
||||
public function testGetTypeReturnsAddedType()
|
||||
{
|
||||
$type = new FooType();
|
||||
$resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
|
||||
|
||||
$resolvedType = $this->registry->resolveType($type);
|
||||
$resolvedType->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo'));
|
||||
|
||||
$this->registry->addType($resolvedType);
|
||||
|
||||
@ -112,13 +81,88 @@ class FormRegistryTest extends \PHPUnit_Framework_TestCase
|
||||
public function testGetTypeFromExtension()
|
||||
{
|
||||
$type = new FooType();
|
||||
$resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
|
||||
|
||||
$this->extension2->addType($type);
|
||||
|
||||
$this->resolvedTypeFactory->expects($this->once())
|
||||
->method('createResolvedType')
|
||||
->with($type)
|
||||
->will($this->returnValue($resolvedType));
|
||||
|
||||
$resolvedType->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo'));
|
||||
|
||||
$resolvedType = $this->registry->getType('foo');
|
||||
|
||||
$this->assertInstanceOf('Symfony\Component\Form\ResolvedFormTypeInterface', $resolvedType);
|
||||
$this->assertSame($type, $resolvedType->getInnerType());
|
||||
$this->assertSame($resolvedType, $this->registry->getType('foo'));
|
||||
}
|
||||
|
||||
public function testGetTypeWithTypeExtensions()
|
||||
{
|
||||
$type = new FooType();
|
||||
$ext1 = new FooTypeBarExtension();
|
||||
$ext2 = new FooTypeBazExtension();
|
||||
$resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
|
||||
|
||||
$this->extension2->addType($type);
|
||||
$this->extension1->addTypeExtension($ext1);
|
||||
$this->extension2->addTypeExtension($ext2);
|
||||
|
||||
$this->resolvedTypeFactory->expects($this->once())
|
||||
->method('createResolvedType')
|
||||
->with($type, array($ext1, $ext2))
|
||||
->will($this->returnValue($resolvedType));
|
||||
|
||||
$resolvedType->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo'));
|
||||
|
||||
$this->assertSame($resolvedType, $this->registry->getType('foo'));
|
||||
}
|
||||
|
||||
public function testGetTypeConnectsParent()
|
||||
{
|
||||
$parentType = new FooType();
|
||||
$type = new FooSubType();
|
||||
$parentResolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
|
||||
$resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
|
||||
|
||||
$this->extension1->addType($parentType);
|
||||
$this->extension2->addType($type);
|
||||
|
||||
$this->resolvedTypeFactory->expects($this->at(0))
|
||||
->method('createResolvedType')
|
||||
->with($parentType)
|
||||
->will($this->returnValue($parentResolvedType));
|
||||
|
||||
$this->resolvedTypeFactory->expects($this->at(1))
|
||||
->method('createResolvedType')
|
||||
->with($type, array(), $parentResolvedType)
|
||||
->will($this->returnValue($resolvedType));
|
||||
|
||||
$parentResolvedType->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo'));
|
||||
|
||||
$resolvedType->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo_sub_type'));
|
||||
|
||||
$this->assertSame($resolvedType, $this->registry->getType('foo_sub_type'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Symfony\Component\Form\Exception\FormException
|
||||
*/
|
||||
public function testGetTypeThrowsExceptionIfParentNotFound()
|
||||
{
|
||||
$type = new FooSubType();
|
||||
|
||||
$this->extension1->addType($type);
|
||||
|
||||
$this->registry->getType($type);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,9 +183,11 @@ class FormRegistryTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testHasTypeAfterAdding()
|
||||
{
|
||||
$type = new FooType();
|
||||
$resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
|
||||
|
||||
$resolvedType = $this->registry->resolveType($type);
|
||||
$resolvedType->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo'));
|
||||
|
||||
$this->assertFalse($this->registry->hasType('foo'));
|
||||
|
||||
@ -153,6 +199,16 @@ class FormRegistryTest extends \PHPUnit_Framework_TestCase
|
||||
public function testHasTypeAfterLoadingFromExtension()
|
||||
{
|
||||
$type = new FooType();
|
||||
$resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
|
||||
|
||||
$this->resolvedTypeFactory->expects($this->once())
|
||||
->method('createResolvedType')
|
||||
->with($type)
|
||||
->will($this->returnValue($resolvedType));
|
||||
|
||||
$resolvedType->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo'));
|
||||
|
||||
$this->assertFalse($this->registry->hasType('foo'));
|
||||
|
||||
|
Reference in New Issue
Block a user