Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
LazyLoadingValueHolderFunctionalTest.php
001 <?php
002 /*
003 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
004 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
005 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
006 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
007 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
008 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
009 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
010 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
011 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
012 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
013 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
014 *
015 * This software consists of voluntary contributions made by many individuals
016 * and is licensed under the MIT license.
017 */
018
019 namespace ProxyManagerTest\Functional;
020
021 use PHPUnit_Framework_TestCase;
022 use PHPUnit_Framework_MockObject_MockObject as Mock;
023 use ProxyManager\Generator\ClassGenerator;
024 use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
025 use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
026 use ProxyManager\Proxy\VirtualProxyInterface;
027 use ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator;
028 use ProxyManagerTestAsset\BaseClass;
029 use ProxyManagerTestAsset\ClassWithPublicArrayProperty;
030 use ProxyManagerTestAsset\ClassWithPublicProperties;
031 use ProxyManagerTestAsset\ClassWithSelfHint;
032 use ReflectionClass;
033
034 /**
035 * Tests for {@see \ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator} produced objects
036 *
037 * @author Marco Pivetta <ocramius@gmail.com>
038 * @license MIT
039 *
040 * @group Functional
041 * @coversNothing
042 */
043 class LazyLoadingValueHolderFunctionalTest extends PHPUnit_Framework_TestCase
044 {
045 /**
046 * @dataProvider getProxyMethods
047 */
048 public function testMethodCalls($className, $instance, $method, $params, $expectedValue)
049 {
050 $proxyName = $this->generateProxy($className);
051
052 /* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */
053 $proxy = new $proxyName($this->createInitializer($className, $instance));
054
055 $this->assertFalse($proxy->isProxyInitialized());
056 $this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
057 $this->assertTrue($proxy->isProxyInitialized());
058 $this->assertSame($instance, $proxy->getWrappedValueHolderValue());
059 }
060
061 /**
062 * @dataProvider getProxyMethods
063 */
064 public function testMethodCallsAfterUnSerialization($className, $instance, $method, $params, $expectedValue)
065 {
066 $proxyName = $this->generateProxy($className);
067
068 /* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */
069 $proxy = unserialize(serialize(new $proxyName($this->createInitializer($className, $instance))));
070
071 $this->assertTrue($proxy->isProxyInitialized());
072 $this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
073 $this->assertEquals($instance, $proxy->getWrappedValueHolderValue());
074 }
075
076 /**
077 * @dataProvider getProxyMethods
078 */
079 public function testMethodCallsAfterCloning($className, $instance, $method, $params, $expectedValue)
080 {
081 $proxyName = $this->generateProxy($className);
082
083 /* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */
084 $proxy = new $proxyName($this->createInitializer($className, $instance));
085 $cloned = clone $proxy;
086
087 $this->assertTrue($cloned->isProxyInitialized());
088 $this->assertNotSame($proxy->getWrappedValueHolderValue(), $cloned->getWrappedValueHolderValue());
089 $this->assertSame($expectedValue, call_user_func_array(array($cloned, $method), $params));
090 $this->assertEquals($instance, $cloned->getWrappedValueHolderValue());
091 }
092
093 /**
094 * @dataProvider getPropertyAccessProxies
095 */
096 public function testPropertyReadAccess($instance, $proxy, $publicProperty, $propertyValue)
097 {
098 /* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */
099 $this->assertSame($propertyValue, $proxy->$publicProperty);
100 $this->assertTrue($proxy->isProxyInitialized());
101 $this->assertEquals($instance, $proxy->getWrappedValueHolderValue());
102 }
103
104 /**
105 * @dataProvider getPropertyAccessProxies
106 */
107 public function testPropertyWriteAccess($instance, $proxy, $publicProperty)
108 {
109 /* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */
110 $newValue = uniqid();
111 $proxy->$publicProperty = $newValue;
112
113 $this->assertTrue($proxy->isProxyInitialized());
114 $this->assertSame($newValue, $proxy->$publicProperty);
115 $this->assertSame($newValue, $proxy->getWrappedValueHolderValue()->$publicProperty);
116 }
117
118 /**
119 * @dataProvider getPropertyAccessProxies
120 */
121 public function testPropertyExistence($instance, $proxy, $publicProperty)
122 {
123 /* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */
124 $this->assertSame(isset($instance->$publicProperty), isset($proxy->$publicProperty));
125 $this->assertTrue($proxy->isProxyInitialized());
126 $this->assertEquals($instance, $proxy->getWrappedValueHolderValue());
127 }
128
129 /**
130 * @dataProvider getPropertyAccessProxies
131 */
132 public function testPropertyAbsence($instance, $proxy, $publicProperty)
133 {
134 /* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */
135 $instance = $proxy->getWrappedValueHolderValue() ? $proxy->getWrappedValueHolderValue() : $instance;
136 $instance->$publicProperty = null;
137 $this->assertFalse(isset($proxy->$publicProperty));
138 $this->assertTrue($proxy->isProxyInitialized());
139 }
140
141 /**
142 * @dataProvider getPropertyAccessProxies
143 */
144 public function testPropertyUnset($instance, $proxy, $publicProperty)
145 {
146 /* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */
147 $instance = $proxy->getWrappedValueHolderValue() ? $proxy->getWrappedValueHolderValue() : $instance;
148 unset($proxy->$publicProperty);
149
150 $this->assertTrue($proxy->isProxyInitialized());
151
152 $this->assertFalse(isset($instance->$publicProperty));
153 $this->assertFalse(isset($proxy->$publicProperty));
154 }
155
156 /**
157 * Verifies that accessing a public property containing an array behaves like in a normal context
158 */
159 public function testCanWriteToArrayKeysInPublicProperty()
160 {
161 $instance = new ClassWithPublicArrayProperty();
162 $className = get_class($instance);
163 $initializer = $this->createInitializer($className, $instance);
164 $proxyName = $this->generateProxy($className);
165 /* @var $proxy ClassWithPublicArrayProperty */
166 $proxy = new $proxyName($initializer);
167
168 $proxy->arrayProperty['foo'] = 'bar';
169
170 $this->assertSame('bar', $proxy->arrayProperty['foo']);
171
172 $proxy->arrayProperty = array('tab' => 'taz');
173
174 $this->assertSame(array('tab' => 'taz'), $proxy->arrayProperty);
175 }
176
177 /**
178 * Verifies that public properties retrieved via `__get` don't get modified in the object itself
179 */
180 public function testWillNotModifyRetrievedPublicProperties()
181 {
182 $instance = new ClassWithPublicProperties();
183 $className = get_class($instance);
184 $initializer = $this->createInitializer($className, $instance);
185 $proxyName = $this->generateProxy($className);
186 /* @var $proxy ClassWithPublicProperties */
187 $proxy = new $proxyName($initializer);
188 $variable = $proxy->property0;
189
190 $this->assertSame('property0', $variable);
191
192 $variable = 'foo';
193
194 $this->assertSame('property0', $proxy->property0);
195 }
196
197 /**
198 * Verifies that public properties references retrieved via `__get` modify in the object state
199 */
200 public function testWillModifyByRefRetrievedPublicProperties()
201 {
202 $instance = new ClassWithPublicProperties();
203 $className = get_class($instance);
204 $initializer = $this->createInitializer($className, $instance);
205 $proxyName = $this->generateProxy($className);
206 /* @var $proxy ClassWithPublicProperties */
207 $proxy = new $proxyName($initializer);
208 $variable = & $proxy->property0;
209
210 $this->assertSame('property0', $variable);
211
212 $variable = 'foo';
213
214 $this->assertSame('foo', $proxy->property0);
215 }
216
217 /**
218 * @group 16
219 *
220 * Verifies that initialization of a value holder proxy may happen multiple times
221 */
222 public function testWillAllowMultipleProxyInitialization()
223 {
224 $proxyClass = $this->generateProxy('ProxyManagerTestAsset\\BaseClass');
225 $counter = 0;
226 $initializer = function (& $wrappedInstance) use (& $counter) {
227 $wrappedInstance = new BaseClass();
228
229 $wrappedInstance->publicProperty = (string) ($counter += 1);
230 };
231
232 /* @var $proxy BaseClass */
233 $proxy = new $proxyClass($initializer);
234
235 $this->assertSame('1', $proxy->publicProperty);
236 $this->assertSame('2', $proxy->publicProperty);
237 $this->assertSame('3', $proxy->publicProperty);
238 }
239
240 /**
241 * Generates a proxy for the given class name, and retrieves its class name
242 *
243 * @param string $parentClassName
244 *
245 * @return string
246 */
247 private function generateProxy($parentClassName)
248 {
249 $generatedClassName = __NAMESPACE__ . '\\' . UniqueIdentifierGenerator::getIdentifier('Foo');
250 $generator = new LazyLoadingValueHolderGenerator();
251 $generatedClass = new ClassGenerator($generatedClassName);
252 $strategy = new EvaluatingGeneratorStrategy();
253
254 $generator->generate(new ReflectionClass($parentClassName), $generatedClass);
255 $strategy->generate($generatedClass);
256
257 return $generatedClassName;
258 }
259
260 /**
261 * @param string $className
262 * @param object $realInstance
263 * @param Mock $initializerMatcher
264 *
265 * @return \Closure
266 */
267 private function createInitializer($className, $realInstance, Mock $initializerMatcher = null)
268 {
269 if (null === $initializerMatcher) {
270 $initializerMatcher = $this->getMock('stdClass', array('__invoke'));
271
272 $initializerMatcher
273 ->expects($this->once())
274 ->method('__invoke')
275 ->with(
276 $this->logicalAnd(
277 $this->isInstanceOf('ProxyManager\\Proxy\\VirtualProxyInterface'),
278 $this->isInstanceOf($className)
279 ),
280 $realInstance
281 );
282 }
283
284 $initializerMatcher = $initializerMatcher ?: $this->getMock('stdClass', array('__invoke'));
285
286 return function (
287 & $wrappedObject,
288 VirtualProxyInterface $proxy,
289 $method,
290 $params,
291 & $initializer
292 ) use (
293 $initializerMatcher,
294 $realInstance
295 ) {
296 $initializer = null;
297 $wrappedObject = $realInstance;
298
299 $initializerMatcher->__invoke($proxy, $wrappedObject, $method, $params);
300 };
301 }
302
303 /**
304 * Generates a list of object | invoked method | parameters | expected result
305 *
306 * @return array
307 */
308 public function getProxyMethods()
309 {
310 $selfHintParam = new ClassWithSelfHint();
311
312 $data = array(
313 array(
314 'ProxyManagerTestAsset\\BaseClass',
315 new BaseClass(),
316 'publicMethod',
317 array(),
318 'publicMethodDefault'
319 ),
320 array(
321 'ProxyManagerTestAsset\\BaseClass',
322 new BaseClass(),
323 'publicTypeHintedMethod',
324 array(new \stdClass()),
325 'publicTypeHintedMethodDefault'
326 ),
327 array(
328 'ProxyManagerTestAsset\\BaseClass',
329 new BaseClass(),
330 'publicByReferenceMethod',
331 array(),
332 'publicByReferenceMethodDefault'
333 ),
334 array(
335 'ProxyManagerTestAsset\\BaseInterface',
336 new BaseClass(),
337 'publicMethod',
338 array(),
339 'publicMethodDefault'
340 ),
341 );
342
343 if (PHP_VERSION_ID >= 50401) {
344 // PHP < 5.4.1 misbehaves, throwing strict standards, see https://bugs.php.net/bug.php?id=60573
345 $data[] = array(
346 'ProxyManagerTestAsset\\ClassWithSelfHint',
347 new ClassWithSelfHint(),
348 'selfHintMethod',
349 array('parameter' => $selfHintParam),
350 $selfHintParam
351 );
352 }
353
354 return $data;
355 }
356
357 /**
358 * Generates proxies and instances with a public property to feed to the property accessor methods
359 *
360 * @return array
361 */
362 public function getPropertyAccessProxies()
363 {
364 $instance1 = new BaseClass();
365 $proxyName1 = $this->generateProxy(get_class($instance1));
366 $instance2 = new BaseClass();
367 $proxyName2 = $this->generateProxy(get_class($instance2));
368
369 return array(
370 array(
371 $instance1,
372 new $proxyName1($this->createInitializer('ProxyManagerTestAsset\\BaseClass', $instance1)),
373 'publicProperty',
374 'publicPropertyDefault',
375 ),
376 array(
377 $instance2,
378 unserialize(
379 serialize(new $proxyName2($this->createInitializer('ProxyManagerTestAsset\\BaseClass', $instance2)))
380 ),
381 'publicProperty',
382 'publicPropertyDefault',
383 ),
384 );
385 }
386 }
387