diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index 624894ffb3fa5..a30a318599bdd 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -133,7 +133,7 @@ UPGRADE FROM 2.x to 3.0 ``` * The `TypeTestCase` class was moved from the `Symfony\Component\Form\Tests\Extension\Core\Type` namespace to the `Symfony\Component\Form\Test` namespace. - + Before: ``` @@ -162,6 +162,12 @@ UPGRADE FROM 2.x to 3.0 `NumberToLocalizedStringTransformer` were renamed to `ROUND_HALF_EVEN`, `ROUND_HALF_UP` and `ROUND_HALF_DOWN`. + * The methods `ChoiceListInterface::getIndicesForChoices()` and + `ChoiceListInterface::getIndicesForValues()` were removed. No direct + replacement exists, although in most cases + `ChoiceListInterface::getChoicesForValues()` and + `ChoiceListInterface::getValuesForChoices()` should be sufficient. + ### FrameworkBundle @@ -249,7 +255,7 @@ UPGRADE FROM 2.x to 3.0 * The Locale component was removed and replaced by the Intl component. Instead of the methods in `Symfony\Component\Locale\Locale`, you should use these equivalent methods in `Symfony\Component\Intl\Intl` now: - + * `Locale::getDisplayCountries()` -> `Intl::getRegionBundle()->getCountryNames()` * `Locale::getCountries()` -> `array_keys(Intl::getRegionBundle()->getCountryNames())` * `Locale::getDisplayLanguages()` -> `Intl::getLanguageBundle()->getLanguageNames()` diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php index 74042a7b41a31..228f9aad2fe18 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php @@ -208,11 +208,26 @@ public function getChoicesForValues(array $values) // Optimize performance in case we have an entity loader and // a single-field identifier if ($this->idAsValue && $this->entityLoader) { - if (empty($values)) { - return array(); + $unorderedEntities = $this->entityLoader->getEntitiesByIds($this->idField, $values); + $entitiesByValue = array(); + $entities = array(); + + // Maintain order and indices from the given $values + // An alternative approach to the following loop is to add the + // "INDEX BY" clause to the Doctrine query in the loader, + // but I'm not sure whether that's doable in a generic fashion. + foreach ($unorderedEntities as $entity) { + $value = $this->fixValue(current($this->getIdentifierValues($entity))); + $entitiesByValue[$value] = $entity; } - return $this->entityLoader->getEntitiesByIds($this->idField, $values); + foreach ($values as $i => $value) { + if (isset($entitiesByValue[$value])) { + $entities[$i] = $entitiesByValue[$value]; + } + } + + return $entities; } $this->load(); @@ -240,10 +255,10 @@ public function getValuesForChoices(array $entities) if ($this->idAsValue) { $values = array(); - foreach ($entities as $entity) { + foreach ($entities as $i => $entity) { if ($entity instanceof $this->class) { // Make sure to convert to the right format - $values[] = $this->fixValue(current($this->getIdentifierValues($entity))); + $values[$i] = $this->fixValue(current($this->getIdentifierValues($entity))); } } @@ -264,6 +279,8 @@ public function getValuesForChoices(array $entities) * @return array * * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + * + * @deprecated Deprecated since version 2.4, to be removed in 3.0. */ public function getIndicesForChoices(array $entities) { @@ -275,10 +292,10 @@ public function getIndicesForChoices(array $entities) if ($this->idAsIndex) { $indices = array(); - foreach ($entities as $entity) { + foreach ($entities as $i => $entity) { if ($entity instanceof $this->class) { // Make sure to convert to the right format - $indices[] = $this->fixIndex(current($this->getIdentifierValues($entity))); + $indices[$i] = $this->fixIndex(current($this->getIdentifierValues($entity))); } } @@ -299,6 +316,8 @@ public function getIndicesForChoices(array $entities) * @return array * * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + * + * @deprecated Deprecated since version 2.4, to be removed in 3.0. */ public function getIndicesForValues(array $values) { diff --git a/src/Symfony/Bridge/Doctrine/Test/DoctrineTestHelper.php b/src/Symfony/Bridge/Doctrine/Test/DoctrineTestHelper.php new file mode 100644 index 0000000000000..c763653ad9f33 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Test/DoctrineTestHelper.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Test; + +use Doctrine\Common\Annotations\AnnotationReader; +use Doctrine\ORM\Mapping\Driver\AnnotationDriver; +use Doctrine\ORM\EntityManager; + +/** + * Provides utility functions needed in tests. + * + * @author Bernhard Schussek + */ +class DoctrineTestHelper +{ + /** + * Returns an entity manager for testing. + * + * @return EntityManager + */ + public static function createTestEntityManager() + { + if (!class_exists('PDO') || !in_array('sqlite', \PDO::getAvailableDrivers())) { + \PHPUnit_Framework_TestCase::markTestSkipped('This test requires SQLite support in your environment'); + } + + $config = new \Doctrine\ORM\Configuration(); + $config->setEntityNamespaces(array('SymfonyTestsDoctrine' => 'Symfony\Bridge\Doctrine\Tests\Fixtures')); + $config->setAutoGenerateProxyClasses(true); + $config->setProxyDir(\sys_get_temp_dir()); + $config->setProxyNamespace('SymfonyTests\Doctrine'); + $config->setMetadataDriverImpl(new AnnotationDriver(new AnnotationReader())); + $config->setQueryCacheImpl(new \Doctrine\Common\Cache\ArrayCache()); + $config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache()); + + $params = array( + 'driver' => 'pdo_sqlite', + 'memory' => true, + ); + + return EntityManager::create($params, $config); + } + + /** + * This class cannot be instantiated. + */ + private function __construct() + { + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/DoctrineOrmTestCase.php b/src/Symfony/Bridge/Doctrine/Tests/DoctrineOrmTestCase.php index 228d34f4d95ae..577d1985990a5 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/DoctrineOrmTestCase.php +++ b/src/Symfony/Bridge/Doctrine/Tests/DoctrineOrmTestCase.php @@ -11,34 +11,21 @@ namespace Symfony\Bridge\Doctrine\Tests; -use Doctrine\Common\Annotations\AnnotationReader; -use Doctrine\ORM\Mapping\Driver\AnnotationDriver; -use Doctrine\ORM\EntityManager; +use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper; +/** + * Class DoctrineOrmTestCase + * + * @deprecated Deprecated as of Symfony 2.4, to be removed in Symfony 3.0. + * Use {@link DoctrineTestHelper} instead. + */ abstract class DoctrineOrmTestCase extends \PHPUnit_Framework_TestCase { /** - * @return EntityManager + * @return \Doctrine\ORM\EntityManager */ - public static function createTestEntityManager($paths = array()) + public static function createTestEntityManager() { - if (!class_exists('PDO') || !in_array('sqlite', \PDO::getAvailableDrivers())) { - self::markTestSkipped('This test requires SQLite support in your environment'); - } - $config = new \Doctrine\ORM\Configuration(); - $config->setEntityNamespaces(array('SymfonyTestsDoctrine' => 'Symfony\Bridge\Doctrine\Tests\Fixtures')); - $config->setAutoGenerateProxyClasses(true); - $config->setProxyDir(\sys_get_temp_dir()); - $config->setProxyNamespace('SymfonyTests\Doctrine'); - $config->setMetadataDriverImpl(new AnnotationDriver(new AnnotationReader())); - $config->setQueryCacheImpl(new \Doctrine\Common\Cache\ArrayCache()); - $config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache()); - - $params = array( - 'driver' => 'pdo_sqlite', - 'memory' => true, - ); - - return EntityManager::create($params, $config); + return DoctrineTestHelper::createTestEntityManager(); } } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/AssociationEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/AssociationEntity.php index 0fe3d145a0019..9a33435ff2eb3 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/AssociationEntity.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/AssociationEntity.php @@ -26,18 +26,18 @@ class AssociationEntity private $id; /** - * @ORM\ManyToOne(targetEntity="SingleIdentEntity") - * @var \Symfony\Bridge\Doctrine\Tests\Form\Fixtures\SingleIdentEntity + * @ORM\ManyToOne(targetEntity="SingleIntIdEntity") + * @var \Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity */ public $single; /** - * @ORM\ManyToOne(targetEntity="CompositeIdentEntity") + * @ORM\ManyToOne(targetEntity="CompositeIntIdEntity") * @ORM\JoinColumns({ * @ORM\JoinColumn(name="composite_id1", referencedColumnName="id1"), * @ORM\JoinColumn(name="composite_id2", referencedColumnName="id2") * }) - * @var \Symfony\Bridge\Doctrine\Tests\Form\Fixtures\CompositeIdentEntity + * @var \Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity */ public $composite; } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeIntIdEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeIntIdEntity.php new file mode 100644 index 0000000000000..740a4f55f49cd --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeIntIdEntity.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Fixtures; + +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; + +/** @Entity */ +class CompositeIntIdEntity +{ + /** @Id @Column(type="integer") */ + protected $id1; + + /** @Id @Column(type="integer") */ + protected $id2; + + /** @Column(type="string") */ + public $name; + + public function __construct($id1, $id2, $name) + { + $this->id1 = $id1; + $this->id2 = $id2; + $this->name = $name; + } + + public function __toString() + { + return $this->name; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeStringIdentEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeStringIdEntity.php similarity index 87% rename from src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeStringIdentEntity.php rename to src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeStringIdEntity.php index 43c71f6e80720..10e083a8f4298 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeStringIdentEntity.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeStringIdEntity.php @@ -16,7 +16,7 @@ use Doctrine\ORM\Mapping\Entity; /** @Entity */ -class CompositeStringIdentEntity +class CompositeStringIdEntity { /** @Id @Column(type="string") */ protected $id1; @@ -33,4 +33,9 @@ public function __construct($id1, $id2, $name) $this->id2 = $id2; $this->name = $name; } + + public function __toString() + { + return $this->name; + } } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoubleIdentEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoubleNameEntity.php similarity index 96% rename from src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoubleIdentEntity.php rename to src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoubleNameEntity.php index 2ac1ad3a8532d..cfb8e8b6664ff 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoubleIdentEntity.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoubleNameEntity.php @@ -16,7 +16,7 @@ use Doctrine\ORM\Mapping\Entity; /** @Entity */ -class DoubleIdentEntity +class DoubleNameEntity { /** @Id @Column(type="integer") */ protected $id; diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/ItemGroupEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/GroupableEntity.php similarity index 97% rename from src/Symfony/Bridge/Doctrine/Tests/Fixtures/ItemGroupEntity.php rename to src/Symfony/Bridge/Doctrine/Tests/Fixtures/GroupableEntity.php index 04d2ddfde9dc5..2e36204bdfdad 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/ItemGroupEntity.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/GroupableEntity.php @@ -16,7 +16,7 @@ use Doctrine\ORM\Mapping\Entity; /** @Entity */ -class ItemGroupEntity +class GroupableEntity { /** @Id @Column(type="integer") */ protected $id; diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIdentEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIntIdEntity.php similarity index 96% rename from src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIdentEntity.php rename to src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIntIdEntity.php index 09ee18a2fc561..44630a1fc51f1 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIdentEntity.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIntIdEntity.php @@ -16,7 +16,7 @@ use Doctrine\ORM\Mapping\Entity; /** @Entity */ -class SingleIdentEntity +class SingleIntIdEntity { /** @Id @Column(type="integer") */ protected $id; diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/NoToStringSingleIdentEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIntIdNoToStringEntity.php similarity index 94% rename from src/Symfony/Bridge/Doctrine/Tests/Fixtures/NoToStringSingleIdentEntity.php rename to src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIntIdNoToStringEntity.php index a5ecb3da27e3f..bcbe7a5f7bdeb 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/NoToStringSingleIdentEntity.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleIntIdNoToStringEntity.php @@ -16,7 +16,7 @@ use Doctrine\ORM\Mapping\Entity; /** @Entity */ -class NoToStringSingleIdentEntity +class SingleIntIdNoToStringEntity { /** @Id @Column(type="integer") */ protected $id; diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleStringIdentEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleStringIdEntity.php similarity index 86% rename from src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleStringIdentEntity.php rename to src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleStringIdEntity.php index 50f53b790efb0..258c5a65158e7 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleStringIdentEntity.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/SingleStringIdEntity.php @@ -16,7 +16,7 @@ use Doctrine\ORM\Mapping\Entity; /** @Entity */ -class SingleStringIdentEntity +class SingleStringIdEntity { /** @Id @Column(type="string") */ protected $id; @@ -29,4 +29,9 @@ public function __construct($id, $name) $this->id = $id; $this->name = $name; } + + public function __toString() + { + return $this->name; + } } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeIdentEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/User.php similarity index 95% rename from src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeIdentEntity.php rename to src/Symfony/Bridge/Doctrine/Tests/Fixtures/User.php index 9d263141f7f56..e59e32c27e82c 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/CompositeIdentEntity.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/User.php @@ -17,7 +17,7 @@ use Symfony\Component\Security\Core\User\UserInterface; /** @Entity */ -class CompositeIdentEntity implements UserInterface +class User implements UserInterface { /** @Id @Column(type="integer") */ protected $id1; diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/AbstractEntityChoiceListCompositeIdTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/AbstractEntityChoiceListCompositeIdTest.php new file mode 100644 index 0000000000000..5980d9c734c54 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/AbstractEntityChoiceListCompositeIdTest.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; + +use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity; + +/** + * @author Bernhard Schussek + */ +abstract class AbstractEntityChoiceListCompositeIdTest extends AbstractEntityChoiceListTest +{ + protected function getEntityClass() + { + return 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity'; + } + + /** + * @return \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + protected function createObjects() + { + return array( + new CompositeIntIdEntity(10, 11, 'A'), + new CompositeIntIdEntity(20, 21, 'B'), + new CompositeIntIdEntity(30, 31, 'C'), + new CompositeIntIdEntity(40, 41, 'D'), + ); + } + + protected function getChoices() + { + return array(0 => $this->obj1, 1 => $this->obj2, 2 => $this->obj3, 3 => $this->obj4); + } + + protected function getLabels() + { + return array(0 => 'A', 1 => 'B', 2 => 'C', 3 => 'D'); + } + + protected function getValues() + { + return array(0 => '0', 1 => '1', 2 => '2', 3 => '3'); + } + + protected function getIndices() + { + return array(0, 1, 2, 3); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/AbstractEntityChoiceListSingleIntIdTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/AbstractEntityChoiceListSingleIntIdTest.php new file mode 100644 index 0000000000000..74af66db360e2 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/AbstractEntityChoiceListSingleIntIdTest.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; + +use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity; + +/** + * @author Bernhard Schussek + */ +abstract class AbstractEntityChoiceListSingleIntIdTest extends AbstractEntityChoiceListTest +{ + protected function getEntityClass() + { + return 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity'; + } + + /** + * @return \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + protected function createObjects() + { + return array( + new SingleIntIdEntity(-10, 'A'), + new SingleIntIdEntity(10, 'B'), + new SingleIntIdEntity(20, 'C'), + new SingleIntIdEntity(30, 'D'), + ); + } + + protected function getChoices() + { + return array('_10' => $this->obj1, 10 => $this->obj2, 20 => $this->obj3, 30 => $this->obj4); + } + + protected function getLabels() + { + return array('_10' => 'A', 10 => 'B', 20 => 'C', 30 => 'D'); + } + + protected function getValues() + { + return array('_10' => '-10', 10 => '10', 20 => '20', 30 => '30'); + } + + protected function getIndices() + { + return array('_10', 10, 20, 30); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/AbstractEntityChoiceListSingleStringIdTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/AbstractEntityChoiceListSingleStringIdTest.php new file mode 100644 index 0000000000000..56b4c21319826 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/AbstractEntityChoiceListSingleStringIdTest.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; + +use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity; + +/** + * @author Bernhard Schussek + */ +abstract class AbstractEntityChoiceListSingleStringIdTest extends AbstractEntityChoiceListTest +{ + protected function getEntityClass() + { + return 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity'; + } + + /** + * @return \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + protected function createObjects() + { + return array( + new SingleStringIdEntity('a', 'A'), + new SingleStringIdEntity('b', 'B'), + new SingleStringIdEntity('c', 'C'), + new SingleStringIdEntity('d', 'D'), + ); + } + + protected function getChoices() + { + return array(0 => $this->obj1, 1 => $this->obj2, 2 => $this->obj3, 3 => $this->obj4); + } + + protected function getLabels() + { + return array(0 => 'A', 1 => 'B', 2 => 'C', 3 => 'D'); + } + + protected function getValues() + { + return array(0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd'); + } + + protected function getIndices() + { + return array(0, 1, 2, 3); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/AbstractEntityChoiceListTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/AbstractEntityChoiceListTest.php new file mode 100644 index 0000000000000..a56123a2a1f04 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/AbstractEntityChoiceListTest.php @@ -0,0 +1,100 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; + +use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper; +use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity; +use Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList; +use Doctrine\ORM\Tools\SchemaTool; +use Symfony\Component\Form\Tests\Extension\Core\ChoiceList\AbstractChoiceListTest; + +/** + * @author Bernhard Schussek + */ +abstract class AbstractEntityChoiceListTest extends AbstractChoiceListTest +{ + /** + * @var \Doctrine\ORM\EntityManager + */ + protected $em; + + protected $obj1; + + protected $obj2; + + protected $obj3; + + protected $obj4; + + protected function setUp() + { + if (!class_exists('Symfony\Component\Form\Form')) { + $this->markTestSkipped('The "Form" component is not available'); + } + + if (!class_exists('Doctrine\DBAL\Platforms\MySqlPlatform')) { + $this->markTestSkipped('Doctrine DBAL is not available.'); + } + + if (!class_exists('Doctrine\Common\Version')) { + $this->markTestSkipped('Doctrine Common is not available.'); + } + + if (!class_exists('Doctrine\ORM\EntityManager')) { + $this->markTestSkipped('Doctrine ORM is not available.'); + } + + $this->em = DoctrineTestHelper::createTestEntityManager(); + + $schemaTool = new SchemaTool($this->em); + $classes = array($this->em->getClassMetadata($this->getEntityClass())); + + try { + $schemaTool->dropSchema($classes); + } catch (\Exception $e) { + } + + try { + $schemaTool->createSchema($classes); + } catch (\Exception $e) { + } + + list($this->obj1, $this->obj2, $this->obj3, $this->obj4) = $this->createObjects(); + + $this->em->persist($this->obj1); + $this->em->persist($this->obj2); + $this->em->persist($this->obj3); + $this->em->persist($this->obj4); + $this->em->flush(); + + parent::setUp(); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->em = null; + } + + abstract protected function getEntityClass(); + + abstract protected function createObjects(); + + /** + * @return \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + protected function createChoiceList() + { + return new EntityChoiceList($this->em, $this->getEntityClass()); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/EntityChoiceListTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/EntityChoiceListTest.php deleted file mode 100644 index 3f9c573da5de6..0000000000000 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/EntityChoiceListTest.php +++ /dev/null @@ -1,354 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; - -use Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader; -use Symfony\Bridge\Doctrine\Tests\DoctrineOrmTestCase; -use Symfony\Bridge\Doctrine\Tests\Fixtures\ItemGroupEntity; -use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity; -use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdentEntity; -use Symfony\Bridge\Doctrine\Tests\Fixtures\NoToStringSingleIdentEntity; -use Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList; -use Symfony\Component\Form\Extension\Core\View\ChoiceView; -use Doctrine\ORM\Tools\SchemaTool; - -class EntityChoiceListTest extends DoctrineOrmTestCase -{ - const ITEM_GROUP_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\ItemGroupEntity'; - - const SINGLE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity'; - - const SINGLE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdentEntity'; - - const COMPOSITE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity'; - - private $em; - - protected function setUp() - { - parent::setUp(); - - $this->em = $this->createTestEntityManager(); - - $schemaTool = new SchemaTool($this->em); - $classes = array( - $this->em->getClassMetadata(self::ITEM_GROUP_CLASS), - $this->em->getClassMetadata(self::SINGLE_IDENT_CLASS), - $this->em->getClassMetadata(self::SINGLE_STRING_IDENT_CLASS), - $this->em->getClassMetadata(self::COMPOSITE_IDENT_CLASS), - ); - - try { - $schemaTool->dropSchema($classes); - } catch (\Exception $e) { - } - - try { - $schemaTool->createSchema($classes); - } catch (\Exception $e) { - } - } - - protected function tearDown() - { - parent::tearDown(); - - $this->em = null; - } - - /** - * @expectedException \Symfony\Component\Form\Exception\StringCastException - * @expectedMessage Entity "Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity" passed to the choice field must have a "__toString()" method defined (or you can also override the "property" option). - */ - public function testEntitiesMustHaveAToStringMethod() - { - $entity1 = new NoToStringSingleIdentEntity(1, 'Foo'); - $entity2 = new NoToStringSingleIdentEntity(2, 'Bar'); - - // Persist for managed state - $this->em->persist($entity1); - $this->em->persist($entity2); - - $choiceList = new EntityChoiceList( - $this->em, - self::SINGLE_IDENT_CLASS, - null, - null, - array( - $entity1, - $entity2, - ) - ); - - $choiceList->getValues(); - } - - /** - * @expectedException \Symfony\Component\Form\Exception\RuntimeException - */ - public function testChoicesMustBeManaged() - { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); - - // no persist here! - - $choiceList = new EntityChoiceList( - $this->em, - self::SINGLE_IDENT_CLASS, - 'name', - null, - array( - $entity1, - $entity2, - ) - ); - - // triggers loading -> exception - $choiceList->getChoices(); - } - - public function testFlattenedChoicesAreManaged() - { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); - - // Persist for managed state - $this->em->persist($entity1); - $this->em->persist($entity2); - - $choiceList = new EntityChoiceList( - $this->em, - self::SINGLE_IDENT_CLASS, - 'name', - null, - array( - $entity1, - $entity2, - ) - ); - - $this->assertSame(array(1 => $entity1, 2 => $entity2), $choiceList->getChoices()); - } - - public function testEmptyChoicesAreManaged() - { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); - - // Persist for managed state - $this->em->persist($entity1); - $this->em->persist($entity2); - - $choiceList = new EntityChoiceList( - $this->em, - self::SINGLE_IDENT_CLASS, - 'name', - null, - array() - ); - - $this->assertSame(array(), $choiceList->getChoices()); - } - - public function testNestedChoicesAreManaged() - { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); - - // Oh yeah, we're persisting with fire now! - $this->em->persist($entity1); - $this->em->persist($entity2); - - $choiceList = new EntityChoiceList( - $this->em, - self::SINGLE_IDENT_CLASS, - 'name', - null, - array( - 'group1' => array($entity1), - 'group2' => array($entity2), - ), - array() - ); - - $this->assertSame(array(1 => $entity1, 2 => $entity2), $choiceList->getChoices()); - $this->assertEquals(array( - 'group1' => array(1 => new ChoiceView($entity1, '1', 'Foo')), - 'group2' => array(2 => new ChoiceView($entity2, '2', 'Bar')) - ), $choiceList->getRemainingViews()); - } - - public function testGroupBySupportsString() - { - $item1 = new ItemGroupEntity(1, 'Foo', 'Group1'); - $item2 = new ItemGroupEntity(2, 'Bar', 'Group1'); - $item3 = new ItemGroupEntity(3, 'Baz', 'Group2'); - $item4 = new ItemGroupEntity(4, 'Boo!', null); - - $this->em->persist($item1); - $this->em->persist($item2); - $this->em->persist($item3); - $this->em->persist($item4); - - $choiceList = new EntityChoiceList( - $this->em, - self::ITEM_GROUP_CLASS, - 'name', - null, - array( - $item1, - $item2, - $item3, - $item4, - ), - array(), - 'groupName' - ); - - $this->assertEquals(array(1 => $item1, 2 => $item2, 3 => $item3, 4 => $item4), $choiceList->getChoices()); - $this->assertEquals(array( - 'Group1' => array(1 => new ChoiceView($item1, '1', 'Foo'), 2 => new ChoiceView($item2, '2', 'Bar')), - 'Group2' => array(3 => new ChoiceView($item3, '3', 'Baz')), - 4 => new ChoiceView($item4, '4', 'Boo!') - ), $choiceList->getRemainingViews()); - } - - public function testGroupByInvalidPropertyPathReturnsFlatChoices() - { - $item1 = new ItemGroupEntity(1, 'Foo', 'Group1'); - $item2 = new ItemGroupEntity(2, 'Bar', 'Group1'); - - $this->em->persist($item1); - $this->em->persist($item2); - - $choiceList = new EntityChoiceList( - $this->em, - self::ITEM_GROUP_CLASS, - 'name', - null, - array( - $item1, - $item2, - ), - array(), - 'child.that.does.not.exist' - ); - - $this->assertEquals(array( - 1 => $item1, - 2 => $item2 - ), $choiceList->getChoices()); - } - - public function testPossibleToProvideShorthandEntityName() - { - $shorthandName = 'SymfonyTestsDoctrine:SingleIdentEntity'; - - $item1 = new SingleIdentEntity(1, 'Foo'); - $item2 = new SingleIdentEntity(2, 'Bar'); - - $this->em->persist($item1); - $this->em->persist($item2); - - $choiceList = new EntityChoiceList( - $this->em, - $shorthandName, - null, - null, - null, - array(), - null - ); - - $this->assertEquals(array(1, 2), $choiceList->getValuesForChoices(array($item1, $item2))); - $this->assertEquals(array(1, 2), $choiceList->getIndicesForChoices(array($item1, $item2))); - } - - // Ticket #3446 - public function testGetEmptyArrayChoicesForEmptyValues() - { - $qb = $this->em->createQueryBuilder()->select('s')->from(self::SINGLE_IDENT_CLASS, 's'); - $entityLoader = new ORMQueryBuilderLoader($qb); - $choiceList = new EntityChoiceList( - $this->em, - self::SINGLE_IDENT_CLASS, - null, - $entityLoader - ); - - $this->assertEquals(array(), $choiceList->getChoicesForValues(array())); - } - - // https://github.com/symfony/symfony/issues/3635 - public function testSingleNonIntIdFallsBackToGeneration() - { - $entity1 = new SingleStringIdentEntity('Id 1', 'Foo'); - $entity2 = new SingleStringIdentEntity('Id 2', 'Bar'); - - // Persist for managed state - $this->em->persist($entity1); - $this->em->persist($entity2); - $this->em->flush(); - - $choiceList = new EntityChoiceList( - $this->em, - self::SINGLE_STRING_IDENT_CLASS, - 'name' - ); - - $this->assertSame(array(0 => $entity1, 1 => $entity2), $choiceList->getChoices()); - } - - public function testMinusReplacedByUnderscoreInNegativeIntIds() - { - $entity1 = new SingleIdentEntity(-1, 'Foo'); - $entity2 = new SingleIdentEntity(1, 'Bar'); - - // Persist for managed state - $this->em->persist($entity1); - $this->em->persist($entity2); - $this->em->flush(); - - $choiceList = new EntityChoiceList( - $this->em, - self::SINGLE_IDENT_CLASS, - 'name' - ); - - $this->assertSame(array('_1' => $entity1, 1 => $entity2), $choiceList->getChoices()); - $this->assertSame(array('_1', 1), $choiceList->getIndicesForChoices(array($entity1, $entity2))); - $this->assertSame(array('_1', 1), $choiceList->getIndicesForValues(array('-1', '1'))); - } - - public function testMinusReplacedByUnderscoreIfNotLoaded() - { - $entity1 = new SingleIdentEntity(-1, 'Foo'); - $entity2 = new SingleIdentEntity(1, 'Bar'); - - // Persist for managed state - $this->em->persist($entity1); - $this->em->persist($entity2); - $this->em->flush(); - - $choiceList = new EntityChoiceList( - $this->em, - self::SINGLE_IDENT_CLASS, - 'name' - ); - - // no getChoices()! - - $this->assertSame(array('_1', 1), $choiceList->getIndicesForChoices(array($entity1, $entity2))); - $this->assertSame(array('_1', 1), $choiceList->getIndicesForValues(array('-1', '1'))); - } -} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/GenericEntityChoiceListTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/GenericEntityChoiceListTest.php new file mode 100644 index 0000000000000..c5910195ca6c1 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/GenericEntityChoiceListTest.php @@ -0,0 +1,286 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; + +use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper; +use Symfony\Bridge\Doctrine\Tests\Fixtures\GroupableEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdNoToStringEntity; +use Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList; +use Symfony\Component\Form\Extension\Core\View\ChoiceView; +use Doctrine\ORM\Tools\SchemaTool; + +class GenericEntityChoiceListTest extends \PHPUnit_Framework_TestCase +{ + const SINGLE_INT_ID_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity'; + + const SINGLE_STRING_ID_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity'; + + const COMPOSITE_ID_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity'; + + const GROUPABLE_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\GroupableEntity'; + + /** + * @var \Doctrine\ORM\EntityManager + */ + private $em; + + protected function setUp() + { + if (!class_exists('Symfony\Component\Form\Form')) { + $this->markTestSkipped('The "Form" component is not available'); + } + + if (!class_exists('Doctrine\DBAL\Platforms\MySqlPlatform')) { + $this->markTestSkipped('Doctrine DBAL is not available.'); + } + + if (!class_exists('Doctrine\Common\Version')) { + $this->markTestSkipped('Doctrine Common is not available.'); + } + + if (!class_exists('Doctrine\ORM\EntityManager')) { + $this->markTestSkipped('Doctrine ORM is not available.'); + } + + $this->em = DoctrineTestHelper::createTestEntityManager(); + + $schemaTool = new SchemaTool($this->em); + $classes = array( + $this->em->getClassMetadata(self::SINGLE_INT_ID_CLASS), + $this->em->getClassMetadata(self::SINGLE_STRING_ID_CLASS), + $this->em->getClassMetadata(self::COMPOSITE_ID_CLASS), + $this->em->getClassMetadata(self::GROUPABLE_CLASS), + ); + + try { + $schemaTool->dropSchema($classes); + } catch (\Exception $e) { + } + + try { + $schemaTool->createSchema($classes); + } catch (\Exception $e) { + } + + parent::setUp(); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->em = null; + } + + /** + * @expectedException \Symfony\Component\Form\Exception\StringCastException + * @expectedMessage Entity "Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity" passed to the choice field must have a "__toString()" method defined (or you can also override the "property" option). + */ + public function testEntitiesMustHaveAToStringMethod() + { + $entity1 = new SingleIntIdNoToStringEntity(1, 'Foo'); + $entity2 = new SingleIntIdNoToStringEntity(2, 'Bar'); + + // Persist for managed state + $this->em->persist($entity1); + $this->em->persist($entity2); + + $choiceList = new EntityChoiceList( + $this->em, + self::SINGLE_INT_ID_CLASS, + null, + null, + array( + $entity1, + $entity2, + ) + ); + + $choiceList->getValues(); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\RuntimeException + */ + public function testChoicesMustBeManaged() + { + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); + + // no persist here! + + $choiceList = new EntityChoiceList( + $this->em, + self::SINGLE_INT_ID_CLASS, + 'name', + null, + array( + $entity1, + $entity2, + ) + ); + + // triggers loading -> exception + $choiceList->getChoices(); + } + + public function testInitExplicitChoices() + { + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); + + // Persist for managed state + $this->em->persist($entity1); + $this->em->persist($entity2); + + $choiceList = new EntityChoiceList( + $this->em, + self::SINGLE_INT_ID_CLASS, + 'name', + null, + array( + $entity1, + $entity2, + ) + ); + + $this->assertSame(array(1 => $entity1, 2 => $entity2), $choiceList->getChoices()); + } + + public function testInitEmptyChoices() + { + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); + + // Persist for managed state + $this->em->persist($entity1); + $this->em->persist($entity2); + + $choiceList = new EntityChoiceList( + $this->em, + self::SINGLE_INT_ID_CLASS, + 'name', + null, + array() + ); + + $this->assertSame(array(), $choiceList->getChoices()); + } + + public function testInitNestedChoices() + { + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); + + // Oh yeah, we're persisting with fire now! + $this->em->persist($entity1); + $this->em->persist($entity2); + + $choiceList = new EntityChoiceList( + $this->em, + self::SINGLE_INT_ID_CLASS, + 'name', + null, + array( + 'group1' => array($entity1), + 'group2' => array($entity2), + ), + array() + ); + + $this->assertSame(array(1 => $entity1, 2 => $entity2), $choiceList->getChoices()); + $this->assertEquals(array( + 'group1' => array(1 => new ChoiceView($entity1, '1', 'Foo')), + 'group2' => array(2 => new ChoiceView($entity2, '2', 'Bar')) + ), $choiceList->getRemainingViews()); + } + + public function testGroupByPropertyPath() + { + $item1 = new GroupableEntity(1, 'Foo', 'Group1'); + $item2 = new GroupableEntity(2, 'Bar', 'Group1'); + $item3 = new GroupableEntity(3, 'Baz', 'Group2'); + $item4 = new GroupableEntity(4, 'Boo!', null); + + $this->em->persist($item1); + $this->em->persist($item2); + $this->em->persist($item3); + $this->em->persist($item4); + + $choiceList = new EntityChoiceList( + $this->em, + self::GROUPABLE_CLASS, + 'name', + null, + array( + $item1, + $item2, + $item3, + $item4, + ), + array(), + 'groupName' + ); + + $this->assertEquals(array(1 => $item1, 2 => $item2, 3 => $item3, 4 => $item4), $choiceList->getChoices()); + $this->assertEquals(array( + 'Group1' => array(1 => new ChoiceView($item1, '1', 'Foo'), 2 => new ChoiceView($item2, '2', 'Bar')), + 'Group2' => array(3 => new ChoiceView($item3, '3', 'Baz')), + 4 => new ChoiceView($item4, '4', 'Boo!') + ), $choiceList->getRemainingViews()); + } + + public function testGroupByInvalidPropertyPathReturnsFlatChoices() + { + $item1 = new GroupableEntity(1, 'Foo', 'Group1'); + $item2 = new GroupableEntity(2, 'Bar', 'Group1'); + + $this->em->persist($item1); + $this->em->persist($item2); + + $choiceList = new EntityChoiceList( + $this->em, + self::GROUPABLE_CLASS, + 'name', + null, + array( + $item1, + $item2, + ), + array(), + 'child.that.does.not.exist' + ); + + $this->assertEquals(array( + 1 => $item1, + 2 => $item2 + ), $choiceList->getChoices()); + } + + public function testInitShorthandEntityName() + { + $item1 = new SingleIntIdEntity(1, 'Foo'); + $item2 = new SingleIntIdEntity(2, 'Bar'); + + $this->em->persist($item1); + $this->em->persist($item2); + + $choiceList = new EntityChoiceList( + $this->em, + 'SymfonyTestsDoctrine:SingleIntIdEntity' + ); + + $this->assertEquals(array(1, 2), $choiceList->getValuesForChoices(array($item1, $item2))); + $this->assertEquals(array(1, 2), $choiceList->getIndicesForChoices(array($item1, $item2))); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/LoadedEntityChoiceListCompositeIdTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/LoadedEntityChoiceListCompositeIdTest.php new file mode 100644 index 0000000000000..90cbf1d7c8b31 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/LoadedEntityChoiceListCompositeIdTest.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; + +/** + * @author Bernhard Schussek + */ +class LoadedEntityChoiceListCompositeIdTest extends AbstractEntityChoiceListCompositeIdTest +{ + /** + * @return \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + protected function createChoiceList() + { + $list = parent::createChoiceList(); + + // load list + $list->getChoices(); + + return $list; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/LoadedEntityChoiceListSingleIntIdTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/LoadedEntityChoiceListSingleIntIdTest.php new file mode 100644 index 0000000000000..52d04c38798a5 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/LoadedEntityChoiceListSingleIntIdTest.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; + +/** + * @author Bernhard Schussek + */ +class LoadedEntityChoiceListSingleIntIdTest extends AbstractEntityChoiceListSingleIntIdTest +{ + /** + * @return \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + protected function createChoiceList() + { + $list = parent::createChoiceList(); + + // load list + $list->getChoices(); + + return $list; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/LoadedEntityChoiceListSingleStringIdTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/LoadedEntityChoiceListSingleStringIdTest.php new file mode 100644 index 0000000000000..690d4b3d2300c --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/LoadedEntityChoiceListSingleStringIdTest.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; + +/** + * @author Bernhard Schussek + */ +class LoadedEntityChoiceListSingleStringIdTest extends AbstractEntityChoiceListSingleStringIdTest +{ + /** + * @return \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + protected function createChoiceList() + { + $list = parent::createChoiceList(); + + // load list + $list->getChoices(); + + return $list; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListCompositeIdTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListCompositeIdTest.php new file mode 100644 index 0000000000000..5740a2ff9434d --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListCompositeIdTest.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; + +/** + * @author Bernhard Schussek + */ +class UnloadedEntityChoiceListCompositeIdTest extends AbstractEntityChoiceListCompositeIdTest +{ + public function testGetIndicesForValuesIgnoresNonExistingValues() + { + $this->markTestSkipped('Non-existing values are not detected for unloaded choice lists.'); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListCompositeIdWithQueryBuilderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListCompositeIdWithQueryBuilderTest.php new file mode 100644 index 0000000000000..9c72ccccd91a4 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListCompositeIdWithQueryBuilderTest.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; + +use Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList; +use Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader; + +/** + * @author Bernhard Schussek + */ +class UnloadedEntityChoiceListCompositeIdWithQueryBuilderTest extends UnloadedEntityChoiceListCompositeIdTest +{ + /** + * @return \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + protected function createChoiceList() + { + $qb = $this->em->createQueryBuilder()->select('s')->from($this->getEntityClass(), 's'); + $loader = new ORMQueryBuilderLoader($qb); + + return new EntityChoiceList($this->em, $this->getEntityClass(), null, $loader); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListSingleIntIdTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListSingleIntIdTest.php new file mode 100644 index 0000000000000..a87687841510b --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListSingleIntIdTest.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; + +/** + * @author Bernhard Schussek + */ +class UnloadedEntityChoiceListSingleIntIdTest extends AbstractEntityChoiceListSingleIntIdTest +{ + public function testGetIndicesForValuesIgnoresNonExistingValues() + { + $this->markTestSkipped('Non-existing values are not detected for unloaded choice lists.'); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListSingleIntIdWithQueryBuilderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListSingleIntIdWithQueryBuilderTest.php new file mode 100644 index 0000000000000..fa5bb80ae7be8 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListSingleIntIdWithQueryBuilderTest.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; + +use Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList; +use Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader; + +/** + * @author Bernhard Schussek + */ +class UnloadedEntityChoiceListSingleIntIdWithQueryBuilderTest extends UnloadedEntityChoiceListSingleIntIdTest +{ + /** + * @return \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + protected function createChoiceList() + { + $qb = $this->em->createQueryBuilder()->select('s')->from($this->getEntityClass(), 's'); + $loader = new ORMQueryBuilderLoader($qb); + + return new EntityChoiceList($this->em, $this->getEntityClass(), null, $loader); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListSingleStringIdTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListSingleStringIdTest.php new file mode 100644 index 0000000000000..5b25b49a710bf --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListSingleStringIdTest.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; + +/** + * @author Bernhard Schussek + */ +class UnloadedEntityChoiceListSingleStringIdTest extends AbstractEntityChoiceListSingleStringIdTest +{ + public function testGetIndicesForValuesIgnoresNonExistingValues() + { + $this->markTestSkipped('Non-existing values are not detected for unloaded choice lists.'); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListSingleStringIdWithQueryBuilderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListSingleStringIdWithQueryBuilderTest.php new file mode 100644 index 0000000000000..9fba5b9295a08 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/UnloadedEntityChoiceListSingleStringIdWithQueryBuilderTest.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; + +use Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList; +use Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader; + +/** + * @author Bernhard Schussek + */ +class UnloadedEntityChoiceListSingleStringIdWithQueryBuilderTest extends UnloadedEntityChoiceListSingleStringIdTest +{ + /** + * @return \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + protected function createChoiceList() + { + $qb = $this->em->createQueryBuilder()->select('s')->from($this->getEntityClass(), 's'); + $loader = new ORMQueryBuilderLoader($qb); + + return new EntityChoiceList($this->em, $this->getEntityClass(), null, $loader); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php index c187608bc28e6..562bb8ee0e715 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypePerformanceTest.php @@ -73,7 +73,7 @@ protected function setUp() foreach ($ids as $id) { $name = 65 + chr($id % 57); - $this->em->persist(new SingleIdentEntity($id, $name)); + $this->em->persist(new SingleIntIdEntity($id, $name)); } $this->em->flush(); diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php index f09c23ede9a0f..b124cae6d5b50 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php @@ -11,14 +11,14 @@ namespace Symfony\Bridge\Doctrine\Tests\Form\Type; +use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper; use Symfony\Component\Form\Exception\UnexpectedTypeException; -use Symfony\Component\Form\Tests\Extension\Core\Type\TypeTestCase; -use Symfony\Bridge\Doctrine\Tests\DoctrineOrmTestCase; -use Symfony\Bridge\Doctrine\Tests\Fixtures\ItemGroupEntity; -use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity; -use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdentEntity; -use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity; -use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeStringIdentEntity; +use Symfony\Component\Form\Test\TypeTestCase; +use Symfony\Bridge\Doctrine\Tests\Fixtures\GroupableEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeStringIdEntity; use Symfony\Bridge\Doctrine\Form\DoctrineOrmExtension; use Doctrine\ORM\Tools\SchemaTool; use Doctrine\Common\Collections\ArrayCollection; @@ -26,11 +26,11 @@ class EntityTypeTest extends TypeTestCase { - const ITEM_GROUP_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\ItemGroupEntity'; - const SINGLE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity'; - const SINGLE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdentEntity'; - const COMPOSITE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity'; - const COMPOSITE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeStringIdentEntity'; + const ITEM_GROUP_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\GroupableEntity'; + const SINGLE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity'; + const SINGLE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity'; + const COMPOSITE_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity'; + const COMPOSITE_STRING_IDENT_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeStringIdEntity'; /** * @var \Doctrine\ORM\EntityManager @@ -44,7 +44,23 @@ class EntityTypeTest extends TypeTestCase protected function setUp() { - $this->em = DoctrineOrmTestCase::createTestEntityManager(); + if (!class_exists('Symfony\Component\Form\Form')) { + $this->markTestSkipped('The "Form" component is not available'); + } + + if (!class_exists('Doctrine\DBAL\Platforms\MySqlPlatform')) { + $this->markTestSkipped('Doctrine DBAL is not available.'); + } + + if (!class_exists('Doctrine\Common\Version')) { + $this->markTestSkipped('Doctrine Common is not available.'); + } + + if (!class_exists('Doctrine\ORM\EntityManager')) { + $this->markTestSkipped('Doctrine ORM is not available.'); + } + + $this->em = DoctrineTestHelper::createTestEntityManager(); $this->emRegistry = $this->createRegistryMock('default', $this->em); parent::setUp(); @@ -105,8 +121,8 @@ public function testClassOptionIsRequired() public function testSetDataToUninitializedEntityWithNonRequired() { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); $this->persist(array($entity1, $entity2)); @@ -122,8 +138,8 @@ public function testSetDataToUninitializedEntityWithNonRequired() public function testSetDataToUninitializedEntityWithNonRequiredToString() { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); $this->persist(array($entity1, $entity2)); @@ -138,8 +154,8 @@ public function testSetDataToUninitializedEntityWithNonRequiredToString() public function testSetDataToUninitializedEntityWithNonRequiredQueryBuilder() { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); $this->persist(array($entity1, $entity2)); $qb = $this->em->createQueryBuilder()->select('e')->from(self::SINGLE_IDENT_CLASS, 'e'); @@ -267,8 +283,8 @@ public function testSubmitMultipleNull() public function testSubmitSingleNonExpandedSingleIdentifier() { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); $this->persist(array($entity1, $entity2)); @@ -289,8 +305,8 @@ public function testSubmitSingleNonExpandedSingleIdentifier() public function testSubmitSingleNonExpandedCompositeIdentifier() { - $entity1 = new CompositeIdentEntity(10, 20, 'Foo'); - $entity2 = new CompositeIdentEntity(30, 40, 'Bar'); + $entity1 = new CompositeIntIdEntity(10, 20, 'Foo'); + $entity2 = new CompositeIntIdEntity(30, 40, 'Bar'); $this->persist(array($entity1, $entity2)); @@ -312,9 +328,9 @@ public function testSubmitSingleNonExpandedCompositeIdentifier() public function testSubmitMultipleNonExpandedSingleIdentifier() { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); - $entity3 = new SingleIdentEntity(3, 'Baz'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); + $entity3 = new SingleIntIdEntity(3, 'Baz'); $this->persist(array($entity1, $entity2, $entity3)); @@ -337,9 +353,9 @@ public function testSubmitMultipleNonExpandedSingleIdentifier() public function testSubmitMultipleNonExpandedSingleIdentifierForExistingData() { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); - $entity3 = new SingleIdentEntity(3, 'Baz'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); + $entity3 = new SingleIntIdEntity(3, 'Baz'); $this->persist(array($entity1, $entity2, $entity3)); @@ -368,9 +384,9 @@ public function testSubmitMultipleNonExpandedSingleIdentifierForExistingData() public function testSubmitMultipleNonExpandedCompositeIdentifier() { - $entity1 = new CompositeIdentEntity(10, 20, 'Foo'); - $entity2 = new CompositeIdentEntity(30, 40, 'Bar'); - $entity3 = new CompositeIdentEntity(50, 60, 'Baz'); + $entity1 = new CompositeIntIdEntity(10, 20, 'Foo'); + $entity2 = new CompositeIntIdEntity(30, 40, 'Bar'); + $entity3 = new CompositeIntIdEntity(50, 60, 'Baz'); $this->persist(array($entity1, $entity2, $entity3)); @@ -394,9 +410,9 @@ public function testSubmitMultipleNonExpandedCompositeIdentifier() public function testSubmitMultipleNonExpandedCompositeIdentifierExistingData() { - $entity1 = new CompositeIdentEntity(10, 20, 'Foo'); - $entity2 = new CompositeIdentEntity(30, 40, 'Bar'); - $entity3 = new CompositeIdentEntity(50, 60, 'Baz'); + $entity1 = new CompositeIntIdEntity(10, 20, 'Foo'); + $entity2 = new CompositeIntIdEntity(30, 40, 'Bar'); + $entity3 = new CompositeIntIdEntity(50, 60, 'Baz'); $this->persist(array($entity1, $entity2, $entity3)); @@ -425,8 +441,8 @@ public function testSubmitMultipleNonExpandedCompositeIdentifierExistingData() public function testSubmitSingleExpanded() { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); $this->persist(array($entity1, $entity2)); @@ -450,9 +466,9 @@ public function testSubmitSingleExpanded() public function testSubmitMultipleExpanded() { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); - $entity3 = new SingleIdentEntity(3, 'Bar'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); + $entity3 = new SingleIntIdEntity(3, 'Bar'); $this->persist(array($entity1, $entity2, $entity3)); @@ -480,9 +496,9 @@ public function testSubmitMultipleExpanded() public function testOverrideChoices() { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); - $entity3 = new SingleIdentEntity(3, 'Baz'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); + $entity3 = new SingleIntIdEntity(3, 'Baz'); $this->persist(array($entity1, $entity2, $entity3)); @@ -504,10 +520,10 @@ public function testOverrideChoices() public function testGroupByChoices() { - $item1 = new ItemGroupEntity(1, 'Foo', 'Group1'); - $item2 = new ItemGroupEntity(2, 'Bar', 'Group1'); - $item3 = new ItemGroupEntity(3, 'Baz', 'Group2'); - $item4 = new ItemGroupEntity(4, 'Boo!', null); + $item1 = new GroupableEntity(1, 'Foo', 'Group1'); + $item2 = new GroupableEntity(2, 'Bar', 'Group1'); + $item3 = new GroupableEntity(3, 'Baz', 'Group2'); + $item4 = new GroupableEntity(4, 'Boo!', null); $this->persist(array($item1, $item2, $item3, $item4)); @@ -531,9 +547,9 @@ public function testGroupByChoices() public function testPreferredChoices() { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); - $entity3 = new SingleIdentEntity(3, 'Baz'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); + $entity3 = new SingleIntIdEntity(3, 'Baz'); $this->persist(array($entity1, $entity2, $entity3)); @@ -550,9 +566,9 @@ public function testPreferredChoices() public function testOverrideChoicesWithPreferredChoices() { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); - $entity3 = new SingleIdentEntity(3, 'Baz'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); + $entity3 = new SingleIntIdEntity(3, 'Baz'); $this->persist(array($entity1, $entity2, $entity3)); @@ -570,9 +586,9 @@ public function testOverrideChoicesWithPreferredChoices() public function testDisallowChoicesThatAreNotIncludedChoicesSingleIdentifier() { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); - $entity3 = new SingleIdentEntity(3, 'Baz'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); + $entity3 = new SingleIntIdEntity(3, 'Baz'); $this->persist(array($entity1, $entity2, $entity3)); @@ -591,9 +607,9 @@ public function testDisallowChoicesThatAreNotIncludedChoicesSingleIdentifier() public function testDisallowChoicesThatAreNotIncludedChoicesCompositeIdentifier() { - $entity1 = new CompositeIdentEntity(10, 20, 'Foo'); - $entity2 = new CompositeIdentEntity(30, 40, 'Bar'); - $entity3 = new CompositeIdentEntity(50, 60, 'Baz'); + $entity1 = new CompositeIntIdEntity(10, 20, 'Foo'); + $entity2 = new CompositeIntIdEntity(30, 40, 'Bar'); + $entity3 = new CompositeIntIdEntity(50, 60, 'Baz'); $this->persist(array($entity1, $entity2, $entity3)); @@ -612,9 +628,9 @@ public function testDisallowChoicesThatAreNotIncludedChoicesCompositeIdentifier( public function testDisallowChoicesThatAreNotIncludedQueryBuilderSingleIdentifier() { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); - $entity3 = new SingleIdentEntity(3, 'Baz'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); + $entity3 = new SingleIntIdEntity(3, 'Baz'); $this->persist(array($entity1, $entity2, $entity3)); @@ -636,9 +652,9 @@ public function testDisallowChoicesThatAreNotIncludedQueryBuilderSingleIdentifie public function testDisallowChoicesThatAreNotIncludedQueryBuilderAsClosureSingleIdentifier() { - $entity1 = new SingleIdentEntity(1, 'Foo'); - $entity2 = new SingleIdentEntity(2, 'Bar'); - $entity3 = new SingleIdentEntity(3, 'Baz'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Bar'); + $entity3 = new SingleIntIdEntity(3, 'Baz'); $this->persist(array($entity1, $entity2, $entity3)); @@ -660,9 +676,9 @@ public function testDisallowChoicesThatAreNotIncludedQueryBuilderAsClosureSingle public function testDisallowChoicesThatAreNotIncludedQueryBuilderAsClosureCompositeIdentifier() { - $entity1 = new CompositeIdentEntity(10, 20, 'Foo'); - $entity2 = new CompositeIdentEntity(30, 40, 'Bar'); - $entity3 = new CompositeIdentEntity(50, 60, 'Baz'); + $entity1 = new CompositeIntIdEntity(10, 20, 'Foo'); + $entity2 = new CompositeIntIdEntity(30, 40, 'Bar'); + $entity3 = new CompositeIntIdEntity(50, 60, 'Baz'); $this->persist(array($entity1, $entity2, $entity3)); @@ -684,7 +700,7 @@ public function testDisallowChoicesThatAreNotIncludedQueryBuilderAsClosureCompos public function testSubmitSingleStringIdentifier() { - $entity1 = new SingleStringIdentEntity('foo', 'Foo'); + $entity1 = new SingleStringIdEntity('foo', 'Foo'); $this->persist(array($entity1)); @@ -705,7 +721,7 @@ public function testSubmitSingleStringIdentifier() public function testSubmitCompositeStringIdentifier() { - $entity1 = new CompositeStringIdentEntity('foo1', 'foo2', 'Foo'); + $entity1 = new CompositeStringIdEntity('foo1', 'foo2', 'Foo'); $this->persist(array($entity1)); diff --git a/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php index 8b60f5e340e04..8c179cd31f246 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php @@ -11,26 +11,26 @@ namespace Symfony\Bridge\Doctrine\Tests\Security\User; -use Symfony\Bridge\Doctrine\Tests\DoctrineOrmTestCase; -use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity; +use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper; +use Symfony\Bridge\Doctrine\Tests\Fixtures\User; use Symfony\Bridge\Doctrine\Security\User\EntityUserProvider; use Doctrine\ORM\Tools\SchemaTool; -class EntityUserProviderTest extends DoctrineOrmTestCase +class EntityUserProviderTest extends \PHPUnit_Framework_TestCase { public function testRefreshUserGetsUserByPrimaryKey() { - $em = $this->createTestEntityManager(); + $em = DoctrineTestHelper::createTestEntityManager(); $this->createSchema($em); - $user1 = new CompositeIdentEntity(1, 1, 'user1'); - $user2 = new CompositeIdentEntity(1, 2, 'user2'); + $user1 = new User(1, 1, 'user1'); + $user2 = new User(1, 2, 'user2'); $em->persist($user1); $em->persist($user2); $em->flush(); - $provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity', 'name'); + $provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\User', 'name'); // try to change the user identity $user1->name = 'user2'; @@ -40,10 +40,10 @@ public function testRefreshUserGetsUserByPrimaryKey() public function testRefreshUserRequiresId() { - $em = $this->createTestEntityManager(); + $em = DoctrineTestHelper::createTestEntityManager(); - $user1 = new CompositeIdentEntity(null, null, 'user1'); - $provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity', 'name'); + $user1 = new User(null, null, 'user1'); + $provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\User', 'name'); $this->setExpectedException( 'InvalidArgumentException', @@ -54,17 +54,17 @@ public function testRefreshUserRequiresId() public function testRefreshInvalidUser() { - $em = $this->createTestEntityManager(); + $em = DoctrineTestHelper::createTestEntityManager(); $this->createSchema($em); - $user1 = new CompositeIdentEntity(1, 1, 'user1'); + $user1 = new User(1, 1, 'user1'); $em->persist($user1); $em->flush(); - $provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity', 'name'); + $provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\User', 'name'); - $user2 = new CompositeIdentEntity(1, 2, 'user2'); + $user2 = new User(1, 2, 'user2'); $this->setExpectedException( 'Symfony\Component\Security\Core\Exception\UsernameNotFoundException', 'User with id {"id1":1,"id2":2} not found' @@ -74,18 +74,18 @@ public function testRefreshInvalidUser() public function testSupportProxy() { - $em = $this->createTestEntityManager(); + $em = DoctrineTestHelper::createTestEntityManager(); $this->createSchema($em); - $user1 = new CompositeIdentEntity(1, 1, 'user1'); + $user1 = new User(1, 1, 'user1'); $em->persist($user1); $em->flush(); $em->clear(); - $provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity', 'name'); + $provider = new EntityUserProvider($this->getManager($em), 'Symfony\Bridge\Doctrine\Tests\Fixtures\User', 'name'); - $user2 = $em->getReference('Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity', array('id1' => 1, 'id2' => 1)); + $user2 = $em->getReference('Symfony\Bridge\Doctrine\Tests\Fixtures\User', array('id1' => 1, 'id2' => 1)); $this->assertTrue($provider->supportsClass(get_class($user2))); } @@ -104,7 +104,7 @@ private function createSchema($em) { $schemaTool = new SchemaTool($em); $schemaTool->createSchema(array( - $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity'), + $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\User'), )); } } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueValidatorTest.php index f7748258ad10e..55e8d5f7b6563 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueValidatorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueValidatorTest.php @@ -11,12 +11,12 @@ namespace Symfony\Bridge\Doctrine\Tests\Validator\Constraints; -use Symfony\Bridge\Doctrine\Tests\DoctrineOrmTestCase; +use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper; +use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity; use Symfony\Component\Validator\DefaultTranslator; use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory; -use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity; -use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleIdentEntity; -use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity; use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator; @@ -24,7 +24,7 @@ use Symfony\Component\Validator\Validator; use Doctrine\ORM\Tools\SchemaTool; -class UniqueValidatorTest extends DoctrineOrmTestCase +class UniqueValidatorTest extends \PHPUnit_Framework_TestCase { protected function createRegistryMock($entityManagerName, $em) { @@ -96,7 +96,7 @@ protected function createValidatorFactory($uniqueValidator) public function createValidator($entityManagerName, $em, $validateClass = null, $uniqueFields = null, $errorPath = null, $repositoryMethod = 'findBy', $ignoreNull = true) { if (!$validateClass) { - $validateClass = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity'; + $validateClass = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity'; } if (!$uniqueFields) { $uniqueFields = array('name'); @@ -127,9 +127,9 @@ private function createSchema($em) { $schemaTool = new SchemaTool($em); $schemaTool->createSchema(array( - $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity'), - $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleIdentEntity'), - $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity'), + $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity'), + $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity'), + $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity'), $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity'), )); } @@ -140,11 +140,11 @@ private function createSchema($em) public function testValidateUniqueness() { $entityManagerName = "foo"; - $em = $this->createTestEntityManager(); + $em = DoctrineTestHelper::createTestEntityManager(); $this->createSchema($em); $validator = $this->createValidator($entityManagerName, $em); - $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); $violationsList = $validator->validate($entity1); $this->assertEquals(0, $violationsList->count(), "No violations found on entity before it is saved to the database."); @@ -154,7 +154,7 @@ public function testValidateUniqueness() $violationsList = $validator->validate($entity1); $this->assertEquals(0, $violationsList->count(), "No violations found on entity after it was saved to the database."); - $entity2 = new SingleIdentEntity(2, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Foo'); $violationsList = $validator->validate($entity2); $this->assertEquals(1, $violationsList->count(), "Violation found on entity with conflicting entity existing in the database."); @@ -168,16 +168,16 @@ public function testValidateUniqueness() public function testValidateCustomErrorPath() { $entityManagerName = "foo"; - $em = $this->createTestEntityManager(); + $em = DoctrineTestHelper::createTestEntityManager(); $this->createSchema($em); $validator = $this->createValidator($entityManagerName, $em, null, null, 'bar'); - $entity1 = new SingleIdentEntity(1, 'Foo'); + $entity1 = new SingleIntIdEntity(1, 'Foo'); $em->persist($entity1); $em->flush(); - $entity2 = new SingleIdentEntity(2, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Foo'); $violationsList = $validator->validate($entity2); $this->assertEquals(1, $violationsList->count(), "Violation found on entity with conflicting entity existing in the database."); @@ -191,12 +191,12 @@ public function testValidateCustomErrorPath() public function testValidateUniquenessWithNull() { $entityManagerName = "foo"; - $em = $this->createTestEntityManager(); + $em = DoctrineTestHelper::createTestEntityManager(); $this->createSchema($em); $validator = $this->createValidator($entityManagerName, $em); - $entity1 = new SingleIdentEntity(1, null); - $entity2 = new SingleIdentEntity(2, null); + $entity1 = new SingleIntIdEntity(1, null); + $entity2 = new SingleIntIdEntity(2, null); $em->persist($entity1); $em->persist($entity2); @@ -209,12 +209,12 @@ public function testValidateUniquenessWithNull() public function testValidateUniquenessWithIgnoreNull() { $entityManagerName = "foo"; - $validateClass = 'Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleIdentEntity'; - $em = $this->createTestEntityManager(); + $validateClass = 'Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity'; + $em = DoctrineTestHelper::createTestEntityManager(); $this->createSchema($em); $validator = $this->createValidator($entityManagerName, $em, $validateClass, array('name', 'name2'), 'bar', 'findby', false); - $entity1 = new DoubleIdentEntity(1, 'Foo', null); + $entity1 = new DoubleNameEntity(1, 'Foo', null); $violationsList = $validator->validate($entity1); $this->assertEquals(0, $violationsList->count(), "No violations found on entity before it is saved to the database."); @@ -224,7 +224,7 @@ public function testValidateUniquenessWithIgnoreNull() $violationsList = $validator->validate($entity1); $this->assertEquals(0, $violationsList->count(), "No violations found on entity after it was saved to the database."); - $entity2 = new DoubleIdentEntity(2, 'Foo', null); + $entity2 = new DoubleNameEntity(2, 'Foo', null); $violationsList = $validator->validate($entity2); $this->assertEquals(1, $violationsList->count(), "Violation found on entity with conflicting entity existing in the database."); @@ -238,12 +238,12 @@ public function testValidateUniquenessWithIgnoreNull() public function testValidateUniquenessAfterConsideringMultipleQueryResults() { $entityManagerName = "foo"; - $em = $this->createTestEntityManager(); + $em = DoctrineTestHelper::createTestEntityManager(); $this->createSchema($em); $validator = $this->createValidator($entityManagerName, $em); - $entity1 = new SingleIdentEntity(1, 'foo'); - $entity2 = new SingleIdentEntity(2, 'foo'); + $entity1 = new SingleIntIdEntity(1, 'foo'); + $entity2 = new SingleIntIdEntity(2, 'foo'); $em->persist($entity1); $em->persist($entity2); @@ -267,7 +267,7 @@ public function testValidateUniquenessUsingCustomRepositoryMethod() $em = $this->createEntityManagerMock($repository); $validator = $this->createValidator($entityManagerName, $em, null, array(), null, 'findByCustom'); - $entity1 = new SingleIdentEntity(1, 'foo'); + $entity1 = new SingleIntIdEntity(1, 'foo'); $violationsList = $validator->validate($entity1); $this->assertEquals(0, $violationsList->count(), 'Violation is using custom repository method.'); @@ -275,7 +275,7 @@ public function testValidateUniquenessUsingCustomRepositoryMethod() public function testValidateUniquenessWithUnrewoundArray() { - $entity = new SingleIdentEntity(1, 'foo'); + $entity = new SingleIntIdEntity(1, 'foo'); $entityManagerName = 'foo'; $repository = $this->createRepositoryMock(); @@ -305,11 +305,11 @@ public function testValidateUniquenessWithUnrewoundArray() public function testAssociatedEntity() { $entityManagerName = "foo"; - $em = $this->createTestEntityManager(); + $em = DoctrineTestHelper::createTestEntityManager(); $this->createSchema($em); $validator = $this->createValidator($entityManagerName, $em, 'Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity', array('single')); - $entity1 = new SingleIdentEntity(1, 'foo'); + $entity1 = new SingleIntIdEntity(1, 'foo'); $associated = new AssociationEntity(); $associated->single = $entity1; @@ -336,11 +336,11 @@ public function testAssociatedEntity() public function testAssociatedCompositeEntity() { $entityManagerName = "foo"; - $em = $this->createTestEntityManager(); + $em = DoctrineTestHelper::createTestEntityManager(); $this->createSchema($em); $validator = $this->createValidator($entityManagerName, $em, 'Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity', array('composite')); - $composite = new CompositeIdentEntity(1, 1, "test"); + $composite = new CompositeIntIdEntity(1, 1, "test"); $associated = new AssociationEntity(); $associated->composite = $composite; diff --git a/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php b/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php index b10e3c278940b..17fec6d7f685a 100644 --- a/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php +++ b/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php @@ -252,6 +252,8 @@ public function getValuesForChoices(array $models) * @return array * * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + * + * @deprecated Deprecated since version 2.4, to be removed in 3.0. */ public function getIndicesForChoices(array $models) { @@ -310,6 +312,8 @@ public function getIndicesForChoices(array $models) * @return array * * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + * + * @deprecated Deprecated since version 2.4, to be removed in 3.0. */ public function getIndicesForValues(array $values) { diff --git a/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceList.php b/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceList.php index f9d381cd0497f..413f7c4f741a6 100644 --- a/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceList.php +++ b/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceList.php @@ -156,11 +156,11 @@ public function getChoicesForValues(array $values) $values = $this->fixValues($values); $choices = array(); - foreach ($values as $j => $givenValue) { - foreach ($this->values as $i => $value) { + foreach ($values as $i => $givenValue) { + foreach ($this->values as $j => $value) { if ($value === $givenValue) { - $choices[] = $this->choices[$i]; - unset($values[$j]); + $choices[$i] = $this->choices[$j]; + unset($values[$i]); if (0 === count($values)) { break 2; @@ -180,11 +180,11 @@ public function getValuesForChoices(array $choices) $choices = $this->fixChoices($choices); $values = array(); - foreach ($this->choices as $i => $choice) { - foreach ($choices as $j => $givenChoice) { + foreach ($choices as $i => $givenChoice) { + foreach ($this->choices as $j => $choice) { if ($choice === $givenChoice) { - $values[] = $this->values[$i]; - unset($choices[$j]); + $values[$i] = $this->values[$j]; + unset($choices[$i]); if (0 === count($choices)) { break 2; @@ -198,17 +198,19 @@ public function getValuesForChoices(array $choices) /** * {@inheritdoc} + * + * @deprecated Deprecated since version 2.4, to be removed in 3.0. */ public function getIndicesForChoices(array $choices) { $choices = $this->fixChoices($choices); $indices = array(); - foreach ($this->choices as $i => $choice) { - foreach ($choices as $j => $givenChoice) { + foreach ($choices as $i => $givenChoice) { + foreach ($this->choices as $j => $choice) { if ($choice === $givenChoice) { - $indices[] = $i; - unset($choices[$j]); + $indices[$i] = $j; + unset($choices[$i]); if (0 === count($choices)) { break 2; @@ -222,17 +224,19 @@ public function getIndicesForChoices(array $choices) /** * {@inheritdoc} + * + * @deprecated Deprecated since version 2.4, to be removed in 3.0. */ public function getIndicesForValues(array $values) { $values = $this->fixValues($values); $indices = array(); - foreach ($this->values as $i => $value) { - foreach ($values as $j => $givenValue) { + foreach ($values as $i => $givenValue) { + foreach ($this->values as $j => $value) { if ($value === $givenValue) { - $indices[] = $i; - unset($values[$j]); + $indices[$i] = $j; + unset($values[$i]); if (0 === count($values)) { break 2; @@ -485,9 +489,9 @@ protected function fixIndices(array $indices) * Extension point. In this implementation, choices are guaranteed to * always maintain their type and thus can be typesafely compared. * - * @param mixed $choice The choice. + * @param mixed $choice The choice * - * @return mixed The fixed choice. + * @return mixed The fixed choice */ protected function fixChoice($choice) { @@ -495,14 +499,14 @@ protected function fixChoice($choice) } /** - * Fixes the data type of the given choices to avoid comparison problems. - * - * @param array $choices The choices. - * - * @return array The fixed choices. - * - * @see fixChoice - */ + * Fixes the data type of the given choices to avoid comparison problems. + * + * @param array $choices The choices. + * + * @return array The fixed choices. + * + * @see fixChoice + */ protected function fixChoices(array $choices) { return $choices; diff --git a/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceListInterface.php b/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceListInterface.php index 099ace8253036..0e5f9459b9ede 100644 --- a/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceListInterface.php +++ b/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceListInterface.php @@ -97,6 +97,9 @@ public function getRemainingViews(); * * The choices can have any data type. * + * The choices must be returned with the same keys and in the same order + * as the corresponding values in the given array. + * * @param array $values An array of choice values. Not existing values in * this array are ignored * @@ -109,6 +112,9 @@ public function getChoicesForValues(array $values); * * The values must be strings. * + * The values must be returned with the same keys and in the same order + * as the corresponding choices in the given array. + * * @param array $choices An array of choices. Not existing choices in this * array are ignored * @@ -125,10 +131,15 @@ public function getValuesForChoices(array $choices); * * The index "placeholder" is internally reserved. * + * The indices must be returned with the same keys and in the same order + * as the corresponding choices in the given array. + * * @param array $choices An array of choices. Not existing choices in this * array are ignored * * @return array An array of indices with ascending, 0-based numeric keys + * + * @deprecated Deprecated since version 2.4, to be removed in 3.0. */ public function getIndicesForChoices(array $choices); @@ -140,10 +151,15 @@ public function getIndicesForChoices(array $choices); * * The index "placeholder" is internally reserved. * + * The indices must be returned with the same keys and in the same order + * as the corresponding values in the given array. + * * @param array $values An array of choice values. Not existing values in * this array are ignored * * @return array An array of indices with ascending, 0-based numeric keys + * + * @deprecated Deprecated since version 2.4, to be removed in 3.0. */ public function getIndicesForValues(array $values); } diff --git a/src/Symfony/Component/Form/Extension/Core/ChoiceList/LazyChoiceList.php b/src/Symfony/Component/Form/Extension/Core/ChoiceList/LazyChoiceList.php index 996f900cf3850..23f3cccbe2fa2 100644 --- a/src/Symfony/Component/Form/Extension/Core/ChoiceList/LazyChoiceList.php +++ b/src/Symfony/Component/Form/Extension/Core/ChoiceList/LazyChoiceList.php @@ -105,6 +105,8 @@ public function getValuesForChoices(array $choices) /** * {@inheritdoc} + * + * @deprecated Deprecated since version 2.4, to be removed in 3.0. */ public function getIndicesForChoices(array $choices) { @@ -117,6 +119,8 @@ public function getIndicesForChoices(array $choices) /** * {@inheritdoc} + * + * @deprecated Deprecated since version 2.4, to be removed in 3.0. */ public function getIndicesForValues(array $values) { diff --git a/src/Symfony/Component/Form/Extension/Core/ChoiceList/SimpleChoiceList.php b/src/Symfony/Component/Form/Extension/Core/ChoiceList/SimpleChoiceList.php index 914dbe5fdb174..e173e742c7349 100644 --- a/src/Symfony/Component/Form/Extension/Core/ChoiceList/SimpleChoiceList.php +++ b/src/Symfony/Component/Form/Extension/Core/ChoiceList/SimpleChoiceList.php @@ -135,9 +135,9 @@ protected function isPreferred($choice, array $preferredChoices) /** * Converts the choice to a valid PHP array key. * - * @param mixed $choice The choice. + * @param mixed $choice The choice * - * @return string|integer A valid PHP array key. + * @return string|integer A valid PHP array key */ protected function fixChoice($choice) { diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/BooleanToStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/BooleanToStringTransformer.php index 95e7332d3e03f..f8e3b5bfcbc1c 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/BooleanToStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/BooleanToStringTransformer.php @@ -49,15 +49,11 @@ public function __construct($trueValue) */ public function transform($value) { - if (null === $value) { - return null; - } - if (!is_bool($value)) { throw new TransformationFailedException('Expected a Boolean.'); } - return true === $value ? $this->trueValue : null; + return $value ? $this->trueValue : null; } /** diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoiceToBooleanArrayTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoiceToBooleanArrayTransformer.php index 79b3f7ac8977b..b521c955720ed 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoiceToBooleanArrayTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoiceToBooleanArrayTransformer.php @@ -60,14 +60,14 @@ public function transform($choice) throw new TransformationFailedException('Can not get the choice list', $e->getCode(), $e); } - $index = current($this->choiceList->getIndicesForChoices(array($choice))); + $valueMap = array_flip($this->choiceList->getValuesForChoices(array($choice))); foreach ($values as $i => $value) { - $values[$i] = $i === $index; + $values[$i] = isset($valueMap[$value]); } if ($this->placeholderPresent) { - $values['placeholder'] = false === $index; + $values['placeholder'] = 0 === count($valueMap); } return $values; diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoicesToBooleanArrayTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoicesToBooleanArrayTransformer.php index a13c0d4d430fe..f1f13fda28845 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoicesToBooleanArrayTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoicesToBooleanArrayTransformer.php @@ -58,10 +58,10 @@ public function transform($array) throw new TransformationFailedException('Can not get the choice list', $e->getCode(), $e); } - $indexMap = array_flip($this->choiceList->getIndicesForChoices($array)); + $valueMap = array_flip($this->choiceList->getValuesForChoices($array)); foreach ($values as $i => $value) { - $values[$i] = isset($indexMap[$i]); + $values[$i] = isset($valueMap[$value]); } return $values; diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/FixCheckboxInputListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/FixCheckboxInputListener.php index 1f62e060ffeac..8e72b04137b79 100644 --- a/src/Symfony/Component/Form/Extension/Core/EventListener/FixCheckboxInputListener.php +++ b/src/Symfony/Component/Form/Extension/Core/EventListener/FixCheckboxInputListener.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Form\Extension\Core\EventListener; +use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\FormEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -38,10 +39,43 @@ public function __construct(ChoiceListInterface $choiceList) public function preSubmit(FormEvent $event) { - $values = (array) $event->getData(); - $indices = $this->choiceList->getIndicesForValues($values); + $data = $event->getData(); - $event->setData(count($indices) > 0 ? array_combine($indices, $values) : array()); + if (is_array($data)) { + // Flip the submitted values for faster lookup + // It's better to flip this array than $existingValues because + // $submittedValues is generally smaller. + $submittedValues = array_flip($data); + + // Since expanded choice fields are completely loaded anyway, we + // can just as well get the values again without losing performance. + $existingValues = $this->choiceList->getValues(); + + // Clear the data array and fill it with correct indices + $data = array(); + + foreach ($existingValues as $index => $value) { + if (isset($submittedValues[$value])) { + // Value was submitted + $data[$index] = $value; + unset($submittedValues[$value]); + } + } + + if (count($submittedValues) > 0) { + throw new TransformationFailedException(sprintf( + 'The following choices were not found: "%s"', + implode('", "', array_keys($submittedValues)) + )); + } + } elseif ('' === $data || null === $data) { + // Empty values are always accepted. + $data = array(); + } + + // Else leave the data unchanged to provoke an error during submission + + $event->setData($data); } /** diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/FixRadioInputListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/FixRadioInputListener.php index bf03792fed014..925585db4046c 100644 --- a/src/Symfony/Component/Form/Extension/Core/EventListener/FixRadioInputListener.php +++ b/src/Symfony/Component/Form/Extension/Core/EventListener/FixRadioInputListener.php @@ -42,10 +42,22 @@ public function __construct(ChoiceListInterface $choiceList, $placeholderPresent public function preSubmit(FormEvent $event) { - $value = $event->getData(); - $index = current($this->choiceList->getIndicesForValues(array($value))); + $data = $event->getData(); - $event->setData(false !== $index ? array($index => $value) : ($this->placeholderPresent ? array('placeholder' => '') : array())) ; + // Since expanded choice fields are completely loaded anyway, we + // can just as well get the values again without losing performance. + $existingValues = $this->choiceList->getValues(); + + if (false !== ($index = array_search($data, $existingValues, true))) { + $data = array($index => $data); + } elseif ('' === $data || null === $data) { + // Empty values are always accepted. + $data = $this->placeholderPresent ? array('placeholder' => '') : array(); + } + + // Else leave the data unchanged to provoke an error during submission + + $event->setData($data); } /** diff --git a/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php b/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php index 214e581aff61f..3952bb3316ca8 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php @@ -25,9 +25,14 @@ class CheckboxType extends AbstractType */ public function buildForm(FormBuilderInterface $builder, array $options) { - $builder - ->addViewTransformer(new BooleanToStringTransformer($options['value'])) - ; + // Unlike in other types, where the data is NULL by default, it + // needs to be a Boolean here. setData(null) is not acceptable + // for checkboxes and radio buttons (unless a custom model + // transformer handles this case). + // We cannot solve this case via overriding the "data" option, because + // doing so also calls setDataLocked(true). + $builder->setData(isset($options['data']) ? $options['data'] : false); + $builder->addViewTransformer(new BooleanToStringTransformer($options['value'])); } /** @@ -46,8 +51,8 @@ public function buildView(FormView $view, FormInterface $form, array $options) */ public function setDefaultOptions(OptionsResolverInterface $resolver) { - $emptyData = function (FormInterface $form, $clientData) { - return $clientData; + $emptyData = function (FormInterface $form, $viewData) { + return $viewData; }; $resolver->setDefaults(array( diff --git a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php index d26ee5f72ae0f..d3d9187c0c0c7 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php @@ -57,7 +57,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) // Check if the choices already contain the empty value // Only add the empty value option if this is not the case - if (null !== $options['empty_value'] && 0 === count($options['choice_list']->getIndicesForValues(array('')))) { + if (null !== $options['empty_value'] && 0 === count($options['choice_list']->getChoicesForValues(array('')))) { $placeholderView = new ChoiceView(null, '', $options['empty_value']); // "placeholder" is a reserved index @@ -120,7 +120,7 @@ public function buildView(FormView $view, FormInterface $form, array $options) // Check if the choices already contain the empty value // Only add the empty value option if this is not the case - if (null !== $options['empty_value'] && 0 === count($options['choice_list']->getIndicesForValues(array('')))) { + if (null !== $options['empty_value'] && 0 === count($options['choice_list']->getChoicesForValues(array('')))) { $view->vars['empty_value'] = $options['empty_value']; } diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index 5399cc99cc8d7..f3324986c8c10 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -522,83 +522,82 @@ public function submit($submittedData, $clearMissing = true) $dispatcher = $this->config->getEventDispatcher(); - // Hook to change content of the data submitted by the browser - if ($dispatcher->hasListeners(FormEvents::PRE_SUBMIT)) { - $event = new FormEvent($this, $submittedData); - $dispatcher->dispatch(FormEvents::PRE_SUBMIT, $event); - $submittedData = $event->getData(); - } + $modelData = null; + $normData = null; + $viewData = null; - // Check whether the form is compound. - // This check is preferable over checking the number of children, - // since forms without children may also be compound. - // (think of empty collection forms) - if ($this->config->getCompound()) { - if (!is_array($submittedData)) { - $submittedData = array(); + try { + // Hook to change content of the data submitted by the browser + if ($dispatcher->hasListeners(FormEvents::PRE_SUBMIT)) { + $event = new FormEvent($this, $submittedData); + $dispatcher->dispatch(FormEvents::PRE_SUBMIT, $event); + $submittedData = $event->getData(); } - foreach ($this->children as $name => $child) { - if (array_key_exists($name, $submittedData) || $clearMissing) { - $child->submit(isset($submittedData[$name]) ? $submittedData[$name] : null, $clearMissing); - unset($submittedData[$name]); + // Check whether the form is compound. + // This check is preferable over checking the number of children, + // since forms without children may also be compound. + // (think of empty collection forms) + if ($this->config->getCompound()) { + if (null === $submittedData) { + $submittedData = array(); } - } - - $this->extraData = $submittedData; - } - // Forms that inherit their parents' data also are not processed, - // because then it would be too difficult to merge the changes in - // the child and the parent form. Instead, the parent form also takes - // changes in the grandchildren (i.e. children of the form that inherits - // its parent's data) into account. - // (see InheritDataAwareIterator below) - if ($this->config->getInheritData()) { - $this->submitted = true; + if (!is_array($submittedData)) { + throw new TransformationFailedException('Compound forms expect an array or NULL on submission.'); + } - // When POST_SUBMIT is reached, the data is not yet updated, so pass - // NULL to prevent hard-to-debug bugs. - $dataForPostSubmit = null; - } else { - // If the form is compound, the default data in view format - // is reused. The data of the children is merged into this - // default data using the data mapper. - // If the form is not compound, the submitted data is also the data in view format. - $viewData = $this->config->getCompound() ? $this->viewData : $submittedData; - - if (FormUtil::isEmpty($viewData)) { - $emptyData = $this->config->getEmptyData(); - - if ($emptyData instanceof \Closure) { - /* @var \Closure $emptyData */ - $emptyData = $emptyData($this, $viewData); + foreach ($this->children as $name => $child) { + if (isset($submittedData[$name]) || $clearMissing) { + $child->submit(isset($submittedData[$name]) ? $submittedData[$name] : null, $clearMissing); + unset($submittedData[$name]); + } } - $viewData = $emptyData; + $this->extraData = $submittedData; } - // Merge form data from children into existing view data - // It is not necessary to invoke this method if the form has no children, - // even if it is compound. - if (count($this->children) > 0) { - // Use InheritDataAwareIterator to process children of - // descendants that inherit this form's data. - // These descendants will not be submitted normally (see the check - // for $this->config->getInheritData() above) - $iterator = new InheritDataAwareIterator($this->children); - $iterator = new \RecursiveIteratorIterator($iterator); - $this->config->getDataMapper()->mapFormsToData($iterator, $viewData); - } + // Forms that inherit their parents' data also are not processed, + // because then it would be too difficult to merge the changes in + // the child and the parent form. Instead, the parent form also takes + // changes in the grandchildren (i.e. children of the form that inherits + // its parent's data) into account. + // (see InheritDataAwareIterator below) + if (!$this->config->getInheritData()) { + // If the form is compound, the default data in view format + // is reused. The data of the children is merged into this + // default data using the data mapper. + // If the form is not compound, the submitted data is also the data in view format. + $viewData = $this->config->getCompound() ? $this->viewData : $submittedData; + + if (FormUtil::isEmpty($viewData)) { + $emptyData = $this->config->getEmptyData(); + + if ($emptyData instanceof \Closure) { + /* @var \Closure $emptyData */ + $emptyData = $emptyData($this, $viewData); + } + + $viewData = $emptyData; + } - $modelData = null; - $normData = null; + // Merge form data from children into existing view data + // It is not necessary to invoke this method if the form has no children, + // even if it is compound. + if (count($this->children) > 0) { + // Use InheritDataAwareIterator to process children of + // descendants that inherit this form's data. + // These descendants will not be submitted normally (see the check + // for $this->config->getInheritData() above) + $childrenIterator = new InheritDataAwareIterator($this->children); + $childrenIterator = new \RecursiveIteratorIterator($childrenIterator); + $this->config->getDataMapper()->mapFormsToData($childrenIterator, $viewData); + } - try { // Normalize data to unified representation $normData = $this->viewToNorm($viewData); - // Hook to change content of the data into the normalized + // Hook to change content of the data in the normalized // representation if ($dispatcher->hasListeners(FormEvents::SUBMIT)) { $event = new FormEvent($this, $normData); @@ -609,20 +608,26 @@ public function submit($submittedData, $clearMissing = true) // Synchronize representations - must not change the content! $modelData = $this->normToModel($normData); $viewData = $this->normToView($normData); - } catch (TransformationFailedException $e) { - $this->synchronized = false; } - - $this->submitted = true; - $this->modelData = $modelData; - $this->normData = $normData; - $this->viewData = $viewData; - - $dataForPostSubmit = $viewData; + } catch (TransformationFailedException $e) { + $this->synchronized = false; + + // If $viewData was not yet set, set it to $submittedData so that + // the erroneous data is accessible on the form. + // Forms that inherit data never set any data, because the getters + // forward to the parent form's getters anyway. + if (null === $viewData && !$this->config->getInheritData()) { + $viewData = $submittedData; + } } + $this->submitted = true; + $this->modelData = $modelData; + $this->normData = $normData; + $this->viewData = $viewData; + if ($dispatcher->hasListeners(FormEvents::POST_SUBMIT)) { - $event = new FormEvent($this, $dataForPostSubmit); + $event = new FormEvent($this, $viewData); $dispatcher->dispatch(FormEvents::POST_SUBMIT, $event); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/AbstractChoiceListTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/AbstractChoiceListTest.php new file mode 100644 index 0000000000000..0e2b6321ccb83 --- /dev/null +++ b/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/AbstractChoiceListTest.php @@ -0,0 +1,297 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\ChoiceList; + +/** + * @author Bernhard Schussek + */ +abstract class AbstractChoiceListTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + protected $list; + + /** + * @var array + */ + protected $choices; + + /** + * @var array + */ + protected $values; + + /** + * @var array + */ + protected $indices; + + /** + * @var array + */ + protected $labels; + + /** + * @var mixed + */ + protected $choice1; + + /** + * @var mixed + */ + protected $choice2; + + /** + * @var mixed + */ + protected $choice3; + + /** + * @var mixed + */ + protected $choice4; + + /** + * @var string + */ + protected $value1; + + /** + * @var string + */ + protected $value2; + + /** + * @var string + */ + protected $value3; + + /** + * @var string + */ + protected $value4; + + /** + * @var int|string + */ + protected $index1; + + /** + * @var int|string + */ + protected $index2; + + /** + * @var int|string + */ + protected $index3; + + /** + * @var int|string + */ + protected $index4; + + /** + * @var string + */ + protected $label1; + + /** + * @var string + */ + protected $label2; + + /** + * @var string + */ + protected $label3; + + /** + * @var string + */ + protected $label4; + + protected function setUp() + { + parent::setUp(); + + $this->list = $this->createChoiceList(); + + $this->choices = $this->getChoices(); + $this->indices = $this->getIndices(); + $this->values = $this->getValues(); + $this->labels = $this->getLabels(); + + // allow access to the individual entries without relying on their indices + reset($this->choices); + reset($this->indices); + reset($this->values); + reset($this->labels); + + for ($i = 1; $i <= 4; ++$i) { + $this->{'choice'.$i} = current($this->choices); + $this->{'index'.$i} = current($this->indices); + $this->{'value'.$i} = current($this->values); + $this->{'label'.$i} = current($this->labels); + + next($this->choices); + next($this->indices); + next($this->values); + next($this->labels); + } + } + + public function testGetChoices() + { + $this->assertSame($this->choices, $this->list->getChoices()); + } + + public function testGetValues() + { + $this->assertSame($this->values, $this->list->getValues()); + } + + public function testGetIndicesForChoices() + { + $choices = array($this->choice1, $this->choice2); + $this->assertSame(array($this->index1, $this->index2), $this->list->getIndicesForChoices($choices)); + } + + public function testGetIndicesForChoicesPreservesKeys() + { + $choices = array(5 => $this->choice1, 8 => $this->choice2); + $this->assertSame(array(5 => $this->index1, 8 => $this->index2), $this->list->getIndicesForChoices($choices)); + } + + public function testGetIndicesForChoicesPreservesOrder() + { + $choices = array($this->choice2, $this->choice1); + $this->assertSame(array($this->index2, $this->index1), $this->list->getIndicesForChoices($choices)); + } + + public function testGetIndicesForChoicesIgnoresNonExistingChoices() + { + $choices = array($this->choice1, $this->choice2, 'foobar'); + $this->assertSame(array($this->index1, $this->index2), $this->list->getIndicesForChoices($choices)); + } + + public function testGetIndicesForChoicesEmpty() + { + $this->assertSame(array(), $this->list->getIndicesForChoices(array())); + } + + public function testGetIndicesForValues() + { + // values and indices are always the same + $values = array($this->value1, $this->value2); + $this->assertSame(array($this->index1, $this->index2), $this->list->getIndicesForValues($values)); + } + + public function testGetIndicesForValuesPreservesKeys() + { + // values and indices are always the same + $values = array(5 => $this->value1, 8 => $this->value2); + $this->assertSame(array(5 => $this->index1, 8 => $this->index2), $this->list->getIndicesForValues($values)); + } + + public function testGetIndicesForValuesPreservesOrder() + { + $values = array($this->value2, $this->value1); + $this->assertSame(array($this->index2, $this->index1), $this->list->getIndicesForValues($values)); + } + + public function testGetIndicesForValuesIgnoresNonExistingValues() + { + $values = array($this->value1, $this->value2, 'foobar'); + $this->assertSame(array($this->index1, $this->index2), $this->list->getIndicesForValues($values)); + } + + public function testGetIndicesForValuesEmpty() + { + $this->assertSame(array(), $this->list->getIndicesForValues(array())); + } + + public function testGetChoicesForValues() + { + $values = array($this->value1, $this->value2); + $this->assertSame(array($this->choice1, $this->choice2), $this->list->getChoicesForValues($values)); + } + + public function testGetChoicesForValuesPreservesKeys() + { + $values = array(5 => $this->value1, 8 => $this->value2); + $this->assertSame(array(5 => $this->choice1, 8 => $this->choice2), $this->list->getChoicesForValues($values)); + } + + public function testGetChoicesForValuesPreservesOrder() + { + $values = array($this->value2, $this->value1); + $this->assertSame(array($this->choice2, $this->choice1), $this->list->getChoicesForValues($values)); + } + + public function testGetChoicesForValuesIgnoresNonExistingValues() + { + $values = array($this->value1, $this->value2, 'foobar'); + $this->assertSame(array($this->choice1, $this->choice2), $this->list->getChoicesForValues($values)); + } + + // https://github.com/symfony/symfony/issues/3446 + public function testGetChoicesForValuesEmpty() + { + $this->assertSame(array(), $this->list->getChoicesForValues(array())); + } + + public function testGetValuesForChoices() + { + $choices = array($this->choice1, $this->choice2); + $this->assertSame(array($this->value1, $this->value2), $this->list->getValuesForChoices($choices)); + } + + + public function testGetValuesForChoicesPreservesKeys() + { + $choices = array(5 => $this->choice1, 8 => $this->choice2); + $this->assertSame(array(5 => $this->value1, 8 => $this->value2), $this->list->getValuesForChoices($choices)); + } + + + public function testGetValuesForChoicesPreservesOrder() + { + $choices = array($this->choice2, $this->choice1); + $this->assertSame(array($this->value2, $this->value1), $this->list->getValuesForChoices($choices)); + } + + public function testGetValuesForChoicesIgnoresNonExistingChoices() + { + $choices = array($this->choice1, $this->choice2, 'foobar'); + $this->assertSame(array($this->value1, $this->value2), $this->list->getValuesForChoices($choices)); + } + + public function testGetValuesForChoicesEmpty() + { + $this->assertSame(array(), $this->list->getValuesForChoices(array())); + } + + /** + * @return \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + abstract protected function createChoiceList(); + + abstract protected function getChoices(); + + abstract protected function getLabels(); + + abstract protected function getValues(); + + abstract protected function getIndices(); +} diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ChoiceListTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ChoiceListTest.php index 63eae9bf7f5ef..59f002d8ccb00 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ChoiceListTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ChoiceListTest.php @@ -14,7 +14,7 @@ use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList; use Symfony\Component\Form\Extension\Core\View\ChoiceView; -class ChoiceListTest extends \PHPUnit_Framework_TestCase +class ChoiceListTest extends AbstractChoiceListTest { private $obj1; @@ -24,39 +24,14 @@ class ChoiceListTest extends \PHPUnit_Framework_TestCase private $obj4; - private $list; - protected function setUp() { - parent::setUp(); - $this->obj1 = new \stdClass(); $this->obj2 = new \stdClass(); $this->obj3 = new \stdClass(); $this->obj4 = new \stdClass(); - $this->list = new ChoiceList( - array( - 'Group 1' => array($this->obj1, $this->obj2), - 'Group 2' => array($this->obj3, $this->obj4), - ), - array( - 'Group 1' => array('A', 'B'), - 'Group 2' => array('C', 'D'), - ), - array($this->obj2, $this->obj3) - ); - } - - protected function tearDown() - { - parent::tearDown(); - - $this->obj1 = null; - $this->obj2 = null; - $this->obj3 = null; - $this->obj4 = null; - $this->list = null; + parent::setUp(); } public function testInitArray() @@ -119,65 +94,10 @@ public function testInitNestedArray() ), $this->list->getRemainingViews()); } - public function testGetIndicesForChoices() - { - $choices = array($this->obj2, $this->obj3); - $this->assertSame(array(1, 2), $this->list->getIndicesForChoices($choices)); - } - - public function testGetIndicesForChoicesIgnoresNonExistingChoices() - { - $choices = array($this->obj2, $this->obj3, 'foobar'); - $this->assertSame(array(1, 2), $this->list->getIndicesForChoices($choices)); - } - - public function testGetIndicesForValues() - { - // values and indices are always the same - $values = array('1', '2'); - $this->assertSame(array(1, 2), $this->list->getIndicesForValues($values)); - } - - public function testGetIndicesForValuesIgnoresNonExistingValues() - { - $values = array('1', '2', '5'); - $this->assertSame(array(1, 2), $this->list->getIndicesForValues($values)); - } - - public function testGetChoicesForValues() - { - $values = array('1', '2'); - $this->assertSame(array($this->obj2, $this->obj3), $this->list->getChoicesForValues($values)); - } - - public function testGetChoicesForValuesCorrectOrderingOfResult() - { - $values = array('2', '1'); - $this->assertSame(array($this->obj3, $this->obj2), $this->list->getChoicesForValues($values)); - } - - public function testGetChoicesForValuesIgnoresNonExistingValues() - { - $values = array('1', '2', '5'); - $this->assertSame(array($this->obj2, $this->obj3), $this->list->getChoicesForValues($values)); - } - - public function testGetValuesForChoices() - { - $choices = array($this->obj2, $this->obj3); - $this->assertSame(array('1', '2'), $this->list->getValuesForChoices($choices)); - } - - public function testGetValuesForChoicesIgnoresNonExistingChoices() - { - $choices = array($this->obj2, $this->obj3, 'foobar'); - $this->assertSame(array('1', '2'), $this->list->getValuesForChoices($choices)); - } - /** * @expectedException \InvalidArgumentException */ - public function testNonMatchingLabels() + public function testInitWithInsufficientLabels() { $this->list = new ChoiceList( array($this->obj1, $this->obj2), @@ -185,7 +105,7 @@ public function testNonMatchingLabels() ); } - public function testLabelsContainingNull() + public function testInitWithLabelsContainingNull() { $this->list = new ChoiceList( array($this->obj1, $this->obj2), @@ -197,4 +117,42 @@ public function testLabelsContainingNull() $this->list->getRemainingViews() ); } + + /** + * @return \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + protected function createChoiceList() + { + return new ChoiceList( + array( + 'Group 1' => array($this->obj1, $this->obj2), + 'Group 2' => array($this->obj3, $this->obj4), + ), + array( + 'Group 1' => array('A', 'B'), + 'Group 2' => array('C', 'D'), + ), + array($this->obj2, $this->obj3) + ); + } + + protected function getChoices() + { + return array(0 => $this->obj1, 1 => $this->obj2, 2 => $this->obj3, 3 => $this->obj4); + } + + protected function getLabels() + { + return array(0 => 'A', 1 => 'B', 2 => 'C', 3 => 'D'); + } + + protected function getValues() + { + return array(0 => '0', 1 => '1', 2 => '2', 3 => '3'); + } + + protected function getIndices() + { + return array(0, 1, 2, 3); + } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ObjectChoiceListTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ObjectChoiceListTest.php index 69c5aa0fcbb3f..27effd9f5c2c0 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ObjectChoiceListTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ObjectChoiceListTest.php @@ -29,7 +29,7 @@ public function __toString() } } -class ObjectChoiceListTest extends \PHPUnit_Framework_TestCase +class ObjectChoiceListTest extends AbstractChoiceListTest { private $obj1; @@ -39,39 +39,14 @@ class ObjectChoiceListTest extends \PHPUnit_Framework_TestCase private $obj4; - /** - * @var ObjectChoiceList - */ - private $list; - protected function setUp() { - parent::setUp(); - $this->obj1 = (object) array('name' => 'A'); $this->obj2 = (object) array('name' => 'B'); $this->obj3 = (object) array('name' => 'C'); $this->obj4 = (object) array('name' => 'D'); - $this->list = new ObjectChoiceList( - array( - 'Group 1' => array($this->obj1, $this->obj2), - 'Group 2' => array($this->obj3, $this->obj4), - ), - 'name', - array($this->obj2, $this->obj3) - ); - } - - protected function tearDown() - { - parent::tearDown(); - - $this->obj1 = null; - $this->obj2 = null; - $this->obj3 = null; - $this->obj4 = null; - $this->list = null; + parent::setUp(); } public function testInitArray() @@ -209,4 +184,39 @@ public function testInitArrayThrowsExceptionIfToStringNotFound() array($this->obj1, $this->obj2, $this->obj3, $this->obj4) ); } + + /** + * @return \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + protected function createChoiceList() + { + return new ObjectChoiceList( + array( + 'Group 1' => array($this->obj1, $this->obj2), + 'Group 2' => array($this->obj3, $this->obj4), + ), + 'name', + array($this->obj2, $this->obj3) + ); + } + + protected function getChoices() + { + return array(0 => $this->obj1, 1 => $this->obj2, 2 => $this->obj3, 3 => $this->obj4); + } + + protected function getLabels() + { + return array(0 => 'A', 1 => 'B', 2 => 'C', 3 => 'D'); + } + + protected function getValues() + { + return array(0 => '0', 1 => '1', 2 => '2', 3 => '3'); + } + + protected function getIndices() + { + return array(0, 1, 2, 3); + } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/SimpleChoiceListTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/SimpleChoiceListTest.php index 69d27a18fd813..838a8e0864e41 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/SimpleChoiceListTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/SimpleChoiceListTest.php @@ -11,43 +11,11 @@ namespace Symfony\Component\Form\Tests\Extension\Core\ChoiceList; -use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList; use Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList; use Symfony\Component\Form\Extension\Core\View\ChoiceView; -class SimpleChoiceListTest extends \PHPUnit_Framework_TestCase +class SimpleChoiceListTest extends AbstractChoiceListTest { - private $list; - - private $numericList; - - protected function setUp() - { - parent::setUp(); - - $choices = array( - 'Group 1' => array('a' => 'A', 'b' => 'B'), - 'Group 2' => array('c' => 'C', 'd' => 'D'), - ); - $numericChoices = array( - 'Group 1' => array(0 => 'A', 1 => 'B'), - 'Group 2' => array(2 => 'C', 3 => 'D'), - ); - - $this->list = new SimpleChoiceList($choices, array('b', 'c')); - - // Use COPY_CHOICE strategy to test for the various associated problems - $this->numericList = new SimpleChoiceList($numericChoices, array(1, 2)); - } - - protected function tearDown() - { - parent::tearDown(); - - $this->list = null; - $this->numericList = null; - } - public function testInitArray() { $choices = array('a' => 'A', 'b' => 'B', 'c' => 'C'); @@ -73,83 +41,6 @@ public function testInitNestedArray() ), $this->list->getRemainingViews()); } - public function testGetIndicesForChoices() - { - $choices = array('b', 'c'); - $this->assertSame(array(1, 2), $this->list->getIndicesForChoices($choices)); - } - - public function testGetIndicesForChoicesIgnoresNonExistingChoices() - { - $choices = array('b', 'c', 'foobar'); - $this->assertSame(array(1, 2), $this->list->getIndicesForChoices($choices)); - } - - public function testGetIndicesForChoicesDealsWithNumericChoices() - { - // Pass choices as strings although they are integers - $choices = array('0', '1'); - $this->assertSame(array(0, 1), $this->numericList->getIndicesForChoices($choices)); - } - - public function testGetIndicesForValues() - { - $values = array('b', 'c'); - $this->assertSame(array(1, 2), $this->list->getIndicesForValues($values)); - } - - public function testGetIndicesForValuesIgnoresNonExistingValues() - { - $values = array('b', 'c', '100'); - $this->assertSame(array(1, 2), $this->list->getIndicesForValues($values)); - } - - public function testGetIndicesForValuesDealsWithNumericValues() - { - // Pass values as strings although they are integers - $values = array('0', '1'); - $this->assertSame(array(0, 1), $this->numericList->getIndicesForValues($values)); - } - - public function testGetChoicesForValues() - { - $values = array('b', 'c'); - $this->assertSame(array('b', 'c'), $this->list->getChoicesForValues($values)); - } - - public function testGetChoicesForValuesIgnoresNonExistingValues() - { - $values = array('b', 'c', '100'); - $this->assertSame(array('b', 'c'), $this->list->getChoicesForValues($values)); - } - - public function testGetChoicesForValuesDealsWithNumericValues() - { - // Pass values as strings although they are integers - $values = array('0', '1'); - $this->assertSame(array(0, 1), $this->numericList->getChoicesForValues($values)); - } - - public function testGetValuesForChoices() - { - $choices = array('b', 'c'); - $this->assertSame(array('b', 'c'), $this->list->getValuesForChoices($choices)); - } - - public function testGetValuesForChoicesIgnoresNonExistingValues() - { - $choices = array('b', 'c', 'foobar'); - $this->assertSame(array('b', 'c'), $this->list->getValuesForChoices($choices)); - } - - public function testGetValuesForChoicesDealsWithNumericValues() - { - // Pass values as strings although they are integers - $values = array('0', '1'); - - $this->assertSame(array('0', '1'), $this->numericList->getValuesForChoices($values)); - } - /** * @dataProvider dirtyValuesProvider */ @@ -164,7 +55,6 @@ public function testGetValuesForChoicesDealsWithDirtyValues($choice, $value) 'foo10' => 'Foo 10', ); - // use COPY_CHOICE strategy to test the problems $this->list = new SimpleChoiceList($choices, array()); $this->assertSame(array($value), $this->list->getValuesForChoices(array($choice))); @@ -185,4 +75,35 @@ public function dirtyValuesProvider() array('foo10', 'foo10'), ); } + + /** + * @return \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + protected function createChoiceList() + { + return new SimpleChoiceList(array( + 'Group 1' => array('a' => 'A', 'b' => 'B'), + 'Group 2' => array('c' => 'C', 'd' => 'D'), + ), array('b', 'c')); + } + + protected function getChoices() + { + return array(0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd'); + } + + protected function getLabels() + { + return array(0 => 'A', 1 => 'B', 2 => 'C', 3 => 'D'); + } + + protected function getValues() + { + return array(0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd'); + } + + protected function getIndices() + { + return array(0, 1, 2, 3); + } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/SimpleNumericChoiceListTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/SimpleNumericChoiceListTest.php new file mode 100644 index 0000000000000..2b57288fb7f36 --- /dev/null +++ b/src/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/SimpleNumericChoiceListTest.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\ChoiceList; + +use Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList; +use Symfony\Component\Form\Extension\Core\View\ChoiceView; + +class SimpleNumericChoiceListTest extends AbstractChoiceListTest +{ + public function testGetIndicesForChoicesDealsWithNumericChoices() + { + // Pass choices as strings although they are integers + $choices = array('0', '1'); + $this->assertSame(array(0, 1), $this->list->getIndicesForChoices($choices)); + } + + public function testGetIndicesForValuesDealsWithNumericValues() + { + // Pass values as strings although they are integers + $values = array('0', '1'); + $this->assertSame(array(0, 1), $this->list->getIndicesForValues($values)); + } + + public function testGetChoicesForValuesDealsWithNumericValues() + { + // Pass values as strings although they are integers + $values = array('0', '1'); + $this->assertSame(array(0, 1), $this->list->getChoicesForValues($values)); + } + + public function testGetValuesForChoicesDealsWithNumericValues() + { + // Pass values as strings although they are integers + $values = array('0', '1'); + + $this->assertSame(array('0', '1'), $this->list->getValuesForChoices($values)); + } + + /** + * @return \Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface + */ + protected function createChoiceList() + { + return new SimpleChoiceList(array( + 'Group 1' => array(0 => 'A', 1 => 'B'), + 'Group 2' => array(2 => 'C', 3 => 'D'), + ), array(1, 2)); + } + + protected function getChoices() + { + return array(0 => 0, 1 => 1, 2 => 2, 3 => 3); + } + + protected function getLabels() + { + return array(0 => 'A', 1 => 'B', 2 => 'C', 3 => 'D'); + } + + protected function getValues() + { + return array(0 => '0', 1 => '1', 2 => '2', 3 => '3'); + } + + protected function getIndices() + { + return array(0, 1, 2, 3); + } +} diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/BooleanToStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/BooleanToStringTransformerTest.php index 41f8f956d7cb1..4f6238aee0d43 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/BooleanToStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/BooleanToStringTransformerTest.php @@ -17,6 +17,9 @@ class BooleanToStringTransformerTest extends \PHPUnit_Framework_TestCase { const TRUE_VALUE = '1'; + /** + * @var BooleanToStringTransformer + */ protected $transformer; protected function setUp() @@ -33,20 +36,29 @@ public function testTransform() { $this->assertEquals(self::TRUE_VALUE, $this->transformer->transform(true)); $this->assertNull($this->transformer->transform(false)); - $this->assertNull($this->transformer->transform(null)); } - public function testTransformExpectsBoolean() + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testTransformFailsIfNull() { - $this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException'); + $this->transformer->transform(null); + } + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testTransformFailsIfString() + { $this->transformer->transform('1'); } - public function testReverseTransformExpectsString() + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformFailsIfInteger() { - $this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException'); - $this->transformer->reverseTransform(1); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php index c782adab04c86..9437bd7eea655 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php @@ -15,6 +15,15 @@ class CheckboxTypeTest extends \Symfony\Component\Form\Test\TypeTestCase { + public function testDataIsFalseByDefault() + { + $form = $this->factory->create('checkbox'); + + $this->assertFalse($form->getData()); + $this->assertFalse($form->getNormData()); + $this->assertNull($form->getViewData()); + } + public function testPassValueToView() { $form = $this->factory->create('checkbox', null, array('value' => 'foobar')); @@ -105,58 +114,60 @@ public function testSubmitWithEmptyValueUnchecked() $this->assertNull($form->getViewData()); } - public function testBindWithEmptyValueAndFalseUnchecked() + public function testSubmitWithEmptyValueAndFalseUnchecked() { $form = $this->factory->create('checkbox', null, array( 'value' => '', )); - $form->bind(false); + $form->submit(false); $this->assertFalse($form->getData()); $this->assertNull($form->getViewData()); } - public function testBindWithEmptyValueAndTrueChecked() + public function testSubmitWithEmptyValueAndTrueChecked() { $form = $this->factory->create('checkbox', null, array( 'value' => '', )); - $form->bind(true); + $form->submit(true); $this->assertTrue($form->getData()); $this->assertSame('', $form->getViewData()); } /** - * @dataProvider provideTransformedData + * @dataProvider provideCustomModelTransformerData */ - public function testTransformedData($data, $expected) + public function testCustomModelTransformer($data, $checked) { // present a binary status field as a checkbox $transformer = new CallbackTransformer( function ($value) { - return 'expedited' == $value; + return 'checked' == $value; }, function ($value) { - return $value ? 'expedited' : 'standard'; + return $value ? 'checked' : 'unchecked'; } ); - $form = $this->builder - ->create('expedited_shipping', 'checkbox') + $form = $this->factory->createBuilder('checkbox') ->addModelTransformer($transformer) ->getForm(); + $form->setData($data); $view = $form->createView(); - $this->assertEquals($expected, $view->vars['checked']); + $this->assertSame($data, $form->getData()); + $this->assertSame($checked, $form->getNormData()); + $this->assertEquals($checked, $view->vars['checked']); } - public function provideTransformedData() + public function provideCustomModelTransformerData() { return array( - array('expedited', true), - array('standard', false), + array('checked', true), + array('unchecked', false), ); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php index 219e8181c0c9f..ee40e74268d9a 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php @@ -231,6 +231,21 @@ public function testSubmitSingleNonExpanded() $this->assertEquals('b', $form->getViewData()); } + public function testSubmitSingleNonExpandedInvalidChoice() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => false, + 'choices' => $this->choices, + )); + + $form->submit('foobar'); + + $this->assertNull($form->getData()); + $this->assertEquals('foobar', $form->getViewData()); + $this->assertFalse($form->isSynchronized()); + } + public function testSubmitSingleNonExpandedObjectChoices() { $form = $this->factory->create('choice', null, array( @@ -268,6 +283,36 @@ public function testSubmitMultipleNonExpanded() $this->assertEquals(array('a', 'b'), $form->getViewData()); } + public function testSubmitMultipleNonExpandedInvalidScalarChoice() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => true, + 'expanded' => false, + 'choices' => $this->choices, + )); + + $form->submit('foobar'); + + $this->assertNull($form->getData()); + $this->assertEquals('foobar', $form->getViewData()); + $this->assertFalse($form->isSynchronized()); + } + + public function testSubmitMultipleNonExpandedInvalidArrayChoice() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => true, + 'expanded' => false, + 'choices' => $this->choices, + )); + + $form->submit(array('a', 'foobar')); + + $this->assertNull($form->getData()); + $this->assertEquals(array('a', 'foobar'), $form->getViewData()); + $this->assertFalse($form->isSynchronized()); + } + public function testSubmitMultipleNonExpandedObjectChoices() { $form = $this->factory->create('choice', null, array( @@ -309,6 +354,8 @@ public function testSubmitSingleExpandedRequired() 3 => false, 4 => false, ), $form->getViewData()); + $this->assertEmpty($form->getExtraData()); + $this->assertTrue($form->isSynchronized()); $this->assertFalse($form[0]->getData()); $this->assertTrue($form[1]->getData()); @@ -322,6 +369,34 @@ public function testSubmitSingleExpandedRequired() $this->assertNull($form[4]->getViewData()); } + public function testSubmitSingleExpandedRequiredInvalidChoice() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'required' => true, + 'choices' => $this->choices, + )); + + $form->submit('foobar'); + + $this->assertSame(null, $form->getData()); + $this->assertSame('foobar', $form->getViewData()); + $this->assertEmpty($form->getExtraData()); + $this->assertFalse($form->isSynchronized()); + + $this->assertFalse($form[0]->getData()); + $this->assertFalse($form[1]->getData()); + $this->assertFalse($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertNull($form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); + } + public function testSubmitSingleExpandedNonRequired() { $form = $this->factory->create('choice', null, array( @@ -342,6 +417,8 @@ public function testSubmitSingleExpandedNonRequired() 4 => false, 'placeholder' => false, ), $form->getViewData()); + $this->assertEmpty($form->getExtraData()); + $this->assertTrue($form->isSynchronized()); $this->assertFalse($form['placeholder']->getData()); $this->assertFalse($form[0]->getData()); @@ -357,7 +434,35 @@ public function testSubmitSingleExpandedNonRequired() $this->assertNull($form[4]->getViewData()); } - public function testSubmitSingleExpandedRequiredNothingChecked() + public function testSubmitSingleExpandedNonRequiredInvalidChoice() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'required' => false, + 'choices' => $this->choices, + )); + + $form->submit('foobar'); + + $this->assertSame(null, $form->getData()); + $this->assertSame('foobar', $form->getViewData()); + $this->assertEmpty($form->getExtraData()); + $this->assertFalse($form->isSynchronized()); + + $this->assertFalse($form[0]->getData()); + $this->assertFalse($form[1]->getData()); + $this->assertFalse($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertNull($form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); + } + + public function testSubmitSingleExpandedRequiredNull() { $form = $this->factory->create('choice', null, array( 'multiple' => false, @@ -376,6 +481,76 @@ public function testSubmitSingleExpandedRequiredNothingChecked() 3 => false, 4 => false, ), $form->getViewData()); + $this->assertEmpty($form->getExtraData()); + $this->assertTrue($form->isSynchronized()); + + $this->assertFalse($form[0]->getData()); + $this->assertFalse($form[1]->getData()); + $this->assertFalse($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertNull($form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); + } + + public function testSubmitSingleExpandedRequiredEmpty() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'required' => true, + 'choices' => $this->choices, + )); + + $form->submit(''); + + $this->assertNull($form->getData()); + $this->assertSame(array( + 0 => false, + 1 => false, + 2 => false, + 3 => false, + 4 => false, + ), $form->getViewData()); + $this->assertEmpty($form->getExtraData()); + $this->assertTrue($form->isSynchronized()); + + $this->assertFalse($form[0]->getData()); + $this->assertFalse($form[1]->getData()); + $this->assertFalse($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertNull($form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); + } + + public function testSubmitSingleExpandedRequiredFalse() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'required' => true, + 'choices' => $this->choices, + )); + + $form->submit(false); + + $this->assertNull($form->getData()); + $this->assertSame(array( + 0 => false, + 1 => false, + 2 => false, + 3 => false, + 4 => false, + ), $form->getViewData()); + $this->assertEmpty($form->getExtraData()); + $this->assertTrue($form->isSynchronized()); $this->assertFalse($form[0]->getData()); $this->assertFalse($form[1]->getData()); @@ -389,7 +564,7 @@ public function testSubmitSingleExpandedRequiredNothingChecked() $this->assertNull($form[4]->getViewData()); } - public function testSubmitSingleExpandedNonRequiredNothingChecked() + public function testSubmitSingleExpandedNonRequiredNull() { $form = $this->factory->create('choice', null, array( 'multiple' => false, @@ -409,6 +584,8 @@ public function testSubmitSingleExpandedNonRequiredNothingChecked() 4 => false, 'placeholder' => true, ), $form->getViewData()); + $this->assertEmpty($form->getExtraData()); + $this->assertTrue($form->isSynchronized()); $this->assertTrue($form['placeholder']->getData()); $this->assertFalse($form[0]->getData()); @@ -424,22 +601,44 @@ public function testSubmitSingleExpandedNonRequiredNothingChecked() $this->assertNull($form[4]->getViewData()); } - public function testSubmitFalseToSingleExpandedRequiredDoesNotProduceExtraChildrenError() + public function testSubmitSingleExpandedNonRequiredEmpty() { $form = $this->factory->create('choice', null, array( 'multiple' => false, 'expanded' => true, - 'required' => true, + 'required' => false, 'choices' => $this->choices, )); - $form->submit(false); + $form->submit(''); - $this->assertEmpty($form->getExtraData()); $this->assertNull($form->getData()); + $this->assertSame(array( + 0 => false, + 1 => false, + 2 => false, + 3 => false, + 4 => false, + 'placeholder' => true, + ), $form->getViewData()); + $this->assertEmpty($form->getExtraData()); + $this->assertTrue($form->isSynchronized()); + + $this->assertTrue($form['placeholder']->getData()); + $this->assertFalse($form[0]->getData()); + $this->assertFalse($form[1]->getData()); + $this->assertFalse($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertSame('', $form['placeholder']->getViewData()); + $this->assertNull($form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); } - public function testSubmitFalseToSingleExpandedNonRequiredDoesNotProduceExtraChildrenError() + public function testSubmitSingleExpandedNonRequiredFalse() { $form = $this->factory->create('choice', null, array( 'multiple' => false, @@ -450,8 +649,30 @@ public function testSubmitFalseToSingleExpandedNonRequiredDoesNotProduceExtraChi $form->submit(false); - $this->assertEmpty($form->getExtraData()); $this->assertNull($form->getData()); + $this->assertSame(array( + 0 => false, + 1 => false, + 2 => false, + 3 => false, + 4 => false, + 'placeholder' => true, + ), $form->getViewData()); + $this->assertEmpty($form->getExtraData()); + $this->assertTrue($form->isSynchronized()); + + $this->assertTrue($form['placeholder']->getData()); + $this->assertFalse($form[0]->getData()); + $this->assertFalse($form[1]->getData()); + $this->assertFalse($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertSame('', $form['placeholder']->getViewData()); + $this->assertNull($form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); } public function testSubmitSingleExpandedWithEmptyChild() @@ -539,6 +760,16 @@ public function testSubmitMultipleExpanded() $form->submit(array('a', 'c')); $this->assertSame(array('a', 'c'), $form->getData()); + $this->assertSame(array( + 0 => true, + 1 => false, + 2 => true, + 3 => false, + 4 => false, + ), $form->getViewData()); + $this->assertEmpty($form->getExtraData()); + $this->assertTrue($form->isSynchronized()); + $this->assertTrue($form[0]->getData()); $this->assertFalse($form[1]->getData()); $this->assertTrue($form[2]->getData()); @@ -551,6 +782,60 @@ public function testSubmitMultipleExpanded() $this->assertNull($form[4]->getViewData()); } + public function testSubmitMultipleExpandedInvalidScalarChoice() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => true, + 'expanded' => true, + 'choices' => $this->choices, + )); + + $form->submit('foobar'); + + $this->assertNull($form->getData()); + $this->assertSame('foobar', $form->getViewData()); + $this->assertEmpty($form->getExtraData()); + $this->assertFalse($form->isSynchronized()); + + $this->assertFalse($form[0]->getData()); + $this->assertFalse($form[1]->getData()); + $this->assertFalse($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertNull($form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); + } + + public function testSubmitMultipleExpandedInvalidArrayChoice() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => true, + 'expanded' => true, + 'choices' => $this->choices, + )); + + $form->submit(array('a', 'foobar')); + + $this->assertNull($form->getData()); + $this->assertSame(array('a', 'foobar'), $form->getViewData()); + $this->assertEmpty($form->getExtraData()); + $this->assertFalse($form->isSynchronized()); + + $this->assertFalse($form[0]->getData()); + $this->assertFalse($form[1]->getData()); + $this->assertFalse($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertNull($form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); + } + public function testSubmitMultipleExpandedEmpty() { $form = $this->factory->create('choice', null, array(