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