Skip to content

Commit

Permalink
[PropertyAccess] Add tests accessing public (dynamic) properties
Browse files Browse the repository at this point in the history
  • Loading branch information
kevcomparadise authored and nicolas-grekas committed Dec 11, 2021
1 parent dcae7a6 commit 21c6c7a
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 1 deletion.
2 changes: 1 addition & 1 deletion PropertyAccessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ private function readProperty(array $zval, string $property, bool $ignoreInvalid
}
} elseif (self::ACCESS_TYPE_PROPERTY === $access[self::ACCESS_TYPE]) {
$name = $access[self::ACCESS_NAME];
if (!method_exists($object, '__get') && !isset($object->$name) && !\array_key_exists($name, (array) $object) && (\PHP_VERSION_ID < 70400 || !(new \ReflectionProperty($class, $name))->hasType())) {
if ($access[self::ACCESS_REF] && !isset($object->$name) && !\array_key_exists($name, (array) $object) && (\PHP_VERSION_ID < 70400 || !(new \ReflectionProperty($class, $name))->hasType())) {
throw new AccessException(sprintf('The property "%s::$%s" is not initialized.', $class, $name));
}

Expand Down
21 changes: 21 additions & 0 deletions Tests/Fixtures/TestPublicPropertyDynamicallyCreated.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?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\PropertyAccess\Tests\Fixtures;

#[\AllowDynamicProperties]
class TestPublicPropertyDynamicallyCreated
{
public function __construct(string $bar)
{
$this->foo = $bar;
}
}
18 changes: 18 additions & 0 deletions Tests/Fixtures/TestPublicPropertyGetterOnObject.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?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\PropertyAccess\Tests\Fixtures;

class TestPublicPropertyGetterOnObject
{
public $a = 'A';
private $b = 'B';
}
25 changes: 25 additions & 0 deletions Tests/Fixtures/TestPublicPropertyGetterOnObjectMagicGet.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?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\PropertyAccess\Tests\Fixtures;

class TestPublicPropertyGetterOnObjectMagicGet
{
public $a = 'A';
private $b = 'B';

public function __get($property)
{
if ('b' === $property) {
return $this->b;
}
}
}
38 changes: 38 additions & 0 deletions Tests/PropertyAccessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassMagicGet;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassSetValue;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassTypeErrorInsideCall;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestPublicPropertyDynamicallyCreated;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestPublicPropertyGetterOnObject;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestPublicPropertyGetterOnObjectMagicGet;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestSingularAndPluralProps;
use Symfony\Component\PropertyAccess\Tests\Fixtures\Ticket5775Object;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TypeHinted;
Expand Down Expand Up @@ -849,4 +852,39 @@ public function testSetterNeedsPublicAccess()
$object = new TestClassSetValue(0);
$this->propertyAccessor->setValue($object, 'foo', 1);
}

public function testGetPublicProperty()
{
$value = 'A';
$path = 'a';
$object = new TestPublicPropertyGetterOnObject();

$this->assertSame($value, $this->propertyAccessor->getValue($object, $path));
}

public function testGetPrivateProperty()
{
$object = new TestPublicPropertyGetterOnObject();

$this->expectException(NoSuchPropertyException::class);
$this->expectExceptionMessageMatches('/.*Neither the property "b" nor one of the methods/');
$this->propertyAccessor->getValue($object, 'b');
}

public function testGetDynamicPublicProperty()
{
$value = 'Bar';
$path = 'foo';
$object = new TestPublicPropertyDynamicallyCreated('Bar');

$this->assertSame($value, $this->propertyAccessor->getValue($object, $path));
}

public function testGetDynamicPublicPropertyWithMagicGetterAllow()
{
$value = 'B';
$path = 'b';
$object = new TestPublicPropertyGetterOnObjectMagicGet();
$this->assertSame($value, $this->propertyAccessor->getValue($object, $path));
}
}

0 comments on commit 21c6c7a

Please sign in to comment.