@@ -31,7 +37,7 @@ class FormRegistryTest extends \PHPUnit_Framework_TestCase
private $registry;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var \PHPUnit_Framework_MockObject_MockObject|ResolvedFormTypeFactoryInterface
*/
private $resolvedTypeFactory;
@@ -71,22 +77,64 @@ protected function setUp()
public function testGetTypeFromExtension()
{
$type = new FooType();
- $resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
+ $resolvedType = new ResolvedFormType($type);
$this->extension2->addType($type);
$this->resolvedTypeFactory->expects($this->once())
->method('createResolvedType')
->with($type)
- ->will($this->returnValue($resolvedType));
+ ->willReturn($resolvedType);
+
+ $this->assertSame($resolvedType, $this->registry->getType(get_class($type)));
+ }
+
+ public function testLoadUnregisteredType()
+ {
+ $type = new FooType();
+ $resolvedType = new ResolvedFormType($type);
+
+ $this->resolvedTypeFactory->expects($this->once())
+ ->method('createResolvedType')
+ ->with($type)
+ ->willReturn($resolvedType);
+
+ $this->assertSame($resolvedType, $this->registry->getType('Symfony\Component\Form\Tests\Fixtures\FooType'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Form\Exception\InvalidArgumentException
+ */
+ public function testFailIfUnregisteredTypeNoClass()
+ {
+ $this->registry->getType('Symfony\Blubb');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Form\Exception\InvalidArgumentException
+ */
+ public function testFailIfUnregisteredTypeNoFormType()
+ {
+ $this->registry->getType('stdClass');
+ }
- $resolvedType->expects($this->any())
- ->method('getName')
- ->will($this->returnValue('foo'));
+ public function testLegacyGetTypeFromExtension()
+ {
+ $type = new LegacyFooType();
+ $resolvedType = new ResolvedFormType($type);
- $resolvedType = $this->registry->getType('foo');
+ $this->extension2->addType($type);
+
+ $this->resolvedTypeFactory->expects($this->once())
+ ->method('createResolvedType')
+ ->with($type)
+ ->willReturn($resolvedType);
$this->assertSame($resolvedType, $this->registry->getType('foo'));
+
+ // Even types with explicit getName() methods must support access by
+ // FQCN to support a smooth transition from 2.8 => 3.0
+ $this->assertSame($resolvedType, $this->registry->getType(get_class($type)));
}
public function testGetTypeWithTypeExtensions()
@@ -94,7 +142,7 @@ public function testGetTypeWithTypeExtensions()
$type = new FooType();
$ext1 = new FooTypeBarExtension();
$ext2 = new FooTypeBazExtension();
- $resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
+ $resolvedType = new ResolvedFormType($type, array($ext1, $ext2));
$this->extension2->addType($type);
$this->extension1->addTypeExtension($ext1);
@@ -103,11 +151,26 @@ public function testGetTypeWithTypeExtensions()
$this->resolvedTypeFactory->expects($this->once())
->method('createResolvedType')
->with($type, array($ext1, $ext2))
- ->will($this->returnValue($resolvedType));
+ ->willReturn($resolvedType);
+
+ $this->assertSame($resolvedType, $this->registry->getType(get_class($type)));
+ }
+
+ public function testLegacyGetTypeWithTypeExtensions()
+ {
+ $type = new LegacyFooType();
+ $ext1 = new LegacyFooTypeBarExtension();
+ $ext2 = new LegacyFooTypeBazExtension();
+ $resolvedType = new ResolvedFormType($type, array($ext1, $ext2));
- $resolvedType->expects($this->any())
- ->method('getName')
- ->will($this->returnValue('foo'));
+ $this->extension2->addType($type);
+ $this->extension1->addTypeExtension($ext1);
+ $this->extension2->addTypeExtension($ext2);
+
+ $this->resolvedTypeFactory->expects($this->once())
+ ->method('createResolvedType')
+ ->with($type, array($ext1, $ext2))
+ ->willReturn($resolvedType);
$this->assertSame($resolvedType, $this->registry->getType('foo'));
}
@@ -116,8 +179,8 @@ public function testGetTypeConnectsParent()
{
$parentType = new FooType();
$type = new FooSubType();
- $parentResolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
- $resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
+ $parentResolvedType = new ResolvedFormType($parentType);
+ $resolvedType = new ResolvedFormType($type);
$this->extension1->addType($parentType);
$this->extension2->addType($type);
@@ -125,49 +188,59 @@ public function testGetTypeConnectsParent()
$this->resolvedTypeFactory->expects($this->at(0))
->method('createResolvedType')
->with($parentType)
- ->will($this->returnValue($parentResolvedType));
+ ->willReturn($parentResolvedType);
$this->resolvedTypeFactory->expects($this->at(1))
->method('createResolvedType')
->with($type, array(), $parentResolvedType)
- ->will($this->returnValue($resolvedType));
+ ->willReturn($resolvedType);
+
+ $this->assertSame($resolvedType, $this->registry->getType(get_class($type)));
+ }
+
+ public function testLegacyGetTypeConnectsParent()
+ {
+ $parentType = new LegacyFooType();
+ $type = new LegacyFooSubType();
+ $parentResolvedType = new ResolvedFormType($parentType);
+ $resolvedType = new ResolvedFormType($type);
- $parentResolvedType->expects($this->any())
- ->method('getName')
- ->will($this->returnValue('foo'));
+ $this->extension1->addType($parentType);
+ $this->extension2->addType($type);
- $resolvedType->expects($this->any())
- ->method('getName')
- ->will($this->returnValue('foo_sub_type'));
+ $this->resolvedTypeFactory->expects($this->at(0))
+ ->method('createResolvedType')
+ ->with($parentType)
+ ->willReturn($parentResolvedType);
+
+ $this->resolvedTypeFactory->expects($this->at(1))
+ ->method('createResolvedType')
+ ->with($type, array(), $parentResolvedType)
+ ->willReturn($resolvedType);
$this->assertSame($resolvedType, $this->registry->getType('foo_sub_type'));
}
+ /**
+ * @group legacy
+ */
public function testGetTypeConnectsParentIfGetParentReturnsInstance()
{
- $type = new FooSubTypeWithParentInstance();
- $parentResolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
- $resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
+ $type = new LegacyFooSubTypeWithParentInstance();
+ $parentResolvedType = new ResolvedFormType($type->getParent());
+ $resolvedType = new ResolvedFormType($type);
$this->extension1->addType($type);
$this->resolvedTypeFactory->expects($this->at(0))
->method('createResolvedType')
- ->with($this->isInstanceOf('Symfony\Component\Form\Tests\Fixtures\FooType'))
- ->will($this->returnValue($parentResolvedType));
+ ->with($type->getParent())
+ ->willReturn($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_parent_instance'));
+ ->willReturn($resolvedType);
$this->assertSame($resolvedType, $this->registry->getType('foo_sub_type_parent_instance'));
}
@@ -184,6 +257,18 @@ public function testGetTypeThrowsExceptionIfParentNotFound()
$this->registry->getType($type);
}
+ /**
+ * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException
+ */
+ public function testLegacyGetTypeThrowsExceptionIfParentNotFound()
+ {
+ $type = new LegacyFooSubType();
+
+ $this->extension1->addType($type);
+
+ $this->registry->getType($type);
+ }
+
/**
* @expectedException \Symfony\Component\Form\Exception\InvalidArgumentException
*/
@@ -203,18 +288,42 @@ public function testGetTypeThrowsExceptionIfNoString()
public function testHasTypeAfterLoadingFromExtension()
{
$type = new FooType();
- $resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
+ $resolvedType = new ResolvedFormType($type);
$this->resolvedTypeFactory->expects($this->once())
->method('createResolvedType')
->with($type)
- ->will($this->returnValue($resolvedType));
+ ->willReturn($resolvedType);
- $resolvedType->expects($this->any())
- ->method('getName')
- ->will($this->returnValue('foo'));
+ $this->extension2->addType($type);
+
+ $this->assertTrue($this->registry->hasType(get_class($type)));
+ }
+
+ public function testHasTypeIfFQCN()
+ {
+ $this->assertTrue($this->registry->hasType('Symfony\Component\Form\Tests\Fixtures\FooType'));
+ }
- $this->assertFalse($this->registry->hasType('foo'));
+ public function testDoesNotHaveTypeIfNonExistingClass()
+ {
+ $this->assertFalse($this->registry->hasType('Symfony\Blubb'));
+ }
+
+ public function testDoesNotHaveTypeIfNoFormType()
+ {
+ $this->assertFalse($this->registry->hasType('stdClass'));
+ }
+
+ public function testLegacyHasTypeAfterLoadingFromExtension()
+ {
+ $type = new LegacyFooType();
+ $resolvedType = new ResolvedFormType($type);
+
+ $this->resolvedTypeFactory->expects($this->once())
+ ->method('createResolvedType')
+ ->with($type)
+ ->willReturn($resolvedType);
$this->extension2->addType($type);
@@ -229,7 +338,8 @@ public function testGetTypeGuesser()
$registry = new FormRegistry(
array($this->getMock('Symfony\Component\Form\FormExtensionInterface')),
- $this->resolvedTypeFactory);
+ $this->resolvedTypeFactory
+ );
$this->assertNull($registry->getTypeGuesser());
}
diff --git a/src/Symfony/Component/Form/Tests/ResolvedFormTypeTest.php b/src/Symfony/Component/Form/Tests/ResolvedFormTypeTest.php
index 234d52cf3903e..36804ebebe8bc 100644
--- a/src/Symfony/Component/Form/Tests/ResolvedFormTypeTest.php
+++ b/src/Symfony/Component/Form/Tests/ResolvedFormTypeTest.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Form\Tests;
+use Symfony\Component\Form\FormTypeExtensionInterface;
+use Symfony\Component\Form\FormTypeInterface;
use Symfony\Component\Form\ResolvedFormType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\OptionsResolver\OptionsResolver;
@@ -34,11 +36,35 @@ class ResolvedFormTypeTest extends \PHPUnit_Framework_TestCase
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $dataMapper;
+
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject|FormTypeInterface
+ */
private $parentType;
+
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject|FormTypeInterface
+ */
private $type;
+
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject|FormTypeExtensionInterface
+ */
private $extension1;
+
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject|FormTypeExtensionInterface
+ */
private $extension2;
+
+ /**
+ * @var ResolvedFormType
+ */
private $parentResolvedType;
+
+ /**
+ * @var ResolvedFormType
+ */
private $resolvedType;
protected function setUp()
@@ -305,12 +331,107 @@ public function testFinishView()
$this->resolvedType->finishView($view, $form, $options);
}
+ /**
+ * @dataProvider provideValidNames
+ */
+ public function testGetName($name)
+ {
+ $this->type->expects($this->once())
+ ->method('getName')
+ ->willReturn($name);
+
+ $resolvedType = new ResolvedFormType($this->type);
+
+ $this->assertSame($name, $resolvedType->getName());
+ }
+
+ /**
+ * @dataProvider provideInvalidNames
+ * @expectedException \Symfony\Component\Form\Exception\InvalidArgumentException
+ */
+ public function testGetNameFailsIfInvalidChars($name)
+ {
+ $this->type->expects($this->once())
+ ->method('getName')
+ ->willReturn($name);
+
+ new ResolvedFormType($this->type);
+ }
+
+ public function provideValidNames()
+ {
+ return array(
+ array('text'),
+ array('type123'),
+ array('my_type123'),
+ );
+ }
+
+ public function provideInvalidNames()
+ {
+ return array(
+ array('my-type'),
+ array('my[type]'),
+ array('my{type}'),
+ );
+ }
+
+ public function testGetBlockPrefix()
+ {
+ $this->type->expects($this->once())
+ ->method('getBlockPrefix')
+ ->willReturn('my_prefix');
+
+ $resolvedType = new ResolvedFormType($this->type);
+
+ $this->assertSame('my_prefix', $resolvedType->getBlockPrefix());
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testBlockPrefixDefaultsToNameIfSet()
+ {
+ // Type without getBlockPrefix() method
+ $type = $this->getMock('Symfony\Component\Form\FormTypeInterface');
+
+ $type->expects($this->once())
+ ->method('getName')
+ ->willReturn('my_prefix');
+
+ $resolvedType = new ResolvedFormType($type);
+
+ $this->assertSame('my_prefix', $resolvedType->getBlockPrefix());
+ }
+
+ /**
+ * @dataProvider provideTypeClassBlockPrefixTuples
+ */
+ public function testBlockPrefixDefaultsToFQCNIfNoName($typeClass, $blockPrefix)
+ {
+ $resolvedType = new ResolvedFormType(new $typeClass());
+
+ $this->assertSame($blockPrefix, $resolvedType->getBlockPrefix());
+ }
+
+ public function provideTypeClassBlockPrefixTuples()
+ {
+ return array(
+ array(__NAMESPACE__.'\Fixtures\FooType', 'foo'),
+ array(__NAMESPACE__.'\Fixtures\Foo', 'foo'),
+ array(__NAMESPACE__.'\Fixtures\Type', 'type'),
+ array(__NAMESPACE__.'\Fixtures\FooBarHTMLType', 'foo_bar_html'),
+ array(__NAMESPACE__.'\Fixtures\Foo1Bar2Type', 'foo1_bar2'),
+ array(__NAMESPACE__.'\Fixtures\FBooType', 'f_boo'),
+ );
+ }
+
/**
* @return \PHPUnit_Framework_MockObject_MockObject
*/
- private function getMockFormType()
+ private function getMockFormType($typeClass = 'Symfony\Component\Form\AbstractType')
{
- return $this->getMock('Symfony\Component\Form\AbstractType', array('getName', 'configureOptions', 'finishView', 'buildView', 'buildForm'));
+ return $this->getMock($typeClass, array('getName', 'getBlockPrefix', 'configureOptions', 'finishView', 'buildView', 'buildForm'));
}
/**
diff --git a/src/Symfony/Component/Form/Tests/SimpleFormTest.php b/src/Symfony/Component/Form/Tests/SimpleFormTest.php
index 6fb24a8cdc9c7..9f5de6dfd764c 100644
--- a/src/Symfony/Component/Form/Tests/SimpleFormTest.php
+++ b/src/Symfony/Component/Form/Tests/SimpleFormTest.php
@@ -1063,7 +1063,7 @@ public function testInitializeFailsIfParent()
*/
public function testCustomOptionsResolver()
{
- $fooType = new Fixtures\FooType();
+ $fooType = new Fixtures\LegacyFooType();
$resolver = new Fixtures\CustomOptionsResolver();
$fooType->setDefaultOptions($resolver);
}
diff --git a/src/Symfony/Component/Form/Util/StringUtil.php b/src/Symfony/Component/Form/Util/StringUtil.php
index 2f51e74afcaac..ee71ae7a52e14 100644
--- a/src/Symfony/Component/Form/Util/StringUtil.php
+++ b/src/Symfony/Component/Form/Util/StringUtil.php
@@ -39,4 +39,19 @@ public static function trim($string)
return trim($string);
}
+
+ /**
+ * Converts a fully-qualified class name to a block prefix.
+ *
+ * @param string $fqcn The fully-qualified class name
+ *
+ * @return string|null The block prefix or null if not a valid FQCN
+ */
+ public static function fqcnToBlockPrefix($fqcn)
+ {
+ // Non-greedy ("+?") to match "type" suffix, if present
+ if (preg_match('~([^\\\\]+?)(type)?$~i', $fqcn, $matches)) {
+ return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), $matches[1]));
+ }
+ }
}
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy