[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/ -> LazyLoadingValueHolderFunctionalTest.php (source)

   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  }


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1