Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[PropertyAccess] Extracted PropertyAccess component out of Form

  • Loading branch information...
commit 831306bdfa0a1cd418c726af286c851df50e67bb 1 parent 2d5bede
@webmozart webmozart authored
Showing with 222 additions and 2,645 deletions.
  1. +9 −0 CHANGELOG.md
  2. +0 −16 Exception/InvalidPropertyException.php
  3. +0 −16 Exception/InvalidPropertyPathException.php
  4. +0 −16 Exception/PropertyAccessDeniedException.php
  5. +35 −26 Extension/Core/ChoiceList/ObjectChoiceList.php
  6. +2 −1  Extension/Core/CoreExtension.php
  7. +25 −3 Extension/Core/DataMapper/PropertyPathMapper.php
  8. +13 −1 Extension/Core/Type/FormType.php
  9. +1 −1  Extension/Validator/ViolationMapper/RelativePath.php
  10. +4 −4 Extension/Validator/ViolationMapper/ViolationMapper.php
  11. +2 −2 Extension/Validator/ViolationMapper/ViolationPath.php
  12. +1 −1  Extension/Validator/ViolationMapper/ViolationPathIterator.php
  13. +1 −1  Form.php
  14. +2 −2 FormConfigBuilder.php
  15. +12 −12 FormConfigBuilderInterface.php
  16. +1 −1  FormConfigInterface.php
  17. +1 −1  FormInterface.php
  18. +3 −0  Tests/Extension/Core/ChoiceList/ObjectChoiceListTest.php
  19. +37 −29 Tests/Extension/Core/DataMapper/PropertyPathMapperTest.php
  20. +0 −2  Tests/Extension/Core/Type/ChoiceTypeTest.php
  21. +1 −1  Tests/Extension/Core/Type/FormTypeTest.php
  22. +1 −1  Tests/Extension/Validator/EventListener/ValidationListenerTest.php
  23. +1 −1  Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php
  24. +0 −27 Tests/Fixtures/Magician.php
  25. +1 −1  Tests/SimpleFormTest.php
  26. +0 −135 Tests/Util/FormUtilTest.php
  27. +0 −20 Tests/Util/PropertyPathArrayObjectTest.php
  28. +0 −20 Tests/Util/PropertyPathArrayTest.php
  29. +0 −251 Tests/Util/PropertyPathBuilderTest.php
  30. +0 −341 Tests/Util/PropertyPathCollectionTest.php
  31. +0 −22 Tests/Util/PropertyPathCustomArrayObjectTest.php
  32. +0 −557 Tests/Util/PropertyPathTest.php
  33. +7 −159 Util/FormUtil.php
  34. +18 −590 Util/PropertyPath.php
  35. +13 −271 Util/PropertyPathBuilder.php
  36. +9 −66 Util/PropertyPathInterface.php
  37. +11 −30 Util/PropertyPathIterator.php
  38. +9 −16 Util/PropertyPathIteratorInterface.php
  39. +2 −1  composer.json
View
9 CHANGELOG.md
@@ -13,6 +13,15 @@ CHANGELOG
* [BC BREAK] FormException is now an interface
* protected FormBuilder methods from being called when it is turned into a FormConfigInterface with getFormConfig()
* [BC BREAK] inserted argument `$message` in the constructor of `FormError`
+ * the PropertyPath class and related classes were moved to a dedicated
+ PropertyAccess component. During the move, InvalidPropertyException was
+ renamed to NoSuchPropertyException. FormUtil was split: FormUtil::singularify()
+ can now be found in Symfony\Component\PropertyAccess\StringUtil. The methods
+ getValue() and setValue() from PropertyPath were extracted into a new class
+ PropertyAccessor.
+ * added an optional PropertyAccessorInterface parameter to FormType,
+ ObjectChoiceList and PropertyPathMapper
+ * [BC BREAK] PropertyPathMapper and FormType now have a constructor
2.1.0
-----
View
16 Exception/InvalidPropertyException.php
@@ -1,16 +0,0 @@
-<?php
-
-/*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Form\Exception;
-
-class InvalidPropertyException extends Exception
-{
-}
View
16 Exception/InvalidPropertyPathException.php
@@ -1,16 +0,0 @@
-<?php
-
-/*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Form\Exception;
-
-class InvalidPropertyPathException extends Exception
-{
-}
View
16 Exception/PropertyAccessDeniedException.php
@@ -1,16 +0,0 @@
-<?php
-
-/*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Form\Exception;
-
-class PropertyAccessDeniedException extends Exception
-{
-}
View
61 Extension/Core/ChoiceList/ObjectChoiceList.php
@@ -11,9 +11,11 @@
namespace Symfony\Component\Form\Extension\Core\ChoiceList;
-use Symfony\Component\Form\Util\PropertyPath;
use Symfony\Component\Form\Exception\StringCastException;
-use Symfony\Component\Form\Exception\InvalidPropertyException;
+use Symfony\Component\PropertyAccess\PropertyPath;
+use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
+use Symfony\Component\PropertyAccess\PropertyAccess;
+use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
/**
* A choice list for object choices.
@@ -33,6 +35,11 @@
class ObjectChoiceList extends ChoiceList
{
/**
+ * @var PropertyAccessorInterface
+ */
+ private $propertyAccessor;
+
+ /**
* The property path used to obtain the choice label.
*
* @var PropertyPath
@@ -56,28 +63,30 @@ class ObjectChoiceList extends ChoiceList
/**
* Creates a new object choice list.
*
- * @param array|\Traversable $choices The array of choices. Choices may also be given
- * as hierarchy of unlimited depth by creating nested
- * arrays. The title of the sub-hierarchy can be
- * stored in the array key pointing to the nested
- * array. The topmost level of the hierarchy may also
- * be a \Traversable.
- * @param string $labelPath A property path pointing to the property used
- * for the choice labels. The value is obtained
- * by calling the getter on the object. If the
- * path is NULL, the object's __toString() method
- * is used instead.
- * @param array $preferredChoices A flat array of choices that should be
- * presented to the user with priority.
- * @param string $groupPath A property path pointing to the property used
- * to group the choices. Only allowed if
- * the choices are given as flat array.
- * @param string $valuePath A property path pointing to the property used
- * for the choice values. If not given, integers
- * are generated instead.
+ * @param array|\Traversable $choices The array of choices. Choices may also be given
+ * as hierarchy of unlimited depth by creating nested
+ * arrays. The title of the sub-hierarchy can be
+ * stored in the array key pointing to the nested
+ * array. The topmost level of the hierarchy may also
+ * be a \Traversable.
+ * @param string $labelPath A property path pointing to the property used
+ * for the choice labels. The value is obtained
+ * by calling the getter on the object. If the
+ * path is NULL, the object's __toString() method
+ * is used instead.
+ * @param array $preferredChoices A flat array of choices that should be
+ * presented to the user with priority.
+ * @param string $groupPath A property path pointing to the property used
+ * to group the choices. Only allowed if
+ * the choices are given as flat array.
+ * @param string $valuePath A property path pointing to the property used
+ * for the choice values. If not given, integers
+ * are generated instead.
+ * @param PropertyAccessorInterface $propertyAccessor The reflection graph for reading property paths.
*/
- public function __construct($choices, $labelPath = null, array $preferredChoices = array(), $groupPath = null, $valuePath = null)
+ public function __construct($choices, $labelPath = null, array $preferredChoices = array(), $groupPath = null, $valuePath = null, PropertyAccessorInterface $propertyAccessor = null)
{
+ $this->propertyAccessor = $propertyAccessor ?: PropertyAccess::getPropertyAccessor();
$this->labelPath = null !== $labelPath ? new PropertyPath($labelPath) : null;
$this->groupPath = null !== $groupPath ? new PropertyPath($groupPath) : null;
$this->valuePath = null !== $valuePath ? new PropertyPath($valuePath) : null;
@@ -108,8 +117,8 @@ protected function initialize($choices, array $labels, array $preferredChoices)
}
try {
- $group = $this->groupPath->getValue($choice);
- } catch (InvalidPropertyException $e) {
+ $group = $this->propertyAccessor->getValue($choice, $this->groupPath);
+ } catch (NoSuchPropertyException $e) {
// Don't group items whose group property does not exist
// see https://github.com/symfony/symfony/commit/d9b7abb7c7a0f28e0ce970afc5e305dce5dccddf
$group = null;
@@ -150,7 +159,7 @@ protected function initialize($choices, array $labels, array $preferredChoices)
protected function createValue($choice)
{
if ($this->valuePath) {
- return (string) $this->valuePath->getValue($choice);
+ return (string) $this->propertyAccessor->getValue($choice, $this->valuePath);
}
return parent::createValue($choice);
@@ -163,7 +172,7 @@ private function extractLabels($choices, array &$labels)
$labels[$i] = array();
$this->extractLabels($choice, $labels[$i]);
} elseif ($this->labelPath) {
- $labels[$i] = $this->labelPath->getValue($choice);
+ $labels[$i] = $this->propertyAccessor->getValue($choice, $this->labelPath);
} elseif (method_exists($choice, '__toString')) {
$labels[$i] = (string) $choice;
} else {
View
3  Extension/Core/CoreExtension.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\Form\Extension\Core;
use Symfony\Component\Form\AbstractExtension;
+use Symfony\Component\PropertyAccess\PropertyAccess;
/**
* Represents the main form extension, which loads the core functionality.
@@ -24,7 +25,7 @@ protected function loadTypes()
{
return array(
new Type\FieldType(),
- new Type\FormType(),
+ new Type\FormType(PropertyAccess::getPropertyAccessor()),
new Type\BirthdayType(),
new Type\CheckboxType(),
new Type\ChoiceType(),
View
28 Extension/Core/DataMapper/PropertyPathMapper.php
@@ -14,10 +14,32 @@
use Symfony\Component\Form\DataMapperInterface;
use Symfony\Component\Form\Util\VirtualFormAwareIterator;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
+use Symfony\Component\PropertyAccess\PropertyAccess;
+use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
+/**
+ * A data mapper using property paths to read/write data.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
class PropertyPathMapper implements DataMapperInterface
{
/**
+ * @var PropertyAccessorInterface
+ */
+ private $propertyAccessor;
+
+ /**
+ * Creates a new property path mapper.
+ *
+ * @param PropertyAccessorInterface $propertyAccessor
+ */
+ public function __construct(PropertyAccessorInterface $propertyAccessor = null)
+ {
+ $this->propertyAccessor = $propertyAccessor ?: PropertyAccess::getPropertyAccessor();
+ }
+
+ /**
* {@inheritdoc}
*/
public function mapDataToForms($data, array $forms)
@@ -39,7 +61,7 @@ public function mapDataToForms($data, array $forms)
$config = $form->getConfig();
if (null !== $propertyPath && $config->getMapped()) {
- $form->setData($propertyPath->getValue($data));
+ $form->setData($this->propertyAccessor->getValue($data, $propertyPath));
}
}
}
@@ -70,8 +92,8 @@ public function mapFormsToData(array $forms, &$data)
if (null !== $propertyPath && $config->getMapped() && $form->isSynchronized() && !$form->isDisabled()) {
// If the data is identical to the value in $data, we are
// dealing with a reference
- if (!is_object($data) || !$config->getByReference() || $form->getData() !== $propertyPath->getValue($data)) {
- $propertyPath->setValue($data, $form->getData());
+ if (!is_object($data) || !$config->getByReference() || $form->getData() !== $this->propertyAccessor->getValue($data, $propertyPath)) {
+ $this->propertyAccessor->setValue($data, $propertyPath, $form->getData());
}
}
}
View
14 Extension/Core/Type/FormType.php
@@ -20,10 +20,22 @@
use Symfony\Component\Form\Exception\Exception;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
+use Symfony\Component\PropertyAccess\PropertyAccess;
+use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
class FormType extends AbstractType
{
/**
+ * @var PropertyAccessorInterface
+ */
+ private $propertyAccessor;
+
+ public function __construct(PropertyAccessorInterface $propertyAccessor = null)
+ {
+ $this->propertyAccessor = $propertyAccessor ?: PropertyAccess::getPropertyAccessor();
+ }
+
+ /**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
@@ -41,7 +53,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
->setCompound($options['compound'])
->setData(isset($options['data']) ? $options['data'] : null)
->setDataLocked(isset($options['data']))
- ->setDataMapper($options['compound'] ? new PropertyPathMapper() : null)
+ ->setDataMapper($options['compound'] ? new PropertyPathMapper($this->propertyAccessor) : null)
;
if ($options['trim']) {
View
2  Extension/Validator/ViolationMapper/RelativePath.php
@@ -12,7 +12,7 @@
namespace Symfony\Component\Form\Extension\Validator\ViolationMapper;
use Symfony\Component\Form\FormInterface;
-use Symfony\Component\Form\Util\PropertyPath;
+use Symfony\Component\PropertyAccess\PropertyPath;
/**
* @author Bernhard Schussek <bschussek@gmail.com>
View
8 Extension/Validator/ViolationMapper/ViolationMapper.php
@@ -13,9 +13,9 @@
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\Util\VirtualFormAwareIterator;
-use Symfony\Component\Form\Util\PropertyPathIterator;
-use Symfony\Component\Form\Util\PropertyPathBuilder;
-use Symfony\Component\Form\Util\PropertyPathIteratorInterface;
+use Symfony\Component\PropertyAccess\PropertyPathIterator;
+use Symfony\Component\PropertyAccess\PropertyPathBuilder;
+use Symfony\Component\PropertyAccess\PropertyPathIteratorInterface;
use Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationPathIterator;
use Symfony\Component\Form\FormError;
use Symfony\Component\Validator\ConstraintViolation;
@@ -265,7 +265,7 @@ private function reconstructPath(ViolationPath $violationPath, FormInterface $or
$propertyPathBuilder->remove(0, $i + 1);
$i = 0;
} else {
- /* @var \Symfony\Component\Form\Util\PropertyPathInterface $propertyPath */
+ /* @var \Symfony\Component\PropertyAccess\PropertyPathInterface $propertyPath */
$propertyPath = $scope->getPropertyPath();
if (null === $propertyPath) {
View
4 Extension/Validator/ViolationMapper/ViolationPath.php
@@ -11,8 +11,8 @@
namespace Symfony\Component\Form\Extension\Validator\ViolationMapper;
-use Symfony\Component\Form\Util\PropertyPath;
-use Symfony\Component\Form\Util\PropertyPathInterface;
+use Symfony\Component\PropertyAccess\PropertyPath;
+use Symfony\Component\PropertyAccess\PropertyPathInterface;
/**
* @author Bernhard Schussek <bschussek@gmail.com>
View
2  Extension/Validator/ViolationMapper/ViolationPathIterator.php
@@ -11,7 +11,7 @@
namespace Symfony\Component\Form\Extension\Validator\ViolationMapper;
-use Symfony\Component\Form\Util\PropertyPathIterator;
+use Symfony\Component\PropertyAccess\PropertyPathIterator;
/**
* @author Bernhard Schussek <bschussek@gmail.com>
View
2  Form.php
@@ -16,8 +16,8 @@
use Symfony\Component\Form\Exception\AlreadyBoundException;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\Form\Util\FormUtil;
-use Symfony\Component\Form\Util\PropertyPath;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\PropertyAccess\PropertyPath;
/**
* Form represents a form.
View
4 FormConfigBuilder.php
@@ -14,8 +14,8 @@
use Symfony\Component\Form\Exception\BadMethodCallException;
use Symfony\Component\Form\Exception\Exception;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
-use Symfony\Component\Form\Util\PropertyPath;
-use Symfony\Component\Form\Util\PropertyPathInterface;
+use Symfony\Component\PropertyAccess\PropertyPath;
+use Symfony\Component\PropertyAccess\PropertyPathInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\ImmutableEventDispatcher;
View
24 FormConfigBuilderInterface.php
@@ -117,7 +117,7 @@ public function setAttributes(array $attributes);
/**
* Sets the data mapper used by the form.
*
- * @param DataMapperInterface $dataMapper
+ * @param DataMapperInterface $dataMapper
*
* @return self The configuration object.
*/
@@ -126,7 +126,7 @@ public function setDataMapper(DataMapperInterface $dataMapper = null);
/**
* Set whether the form is disabled.
*
- * @param Boolean $disabled Whether the form is disabled
+ * @param Boolean $disabled Whether the form is disabled
*
* @return self The configuration object.
*/
@@ -135,7 +135,7 @@ public function setDisabled($disabled);
/**
* Sets the data used for the client data when no value is bound.
*
- * @param mixed $emptyData The empty data.
+ * @param mixed $emptyData The empty data.
*
* @return self The configuration object.
*/
@@ -144,7 +144,7 @@ public function setEmptyData($emptyData);
/**
* Sets whether errors bubble up to the parent.
*
- * @param Boolean $errorBubbling
+ * @param Boolean $errorBubbling
*
* @return self The configuration object.
*/
@@ -162,9 +162,9 @@ public function setRequired($required);
/**
* Sets the property path that the form should be mapped to.
*
- * @param null|string|PropertyPathInterface $propertyPath The property path or null if the path
- * should be set automatically based on
- * the form's name.
+ * @param null|string|\Symfony\Component\PropertyAccess\PropertyPathInterface $propertyPath
+ * The property path or null if the path should be set
+ * automatically based on the form's name.
*
* @return self The configuration object.
*/
@@ -174,7 +174,7 @@ public function setPropertyPath($propertyPath);
* Sets whether the form should be mapped to an element of its
* parent's data.
*
- * @param Boolean $mapped Whether the form should be mapped.
+ * @param Boolean $mapped Whether the form should be mapped.
*
* @return self The configuration object.
*/
@@ -183,7 +183,7 @@ public function setMapped($mapped);
/**
* Sets whether the form's data should be modified by reference.
*
- * @param Boolean $byReference Whether the data should be
+ * @param Boolean $byReference Whether the data should be
* modified by reference.
*
* @return self The configuration object.
@@ -193,7 +193,7 @@ public function setByReference($byReference);
/**
* Sets whether the form should be virtual.
*
- * @param Boolean $virtual Whether the form should be virtual.
+ * @param Boolean $virtual Whether the form should be virtual.
*
* @return self The configuration object.
*/
@@ -202,7 +202,7 @@ public function setVirtual($virtual);
/**
* Sets whether the form should be compound.
*
- * @param Boolean $compound Whether the form should be compound.
+ * @param Boolean $compound Whether the form should be compound.
*
* @return self The configuration object.
*
@@ -235,7 +235,7 @@ public function setData($data);
* this configuration. The data can only be modified then by
* binding the form.
*
- * @param Boolean $locked Whether to lock the default data.
+ * @param Boolean $locked Whether to lock the default data.
*
* @return self The configuration object.
*/
View
2  FormConfigInterface.php
@@ -35,7 +35,7 @@ public function getName();
/**
* Returns the property path that the form should be mapped to.
*
- * @return null|Util\PropertyPathInterface The property path.
+ * @return null|\Symfony\Component\PropertyAccess\PropertyPathInterface The property path.
*/
public function getPropertyPath();
View
2  FormInterface.php
@@ -166,7 +166,7 @@ public function getName();
/**
* Returns the property path that the form is mapped to.
*
- * @return Util\PropertyPathInterface The property path.
+ * @return \Symfony\Component\PropertyAccess\PropertyPathInterface The property path.
*/
public function getPropertyPath();
View
3  Tests/Extension/Core/ChoiceList/ObjectChoiceListTest.php
@@ -39,6 +39,9 @@ class ObjectChoiceListTest extends \PHPUnit_Framework_TestCase
private $obj4;
+ /**
+ * @var ObjectChoiceList
+ */
private $list;
protected function setUp()
View
66 Tests/Extension/Core/DataMapper/PropertyPathMapperTest.php
@@ -11,10 +11,8 @@
namespace Symfony\Component\Form\Tests\Extension\Core\DataMapper;
-use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormConfigBuilder;
use Symfony\Component\Form\FormConfigInterface;
-use Symfony\Component\Form\Util\PropertyPath;
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
@@ -29,14 +27,24 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
*/
private $dispatcher;
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject
+ */
+ private $propertyAccessor;
+
protected function setUp()
{
if (!class_exists('Symfony\Component\EventDispatcher\Event')) {
$this->markTestSkipped('The "EventDispatcher" component is not available');
}
+ if (!class_exists('Symfony\Component\PropertyAccess\PropertyAccess')) {
+ $this->markTestSkipped('The "PropertyAccess" component is not available');
+ }
+
$this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
- $this->mapper = new PropertyPathMapper();
+ $this->propertyAccessor = $this->getMock('Symfony\Component\PropertyAccess\PropertyAccessorInterface');
+ $this->mapper = new PropertyPathMapper($this->propertyAccessor);
}
/**
@@ -45,7 +53,7 @@ protected function setUp()
*/
private function getPropertyPath($path)
{
- return $this->getMockBuilder('Symfony\Component\Form\Util\PropertyPath')
+ return $this->getMockBuilder('Symfony\Component\PropertyAccess\PropertyPath')
->setConstructorArgs(array($path))
->setMethods(array('getValue', 'setValue'))
->getMock();
@@ -84,9 +92,9 @@ public function testMapDataToFormsPassesObjectRefIfByReference()
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
- $propertyPath->expects($this->once())
+ $this->propertyAccessor->expects($this->once())
->method('getValue')
- ->with($car)
+ ->with($car, $propertyPath)
->will($this->returnValue($engine));
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
@@ -107,9 +115,9 @@ public function testMapDataToFormsPassesObjectCloneIfNotByReference()
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
- $propertyPath->expects($this->once())
+ $this->propertyAccessor->expects($this->once())
->method('getValue')
- ->with($car)
+ ->with($car, $propertyPath)
->will($this->returnValue($engine));
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
@@ -143,7 +151,7 @@ public function testMapDataToFormsIgnoresUnmapped()
$car = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
- $propertyPath->expects($this->never())
+ $this->propertyAccessor->expects($this->never())
->method('getValue');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
@@ -161,7 +169,7 @@ public function testMapDataToFormsIgnoresEmptyData()
{
$propertyPath = $this->getPropertyPath('engine');
- $propertyPath->expects($this->never())
+ $this->propertyAccessor->expects($this->never())
->method('getValue');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
@@ -180,9 +188,9 @@ public function testMapDataToFormsSkipsVirtualForms()
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
- $propertyPath->expects($this->once())
+ $this->propertyAccessor->expects($this->once())
->method('getValue')
- ->with($car)
+ ->with($car, $propertyPath)
->will($this->returnValue($engine));
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
@@ -211,9 +219,9 @@ public function testMapFormsToDataWritesBackIfNotByReference()
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
- $propertyPath->expects($this->once())
+ $this->propertyAccessor->expects($this->once())
->method('setValue')
- ->with($car, $engine);
+ ->with($car, $propertyPath, $engine);
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config->setByReference(false);
@@ -230,9 +238,9 @@ public function testMapFormsToDataWritesBackIfByReferenceButNoReference()
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
- $propertyPath->expects($this->once())
+ $this->propertyAccessor->expects($this->once())
->method('setValue')
- ->with($car, $engine);
+ ->with($car, $propertyPath, $engine);
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config->setByReference(true);
@@ -250,12 +258,12 @@ public function testMapFormsToDataWritesBackIfByReferenceAndReference()
$propertyPath = $this->getPropertyPath('engine');
// $car already contains the reference of $engine
- $propertyPath->expects($this->once())
+ $this->propertyAccessor->expects($this->once())
->method('getValue')
- ->with($car)
+ ->with($car, $propertyPath)
->will($this->returnValue($engine));
- $propertyPath->expects($this->never())
+ $this->propertyAccessor->expects($this->never())
->method('setValue');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
@@ -273,7 +281,7 @@ public function testMapFormsToDataIgnoresUnmapped()
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
- $propertyPath->expects($this->never())
+ $this->propertyAccessor->expects($this->never())
->method('setValue');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
@@ -291,7 +299,7 @@ public function testMapFormsToDataIgnoresEmptyData()
$car = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
- $propertyPath->expects($this->never())
+ $this->propertyAccessor->expects($this->never())
->method('setValue');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
@@ -309,7 +317,7 @@ public function testMapFormsToDataIgnoresUnsynchronized()
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
- $propertyPath->expects($this->never())
+ $this->propertyAccessor->expects($this->never())
->method('setValue');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
@@ -327,7 +335,7 @@ public function testMapFormsToDataIgnoresDisabled()
$engine = new \stdClass();
$propertyPath = $this->getPropertyPath('engine');
- $propertyPath->expects($this->never())
+ $this->propertyAccessor->expects($this->never())
->method('setValue');
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
@@ -347,14 +355,14 @@ public function testMapFormsToDataSkipsVirtualForms()
$parentPath = $this->getPropertyPath('name');
$childPath = $this->getPropertyPath('engine');
- $parentPath->expects($this->never())
- ->method('getValue');
- $parentPath->expects($this->never())
- ->method('setValue');
+ // getValue() and setValue() must never be invoked for $parentPath
- $childPath->expects($this->once())
+ $this->propertyAccessor->expects($this->once())
+ ->method('getValue')
+ ->with($car, $childPath);
+ $this->propertyAccessor->expects($this->once())
->method('setValue')
- ->with($car, $engine);
+ ->with($car, $childPath, $engine);
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
$config->setPropertyPath($parentPath);
View
2  Tests/Extension/Core/Type/ChoiceTypeTest.php
@@ -11,8 +11,6 @@
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
-use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList;
-
use Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList;
use Symfony\Component\Form\Extension\Core\View\ChoiceView;
View
2  Tests/Extension/Core/Type/FormTypeTest.php
@@ -11,7 +11,7 @@
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
-use Symfony\Component\Form\Util\PropertyPath;
+use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Tests\Fixtures\Author;
View
2  Tests/Extension/Validator/EventListener/ValidationListenerTest.php
@@ -14,7 +14,7 @@
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormError;
-use Symfony\Component\Form\Util\PropertyPath;
+use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\Form\Extension\Validator\Constraints\Form;
use Symfony\Component\Form\Extension\Validator\EventListener\ValidationListener;
use Symfony\Component\Validator\ConstraintViolation;
View
2  Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php
@@ -17,7 +17,7 @@
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormConfigBuilder;
use Symfony\Component\Form\FormError;
-use Symfony\Component\Form\Util\PropertyPath;
+use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\Validator\ConstraintViolation;
/**
View
27 Tests/Fixtures/Magician.php
@@ -1,27 +0,0 @@
-<?php
-
-/*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Form\Tests\Fixtures;
-
-class Magician
-{
- private $foobar;
-
- public function __set($property, $value)
- {
- $this->$property = $value;
- }
-
- public function __get($property)
- {
- return isset($this->$property) ? $this->$property : null;
- }
-}
View
2  Tests/SimpleFormTest.php
@@ -14,7 +14,7 @@
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
-use Symfony\Component\Form\Util\PropertyPath;
+use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\Form\FormConfigBuilder;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\Exception\TransformationFailedException;
View
135 Tests/Util/FormUtilTest.php
@@ -1,135 +0,0 @@
-<?php
-
-/*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Form\Tests\Util;
-
-use Symfony\Component\Form\Util\FormUtil;
-
-class FormUtilTest extends \PHPUnit_Framework_TestCase
-{
- public function singularifyProvider()
- {
- // see http://english-zone.com/spelling/plurals.html
- // see http://www.scribd.com/doc/3271143/List-of-100-Irregular-Plural-Nouns-in-English
- return array(
- array('tags', 'tag'),
- array('alumni', 'alumnus'),
- array('funguses', array('fungus', 'funguse', 'fungusis')),
- array('fungi', 'fungus'),
- array('axes', array('ax', 'axe', 'axis')),
- array('appendices', array('appendex', 'appendix', 'appendice')),
- array('indices', array('index', 'indix', 'indice')),
- array('prices', array('prex', 'prix', 'price')),
- array('indexes', 'index'),
- array('children', 'child'),
- array('men', 'man'),
- array('women', 'woman'),
- array('oxen', 'ox'),
- array('bacteria', array('bacterion', 'bacterium')),
- array('criteria', array('criterion', 'criterium')),
- array('feet', 'foot'),
- array('nebulae', 'nebula'),
- array('babies', 'baby'),
- array('hooves', 'hoof'),
- array('chateaux', 'chateau'),
- array('echoes', array('echo', 'echoe')),
- array('analyses', array('analys', 'analyse', 'analysis')),
- array('theses', array('thes', 'these', 'thesis')),
- array('foci', 'focus'),
- array('focuses', array('focus', 'focuse', 'focusis')),
- array('oases', array('oas', 'oase', 'oasis')),
- array('matrices', array('matrex', 'matrix', 'matrice')),
- array('matrixes', 'matrix'),
- array('bureaus', 'bureau'),
- array('bureaux', 'bureau'),
- array('beaux', 'beau'),
- array('data', array('daton', 'datum')),
- array('phenomena', array('phenomenon', 'phenomenum')),
- array('strata', array('straton', 'stratum')),
- array('geese', 'goose'),
- array('teeth', 'tooth'),
- array('antennae', 'antenna'),
- array('antennas', 'antenna'),
- array('houses', array('hous', 'house', 'housis')),
- array('arches', array('arch', 'arche')),
- array('atlases', array('atlas', 'atlase', 'atlasis')),
- array('batches', array('batch', 'batche')),
- array('bushes', array('bush', 'bushe')),
- array('buses', array('bus', 'buse', 'busis')),
- array('calves', 'calf'),
- array('circuses', array('circus', 'circuse', 'circusis')),
- array('crises', array('cris', 'crise', 'crisis')),
- array('dwarves', 'dwarf'),
- array('elves', 'elf'),
- array('emphases', array('emphas', 'emphase', 'emphasis')),
- array('faxes', 'fax'),
- array('halves', 'half'),
- array('heroes', array('hero', 'heroe')),
- array('hoaxes', 'hoax'),
- array('irises', array('iris', 'irise', 'irisis')),
- array('kisses', array('kiss', 'kisse', 'kissis')),
- array('knives', 'knife'),
- array('lives', 'life'),
- array('lice', 'louse'),
- array('mice', 'mouse'),
- array('neuroses', array('neuros', 'neurose', 'neurosis')),
- array('plateaux', 'plateau'),
- array('poppies', 'poppy'),
- array('quizzes', 'quiz'),
- array('scarves', 'scarf'),
- array('spies', 'spy'),
- array('stories', 'story'),
- array('syllabi', 'syllabus'),
- array('thieves', 'thief'),
- array('waltzes', array('waltz', 'waltze')),
- array('wharves', 'wharf'),
- array('wives', 'wife'),
- array('ions', 'ion'),
- array('bases', array('bas', 'base', 'basis')),
- array('cars', 'car'),
- array('cassettes', array('cassett', 'cassette')),
- array('lamps', 'lamp'),
- array('hats', 'hat'),
- array('cups', 'cup'),
- array('boxes', 'box'),
- array('sandwiches', array('sandwich', 'sandwiche')),
- array('suitcases', array('suitcas', 'suitcase', 'suitcasis')),
- array('roses', array('ros', 'rose', 'rosis')),
- array('garages', array('garag', 'garage')),
- array('shoes', array('sho', 'shoe')),
- array('days', 'day'),
- array('boys', 'boy'),
- array('roofs', 'roof'),
- array('cliffs', 'cliff'),
- array('sheriffs', 'sheriff'),
- array('discos', 'disco'),
- array('pianos', 'piano'),
- array('photos', 'photo'),
- array('trees', array('tre', 'tree')),
- array('bees', array('be', 'bee')),
- array('cheeses', array('chees', 'cheese', 'cheesis')),
- array('radii', 'radius'),
-
- // test casing: if the first letter was uppercase, it should remain so
- array('Men', 'Man'),
- array('GrandChildren', 'GrandChild'),
- array('SubTrees', array('SubTre', 'SubTree')),
- );
- }
-
- /**
- * @dataProvider singularifyProvider
- */
- public function testSingularify($plural, $singular)
- {
- $this->assertEquals($singular, FormUtil::singularify($plural));
- }
-}
View
20 Tests/Util/PropertyPathArrayObjectTest.php
@@ -1,20 +0,0 @@
-<?php
-
-/*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Form\Tests\Util;
-
-class PropertyPathArrayObjectTest extends PropertyPathCollectionTest
-{
- protected function getCollection(array $array)
- {
- return new \ArrayObject($array);
- }
-}
View
20 Tests/Util/PropertyPathArrayTest.php
@@ -1,20 +0,0 @@
-<?php
-
-/*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Form\Tests\Util;
-
-class PropertyPathArrayTest extends PropertyPathCollectionTest
-{
- protected function getCollection(array $array)
- {
- return $array;
- }
-}
View
251 Tests/Util/PropertyPathBuilderTest.php
@@ -1,251 +0,0 @@
-<?php
-
-/*
- * This file is new3 of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Form\Tests\Util;
-
-use Symfony\Component\Form\Util\PropertyPath;
-use Symfony\Component\Form\Util\PropertyPathBuilder;
-
-/**
- * @author Bernhard Schussek <bschussek@gmail.com>
- */
-class PropertyPathBuilderTest extends \PHPUnit_Framework_TestCase
-{
- /**
- * @var string
- */
- const PREFIX = 'old1[old2].old3[old4][old5].old6';
-
- /**
- * @var PropertyPathBuilder
- */
- private $builder;
-
- protected function setUp()
- {
- $this->builder = new PropertyPathBuilder(new PropertyPath(self::PREFIX));
- }
-
- public function testCreateEmpty()
- {
- $builder = new PropertyPathBuilder();
-
- $this->assertNull($builder->getPropertyPath());
- }
-
- public function testCreateCopyPath()
- {
- $this->assertEquals(new PropertyPath(self::PREFIX), $this->builder->getPropertyPath());
- }
-
- public function testAppendIndex()
- {
- $this->builder->appendIndex('new1');
-
- $path = new PropertyPath(self::PREFIX . '[new1]');
-
- $this->assertEquals($path, $this->builder->getPropertyPath());
- }
-
- public function testAppendProperty()
- {
- $this->builder->appendProperty('new1');
-
- $path = new PropertyPath(self::PREFIX . '.new1');
-
- $this->assertEquals($path, $this->builder->getPropertyPath());
- }
-
- public function testAppend()
- {
- $this->builder->append(new PropertyPath('new1[new2]'));
-
- $path = new PropertyPath(self::PREFIX . '.new1[new2]');
-
- $this->assertEquals($path, $this->builder->getPropertyPath());
- }
-
- public function testAppendWithOffset()
- {
- $this->builder->append(new PropertyPath('new1[new2].new3'), 1);
-
- $path = new PropertyPath(self::PREFIX . '[new2].new3');
-
- $this->assertEquals($path, $this->builder->getPropertyPath());
- }
-
- public function testAppendWithOffsetAndLength()
- {
- $this->builder->append(new PropertyPath('new1[new2].new3'), 1, 1);
-
- $path = new PropertyPath(self::PREFIX . '[new2]');
-
- $this->assertEquals($path, $this->builder->getPropertyPath());
- }
-
- public function testReplaceByIndex()
- {
- $this->builder->replaceByIndex(1, 'new1');
-
- $path = new PropertyPath('old1[new1].old3[old4][old5].old6');
-
- $this->assertEquals($path, $this->builder->getPropertyPath());
- }
-
- public function testReplaceByIndexWithoutName()
- {
- $this->builder->replaceByIndex(0);
-
- $path = new PropertyPath('[old1][old2].old3[old4][old5].old6');
-
- $this->assertEquals($path, $this->builder->getPropertyPath());
- }
-
- /**
- * @expectedException \OutOfBoundsException
- */
- public function testReplaceByIndexDoesNotAllowInvalidOffsets()
- {
- $this->builder->replaceByIndex(6, 'new1');
- }
-
- /**
- * @expectedException \OutOfBoundsException
- */
- public function testReplaceByIndexDoesNotAllowNegativeOffsets()
- {
- $this->builder->replaceByIndex(-1, 'new1');
- }
-
- public function testReplaceByProperty()
- {
- $this->builder->replaceByProperty(1, 'new1');
-
- $path = new PropertyPath('old1.new1.old3[old4][old5].old6');
-
- $this->assertEquals($path, $this->builder->getPropertyPath());
- }
-
- public function testReplaceByPropertyWithoutName()
- {
- $this->builder->replaceByProperty(1);
-
- $path = new PropertyPath('old1.old2.old3[old4][old5].old6');
-
- $this->assertEquals($path, $this->builder->getPropertyPath());
- }
-
- /**
- * @expectedException \OutOfBoundsException
- */
- public function testReplaceByPropertyDoesNotAllowInvalidOffsets()
- {
- $this->builder->replaceByProperty(6, 'new1');
- }
-
- /**
- * @expectedException \OutOfBoundsException
- */
- public function testReplaceByPropertyDoesNotAllowNegativeOffsets()
- {
- $this->builder->replaceByProperty(-1, 'new1');
- }
-
- public function testReplace()
- {
- $this->builder->replace(1, 1, new PropertyPath('new1[new2].new3'));
-
- $path = new PropertyPath('old1.new1[new2].new3.old3[old4][old5].old6');
-
- $this->assertEquals($path, $this->builder->getPropertyPath());
- }
-
- /**
- * @expectedException \OutOfBoundsException
- */
- public function testReplaceDoesNotAllowInvalidOffsets()
- {
- $this->builder->replace(6, 1, new PropertyPath('new1[new2].new3'));
- }
-
- /**
- * @expectedException \OutOfBoundsException
- */
- public function testReplaceDoesNotAllowNegativeOffsets()
- {
- $this->builder->replace(-1, 1, new PropertyPath('new1[new2].new3'));
- }
-
- public function testReplaceWithLengthGreaterOne()
- {
- $this->builder->replace(0, 2, new PropertyPath('new1[new2].new3'));
-
- $path = new PropertyPath('new1[new2].new3.old3[old4][old5].old6');
-
- $this->assertEquals($path, $this->builder->getPropertyPath());
- }
-
- public function testReplaceSubstring()
- {
- $this->builder->replace(1, 1, new PropertyPath('new1[new2].new3.new4[new5]'), 1, 3);
-
- $path = new PropertyPath('old1[new2].new3.new4.old3[old4][old5].old6');
-
- $this->assertEquals($path, $this->builder->getPropertyPath());
- }
-
- public function testReplaceSubstringWithLengthGreaterOne()
- {
- $this->builder->replace(1, 2, new PropertyPath('new1[new2].new3.new4[new5]'), 1, 3);
-
- $path = new PropertyPath('old1[new2].new3.new4[old4][old5].old6');
-
- $this->assertEquals($path, $this->builder->getPropertyPath());
- }
-
- // https://github.com/symfony/symfony/issues/5605
- public function testReplaceWithLongerPath()
- {
- // error occurs when path contains at least two more elements
- // than the builder
- $path = new PropertyPath('new1.new2.new3');
-
- $builder = new PropertyPathBuilder(new PropertyPath('old1'));
- $builder->replace(0, 1, $path);
-
- $this->assertEquals($path, $builder->getPropertyPath());
- }
-
- public function testRemove()
- {
- $this->builder->remove(3);
-
- $path = new PropertyPath('old1[old2].old3[old5].old6');
-
- $this->assertEquals($path, $this->builder->getPropertyPath());
- }
-
- /**
- * @expectedException \OutOfBoundsException
- */
- public function testRemoveDoesNotAllowInvalidOffsets()
- {
- $this->builder->remove(6);
- }
-
- /**
- * @expectedException \OutOfBoundsException
- */
- public function testRemoveDoesNotAllowNegativeOffsets()
- {
- $this->builder->remove(-1);
- }
-}
View
341 Tests/Util/PropertyPathCollectionTest.php
@@ -1,341 +0,0 @@
-<?php
-
-/*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Form\Tests\Util;
-
-use Symfony\Component\Form\Util\PropertyPath;
-use Symfony\Component\Form\Util\FormUtil;
-
-class PropertyPathCollectionTest_Car
-{
- private $axes;
-
- public function __construct($axes = null)
- {
- $this->axes = $axes;
- }
-
- // In the test, use a name that FormUtil can't uniquely singularify
- public function addAxis($axis)
- {
- $this->axes[] = $axis;
- }
-
- public function removeAxis($axis)
- {
- foreach ($this->axes as $key => $value) {
- if ($value === $axis) {
- unset($this->axes[$key]);
-
- return;
- }
- }
- }
-
- public function getAxes()
- {
- return $this->axes;
- }
-}
-
-class PropertyPathCollectionTest_CarCustomSingular
-{
- public function addFoo($axis) {}
-
- public function removeFoo($axis) {}
-
- public function getAxes() {}
-}
-
-class PropertyPathCollectionTest_Engine
-{
-}
-
-class PropertyPathCollectionTest_CarOnlyAdder
-{
- public function addAxis($axis) {}
-
- public function getAxes() {}
-}
-
-class PropertyPathCollectionTest_CarOnlyRemover
-{
- public function removeAxis($axis) {}
-
- public function getAxes() {}
-}
-
-class PropertyPathCollectionTest_CarNoAdderAndRemover
-{
- public function getAxes() {}
-}
-
-class PropertyPathCollectionTest_CarNoAdderAndRemoverWithProperty
-{
- protected $axes = array();
-
- public function getAxes() {}
-}
-
-class PropertyPathCollectionTest_CompositeCar
-{
- public function getStructure() {}
-
- public function setStructure($structure) {}
-}
-
-class PropertyPathCollectionTest_CarStructure
-{
- public function addAxis($axis) {}
-
- public function removeAxis($axis) {}
-
- public function getAxes() {}
-}
-
-abstract class PropertyPathCollectionTest extends \PHPUnit_Framework_TestCase
-{
- abstract protected function getCollection(array $array);
-
- public function testGetValueReadsArrayAccess()
- {
- $object = $this->getCollection(array('firstName' => 'Bernhard'));
-
- $path = new PropertyPath('[firstName]');
-
- $this->assertEquals('Bernhard', $path->getValue($object));
- }
-
- public function testGetValueReadsNestedArrayAccess()
- {
- $object = $this->getCollection(array('person' => array('firstName' => 'Bernhard')));
-
- $path = new PropertyPath('[person][firstName]');
-
- $this->assertEquals('Bernhard', $path->getValue($object));
- }
-
- /**
- * @expectedException \Symfony\Component\Form\Exception\InvalidPropertyException
- */
- public function testGetValueThrowsExceptionIfArrayAccessExpected()
- {
- $path = new PropertyPath('[firstName]');
-
- $path->getValue(new \stdClass());
- }
-
- public function testSetValueUpdatesArrayAccess()
- {
- $object = $this->getCollection(array());
-
- $path = new PropertyPath('[firstName]');
- $path->setValue($object, 'Bernhard');
-
- $this->assertEquals('Bernhard', $object['firstName']);
- }
-
- public function testSetValueUpdatesNestedArrayAccess()
- {
- $object = $this->getCollection(array());
-
- $path = new PropertyPath('[person][firstName]');
- $path->setValue($object, 'Bernhard');
-
- $this->assertEquals('Bernhard', $object['person']['firstName']);
- }
-
- /**
- * @expectedException \Symfony\Component\Form\Exception\InvalidPropertyException
- */
- public function testSetValueThrowsExceptionIfArrayAccessExpected()
- {
- $path = new PropertyPath('[firstName]');
-
- $path->setValue(new \stdClass(), 'Bernhard');
- }
-
- public function testSetValueCallsAdderAndRemoverForCollections()
- {
- $axesBefore = $this->getCollection(array(1 => 'second', 3 => 'fourth', 4 => 'fifth'));
- $axesMerged = $this->getCollection(array(1 => 'first', 2 => 'second', 3 => 'third'));
- $axesAfter = $this->getCollection(array(1 => 'second', 5 => 'first', 6 => 'third'));
- $axesMergedCopy = is_object($axesMerged) ? clone $axesMerged : $axesMerged;
-
- // Don't use a mock in order to test whether the collections are
- // modified while iterating them
- $car = new PropertyPathCollectionTest_Car($axesBefore);
-
- $path = new PropertyPath('axes');
-
- $path->setValue($car, $axesMerged);
-
- $this->assertEquals($axesAfter, $car->getAxes());
-
- // The passed collection was not modified
- $this->assertEquals($axesMergedCopy, $axesMerged);
- }
-
- public function testSetValueCallsAdderAndRemoverForNestedCollections()
- {
- $car = $this->getMock(__CLASS__ . '_CompositeCar');
- $structure = $this->getMock(__CLASS__ . '_CarStructure');
- $axesBefore = $this->getCollection(array(1 => 'second', 3 => 'fourth'));
- $axesAfter = $this->getCollection(array(0 => 'first', 1 => 'second', 2 => 'third'));
-
- $path = new PropertyPath('structure.axes');
-
- $car->expects($this->any())
- ->method('getStructure')
- ->will($this->returnValue($structure));
-
- $structure->expects($this->at(0))
- ->method('getAxes')
- ->will($this->returnValue($axesBefore));
- $structure->expects($this->at(1))
- ->method('removeAxis')
- ->with('fourth');
- $structure->expects($this->at(2))
- ->method('addAxis')
- ->with('first');
- $structure->expects($this->at(3))
- ->method('addAxis')
- ->with('third');
-
- $path->setValue($car, $axesAfter);
- }
-
- public function testSetValueCallsCustomAdderAndRemover()
- {
- $this->markTestSkipped('This feature is temporarily disabled as of 2.1');
-
- $car = $this->getMock(__CLASS__ . '_CarCustomSingular');
- $axesBefore = $this->getCollection(array(1 => 'second', 3 => 'fourth'));
- $axesAfter = $this->getCollection(array(0 => 'first', 1 => 'second', 2 => 'third'));
-
- $path = new PropertyPath('axes|foo');
-
- $car->expects($this->at(0))
- ->method('getAxes')
- ->will($this->returnValue($axesBefore));
- $car->expects($this->at(1))
- ->method('removeFoo')
- ->with('fourth');
- $car->expects($this->at(2))
- ->method('addFoo')
- ->with('first');
- $car->expects($this->at(3))
- ->method('addFoo')
- ->with('third');
-
- $path->setValue($car, $axesAfter);
- }
-
- /**
- * @expectedException \Symfony\Component\Form\Exception\InvalidPropertyException
- */
- public function testMapFormToDataFailsIfOnlyAdderFound()
- {
- $car = $this->getMock(__CLASS__ . '_CarOnlyAdder');
- $axesBefore = $this->getCollection(array(1 => 'second', 3 => 'fourth'));
- $axesAfter = $this->getCollection(array(0 => 'first', 1 => 'second', 2 => 'third'));
-
- $path = new PropertyPath('axes');
-
- $car->expects($this->any())
- ->method('getAxes')
- ->will($this->returnValue($axesBefore));
-
- $path->setValue($car, $axesAfter);
- }
-
- /**
- * @expectedException \Symfony\Component\Form\Exception\InvalidPropertyException
- */
- public function testMapFormToDataFailsIfOnlyRemoverFound()
- {
- $car = $this->getMock(__CLASS__ . '_CarOnlyRemover');
- $axesBefore = $this->getCollection(array(1 => 'second', 3 => 'fourth'));
- $axesAfter = $this->getCollection(array(0 => 'first', 1 => 'second', 2 => 'third'));
-
- $path = new PropertyPath('axes');
-
- $car->expects($this->any())
- ->method('getAxes')
- ->will($this->returnValue($axesBefore));
-
- $path->setValue($car, $axesAfter);
- }
-
- /**
- * @dataProvider noAdderRemoverData
- */
- public function testNoAdderAndRemoverThrowsSensibleError($car, $path, $message)
- {
- $axes = $this->getCollection(array(0 => 'first', 1 => 'second', 2 => 'third'));
-
- try {
- $path->setValue($car, $axes);
- $this->fail('An expected exception was not thrown!');
- } catch (\Symfony\Component\Form\Exception\Exception $e) {
- $this->assertEquals($message, $e->getMessage());
- }
- }
-
- public function noAdderRemoverData()
- {
- $data = array();
-
- $car = $this->getMock(__CLASS__ . '_CarNoAdderAndRemover');
- $propertyPath = new PropertyPath('axes');
- $expectedMessage = sprintf(
- 'Neither element "axes" nor method "setAxes()" exists in class '
- .'"%s", nor could adders and removers be found based on the '
- .'guessed singulars: %s'
-// . '(provide a singular by suffixing the '
-// .'property path with "|{singular}" to override the guesser)'
- ,
- get_class($car),
- implode(', ', (array) $singulars = FormUtil::singularify('Axes'))
- );
- $data[] = array($car, $propertyPath, $expectedMessage);
-
- /*
- Temporarily disabled in 2.1
-
- $propertyPath = new PropertyPath('axes|boo');
- $expectedMessage = sprintf(
- 'Neither element "axes" nor method "setAxes()" exists in class '
- .'"%s", nor could adders and removers be found based on the '
- .'passed singular: %s',
- get_class($car),
- 'boo'
- );
- $data[] = array($car, $propertyPath, $expectedMessage);
- */
-
- $car = $this->getMock(__CLASS__ . '_CarNoAdderAndRemoverWithProperty');
- $propertyPath = new PropertyPath('axes');
- $expectedMessage = sprintf(
- 'Property "axes" is not public in class "%s", nor could adders and '
- .'removers be found based on the guessed singulars: %s'
-// .' (provide a singular by suffixing the property path with '
-// .'"|{singular}" to override the guesser)'
- . '. Maybe you should '
- .'create the method "setAxes()"?',
- get_class($car),
- implode(', ', (array) $singulars = FormUtil::singularify('Axes'))
- );
- $data[] = array($car, $propertyPath, $expectedMessage);
-
- return $data;
- }
-}
View
22 Tests/Util/PropertyPathCustomArrayObjectTest.php
@@ -1,22 +0,0 @@
-<?php
-
-/*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Form\Tests\Util;
-
-use Symfony\Component\Form\Tests\Fixtures\CustomArrayObject;
-
-class PropertyPathCustomArrayObjectTest extends PropertyPathCollectionTest
-{
- protected function getCollection(array $array)
- {
- return new CustomArrayObject($array);
- }
-}
View
557 Tests/Util/PropertyPathTest.php
@@ -1,557 +0,0 @@
-<?php
-
-/*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Form\Tests\Util;
-
-use Symfony\Component\Form\Util\PropertyPath;
-use Symfony\Component\Form\Tests\Fixtures\Author;
-use Symfony\Component\Form\Tests\Fixtures\Magician;
-
-class PropertyPathTest extends \PHPUnit_Framework_TestCase
-{
- public function testGetValueReadsArray()
- {
- $array = array('firstName' => 'Bernhard');
-
- $path = new PropertyPath('[firstName]');
-
- $this->assertEquals('Bernhard', $path->getValue($array));
- }
-
- /**
- * @expectedException \Symfony\Component\Form\Exception\InvalidPropertyException
- */
- public function testGetValueThrowsExceptionIfIndexNotationExpected()
- {
- $array = array('firstName' => 'Bernhard');
-
- $path = new PropertyPath('firstName');
-
- $path->getValue($array);
- }
-
- public function testGetValueReadsZeroIndex()
- {
- $array = array('Bernhard');
-
- $path = new PropertyPath('[0]');
-
- $this->assertEquals('Bernhard', $path->getValue($array));
- }
-
- public function testGetValueReadsIndexWithSpecialChars()
- {
- $array = array('%!@$§.' => 'Bernhard');
-
- $path = new PropertyPath('[%!@$§.]');
-
- $this->assertEquals('Bernhard', $path->getValue($array));
- }
-
- public function testGetValueReadsNestedIndexWithSpecialChars()
- {
- $array = array('root' => array('%!@$§.' => 'Bernhard'));
-
- $path = new PropertyPath('[root][%!@$§.]');
-
- $this->assertEquals('Bernhard', $path->getValue($array));
- }
-
- public function testGetValueReadsArrayWithCustomPropertyPath()
- {
- $array = array('child' => array('index' => array('firstName' => 'Bernhard')));
-
- $path = new PropertyPath('[child][index][firstName]');
-
- $this->assertEquals('Bernhard', $path->getValue($array));
- }
-
- public function testGetValueReadsArrayWithMissingIndexForCustomPropertyPath()
- {
- $array = array('child' => array('index' => array()));
-
- $path = new PropertyPath('[child][index][firstName]');
-
- $this->assertNull($path->getValue($array));
- }
-
- public function testGetValueReadsProperty()
- {
- $object = new Author();
- $object->firstName = 'Bernhard';
-
- $path = new PropertyPath('firstName');
-
- $this->assertEquals('Bernhard', $path->getValue($object));
- }
-
- public function testGetValueIgnoresSingular()
- {
- $this->markTestSkipped('This feature is temporarily disabled as of 2.1');
-
- $object = (object) array('children' => 'Many');
-
- $path = new PropertyPath('children|child');
-
- $this->assertEquals('Many', $path->getValue($object));
- }
-
- public function testGetValueReadsPropertyWithSpecialCharsExceptDot()
- {
- $array = (object) array('%!@$§' => 'Bernhard');
-
- $path = new PropertyPath('%!@$§');
-
- $this->assertEquals('Bernhard', $path->getValue($array));
- }
-
- public function testGetValueReadsPropertyWithCustomPropertyPath()
- {
- $object = new Author();
- $object->child = array();
- $object->child['index'] = new Author();
- $object->child['index']->firstName = 'Bernhard';
-
- $path = new PropertyPath('child[index].firstName');
-
- $this->assertEquals('Bernhard', $path->getValue($object));
- }
-
- /**
- * @expectedException \Symfony\Component\Form\Exception\PropertyAccessDeniedException
- */
- public function testGetValueThrowsExceptionIfPropertyIsNotPublic()
- {
- $path = new PropertyPath('privateProperty');
-
- $path->getValue(new Author());
- }
-
- public function testGetValueReadsGetters()
- {
- $path = new PropertyPath('lastName');
-
- $object = new Author();
- $object->setLastName('Schussek');
-
- $this->assertEquals('Schussek', $path->getValue($object));
- }
-
- public function testGetValueCamelizesGetterNames()
- {
- $path = new PropertyPath('last_name');
-
- $object = new Author();
- $object->setLastName('Schussek');
-
- $this->assertEquals('Schussek', $path->getValue($object));
- }
-
- /**
- * @expectedException \Symfony\Component\Form\Exception\PropertyAccessDeniedException
- */
- public function testGetValueThrowsExceptionIfGetterIsNotPublic()
- {
- $path = new PropertyPath('privateGetter');
-
- $path->getValue(new Author());
- }
-
- public function testGetValueReadsIssers()
- {
- $path = new PropertyPath('australian');
-
- $object = new Author();
- $object->setAustralian(false);
-
- $this->assertFalse($path->getValue($object));
- }
-
- public function testGetValueReadHassers()
- {
- $path = new PropertyPath('read_permissions');
-
- $object = new Author();
- $object->setReadPermissions(true);
-
- $this->assertTrue($path->getValue($object));
- }
-
- public function testGetValueReadsMagicGet()
- {
- $path = new PropertyPath('magicProperty');
-
- $object = new Magician();
- $object->__set('magicProperty', 'foobar');
-
- $this->assertSame('foobar', $path->getValue($object));
- }
-
- /*
- * https://github.com/symfony/symfony/pull/4450
- */
- public function testGetValueReadsMagicGetThatReturnsConstant()
- {
- $path = new PropertyPath('magicProperty');
-
- $object = new Magician();
-
- $this->assertNull($path->getValue($object));
- }
-
- /**
- * @expectedException \Symfony\Component\Form\Exception\PropertyAccessDeniedException
- */
- public function testGetValueThrowsExceptionIfIsserIsNotPublic()
- {
- $path = new PropertyPath('privateIsser');
-
- $path->getValue(new Author());
- }
-
- /**
- * @expectedException \Symfony\Component\Form\Exception\InvalidPropertyException
- */
- public function testGetValueThrowsExceptionIfPropertyDoesNotExist()
- {
- $path = new PropertyPath('foobar');
-
- $path->getValue(new Author());
- }
-
- /**
- * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException
- */
- public function testGetValueThrowsExceptionIfNotObjectOrArray()
- {
- $path = new PropertyPath('foobar');
-
- $path->getValue('baz');
- }
-
- /**
- * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException
- */
- public function testGetValueThrowsExceptionIfNull()
- {
- $path = new PropertyPath('foobar');
-
- $path->getValue(null);
- }
-
- /**
- * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException
- */
- public function testGetValueThrowsExceptionIfEmpty()
- {
- $path = new PropertyPath('foobar');
-
- $path->getValue('');
- }
-
- public function testSetValueUpdatesArrays()
- {
- $array = array();
-
- $path = new PropertyPath('[firstName]');
- $path->setValue($array, 'Bernhard');
-
- $this->assertEquals(array('firstName' => 'Bernhard'), $array);
- }
-
- /**
- * @expectedException \Symfony\Component\Form\Exception\InvalidPropertyException
- */
- public function testSetValueThrowsExceptionIfIndexNotationExpected()
- {
- $array = array();
-
- $path = new PropertyPath('firstName');
- $path->setValue($array, 'Bernhard');
- }
-
- public function testSetValueUpdatesArraysWithCustomPropertyPath()
- {
- $array = array();
-
- $path = new PropertyPath('[child][index][firstName]');
- $path->setValue($array, 'Bernhard');
-
- $this->assertEquals(array('child' => array('index' => array('firstName' => 'Bernhard'))), $array);
- }
-
- public function testSetValueUpdatesProperties()
- {
- $object = new Author();
-
- $path = new PropertyPath('firstName');
- $path->setValue($object, 'Bernhard');
-
- $this->assertEquals('Bernhard', $object->firstName);
- }
-
- public function testSetValueUpdatesPropertiesWithCustomPropertyPath()
- {
- $object = new Author();
- $object->child = array();
- $object->child['index'] = new Author();
-
- $path = new PropertyPath('child[index].firstName');
- $path->setValue($object, 'Bernhard');
-
- $this->assertEquals('Bernhard', $object->child['index']->firstName);
- }
-
- public function testSetValueUpdateMagicSet()
- {
- $object = new Magician();
-
- $path = new PropertyPath('magicProperty');
- $path->setValue($object, 'foobar');
-
- $this->assertEquals('foobar', $object->__get('magicProperty'));
- }
-
- public function testSetValueUpdatesSetters()
- {
- $object = new Author();
-
- $path = new PropertyPath('lastName');
- $path->setValue($object, 'Schussek');
-
- $this->assertEquals('Schussek', $object->getLastName());
- }
-
- public function testSetValueCamelizesSetterNames()
- {
- $object = new Author();
-
- $path = new PropertyPath('last_name');