From 56143036c934bc1aac9d7ba2f0fb781bccbae9fc Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Fri, 28 Mar 2014 15:50:34 +0100 Subject: [PATCH] [PropertyAccess] Refactored PropertyAccessorTest --- .../PropertyAccess/PropertyAccessor.php | 11 +- .../PropertyAccess/Tests/Fixtures/Author.php | 71 ---- .../Tests/Fixtures/Magician.php | 27 -- .../Tests/Fixtures/MagicianCall.php | 28 -- .../Tests/Fixtures/TestClass.php | 115 +++++ .../Tests/Fixtures/TestClassMagicCall.php | 39 ++ .../Tests/Fixtures/TestClassMagicGet.php | 42 ++ .../Tests/PropertyAccessorTest.php | 393 ++++++------------ 8 files changed, 335 insertions(+), 391 deletions(-) delete mode 100644 src/Symfony/Component/PropertyAccess/Tests/Fixtures/Author.php delete mode 100644 src/Symfony/Component/PropertyAccess/Tests/Fixtures/Magician.php delete mode 100644 src/Symfony/Component/PropertyAccess/Tests/Fixtures/MagicianCall.php create mode 100644 src/Symfony/Component/PropertyAccess/Tests/Fixtures/TestClass.php create mode 100644 src/Symfony/Component/PropertyAccess/Tests/Fixtures/TestClassMagicCall.php create mode 100644 src/Symfony/Component/PropertyAccess/Tests/Fixtures/TestClassMagicGet.php diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index 0e400f4380de..02d2311c8dc5 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -116,7 +116,7 @@ public function setValue(&$objectOrArray, $propertyPath, $value) * * @throws UnexpectedTypeException If a value within the path is neither object nor array. */ - private function &readPropertiesUntil(&$objectOrArray, PropertyPathInterface $propertyPath, $lastIndex, $throwExceptionOnNonexistantIndex = false) + private function &readPropertiesUntil(&$objectOrArray, PropertyPathInterface $propertyPath, $lastIndex, $throwExceptionOnInvalidIndex = false) { $propertyValues = array(); @@ -131,9 +131,10 @@ private function &readPropertiesUntil(&$objectOrArray, PropertyPathInterface $pr // Create missing nested arrays on demand if ($isIndex && $isArrayAccess && !isset($objectOrArray[$property])) { - if ($throwExceptionOnNonexistantIndex) { + if ($throwExceptionOnInvalidIndex) { throw new NoSuchIndexException(sprintf('Cannot read property "%s". Available properties are "%s"', $property, print_r(array_keys($objectOrArray), true))); } + $objectOrArray[$property] = $i + 1 < $propertyPath->getLength() ? array() : null; } @@ -412,8 +413,8 @@ private function findAdderAndRemover(\ReflectionClass $reflClass, array $singula $addMethod = 'add'.$singular; $removeMethod = 'remove'.$singular; - $addMethodFound = $this->isAccessible($reflClass, $addMethod, 1); - $removeMethodFound = $this->isAccessible($reflClass, $removeMethod, 1); + $addMethodFound = $this->isMethodAccessible($reflClass, $addMethod, 1); + $removeMethodFound = $this->isMethodAccessible($reflClass, $removeMethod, 1); if ($addMethodFound && $removeMethodFound) { return array($addMethod, $removeMethod); @@ -440,7 +441,7 @@ private function findAdderAndRemover(\ReflectionClass $reflClass, array $singula * @return bool Whether the method is public and has $parameters * required parameters */ - private function isAccessible(\ReflectionClass $class, $methodName, $parameters) + private function isMethodAccessible(\ReflectionClass $class, $methodName, $parameters) { if ($class->hasMethod($methodName)) { $method = $class->getMethod($methodName); diff --git a/src/Symfony/Component/PropertyAccess/Tests/Fixtures/Author.php b/src/Symfony/Component/PropertyAccess/Tests/Fixtures/Author.php deleted file mode 100644 index ed2331bab04f..000000000000 --- a/src/Symfony/Component/PropertyAccess/Tests/Fixtures/Author.php +++ /dev/null @@ -1,71 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\PropertyAccess\Tests\Fixtures; - -class Author -{ - public $firstName; - private $lastName; - private $australian; - public $child; - private $readPermissions; - - private $privateProperty; - - public function setLastName($lastName) - { - $this->lastName = $lastName; - } - - public function getLastName() - { - return $this->lastName; - } - - private function getPrivateGetter() - { - return 'foobar'; - } - - public function setAustralian($australian) - { - $this->australian = $australian; - } - - public function isAustralian() - { - return $this->australian; - } - - public function setReadPermissions($bool) - { - $this->readPermissions = $bool; - } - - public function hasReadPermissions() - { - return $this->readPermissions; - } - - private function isPrivateIsser() - { - return true; - } - - public function getPrivateSetter() - { - } - - private function setPrivateSetter($data) - { - } -} diff --git a/src/Symfony/Component/PropertyAccess/Tests/Fixtures/Magician.php b/src/Symfony/Component/PropertyAccess/Tests/Fixtures/Magician.php deleted file mode 100644 index 6faa5dbf7bb3..000000000000 --- a/src/Symfony/Component/PropertyAccess/Tests/Fixtures/Magician.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\PropertyAccess\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; - } -} diff --git a/src/Symfony/Component/PropertyAccess/Tests/Fixtures/MagicianCall.php b/src/Symfony/Component/PropertyAccess/Tests/Fixtures/MagicianCall.php deleted file mode 100644 index 0508a71da1e4..000000000000 --- a/src/Symfony/Component/PropertyAccess/Tests/Fixtures/MagicianCall.php +++ /dev/null @@ -1,28 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\PropertyAccess\Tests\Fixtures; - -class MagicianCall -{ - private $foobar; - - public function __call($name, $args) - { - $property = lcfirst(substr($name, 3)); - if ('get' === substr($name, 0, 3)) { - return isset($this->$property) ? $this->$property : null; - } elseif ('set' === substr($name, 0, 3)) { - $value = 1 == count($args) ? $args[0] : null; - $this->$property = $value; - } - } -} diff --git a/src/Symfony/Component/PropertyAccess/Tests/Fixtures/TestClass.php b/src/Symfony/Component/PropertyAccess/Tests/Fixtures/TestClass.php new file mode 100644 index 000000000000..178d7f618abb --- /dev/null +++ b/src/Symfony/Component/PropertyAccess/Tests/Fixtures/TestClass.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\PropertyAccess\Tests\Fixtures; + +class TestClass +{ + public $publicProperty; + protected $protectedProperty; + private $privateProperty; + + private $publicAccessor; + private $publicIsAccessor; + private $publicHasAccessor; + + public function __construct($value) + { + $this->publicProperty = $value; + $this->publicAccessor = $value; + $this->publicIsAccessor = $value; + $this->publicHasAccessor = $value; + } + + public function setPublicAccessor($value) + { + $this->publicAccessor = $value; + } + + public function getPublicAccessor() + { + return $this->publicAccessor; + } + + public function setPublicIsAccessor($value) + { + $this->publicIsAccessor = $value; + } + + public function isPublicIsAccessor() + { + return $this->publicIsAccessor; + } + + public function setPublicHasAccessor($value) + { + $this->publicHasAccessor = $value; + } + + public function hasPublicHasAccessor() + { + return $this->publicHasAccessor; + } + + protected function setProtectedAccessor($value) + { + } + + protected function getProtectedAccessor() + { + return 'foobar'; + } + + protected function setProtectedIsAccessor($value) + { + } + + protected function isProtectedIsAccessor() + { + return 'foobar'; + } + + protected function setProtectedHasAccessor($value) + { + } + + protected function hasProtectedHasAccessor() + { + return 'foobar'; + } + + private function setPrivateAccessor($value) + { + } + + private function getPrivateAccessor() + { + return 'foobar'; + } + + private function setPrivateIsAccessor($value) + { + } + + private function isPrivateIsAccessor() + { + return 'foobar'; + } + + private function setPrivateHasAccessor($value) + { + } + + private function hasPrivateHasAccessor() + { + return 'foobar'; + } +} diff --git a/src/Symfony/Component/PropertyAccess/Tests/Fixtures/TestClassMagicCall.php b/src/Symfony/Component/PropertyAccess/Tests/Fixtures/TestClassMagicCall.php new file mode 100644 index 000000000000..d49967abd1a6 --- /dev/null +++ b/src/Symfony/Component/PropertyAccess/Tests/Fixtures/TestClassMagicCall.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\PropertyAccess\Tests\Fixtures; + +class TestClassMagicCall +{ + private $magicCallProperty; + + public function __construct($value) + { + $this->magicCallProperty = $value; + } + + public function __call($method, array $args) + { + if ('getMagicCallProperty' === $method) { + return $this->magicCallProperty; + } + + if ('getConstantMagicCallProperty' === $method) { + return 'constant value'; + } + + if ('setMagicCallProperty' === $method) { + $this->magicCallProperty = reset($args); + } + + return null; + } +} diff --git a/src/Symfony/Component/PropertyAccess/Tests/Fixtures/TestClassMagicGet.php b/src/Symfony/Component/PropertyAccess/Tests/Fixtures/TestClassMagicGet.php new file mode 100644 index 000000000000..fee831896672 --- /dev/null +++ b/src/Symfony/Component/PropertyAccess/Tests/Fixtures/TestClassMagicGet.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\PropertyAccess\Tests\Fixtures; + +class TestClassMagicGet +{ + private $magicProperty; + + public function __construct($value) + { + $this->magicProperty = $value; + } + + public function __set($property, $value) + { + if ('magicProperty' === $property) { + $this->magicProperty = $value; + } + } + + public function __get($property) + { + if ('magicProperty' === $property) { + return $this->magicProperty; + } + + if ('constantMagicProperty' === $property) { + return 'constant value'; + } + + return null; + } +} diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php index a64930a93a7b..5a7d22955cb2 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php @@ -12,221 +12,155 @@ namespace Symfony\Component\PropertyAccess\Tests; use Symfony\Component\PropertyAccess\PropertyAccessor; -use Symfony\Component\PropertyAccess\Tests\Fixtures\Author; +use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClass; use Symfony\Component\PropertyAccess\Tests\Fixtures\Magician; -use Symfony\Component\PropertyAccess\Tests\Fixtures\MagicianCall; -use Symfony\Component\PropertyAccess\PropertyAccessorBuilder; +use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassMagicCall; +use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassMagicGet; class PropertyAccessorTest extends \PHPUnit_Framework_TestCase { /** - * @var PropertyAccessorBuilder + * @var PropertyAccessor */ - private $propertyAccessorBuilder; + private $propertyAccessor; protected function setUp() { - $this->propertyAccessorBuilder = new PropertyAccessorBuilder(); + $this->propertyAccessor = new PropertyAccessor(); } - /** - * Get PropertyAccessor configured - * - * @param string $withMagicCall - * @param string $throwExceptionOnInvalidIndex - * @return PropertyAccessorInterface - */ - protected function getPropertyAccessor($withMagicCall = false, $throwExceptionOnInvalidIndex = false) - { - if ($withMagicCall) { - $this->propertyAccessorBuilder->enableMagicCall(); - } else { - $this->propertyAccessorBuilder->disableMagicCall(); - } - - if ($throwExceptionOnInvalidIndex) { - $this->propertyAccessorBuilder->enableExceptionOnInvalidIndex(); - } else { - $this->propertyAccessorBuilder->disableExceptionOnInvalidIndex(); - } - - return $this->propertyAccessorBuilder->getPropertyAccessor(); - } - - public function testGetValueReadsArray() - { - $array = array('firstName' => 'Bernhard'); - - $this->assertEquals('Bernhard', $this->getPropertyAccessor()->getValue($array, '[firstName]')); - } - - /** - * @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException - */ - public function testGetValueThrowsExceptionIfIndexNotationExpected() - { - $array = array('firstName' => 'Bernhard'); - - $this->getPropertyAccessor()->getValue($array, 'firstName'); - } - - public function testGetValueReadsZeroIndex() + public function getValidPropertyPaths() { - $array = array('Bernhard'); - $this->assertEquals('Bernhard', $this->getPropertyAccessor()->getValue($array, '[0]')); - } + return array( + array(array('Bernhard', 'Schussek'), '[0]', 'Bernhard'), + array(array('Bernhard', 'Schussek'), '[1]', 'Schussek'), + array(array('firstName' => 'Bernhard'), '[firstName]', 'Bernhard'), + array(array('index' => array('firstName' => 'Bernhard')), '[index][firstName]', 'Bernhard'), + array((object) array('firstName' => 'Bernhard'), 'firstName', 'Bernhard'), + array((object) array('property' => array('firstName' => 'Bernhard')), 'property[firstName]', 'Bernhard'), + array(array('index' => (object) array('firstName' => 'Bernhard')), '[index].firstName', 'Bernhard'), + array((object) array('property' => (object) array('firstName' => 'Bernhard')), 'property.firstName', 'Bernhard'), - public function testGetValueReadsIndexWithSpecialChars() - { - $array = array('%!@$§.' => 'Bernhard'); + // Accessor methods + array(new TestClass('Bernhard'), 'publicProperty', 'Bernhard'), + array(new TestClass('Bernhard'), 'publicAccessor', 'Bernhard'), + array(new TestClass('Bernhard'), 'publicIsAccessor', 'Bernhard'), + array(new TestClass('Bernhard'), 'publicHasAccessor', 'Bernhard'), - $this->assertEquals('Bernhard', $this->getPropertyAccessor()->getValue($array, '[%!@$§.]')); - } + // Methods are camelized + array(new TestClass('Bernhard'), 'public_accessor', 'Bernhard'), - public function testGetValueReadsNestedIndexWithSpecialChars() - { - $array = array('root' => array('%!@$§.' => 'Bernhard')); + // Missing indices + array(array('index' => array()), '[index][firstName]', null), + array(array('root' => array('index' => array())), '[root][index][firstName]', null), - $this->assertEquals('Bernhard', $this->getPropertyAccessor()->getValue($array, '[root][%!@$§.]')); + // Special chars + array(array('%!@$§.' => 'Bernhard'), '[%!@$§.]', 'Bernhard'), + array(array('index' => array('%!@$§.' => 'Bernhard')), '[index][%!@$§.]', 'Bernhard'), + array((object) array('%!@$§' => 'Bernhard'), '%!@$§', 'Bernhard'), + ); } - public function testGetValueReadsArrayWithCustomPropertyPath() + public function getPathsWithMissingProperty() { - $array = array('child' => array('index' => array('firstName' => 'Bernhard'))); - - $this->assertEquals('Bernhard', $this->getPropertyAccessor()->getValue($array, '[child][index][firstName]')); - } - public function testGetValueReadsArrayWithMissingIndexForCustomPropertyPath() - { - $array = array('child' => array('index' => array())); + return array( + array((object) array('firstName' => 'Bernhard'), 'lastName'), + array((object) array('property' => (object) array('firstName' => 'Bernhard')), 'property.lastName'), + array(array('index' => (object) array('firstName' => 'Bernhard')), '[index].lastName'), + array(new TestClass('Bernhard'), 'protectedProperty'), + array(new TestClass('Bernhard'), 'privateProperty'), + array(new TestClass('Bernhard'), 'protectedAccessor'), + array(new TestClass('Bernhard'), 'protectedIsAccessor'), + array(new TestClass('Bernhard'), 'protectedHasAccessor'), + array(new TestClass('Bernhard'), 'privateAccessor'), + array(new TestClass('Bernhard'), 'privateIsAccessor'), + array(new TestClass('Bernhard'), 'privateHasAccessor'), - // No BC break - $this->assertNull($this->getPropertyAccessor()->getValue($array, '[child][index][firstName]')); - - try { - $this->getPropertyAccessor(false, true)->getValue($array, '[child][index][firstName]'); - $this->fail('Getting value on a nonexistent path from array should throw a Symfony\Component\PropertyAccess\Exception\NoSuchIndexException exception'); - } catch (\Exception $e) { - $this->assertInstanceof('Symfony\Component\PropertyAccess\Exception\NoSuchIndexException', $e, 'Getting value on a nonexistent path from array should throw a Symfony\Component\PropertyAccess\Exception\NoSuchIndexException exception'); - } + // Properties are not camelized + array(new TestClass('Bernhard'), 'public_property'), + ); } - public function testGetValueReadsProperty() + public function getPathsWithMissingIndex() { - $object = new Author(); - $object->firstName = 'Bernhard'; - - $this->assertEquals('Bernhard', $this->getPropertyAccessor()->getValue($object, 'firstName')); - } - - public function testGetValueIgnoresSingular() - { - $this->markTestSkipped('This feature is temporarily disabled as of 2.1'); - - $object = (object) array('children' => 'Many'); - - $this->assertEquals('Many', $this->getPropertyAccessor()->getValue($object, 'children|child')); - } - - public function testGetValueReadsPropertyWithSpecialCharsExceptDot() - { - $array = (object) array('%!@$§' => 'Bernhard'); - - $this->assertEquals('Bernhard', $this->getPropertyAccessor()->getValue($array, '%!@$§')); - } - - public function testGetValueReadsPropertyWithCustomPropertyPath() - { - $object = new Author(); - $object->child = array(); - $object->child['index'] = new Author(); - $object->child['index']->firstName = 'Bernhard'; - - $this->assertEquals('Bernhard', $this->getPropertyAccessor()->getValue($object, 'child[index].firstName')); + return array( + array(array('firstName' => 'Bernhard'), '[lastName]'), + array(array(), '[index][lastName]'), + array(array('index' => array()), '[index][lastName]'), + array(array('index' => array('firstName' => 'Bernhard')), '[index][lastName]'), + array((object) array('property' => array('firstName' => 'Bernhard')), 'property[lastName]'), + ); } /** - * @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException + * @dataProvider getValidPropertyPaths */ - public function testGetValueThrowsExceptionIfPropertyIsNotPublic() + public function testGetValue($objectOrArray, $path, $value) { - $this->getPropertyAccessor()->getValue(new Author(), 'privateProperty'); - } - - public function testGetValueReadsGetters() - { - $object = new Author(); - $object->setLastName('Schussek'); - - $this->assertEquals('Schussek', $this->getPropertyAccessor()->getValue($object, 'lastName')); - } - - public function testGetValueCamelizesGetterNames() - { - $object = new Author(); - $object->setLastName('Schussek'); - - $this->assertEquals('Schussek', $this->getPropertyAccessor()->getValue($object, 'last_name')); + $this->assertSame($value, $this->propertyAccessor->getValue($objectOrArray, $path)); } /** + * @dataProvider getPathsWithMissingProperty * @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException */ - public function testGetValueThrowsExceptionIfGetterIsNotPublic() + public function testGetValueThrowsExceptionIfPropertyNotFound($objectOrArray, $path) { - $this->getPropertyAccessor()->getValue(new Author(), 'privateGetter'); + $this->propertyAccessor->getValue($objectOrArray, $path); } - public function testGetValueReadsIssers() + /** + * @dataProvider getPathsWithMissingIndex + */ + public function testGetValueThrowsNoExceptionIfIndexNotFound($objectOrArray, $path) { - $object = new Author(); - $object->setAustralian(false); - - $this->assertFalse($this->getPropertyAccessor()->getValue($object, 'australian')); + $this->assertNull($this->propertyAccessor->getValue($objectOrArray, $path)); } - public function testGetValueReadHassers() + /** + * @dataProvider getPathsWithMissingIndex + * @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchIndexException + */ + public function testGetValueThrowsExceptionIfIndexNotFoundAndIndexExceptionsEnabled($objectOrArray, $path) { - $object = new Author(); - $object->setReadPermissions(true); - - $this->assertTrue($this->getPropertyAccessor()->getValue($object, 'read_permissions')); + $this->propertyAccessor = new PropertyAccessor(false, true); + $this->propertyAccessor->getValue($objectOrArray, $path); } public function testGetValueReadsMagicGet() { - $object = new Magician(); - $object->__set('magicProperty', 'foobar'); - - $this->assertSame('foobar', $this->getPropertyAccessor()->getValue($object, 'magicProperty')); + $this->assertSame('Bernhard', $this->propertyAccessor->getValue(new TestClassMagicGet('Bernhard'), 'magicProperty')); } - /* - * https://github.com/symfony/symfony/pull/4450 - */ + // https://github.com/symfony/symfony/pull/4450 public function testGetValueReadsMagicGetThatReturnsConstant() { - $object = new Magician(); - - $this->assertNull($this->getPropertyAccessor()->getValue($object, 'magicProperty')); + $this->assertSame('constant value', $this->propertyAccessor->getValue(new TestClassMagicGet('Bernhard'), 'constantMagicProperty')); } /** * @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException */ - public function testGetValueThrowsExceptionIfIsserIsNotPublic() + public function testGetValueDoesNotReadMagicCallByDefault() { - $this->getPropertyAccessor()->getValue(new Author(), 'privateIsser'); + $this->propertyAccessor->getValue(new TestClassMagicCall('Bernhard'), 'magicCallProperty'); } - /** - * @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException - */ - public function testGetValueThrowsExceptionIfPropertyDoesNotExist() + public function testGetValueReadsMagicCallIfEnabled() { - $this->getPropertyAccessor()->getValue(new Author(), 'foobar'); + $this->propertyAccessor = new PropertyAccessor(true); + + $this->assertSame('Bernhard', $this->propertyAccessor->getValue(new TestClassMagicCall('Bernhard'), 'magicCallProperty')); + } + + // https://github.com/symfony/symfony/pull/4450 + public function testGetValueReadsMagicCallThatReturnsConstant() + { + $this->propertyAccessor = new PropertyAccessor(true); + + $this->assertSame('constant value', $this->propertyAccessor->getValue(new TestClassMagicCall('Bernhard'), 'constantMagicCallProperty')); } /** @@ -234,7 +168,7 @@ public function testGetValueThrowsExceptionIfPropertyDoesNotExist() */ public function testGetValueThrowsExceptionIfNotObjectOrArray() { - $this->getPropertyAccessor()->getValue('baz', 'foobar'); + $this->propertyAccessor->getValue('baz', 'foobar'); } /** @@ -242,7 +176,7 @@ public function testGetValueThrowsExceptionIfNotObjectOrArray() */ public function testGetValueThrowsExceptionIfNull() { - $this->getPropertyAccessor()->getValue(null, 'foobar'); + $this->propertyAccessor->getValue(null, 'foobar'); } /** @@ -250,90 +184,77 @@ public function testGetValueThrowsExceptionIfNull() */ public function testGetValueThrowsExceptionIfEmpty() { - $this->getPropertyAccessor()->getValue('', 'foobar'); + $this->propertyAccessor->getValue('', 'foobar'); } - public function testSetValueUpdatesArrays() + /** + * @dataProvider getValidPropertyPaths + */ + public function testSetValue($objectOrArray, $path) { - $array = array(); + $this->propertyAccessor->setValue($objectOrArray, $path, 'Updated'); - $this->getPropertyAccessor()->setValue($array, '[firstName]', 'Bernhard'); - - $this->assertEquals(array('firstName' => 'Bernhard'), $array); + $this->assertSame('Updated', $this->propertyAccessor->getValue($objectOrArray, $path)); } /** + * @dataProvider getPathsWithMissingProperty * @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException */ - public function testSetValueThrowsExceptionIfIndexNotationExpected() + public function testSetValueThrowsExceptionIfPropertyNotFound($objectOrArray, $path) { - $array = array(); - - $this->getPropertyAccessor()->setValue($array, 'firstName', 'Bernhard'); - } - - public function testSetValueUpdatesArraysWithCustomPropertyPath() - { - $array = array(); - - $this->getPropertyAccessor()->setValue($array, '[child][index][firstName]', 'Bernhard'); - - $this->assertEquals(array('child' => array('index' => array('firstName' => 'Bernhard'))), $array); + $this->propertyAccessor->setValue($objectOrArray, $path, 'Updated'); } - public function testSetValueUpdatesProperties() + /** + * @dataProvider getPathsWithMissingIndex + */ + public function testSetValueThrowsNoExceptionIfIndexNotFound($objectOrArray, $path) { - $object = new Author(); + $this->propertyAccessor->setValue($objectOrArray, $path, 'Updated'); - $this->getPropertyAccessor()->setValue($object, 'firstName', 'Bernhard'); - - $this->assertEquals('Bernhard', $object->firstName); + $this->assertSame('Updated', $this->propertyAccessor->getValue($objectOrArray, $path)); } - public function testSetValueUpdatesPropertiesWithCustomPropertyPath() + /** + * @dataProvider getPathsWithMissingIndex + */ + public function testSetValueThrowsNoExceptionIfIndexNotFoundAndIndexExceptionsEnabled($objectOrArray, $path) { - $object = new Author(); - $object->child = array(); - $object->child['index'] = new Author(); - - $this->getPropertyAccessor()->setValue($object, 'child[index].firstName', 'Bernhard'); + $this->propertyAccessor = new PropertyAccessor(false, true); + $this->propertyAccessor->setValue($objectOrArray, $path, 'Updated'); - $this->assertEquals('Bernhard', $object->child['index']->firstName); + $this->assertSame('Updated', $this->propertyAccessor->getValue($objectOrArray, $path)); } - public function testSetValueUpdateMagicSet() + public function testSetValueUpdatesMagicSet() { - $object = new Magician(); + $author = new TestClassMagicGet('Bernhard'); - $this->getPropertyAccessor()->setValue($object, 'magicProperty', 'foobar'); + $this->propertyAccessor->setValue($author, 'magicProperty', 'Updated'); - $this->assertEquals('foobar', $object->__get('magicProperty')); + $this->assertEquals('Updated', $author->__get('magicProperty')); } - public function testSetValueUpdatesSetters() + /** + * @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException + */ + public function testSetValueDoesNotUpdateMagicCallByDefault() { - $object = new Author(); - - $this->getPropertyAccessor()->setValue($object, 'lastName', 'Schussek'); + $author = new TestClassMagicCall('Bernhard'); - $this->assertEquals('Schussek', $object->getLastName()); + $this->propertyAccessor->setValue($author, 'magicCallProperty', 'Updated'); } - public function testSetValueCamelizesSetterNames() + public function testSetValueUpdatesMagicCallIfEnabled() { - $object = new Author(); + $this->propertyAccessor = new PropertyAccessor(true); - $this->getPropertyAccessor()->setValue($object, 'last_name', 'Schussek'); + $author = new TestClassMagicCall('Bernhard'); - $this->assertEquals('Schussek', $object->getLastName()); - } + $this->propertyAccessor->setValue($author, 'magicCallProperty', 'Updated'); - /** - * @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException - */ - public function testSetValueThrowsExceptionIfGetterIsNotPublic() - { - $this->getPropertyAccessor()->setValue(new Author(), 'privateSetter', 'foobar'); + $this->assertEquals('Updated', $author->__call('getMagicCallProperty', array())); } /** @@ -343,7 +264,7 @@ public function testSetValueThrowsExceptionIfNotObjectOrArray() { $value = 'baz'; - $this->getPropertyAccessor()->setValue($value, 'foobar', 'bam'); + $this->propertyAccessor->setValue($value, 'foobar', 'bam'); } /** @@ -353,7 +274,7 @@ public function testSetValueThrowsExceptionIfNull() { $value = null; - $this->getPropertyAccessor()->setValue($value, 'foobar', 'bam'); + $this->propertyAccessor->setValue($value, 'foobar', 'bam'); } /** @@ -363,54 +284,6 @@ public function testSetValueThrowsExceptionIfEmpty() { $value = ''; - $this->getPropertyAccessor()->setValue($value, 'foobar', 'bam'); + $this->propertyAccessor->setValue($value, 'foobar', 'bam'); } - - /** - * @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException - */ - public function testSetValueFailsIfMagicCallDisabled() - { - $value = new MagicianCall(); - - $this->getPropertyAccessor()->setValue($value, 'foobar', 'bam'); - } - - /** - * @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException - */ - public function testGetValueFailsIfMagicCallDisabled() - { - $value = new MagicianCall(); - - $this->getPropertyAccessor()->getValue($value, 'foobar', 'bam'); - } - - public function testGetValueReadsMagicCall() - { - $propertyAccessor = new PropertyAccessor(true); - $object = new MagicianCall(); - $object->setMagicProperty('foobar'); - - $this->assertSame('foobar', $propertyAccessor->getValue($object, 'magicProperty')); - } - - public function testGetValueReadsMagicCallThatReturnsConstant() - { - $propertyAccessor = new PropertyAccessor(true); - $object = new MagicianCall(); - - $this->assertNull($propertyAccessor->getValue($object, 'MagicProperty')); - } - - public function testSetValueUpdatesMagicCall() - { - $propertyAccessor = new PropertyAccessor(true); - $object = new MagicianCall(); - - $propertyAccessor->setValue($object, 'magicProperty', 'foobar'); - - $this->assertEquals('foobar', $object->getMagicProperty()); - } - }