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

LazyLoadingValueHolderFunctionalTest.php

Zuletzt modifiziert: 09.10.2024, 12:58 - Dateigröße: 13.72 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\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