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.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

LazyLoadingGhostFunctionalTest.php

Zuletzt modifiziert: 09.10.2024, 12:58 - Dateigröße: 15.19 KiB


 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\GhostObjectInterface;
 027  use ProxyManager\ProxyGenerator\LazyLoadingGhostGenerator;
 028  use ProxyManagerTestAsset\BaseClass;
 029  use ProxyManagerTestAsset\ClassWithPublicArrayProperty;
 030  use ProxyManagerTestAsset\ClassWithPublicProperties;
 031  use ProxyManagerTestAsset\ClassWithProtectedProperties;
 032  use ProxyManagerTestAsset\ClassWithPrivateProperties;
 033  use ProxyManagerTestAsset\ClassWithSelfHint;
 034  use ReflectionClass;
 035  use ReflectionProperty;
 036   
 037  /**
 038   * Tests for {@see \ProxyManager\ProxyGenerator\LazyLoadingGhostGenerator} produced objects
 039   *
 040   * @author Marco Pivetta <ocramius@gmail.com>
 041   * @license MIT
 042   *
 043   * @group Functional
 044   * @coversNothing
 045   */
 046  class LazyLoadingGhostFunctionalTest extends PHPUnit_Framework_TestCase
 047  {
 048      /**
 049       * @dataProvider getProxyMethods
 050       */
 051      public function testMethodCalls($className, $instance, $method, $params, $expectedValue)
 052      {
 053          $proxyName = $this->generateProxy($className);
 054   
 055          /* @var $proxy \ProxyManager\Proxy\GhostObjectInterface|BaseClass */
 056          $proxy = new $proxyName($this->createInitializer($className, $instance));
 057   
 058          $this->assertFalse($proxy->isProxyInitialized());
 059          $this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
 060          $this->assertTrue($proxy->isProxyInitialized());
 061      }
 062   
 063      /**
 064       * @dataProvider getProxyMethods
 065       */
 066      public function testMethodCallsAfterUnSerialization($className, $instance, $method, $params, $expectedValue)
 067      {
 068          $proxyName = $this->generateProxy($className);
 069   
 070          /* @var $proxy \ProxyManager\Proxy\GhostObjectInterface|BaseClass */
 071          $proxy = unserialize(serialize(new $proxyName($this->createInitializer($className, $instance))));
 072   
 073          $this->assertTrue($proxy->isProxyInitialized());
 074          $this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
 075      }
 076   
 077      /**
 078       * @dataProvider getProxyMethods
 079       */
 080      public function testMethodCallsAfterCloning($className, $instance, $method, $params, $expectedValue)
 081      {
 082          $proxyName = $this->generateProxy($className);
 083   
 084          /* @var $proxy \ProxyManager\Proxy\GhostObjectInterface|BaseClass */
 085          $proxy  = new $proxyName($this->createInitializer($className, $instance));
 086          $cloned = clone $proxy;
 087   
 088          $this->assertTrue($cloned->isProxyInitialized());
 089          $this->assertSame($expectedValue, call_user_func_array(array($cloned, $method), $params));
 090      }
 091   
 092      /**
 093       * @dataProvider getPropertyAccessProxies
 094       */
 095      public function testPropertyReadAccess($instance, $proxy, $publicProperty, $propertyValue)
 096      {
 097          /* @var $proxy \ProxyManager\Proxy\GhostObjectInterface */
 098          $this->assertSame($propertyValue, $proxy->$publicProperty);
 099          $this->assertTrue($proxy->isProxyInitialized());
 100      }
 101   
 102      /**
 103       * @dataProvider getPropertyAccessProxies
 104       */
 105      public function testPropertyWriteAccess($instance, $proxy, $publicProperty)
 106      {
 107          /* @var $proxy \ProxyManager\Proxy\GhostObjectInterface */
 108          $newValue               = uniqid();
 109          $proxy->$publicProperty = $newValue;
 110   
 111          $this->assertTrue($proxy->isProxyInitialized());
 112          $this->assertSame($newValue, $proxy->$publicProperty);
 113      }
 114   
 115      /**
 116       * @dataProvider getPropertyAccessProxies
 117       */
 118      public function testPropertyExistence($instance, $proxy, $publicProperty)
 119      {
 120          /* @var $proxy \ProxyManager\Proxy\GhostObjectInterface */
 121          $this->assertSame(isset($instance->$publicProperty), isset($proxy->$publicProperty));
 122          $this->assertTrue($proxy->isProxyInitialized());
 123      }
 124   
 125      /**
 126       * @dataProvider getPropertyAccessProxies
 127       */
 128      public function testPropertyAbsence($instance, $proxy, $publicProperty)
 129      {
 130          /* @var $proxy \ProxyManager\Proxy\GhostObjectInterface */
 131          $proxy->$publicProperty = null;
 132          $this->assertFalse(isset($proxy->$publicProperty));
 133          $this->assertTrue($proxy->isProxyInitialized());
 134      }
 135   
 136      /**
 137       * @dataProvider getPropertyAccessProxies
 138       */
 139      public function testPropertyUnset($instance, $proxy, $publicProperty)
 140      {
 141          /* @var $proxy \ProxyManager\Proxy\GhostObjectInterface */
 142   
 143          unset($proxy->$publicProperty);
 144   
 145          $this->assertTrue($proxy->isProxyInitialized());
 146          $this->assertTrue(isset($instance->$publicProperty));
 147          $this->assertFalse(isset($proxy->$publicProperty));
 148      }
 149   
 150      /**
 151       * Verifies that accessing a public property containing an array behaves like in a normal context
 152       */
 153      public function testCanWriteToArrayKeysInPublicProperty()
 154      {
 155          $instance    = new ClassWithPublicArrayProperty();
 156          $className   = get_class($instance);
 157          $initializer = $this->createInitializer($className, $instance);
 158          $proxyName   = $this->generateProxy($className);
 159          /* @var $proxy ClassWithPublicArrayProperty */
 160          $proxy       = new $proxyName($initializer);
 161   
 162          $proxy->arrayProperty['foo'] = 'bar';
 163   
 164          $this->assertSame('bar', $proxy->arrayProperty['foo']);
 165   
 166          $proxy->arrayProperty = array('tab' => 'taz');
 167   
 168          $this->assertSame(array('tab' => 'taz'), $proxy->arrayProperty);
 169      }
 170   
 171      /**
 172       * Verifies that public properties retrieved via `__get` don't get modified in the object itself
 173       */
 174      public function testWillNotModifyRetrievedPublicProperties()
 175      {
 176          $instance    = new ClassWithPublicProperties();
 177          $className   = get_class($instance);
 178          $initializer = $this->createInitializer($className, $instance);
 179          $proxyName   = $this->generateProxy($className);
 180          /* @var $proxy ClassWithPublicProperties */
 181          $proxy       = new $proxyName($initializer);
 182          $variable    = $proxy->property0;
 183   
 184          $this->assertSame('property0', $variable);
 185   
 186          $variable = 'foo';
 187   
 188          $this->assertSame('property0', $proxy->property0);
 189      }
 190   
 191      /**
 192       * Verifies that public properties references retrieved via `__get` modify in the object state
 193       */
 194      public function testWillModifyByRefRetrievedPublicProperties()
 195      {
 196          $instance    = new ClassWithPublicProperties();
 197          $className   = get_class($instance);
 198          $initializer = $this->createInitializer($className, $instance);
 199          $proxyName   = $this->generateProxy($className);
 200          /* @var $proxy ClassWithPublicProperties */
 201          $proxy       = new $proxyName($initializer);
 202          $variable    = & $proxy->property0;
 203   
 204          $this->assertSame('property0', $variable);
 205   
 206          $variable = 'foo';
 207   
 208          $this->assertSame('foo', $proxy->property0);
 209      }
 210   
 211      public function testKeepsInitializerWhenNotOverwitten()
 212      {
 213          $instance    = new BaseClass();
 214          $proxyName   = $this->generateProxy(get_class($instance));
 215          $initializer = function () {
 216          };
 217          /* @var $proxy \ProxyManager\Proxy\GhostObjectInterface */
 218          $proxy       = new $proxyName($initializer);
 219   
 220          $proxy->initializeProxy();
 221   
 222          $this->assertSame($initializer, $proxy->getProxyInitializer());
 223      }
 224   
 225      /**
 226       * Verifies that public properties are not being initialized multiple times
 227       */
 228      public function testKeepsInitializedPublicProperties()
 229      {
 230          $instance    = new BaseClass();
 231          $proxyName   = $this->generateProxy(get_class($instance));
 232          $initializer = function (BaseClass $proxy, $method, $parameters, & $initializer) {
 233              $initializer           = null;
 234              $proxy->publicProperty = 'newValue';
 235          };
 236          /* @var $proxy \ProxyManager\Proxy\GhostObjectInterface|BaseClass */
 237          $proxy       = new $proxyName($initializer);
 238   
 239          $proxy->initializeProxy();
 240          $this->assertSame('newValue', $proxy->publicProperty);
 241   
 242          $proxy->publicProperty = 'otherValue';
 243   
 244          $proxy->initializeProxy();
 245   
 246          $this->assertSame('otherValue', $proxy->publicProperty);
 247      }
 248   
 249      /**
 250       * Verifies that properties' default values are preserved
 251       */
 252      public function testPublicPropertyDefaultWillBePreserved()
 253      {
 254          $instance    = new ClassWithPublicProperties();
 255          $proxyName   = $this->generateProxy(get_class($instance));
 256          /* @var $proxy ClassWithPublicProperties */
 257          $proxy       = new $proxyName(function () {
 258          });
 259   
 260          $this->assertSame('property0', $proxy->property0);
 261      }
 262   
 263      /**
 264       * Verifies that protected properties' default values are preserved
 265       */
 266      public function testProtectedPropertyDefaultWillBePreserved()
 267      {
 268          $instance    = new ClassWithProtectedProperties();
 269          $proxyName   = $this->generateProxy(get_class($instance));
 270          /* @var $proxy ClassWithProtectedProperties */
 271          $proxy       = new $proxyName(function () {
 272          });
 273   
 274          // Check protected property via reflection
 275          $reflectionProperty = new ReflectionProperty($instance, 'property0');
 276          $reflectionProperty->setAccessible(true);
 277   
 278          $this->assertSame('property0', $reflectionProperty->getValue($proxy));
 279      }
 280   
 281      /**
 282       * Verifies that private properties' default values are preserved
 283       */
 284      public function testPrivatePropertyDefaultWillBePreserved()
 285      {
 286          $instance  = new ClassWithPrivateProperties();
 287          $proxyName = $this->generateProxy(get_class($instance));
 288          /* @var $proxy ClassWithPrivateProperties */
 289          $proxy     = new $proxyName(function () {
 290          });
 291   
 292          // Check protected property via reflection
 293          $reflectionProperty = new ReflectionProperty($instance, 'property0');
 294          $reflectionProperty->setAccessible(true);
 295   
 296          $this->assertSame('property0', $reflectionProperty->getValue($proxy));
 297      }
 298   
 299      /**
 300       * Generates a proxy for the given class name, and retrieves its class name
 301       *
 302       * @param string $parentClassName
 303       *
 304       * @return string
 305       */
 306      private function generateProxy($parentClassName)
 307      {
 308          $generatedClassName = __NAMESPACE__ . '\\' . UniqueIdentifierGenerator::getIdentifier('Foo');
 309          $generator          = new LazyLoadingGhostGenerator();
 310          $generatedClass     = new ClassGenerator($generatedClassName);
 311          $strategy           = new EvaluatingGeneratorStrategy();
 312   
 313          $generator->generate(new ReflectionClass($parentClassName), $generatedClass);
 314          $strategy->generate($generatedClass);
 315   
 316          return $generatedClassName;
 317      }
 318   
 319      /**
 320       * @param string $className
 321       * @param object $realInstance
 322       * @param Mock   $initializerMatcher
 323       *
 324       * @return \Closure
 325       */
 326      private function createInitializer($className, $realInstance, Mock $initializerMatcher = null)
 327      {
 328          if (null === $initializerMatcher) {
 329              $initializerMatcher = $this->getMock('stdClass', array('__invoke'));
 330   
 331              $initializerMatcher
 332                  ->expects($this->once())
 333                  ->method('__invoke')
 334                  ->with(
 335                      $this->logicalAnd(
 336                          $this->isInstanceOf('ProxyManager\\Proxy\\GhostObjectInterface'),
 337                          $this->isInstanceOf($className)
 338                      )
 339                  );
 340          }
 341   
 342          $initializerMatcher = $initializerMatcher ?: $this->getMock('stdClass', array('__invoke'));
 343   
 344          return function (
 345              GhostObjectInterface $proxy,
 346              $method,
 347              $params,
 348              & $initializer
 349          ) use (
 350              $initializerMatcher,
 351              $realInstance
 352          ) {
 353              $initializer     = null;
 354              $reflectionClass = new ReflectionClass($realInstance);
 355   
 356              foreach ($reflectionClass->getProperties() as $property) {
 357                  $property->setAccessible(true);
 358                  $property->setValue($proxy, $property->getValue($realInstance));
 359              }
 360   
 361              $initializerMatcher->__invoke($proxy, $method, $params);
 362          };
 363      }
 364   
 365      /**
 366       * Generates a list of object | invoked method | parameters | expected result
 367       *
 368       * @return array
 369       */
 370      public function getProxyMethods()
 371      {
 372          $selfHintParam = new ClassWithSelfHint();
 373   
 374          $data = array(
 375              array(
 376                  'ProxyManagerTestAsset\\BaseClass',
 377                  new BaseClass(),
 378                  'publicMethod',
 379                  array(),
 380                  'publicMethodDefault'
 381              ),
 382              array(
 383                  'ProxyManagerTestAsset\\BaseClass',
 384                  new BaseClass(),
 385                  'publicTypeHintedMethod',
 386                  array(new \stdClass()),
 387                  'publicTypeHintedMethodDefault'
 388              ),
 389              array(
 390                  'ProxyManagerTestAsset\\BaseClass',
 391                  new BaseClass(),
 392                  'publicByReferenceMethod',
 393                  array(),
 394                  'publicByReferenceMethodDefault'
 395              ),
 396          );
 397   
 398          if (PHP_VERSION_ID >= 50401) {
 399              // PHP < 5.4.1 misbehaves, throwing strict standards, see https://bugs.php.net/bug.php?id=60573
 400              $data[] = array(
 401                  'ProxyManagerTestAsset\\ClassWithSelfHint',
 402                  new ClassWithSelfHint(),
 403                  'selfHintMethod',
 404                  array('parameter' => $selfHintParam),
 405                  $selfHintParam
 406              );
 407          }
 408   
 409          return $data;
 410      }
 411   
 412      /**
 413       * Generates proxies and instances with a public property to feed to the property accessor methods
 414       *
 415       * @return array
 416       */
 417      public function getPropertyAccessProxies()
 418      {
 419          $instance1 = new BaseClass();
 420          $proxyName1 = $this->generateProxy(get_class($instance1));
 421          $instance2 = new BaseClass();
 422          $proxyName2 = $this->generateProxy(get_class($instance2));
 423   
 424          return array(
 425              array(
 426                  $instance1,
 427                  new $proxyName1($this->createInitializer('ProxyManagerTestAsset\\BaseClass', $instance1)),
 428                  'publicProperty',
 429                  'publicPropertyDefault',
 430              ),
 431              array(
 432                  $instance2,
 433                  unserialize(
 434                      serialize(new $proxyName2($this->createInitializer('ProxyManagerTestAsset\\BaseClass', $instance2)))
 435                  ),
 436                  'publicProperty',
 437                  'publicPropertyDefault',
 438              ),
 439          );
 440      }
 441  }
 442