[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 /* 3 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 4 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 5 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 6 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 7 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 8 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 9 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 10 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 11 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 12 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 13 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 * 15 * This software consists of voluntary contributions made by many individuals 16 * and is licensed under the MIT license. 17 */ 18 19 namespace ProxyManagerTest\Functional; 20 21 use PHPUnit_Framework_TestCase; 22 use PHPUnit_Framework_MockObject_MockObject as Mock; 23 use ProxyManager\Generator\ClassGenerator; 24 use ProxyManager\Generator\Util\UniqueIdentifierGenerator; 25 use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy; 26 use ProxyManager\Proxy\VirtualProxyInterface; 27 use ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator; 28 use ProxyManagerTestAsset\BaseClass; 29 use ProxyManagerTestAsset\ClassWithPublicArrayProperty; 30 use ProxyManagerTestAsset\ClassWithPublicProperties; 31 use ProxyManagerTestAsset\ClassWithSelfHint; 32 use ReflectionClass; 33 34 /** 35 * Tests for {@see \ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator} produced objects 36 * 37 * @author Marco Pivetta <ocramius@gmail.com> 38 * @license MIT 39 * 40 * @group Functional 41 * @coversNothing 42 */ 43 class LazyLoadingValueHolderFunctionalTest extends PHPUnit_Framework_TestCase 44 { 45 /** 46 * @dataProvider getProxyMethods 47 */ 48 public function testMethodCalls($className, $instance, $method, $params, $expectedValue) 49 { 50 $proxyName = $this->generateProxy($className); 51 52 /* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */ 53 $proxy = new $proxyName($this->createInitializer($className, $instance)); 54 55 $this->assertFalse($proxy->isProxyInitialized()); 56 $this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params)); 57 $this->assertTrue($proxy->isProxyInitialized()); 58 $this->assertSame($instance, $proxy->getWrappedValueHolderValue()); 59 } 60 61 /** 62 * @dataProvider getProxyMethods 63 */ 64 public function testMethodCallsAfterUnSerialization($className, $instance, $method, $params, $expectedValue) 65 { 66 $proxyName = $this->generateProxy($className); 67 68 /* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */ 69 $proxy = unserialize(serialize(new $proxyName($this->createInitializer($className, $instance)))); 70 71 $this->assertTrue($proxy->isProxyInitialized()); 72 $this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params)); 73 $this->assertEquals($instance, $proxy->getWrappedValueHolderValue()); 74 } 75 76 /** 77 * @dataProvider getProxyMethods 78 */ 79 public function testMethodCallsAfterCloning($className, $instance, $method, $params, $expectedValue) 80 { 81 $proxyName = $this->generateProxy($className); 82 83 /* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */ 84 $proxy = new $proxyName($this->createInitializer($className, $instance)); 85 $cloned = clone $proxy; 86 87 $this->assertTrue($cloned->isProxyInitialized()); 88 $this->assertNotSame($proxy->getWrappedValueHolderValue(), $cloned->getWrappedValueHolderValue()); 89 $this->assertSame($expectedValue, call_user_func_array(array($cloned, $method), $params)); 90 $this->assertEquals($instance, $cloned->getWrappedValueHolderValue()); 91 } 92 93 /** 94 * @dataProvider getPropertyAccessProxies 95 */ 96 public function testPropertyReadAccess($instance, $proxy, $publicProperty, $propertyValue) 97 { 98 /* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */ 99 $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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |