Skip to content

Commit

Permalink
minor #13742 [PropertyAccess] refactor type checks (Tobion)
Browse files Browse the repository at this point in the history
This PR was merged into the 2.3 branch.

Discussion
----------

[PropertyAccess] refactor type checks

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        | -

#13735 for 2.3

Commits
-------

9cacecb [PropertyAccess] the property path constructor already implements the type check
4e11c07 [PropertyAccess] refactor type checks to remove duplicate logic
  • Loading branch information
fabpot committed Feb 21, 2015
2 parents 19aa6dc + 9cacecb commit 7b9bc80
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 56 deletions.
25 changes: 11 additions & 14 deletions src/Symfony/Component/PropertyAccess/PropertyAccessor.php
Expand Up @@ -40,10 +40,8 @@ public function __construct($magicCall = false)
*/
public function getValue($objectOrArray, $propertyPath)
{
if (is_string($propertyPath)) {
if (!$propertyPath instanceof PropertyPathInterface) {
$propertyPath = new PropertyPath($propertyPath);
} elseif (!$propertyPath instanceof PropertyPathInterface) {
throw new UnexpectedTypeException($propertyPath, 'string or Symfony\Component\PropertyAccess\PropertyPathInterface');
}

$propertyValues = & $this->readPropertiesUntil($objectOrArray, $propertyPath, $propertyPath->getLength());
Expand All @@ -56,10 +54,8 @@ public function getValue($objectOrArray, $propertyPath)
*/
public function setValue(&$objectOrArray, $propertyPath, $value)
{
if (is_string($propertyPath)) {
if (!$propertyPath instanceof PropertyPathInterface) {
$propertyPath = new PropertyPath($propertyPath);
} elseif (!$propertyPath instanceof PropertyPathInterface) {
throw new UnexpectedTypeException($propertyPath, 'string or Symfony\Component\PropertyAccess\PropertyPathInterface');
}

$propertyValues = & $this->readPropertiesUntil($objectOrArray, $propertyPath, $propertyPath->getLength() - 1);
Expand All @@ -75,10 +71,6 @@ public function setValue(&$objectOrArray, $propertyPath, $value)
$objectOrArray = & $propertyValues[$i][self::VALUE];

if ($overwrite) {
if (!is_object($objectOrArray) && !is_array($objectOrArray)) {
throw new UnexpectedTypeException($objectOrArray, 'object or array');
}

$property = $propertyPath->getElement($i);
//$singular = $propertyPath->singulars[$i];
$singular = null;
Expand Down Expand Up @@ -108,13 +100,13 @@ public function setValue(&$objectOrArray, $propertyPath, $value)
*/
private function &readPropertiesUntil(&$objectOrArray, PropertyPathInterface $propertyPath, $lastIndex)
{
if (!is_object($objectOrArray) && !is_array($objectOrArray)) {
throw new UnexpectedTypeException($objectOrArray, 'object or array');
}

$propertyValues = array();

for ($i = 0; $i < $lastIndex; ++$i) {
if (!is_object($objectOrArray) && !is_array($objectOrArray)) {
throw new UnexpectedTypeException($objectOrArray, 'object or array');
}

$property = $propertyPath->getElement($i);
$isIndex = $propertyPath->isIndex($i);

Expand All @@ -137,6 +129,11 @@ private function &readPropertiesUntil(&$objectOrArray, PropertyPathInterface $pr

$objectOrArray = & $propertyValue[self::VALUE];

// the final value of the path must not be validated
if ($i + 1 < $propertyPath->getLength() && !is_object($objectOrArray) && !is_array($objectOrArray)) {
throw new UnexpectedTypeException($objectOrArray, 'object or array');
}

$propertyValues[] = & $propertyValue;
}

Expand Down
64 changes: 22 additions & 42 deletions src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php
Expand Up @@ -29,6 +29,20 @@ protected function setUp()
$this->propertyAccessor = new PropertyAccessor();
}

public function getPathsWithUnexpectedType()
{
return array(
array('', 'foobar'),
array('foo', 'foobar'),
array(null, 'foobar'),
array(123, 'foobar'),
array((object) array('prop' => null), 'prop.foobar'),
array((object) array('prop' => (object) array('subProp' => null)), 'prop.subProp.foobar'),
array(array('index' => null), '[index][foobar]'),
array(array('index' => array('subIndex' => null)), '[index][subIndex][foobar]'),
);
}

public function testGetValueReadsArray()
{
$array = array('firstName' => 'Bernhard');
Expand Down Expand Up @@ -198,27 +212,13 @@ public function testGetValueThrowsExceptionIfPropertyDoesNotExist()
}

/**
* @dataProvider getPathsWithUnexpectedType
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
* @expectedExceptionMessage Expected argument of type "object or array"
*/
public function testGetValueThrowsExceptionIfNotObjectOrArray()
{
$this->propertyAccessor->getValue('baz', 'foobar');
}

/**
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
*/
public function testGetValueThrowsExceptionIfNull()
public function testGetValueThrowsExceptionIfNotObjectOrArray($objectOrArray, $path)
{
$this->propertyAccessor->getValue(null, 'foobar');
}

/**
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
*/
public function testGetValueThrowsExceptionIfEmpty()
{
$this->propertyAccessor->getValue('', 'foobar');
$this->propertyAccessor->getValue($objectOrArray, $path);
}

public function testGetValueWhenArrayValueIsNull()
Expand Down Expand Up @@ -311,33 +311,13 @@ public function testSetValueThrowsExceptionIfGetterIsNotPublic()
}

/**
* @dataProvider getPathsWithUnexpectedType
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
* @expectedExceptionMessage Expected argument of type "object or array"
*/
public function testSetValueThrowsExceptionIfNotObjectOrArray()
public function testSetValueThrowsExceptionIfNotObjectOrArray($objectOrArray, $path)
{
$value = 'baz';

$this->propertyAccessor->setValue($value, 'foobar', 'bam');
}

/**
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
*/
public function testSetValueThrowsExceptionIfNull()
{
$value = null;

$this->propertyAccessor->setValue($value, 'foobar', 'bam');
}

/**
* @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException
*/
public function testSetValueThrowsExceptionIfEmpty()
{
$value = '';

$this->propertyAccessor->setValue($value, 'foobar', 'bam');
$this->propertyAccessor->setValue($objectOrArray, $path, 'value');
}

/**
Expand Down

0 comments on commit 7b9bc80

Please sign in to comment.