1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Doctrine\Tests\Common\Reflection; |
4
|
|
|
|
5
|
|
|
use Closure; |
6
|
|
|
use Doctrine\Common\Proxy\Proxy; |
7
|
|
|
use Doctrine\Common\Reflection\RuntimePublicReflectionProperty; |
8
|
|
|
use PHPUnit\Framework\TestCase; |
9
|
|
|
use function call_user_func; |
10
|
|
|
|
11
|
|
|
class RuntimePublicReflectionPropertyTest extends TestCase |
12
|
|
|
{ |
13
|
|
|
public function testGetValue() : void |
14
|
|
|
{ |
15
|
|
|
$object = new RuntimePublicReflectionPropertyTestClass(); |
16
|
|
|
|
17
|
|
|
$reflProperty = new RuntimePublicReflectionProperty(RuntimePublicReflectionPropertyTestClass::class, 'test'); |
18
|
|
|
|
19
|
|
|
self::assertSame('testValue', $reflProperty->getValue($object)); |
20
|
|
|
|
21
|
|
|
unset($object->test); |
22
|
|
|
|
23
|
|
|
self::assertNull($reflProperty->getValue($object)); |
24
|
|
|
} |
25
|
|
|
|
26
|
|
|
public function testSetValue() : void |
27
|
|
|
{ |
28
|
|
|
$object = new RuntimePublicReflectionPropertyTestClass(); |
29
|
|
|
|
30
|
|
|
$reflProperty = new RuntimePublicReflectionProperty(RuntimePublicReflectionPropertyTestClass::class, 'test'); |
31
|
|
|
|
32
|
|
|
self::assertSame('testValue', $reflProperty->getValue($object)); |
33
|
|
|
|
34
|
|
|
$reflProperty->setValue($object, 'changedValue'); |
35
|
|
|
|
36
|
|
|
self::assertSame('changedValue', $reflProperty->getValue($object)); |
37
|
|
|
} |
38
|
|
|
|
39
|
|
|
public function testGetValueOnProxyPublicProperty() : void |
40
|
|
|
{ |
41
|
|
|
$getCheckMock = $this->getMockBuilder('stdClass')->setMethods(['callGet'])->getMock(); |
42
|
|
|
$getCheckMock->expects($this->never())->method('callGet'); |
43
|
|
|
$initializer = static function () use ($getCheckMock) { |
44
|
|
|
call_user_func($getCheckMock); |
45
|
|
|
}; |
46
|
|
|
|
47
|
|
|
$mockProxy = new RuntimePublicReflectionPropertyTestProxyMock(); |
48
|
|
|
$mockProxy->__setInitializer($initializer); |
49
|
|
|
|
50
|
|
|
$reflProperty = new RuntimePublicReflectionProperty( |
51
|
|
|
__NAMESPACE__ . '\RuntimePublicReflectionPropertyTestProxyMock', |
52
|
|
|
'checkedProperty' |
53
|
|
|
); |
54
|
|
|
|
55
|
|
|
self::assertSame('testValue', $reflProperty->getValue($mockProxy)); |
56
|
|
|
unset($mockProxy->checkedProperty); |
57
|
|
|
self::assertNull($reflProperty->getValue($mockProxy)); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
public function testSetValueOnProxyPublicProperty() : void |
61
|
|
|
{ |
62
|
|
|
$setCheckMock = $this->getMockBuilder('stdClass')->setMethods(['neverCallSet'])->getMock(); |
63
|
|
|
$setCheckMock->expects($this->never())->method('neverCallSet'); |
64
|
|
|
$initializer = static function () use ($setCheckMock) { |
65
|
|
|
call_user_func([$setCheckMock, 'neverCallSet']); |
66
|
|
|
}; |
67
|
|
|
|
68
|
|
|
$mockProxy = new RuntimePublicReflectionPropertyTestProxyMock(); |
69
|
|
|
$mockProxy->__setInitializer($initializer); |
70
|
|
|
|
71
|
|
|
$reflProperty = new RuntimePublicReflectionProperty( |
72
|
|
|
__NAMESPACE__ . '\RuntimePublicReflectionPropertyTestProxyMock', |
73
|
|
|
'checkedProperty' |
74
|
|
|
); |
75
|
|
|
|
76
|
|
|
$reflProperty->setValue($mockProxy, 'newValue'); |
77
|
|
|
self::assertSame('newValue', $mockProxy->checkedProperty); |
78
|
|
|
|
79
|
|
|
unset($mockProxy->checkedProperty); |
80
|
|
|
$reflProperty->setValue($mockProxy, 'otherNewValue'); |
81
|
|
|
self::assertSame('otherNewValue', $mockProxy->checkedProperty); |
82
|
|
|
|
83
|
|
|
$setCheckMock = $this->getMockBuilder('stdClass')->setMethods(['callSet'])->getMock(); |
84
|
|
|
$setCheckMock->expects($this->once())->method('callSet'); |
85
|
|
|
$initializer = static function () use ($setCheckMock) { |
86
|
|
|
call_user_func([$setCheckMock, 'callSet']); |
87
|
|
|
}; |
88
|
|
|
|
89
|
|
|
$mockProxy->__setInitializer($initializer); |
90
|
|
|
$mockProxy->__setInitialized(true); |
91
|
|
|
|
92
|
|
|
unset($mockProxy->checkedProperty); |
93
|
|
|
$reflProperty->setValue($mockProxy, 'againNewValue'); |
94
|
|
|
self::assertSame('againNewValue', $mockProxy->checkedProperty); |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* Mock that simulates proxy public property lazy loading |
100
|
|
|
*/ |
101
|
|
|
class RuntimePublicReflectionPropertyTestProxyMock implements Proxy |
|
|
|
|
102
|
|
|
{ |
103
|
|
|
/** @var Closure|null */ |
104
|
|
|
private $initializer = null; |
105
|
|
|
|
106
|
|
|
/** @var bool */ |
107
|
|
|
private $initialized = false; |
108
|
|
|
|
109
|
|
|
/** @var string */ |
110
|
|
|
public $checkedProperty = 'testValue'; |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* {@inheritDoc} |
114
|
|
|
*/ |
115
|
|
|
public function __getInitializer() |
116
|
|
|
{ |
117
|
|
|
return $this->initializer; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* {@inheritDoc} |
122
|
|
|
*/ |
123
|
|
|
public function __setInitializer(?Closure $initializer = null) |
124
|
|
|
{ |
125
|
|
|
$this->initializer = $initializer; |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* {@inheritDoc} |
130
|
|
|
*/ |
131
|
|
|
public function __getLazyProperties() |
132
|
|
|
{ |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* {@inheritDoc} |
137
|
|
|
*/ |
138
|
|
|
public function __load() |
139
|
|
|
{ |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* {@inheritDoc} |
144
|
|
|
*/ |
145
|
|
|
public function __isInitialized() |
146
|
|
|
{ |
147
|
|
|
return $this->initialized; |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* {@inheritDoc} |
152
|
|
|
*/ |
153
|
|
|
public function __setInitialized($initialized) |
154
|
|
|
{ |
155
|
|
|
$this->initialized = (bool) $initialized; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* @param string $name |
160
|
|
|
*/ |
161
|
|
|
public function __get($name) |
162
|
|
|
{ |
163
|
|
|
if ($this->initializer) { |
164
|
|
|
$cb = $this->initializer; |
165
|
|
|
$cb(); |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
return $this->checkedProperty; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
/** |
172
|
|
|
* @param string $name |
173
|
|
|
* @param mixed $value |
174
|
|
|
*/ |
175
|
|
|
public function __set($name, $value) |
176
|
|
|
{ |
177
|
|
|
if ($this->initializer) { |
178
|
|
|
$cb = $this->initializer; |
179
|
|
|
$cb(); |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
// triggers notices if `$name` is used: see https://bugs.php.net/bug.php?id=63463 |
183
|
|
|
$this->checkedProperty = $value; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* @param string $name |
188
|
|
|
* |
189
|
|
|
* @return bool |
190
|
|
|
*/ |
191
|
|
|
public function __isset($name) |
192
|
|
|
{ |
193
|
|
|
if ($this->initializer) { |
194
|
|
|
$cb = $this->initializer; |
195
|
|
|
$cb(); |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
return isset($this->checkedProperty); |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
/** |
202
|
|
|
* {@inheritDoc} |
203
|
|
|
*/ |
204
|
|
|
public function __setCloner(?Closure $cloner = null) |
205
|
|
|
{ |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* {@inheritDoc} |
210
|
|
|
*/ |
211
|
|
|
public function __getCloner() |
212
|
|
|
{ |
213
|
|
|
} |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
class RuntimePublicReflectionPropertyTestClass |
217
|
|
|
{ |
218
|
|
|
/** @var string|null */ |
219
|
|
|
public $test = 'testValue'; |
220
|
|
|
} |
221
|
|
|
|
This interface has been deprecated. The supplier of the interface has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the interface will be removed and what other interface to use instead.