1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
<?php
declare(strict_types=1);
namespace Doctrine\Tests\Persistence;
use Closure;
use Doctrine\Persistence\Proxy;
use Doctrine\Persistence\Reflection\RuntimeReflectionProperty;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
class DummyMock
{
public function callGet(): void
{
}
public function callSet(): void
{
}
}
class RuntimeReflectionPropertyTest extends TestCase
{
#[testWith(["test", "testValue"])]
#[testWith(["privateTest", "privateTestValue"])]
public function testGetSetValue(string $name, string $value): void
{
$object = new RuntimeReflectionPropertyTestClass();
$reflProperty = new RuntimeReflectionProperty(RuntimeReflectionPropertyTestClass::class, $name);
self::assertSame($value, $reflProperty->getValue($object));
$reflProperty->setValue($object, 'changedValue');
self::assertSame('changedValue', $reflProperty->getValue($object));
}
/**
* @param class-string<RuntimeReflectionPropertyTestProxyMock> $proxyClass
*/
#[testWith(["Doctrine\\Tests\\Persistence\\RuntimeReflectionPropertyTestProxyMock"])]
#[testWith(["\\Doctrine\\Tests\\Persistence\\RuntimeReflectionPropertyTestProxyMock"])]
public function testGetValueOnProxyProperty(string $proxyClass): void
{
$getCheckMock = $this->createMock(DummyMock::class);
$getCheckMock->expects(self::never())->method('callGet');
$initializer = static function () use ($getCheckMock): void {
$getCheckMock->callGet();
};
$mockProxy = new $proxyClass($initializer);
$reflProperty = new RuntimeReflectionProperty($proxyClass, 'checkedProperty');
self::assertSame('testValue', $reflProperty->getValue($mockProxy));
unset($mockProxy->checkedProperty);
self::assertNull($reflProperty->getValue($mockProxy));
}
public function testSetValueOnProxyProperty(): void
{
$setCheckMock = $this->createMock(DummyMock::class);
$setCheckMock->expects(self::never())->method('callSet');
$initializer = static function () use ($setCheckMock): void {
$setCheckMock->callSet();
};
$mockProxy = new RuntimeReflectionPropertyTestProxyMock($initializer);
$reflProperty = new RuntimeReflectionProperty(RuntimeReflectionPropertyTestProxyMock::class, 'checkedProperty');
$reflProperty->setValue($mockProxy, 'newValue');
self::assertSame('newValue', $mockProxy->checkedProperty);
unset($mockProxy->checkedProperty);
$reflProperty->setValue($mockProxy, 'otherNewValue');
self::assertSame('otherNewValue', $mockProxy->checkedProperty);
}
}
/**
* Mock that simulates proxy property lazy loading
*
* @implements Proxy<object>
*/
class RuntimeReflectionPropertyTestProxyMock implements Proxy
{
private bool $initialized = false;
public string $checkedProperty = 'testValue';
/**
* {@inheritDoc}
*/
public function __construct(protected Closure|null $initializer = null)
{
}
public function __load(): void
{
}
public function __isInitialized(): bool
{
return $this->initialized;
}
/**
* {@inheritDoc}
*/
public function __setInitialized($initialized): void
{
$this->initialized = $initialized;
}
public function __get(string $name): mixed
{
if (! $this->initialized && $this->initializer !== null) {
($this->initializer)();
}
return $this->checkedProperty;
}
public function __set(string $name, mixed $value): void
{
if (! $this->initialized && $this->initializer !== null) {
($this->initializer)();
}
$this->checkedProperty = $value;
}
public function __isset(string $name): bool
{
if (! $this->initialized && $this->initializer !== null) {
($this->initializer)();
}
return isset($this->checkedProperty);
}
}
class RuntimeReflectionPropertyTestClass
{
public string $test = 'testValue';
private string $privateTest = 'privateTestValue';
public function getPrivateTest(): string|null
{
return $this->privateTest;
}
}
|