Ajout du FR
Ajout du FR + correction du "functions.php"
This commit is contained in:
@@ -0,0 +1,388 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
namespace ProxyManagerTest\Functional;
|
||||
|
||||
use PHPUnit_Framework_SkippedTestError;
|
||||
use PHPUnit_Framework_TestCase;
|
||||
use ProxyManager\Exception\UnsupportedProxiedClassException;
|
||||
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
|
||||
use ProxyManager\Proxy\AccessInterceptorInterface;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizerGenerator;
|
||||
use ProxyManagerTestAsset\BaseClass;
|
||||
use ProxyManagerTestAsset\ClassWithPublicArrayProperty;
|
||||
use ProxyManagerTestAsset\ClassWithPublicProperties;
|
||||
use ProxyManagerTestAsset\ClassWithSelfHint;
|
||||
use ReflectionClass;
|
||||
use ProxyManager\Generator\ClassGenerator;
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
|
||||
/**
|
||||
* Tests for {@see \ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizerGenerator} produced objects
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @group Functional
|
||||
* @coversNothing
|
||||
*/
|
||||
class AccessInterceptorScopeLocalizerFunctionalTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (! method_exists('Closure', 'bind')) {
|
||||
throw new PHPUnit_Framework_SkippedTestError(
|
||||
'PHP 5.3 doesn\'t support scope localization of private properties'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCalls($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface */
|
||||
$proxy = new $proxyName($instance);
|
||||
|
||||
$this->assertProxySynchronized($instance, $proxy);
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
|
||||
|
||||
$listener = $this->getMock('stdClass', array('__invoke'));
|
||||
$listener
|
||||
->expects($this->once())
|
||||
->method('__invoke')
|
||||
->with($proxy, $proxy, $method, $params, false);
|
||||
|
||||
$proxy->setMethodPrefixInterceptor(
|
||||
$method,
|
||||
function ($proxy, $instance, $method, $params, & $returnEarly) use ($listener) {
|
||||
$listener->__invoke($proxy, $instance, $method, $params, $returnEarly);
|
||||
}
|
||||
);
|
||||
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
|
||||
|
||||
$random = uniqid();
|
||||
|
||||
$proxy->setMethodPrefixInterceptor(
|
||||
$method,
|
||||
function ($proxy, $instance, $method, $params, & $returnEarly) use ($random) {
|
||||
$returnEarly = true;
|
||||
|
||||
return $random;
|
||||
}
|
||||
);
|
||||
|
||||
$this->assertSame($random, call_user_func_array(array($proxy, $method), $params));
|
||||
$this->assertProxySynchronized($instance, $proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCallsWithSuffixListener($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface */
|
||||
$proxy = new $proxyName($instance);
|
||||
$listener = $this->getMock('stdClass', array('__invoke'));
|
||||
$listener
|
||||
->expects($this->once())
|
||||
->method('__invoke')
|
||||
->with($proxy, $proxy, $method, $params, $expectedValue, false);
|
||||
|
||||
$proxy->setMethodSuffixInterceptor(
|
||||
$method,
|
||||
function ($proxy, $instance, $method, $params, $returnValue, & $returnEarly) use ($listener) {
|
||||
$listener->__invoke($proxy, $instance, $method, $params, $returnValue, $returnEarly);
|
||||
}
|
||||
);
|
||||
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
|
||||
|
||||
$random = uniqid();
|
||||
|
||||
$proxy->setMethodSuffixInterceptor(
|
||||
$method,
|
||||
function ($proxy, $instance, $method, $params, $returnValue, & $returnEarly) use ($random) {
|
||||
$returnEarly = true;
|
||||
|
||||
return $random;
|
||||
}
|
||||
);
|
||||
|
||||
$this->assertSame($random, call_user_func_array(array($proxy, $method), $params));
|
||||
$this->assertProxySynchronized($instance, $proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCallsAfterUnSerialization($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
/* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface */
|
||||
$proxy = unserialize(serialize(new $proxyName($instance)));
|
||||
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
|
||||
$this->assertProxySynchronized($instance, $proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCallsAfterCloning($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface */
|
||||
$proxy = new $proxyName($instance);
|
||||
$cloned = clone $proxy;
|
||||
|
||||
$this->assertProxySynchronized($instance, $proxy);
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($cloned, $method), $params));
|
||||
$this->assertProxySynchronized($instance, $proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyReadAccess($instance, $proxy, $publicProperty, $propertyValue)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface */
|
||||
$this->assertSame($propertyValue, $proxy->$publicProperty);
|
||||
$this->assertProxySynchronized($instance, $proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyWriteAccess($instance, $proxy, $publicProperty)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface */
|
||||
$newValue = uniqid();
|
||||
$proxy->$publicProperty = $newValue;
|
||||
|
||||
$this->assertSame($newValue, $proxy->$publicProperty);
|
||||
$this->assertProxySynchronized($instance, $proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyExistence($instance, $proxy, $publicProperty)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface */
|
||||
$this->assertSame(isset($instance->$publicProperty), isset($proxy->$publicProperty));
|
||||
$this->assertProxySynchronized($instance, $proxy);
|
||||
|
||||
$instance->$publicProperty = null;
|
||||
$this->assertFalse(isset($proxy->$publicProperty));
|
||||
$this->assertProxySynchronized($instance, $proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyUnset($instance, $proxy, $publicProperty)
|
||||
{
|
||||
$this->markTestSkipped('It is currently not possible to synchronize properties un-setting');
|
||||
/* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface */
|
||||
unset($proxy->$publicProperty);
|
||||
|
||||
$this->assertFalse(isset($instance->$publicProperty));
|
||||
$this->assertFalse(isset($proxy->$publicProperty));
|
||||
$this->assertProxySynchronized($instance, $proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that accessing a public property containing an array behaves like in a normal context
|
||||
*/
|
||||
public function testCanWriteToArrayKeysInPublicProperty()
|
||||
{
|
||||
$instance = new ClassWithPublicArrayProperty();
|
||||
$className = get_class($instance);
|
||||
$proxyName = $this->generateProxy($className);
|
||||
/* @var $proxy ClassWithPublicArrayProperty */
|
||||
$proxy = new $proxyName($instance);
|
||||
|
||||
$proxy->arrayProperty['foo'] = 'bar';
|
||||
|
||||
$this->assertSame('bar', $proxy->arrayProperty['foo']);
|
||||
|
||||
$proxy->arrayProperty = array('tab' => 'taz');
|
||||
|
||||
$this->assertSame(array('tab' => 'taz'), $proxy->arrayProperty);
|
||||
$this->assertProxySynchronized($instance, $proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that public properties retrieved via `__get` don't get modified in the object state
|
||||
*/
|
||||
public function testWillNotModifyRetrievedPublicProperties()
|
||||
{
|
||||
$instance = new ClassWithPublicProperties();
|
||||
$className = get_class($instance);
|
||||
$proxyName = $this->generateProxy($className);
|
||||
/* @var $proxy ClassWithPublicProperties */
|
||||
$proxy = new $proxyName($instance);
|
||||
$variable = $proxy->property0;
|
||||
|
||||
$this->assertSame('property0', $variable);
|
||||
|
||||
$variable = 'foo';
|
||||
|
||||
$this->assertSame('property0', $proxy->property0);
|
||||
$this->assertProxySynchronized($instance, $proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that public properties references retrieved via `__get` modify in the object state
|
||||
*/
|
||||
public function testWillModifyByRefRetrievedPublicProperties()
|
||||
{
|
||||
$instance = new ClassWithPublicProperties();
|
||||
$className = get_class($instance);
|
||||
$proxyName = $this->generateProxy($className);
|
||||
/* @var $proxy ClassWithPublicProperties */
|
||||
$proxy = new $proxyName($instance);
|
||||
$variable = & $proxy->property0;
|
||||
|
||||
$this->assertSame('property0', $variable);
|
||||
|
||||
$variable = 'foo';
|
||||
|
||||
$this->assertSame('foo', $proxy->property0);
|
||||
$this->assertProxySynchronized($instance, $proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a proxy for the given class name, and retrieves its class name
|
||||
*
|
||||
* @param string $parentClassName
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws UnsupportedProxiedClassException
|
||||
*/
|
||||
private function generateProxy($parentClassName)
|
||||
{
|
||||
$generatedClassName = __NAMESPACE__ . '\\' . UniqueIdentifierGenerator::getIdentifier('Foo');
|
||||
$generator = new AccessInterceptorScopeLocalizerGenerator();
|
||||
$generatedClass = new ClassGenerator($generatedClassName);
|
||||
$strategy = new EvaluatingGeneratorStrategy();
|
||||
|
||||
$generator->generate(new ReflectionClass($parentClassName), $generatedClass);
|
||||
$strategy->generate($generatedClass);
|
||||
|
||||
return $generatedClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a list of object | invoked method | parameters | expected result
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProxyMethods()
|
||||
{
|
||||
$selfHintParam = new ClassWithSelfHint();
|
||||
|
||||
$data = array(
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseClass',
|
||||
new BaseClass(),
|
||||
'publicMethod',
|
||||
array(),
|
||||
'publicMethodDefault'
|
||||
),
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseClass',
|
||||
new BaseClass(),
|
||||
'publicTypeHintedMethod',
|
||||
array('param' => new \stdClass()),
|
||||
'publicTypeHintedMethodDefault'
|
||||
),
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseClass',
|
||||
new BaseClass(),
|
||||
'publicByReferenceMethod',
|
||||
array(),
|
||||
'publicByReferenceMethodDefault'
|
||||
),
|
||||
);
|
||||
|
||||
if (PHP_VERSION_ID >= 50401) {
|
||||
// PHP < 5.4.1 misbehaves, throwing strict standards, see https://bugs.php.net/bug.php?id=60573
|
||||
$data[] = array(
|
||||
'ProxyManagerTestAsset\\ClassWithSelfHint',
|
||||
new ClassWithSelfHint(),
|
||||
'selfHintMethod',
|
||||
array('parameter' => $selfHintParam),
|
||||
$selfHintParam
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates proxies and instances with a public property to feed to the property accessor methods
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPropertyAccessProxies()
|
||||
{
|
||||
$instance1 = new BaseClass();
|
||||
$proxyName1 = $this->generateProxy(get_class($instance1));
|
||||
|
||||
return array(
|
||||
array(
|
||||
$instance1,
|
||||
new $proxyName1($instance1),
|
||||
'publicProperty',
|
||||
'publicPropertyDefault',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $instance
|
||||
* @param AccessInterceptorInterface $proxy
|
||||
*/
|
||||
private function assertProxySynchronized($instance, AccessInterceptorInterface $proxy)
|
||||
{
|
||||
$reflectionClass = new ReflectionClass($instance);
|
||||
|
||||
foreach ($reflectionClass->getProperties() as $property) {
|
||||
$property->setAccessible(true);
|
||||
|
||||
$this->assertSame(
|
||||
$property->getValue($instance),
|
||||
$property->getValue($proxy),
|
||||
'Property "' . $property->getName() . '" is synchronized between instance and proxy'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,360 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
namespace ProxyManagerTest\Functional;
|
||||
|
||||
use PHPUnit_Framework_TestCase;
|
||||
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
|
||||
use ProxyManager\ProxyGenerator\AccessInterceptorValueHolderGenerator;
|
||||
use ProxyManagerTestAsset\BaseClass;
|
||||
use ProxyManagerTestAsset\ClassWithPublicArrayProperty;
|
||||
use ProxyManagerTestAsset\ClassWithPublicProperties;
|
||||
use ProxyManagerTestAsset\ClassWithSelfHint;
|
||||
use ReflectionClass;
|
||||
use ProxyManager\Generator\ClassGenerator;
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
|
||||
/**
|
||||
* Tests for {@see \ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator} produced objects
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @group Functional
|
||||
* @coversNothing
|
||||
*/
|
||||
class AccessInterceptorValueHolderFunctionalTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCalls($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface */
|
||||
$proxy = new $proxyName($instance);
|
||||
|
||||
$this->assertSame($instance, $proxy->getWrappedValueHolderValue());
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
|
||||
|
||||
$listener = $this->getMock('stdClass', array('__invoke'));
|
||||
$listener
|
||||
->expects($this->once())
|
||||
->method('__invoke')
|
||||
->with($proxy, $instance, $method, $params, false);
|
||||
|
||||
$proxy->setMethodPrefixInterceptor(
|
||||
$method,
|
||||
function ($proxy, $instance, $method, $params, & $returnEarly) use ($listener) {
|
||||
$listener->__invoke($proxy, $instance, $method, $params, $returnEarly);
|
||||
}
|
||||
);
|
||||
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
|
||||
|
||||
$random = uniqid();
|
||||
|
||||
$proxy->setMethodPrefixInterceptor(
|
||||
$method,
|
||||
function ($proxy, $instance, $method, $params, & $returnEarly) use ($random) {
|
||||
$returnEarly = true;
|
||||
|
||||
return $random;
|
||||
}
|
||||
);
|
||||
|
||||
$this->assertSame($random, call_user_func_array(array($proxy, $method), $params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCallsWithSuffixListener($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface */
|
||||
$proxy = new $proxyName($instance);
|
||||
$listener = $this->getMock('stdClass', array('__invoke'));
|
||||
$listener
|
||||
->expects($this->once())
|
||||
->method('__invoke')
|
||||
->with($proxy, $instance, $method, $params, $expectedValue, false);
|
||||
|
||||
$proxy->setMethodSuffixInterceptor(
|
||||
$method,
|
||||
function ($proxy, $instance, $method, $params, $returnValue, & $returnEarly) use ($listener) {
|
||||
$listener->__invoke($proxy, $instance, $method, $params, $returnValue, $returnEarly);
|
||||
}
|
||||
);
|
||||
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
|
||||
|
||||
$random = uniqid();
|
||||
|
||||
$proxy->setMethodSuffixInterceptor(
|
||||
$method,
|
||||
function ($proxy, $instance, $method, $params, $returnValue, & $returnEarly) use ($random) {
|
||||
$returnEarly = true;
|
||||
|
||||
return $random;
|
||||
}
|
||||
);
|
||||
|
||||
$this->assertSame($random, call_user_func_array(array($proxy, $method), $params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCallsAfterUnSerialization($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
/* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface */
|
||||
$proxy = unserialize(serialize(new $proxyName($instance)));
|
||||
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
|
||||
$this->assertEquals($instance, $proxy->getWrappedValueHolderValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCallsAfterCloning($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface */
|
||||
$proxy = new $proxyName($instance);
|
||||
$cloned = clone $proxy;
|
||||
|
||||
$this->assertNotSame($proxy->getWrappedValueHolderValue(), $cloned->getWrappedValueHolderValue());
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($cloned, $method), $params));
|
||||
$this->assertEquals($instance, $cloned->getWrappedValueHolderValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyReadAccess($instance, $proxy, $publicProperty, $propertyValue)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface */
|
||||
$this->assertSame($propertyValue, $proxy->$publicProperty);
|
||||
$this->assertEquals($instance, $proxy->getWrappedValueHolderValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyWriteAccess($instance, $proxy, $publicProperty)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface */
|
||||
$newValue = uniqid();
|
||||
$proxy->$publicProperty = $newValue;
|
||||
|
||||
$this->assertSame($newValue, $proxy->$publicProperty);
|
||||
$this->assertSame($newValue, $proxy->getWrappedValueHolderValue()->$publicProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyExistence($instance, $proxy, $publicProperty)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface */
|
||||
$this->assertSame(isset($instance->$publicProperty), isset($proxy->$publicProperty));
|
||||
$this->assertEquals($instance, $proxy->getWrappedValueHolderValue());
|
||||
|
||||
$proxy->getWrappedValueHolderValue()->$publicProperty = null;
|
||||
$this->assertFalse(isset($proxy->$publicProperty));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyUnset($instance, $proxy, $publicProperty)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\AccessInterceptorInterface|\ProxyManager\Proxy\ValueHolderInterface */
|
||||
$instance = $proxy->getWrappedValueHolderValue() ? $proxy->getWrappedValueHolderValue() : $instance;
|
||||
unset($proxy->$publicProperty);
|
||||
|
||||
$this->assertFalse(isset($instance->$publicProperty));
|
||||
$this->assertFalse(isset($proxy->$publicProperty));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that accessing a public property containing an array behaves like in a normal context
|
||||
*/
|
||||
public function testCanWriteToArrayKeysInPublicProperty()
|
||||
{
|
||||
$instance = new ClassWithPublicArrayProperty();
|
||||
$className = get_class($instance);
|
||||
$proxyName = $this->generateProxy($className);
|
||||
/* @var $proxy ClassWithPublicArrayProperty */
|
||||
$proxy = new $proxyName($instance);
|
||||
|
||||
$proxy->arrayProperty['foo'] = 'bar';
|
||||
|
||||
$this->assertSame('bar', $proxy->arrayProperty['foo']);
|
||||
|
||||
$proxy->arrayProperty = array('tab' => 'taz');
|
||||
|
||||
$this->assertSame(array('tab' => 'taz'), $proxy->arrayProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that public properties retrieved via `__get` don't get modified in the object state
|
||||
*/
|
||||
public function testWillNotModifyRetrievedPublicProperties()
|
||||
{
|
||||
$instance = new ClassWithPublicProperties();
|
||||
$className = get_class($instance);
|
||||
$proxyName = $this->generateProxy($className);
|
||||
/* @var $proxy ClassWithPublicProperties */
|
||||
$proxy = new $proxyName($instance);
|
||||
$variable = $proxy->property0;
|
||||
|
||||
$this->assertSame('property0', $variable);
|
||||
|
||||
$variable = 'foo';
|
||||
|
||||
$this->assertSame('property0', $proxy->property0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that public properties references retrieved via `__get` modify in the object state
|
||||
*/
|
||||
public function testWillModifyByRefRetrievedPublicProperties()
|
||||
{
|
||||
$instance = new ClassWithPublicProperties();
|
||||
$className = get_class($instance);
|
||||
$proxyName = $this->generateProxy($className);
|
||||
/* @var $proxy ClassWithPublicProperties */
|
||||
$proxy = new $proxyName($instance);
|
||||
$variable = & $proxy->property0;
|
||||
|
||||
$this->assertSame('property0', $variable);
|
||||
|
||||
$variable = 'foo';
|
||||
|
||||
$this->assertSame('foo', $proxy->property0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a proxy for the given class name, and retrieves its class name
|
||||
*
|
||||
* @param string $parentClassName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateProxy($parentClassName)
|
||||
{
|
||||
$generatedClassName = __NAMESPACE__ . '\\' . UniqueIdentifierGenerator::getIdentifier('Foo');
|
||||
$generator = new AccessInterceptorValueHolderGenerator();
|
||||
$generatedClass = new ClassGenerator($generatedClassName);
|
||||
$strategy = new EvaluatingGeneratorStrategy();
|
||||
|
||||
$generator->generate(new ReflectionClass($parentClassName), $generatedClass);
|
||||
$strategy->generate($generatedClass);
|
||||
|
||||
return $generatedClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a list of object | invoked method | parameters | expected result
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProxyMethods()
|
||||
{
|
||||
$selfHintParam = new ClassWithSelfHint();
|
||||
|
||||
$data = array(
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseClass',
|
||||
new BaseClass(),
|
||||
'publicMethod',
|
||||
array(),
|
||||
'publicMethodDefault'
|
||||
),
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseClass',
|
||||
new BaseClass(),
|
||||
'publicTypeHintedMethod',
|
||||
array('param' => new \stdClass()),
|
||||
'publicTypeHintedMethodDefault'
|
||||
),
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseClass',
|
||||
new BaseClass(),
|
||||
'publicByReferenceMethod',
|
||||
array(),
|
||||
'publicByReferenceMethodDefault'
|
||||
),
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseInterface',
|
||||
new BaseClass(),
|
||||
'publicMethod',
|
||||
array(),
|
||||
'publicMethodDefault'
|
||||
),
|
||||
);
|
||||
|
||||
if (PHP_VERSION_ID >= 50401) {
|
||||
// PHP < 5.4.1 misbehaves, throwing strict standards, see https://bugs.php.net/bug.php?id=60573
|
||||
$data[] = array(
|
||||
'ProxyManagerTestAsset\\ClassWithSelfHint',
|
||||
new ClassWithSelfHint(),
|
||||
'selfHintMethod',
|
||||
array('parameter' => $selfHintParam),
|
||||
$selfHintParam
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates proxies and instances with a public property to feed to the property accessor methods
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPropertyAccessProxies()
|
||||
{
|
||||
$instance1 = new BaseClass();
|
||||
$proxyName1 = $this->generateProxy(get_class($instance1));
|
||||
$instance2 = new BaseClass();
|
||||
$proxyName2 = $this->generateProxy(get_class($instance2));
|
||||
|
||||
return array(
|
||||
array(
|
||||
$instance1,
|
||||
new $proxyName1($instance1),
|
||||
'publicProperty',
|
||||
'publicPropertyDefault',
|
||||
),
|
||||
array(
|
||||
$instance2,
|
||||
unserialize(serialize(new $proxyName2($instance2))),
|
||||
'publicProperty',
|
||||
'publicPropertyDefault',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
196
vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/BaseLazyLoadingPerformanceTest.php
vendored
Normal file
196
vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/BaseLazyLoadingPerformanceTest.php
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
namespace ProxyManagerTest\Functional;
|
||||
|
||||
/**
|
||||
* Base performance test logic for lazy loading proxies
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @group Performance
|
||||
* @coversNothing
|
||||
*/
|
||||
abstract class BaseLazyLoadingPerformanceTest extends BasePerformanceTest
|
||||
{
|
||||
/**
|
||||
* @param string $className
|
||||
* @param object[] $instances
|
||||
* @param \ProxyManager\Proxy\LazyLoadingInterface[] $proxies
|
||||
* @param string $methodName
|
||||
* @param array $parameters
|
||||
*/
|
||||
protected function profileMethodAccess($className, array $instances, array $proxies, $methodName, array $parameters)
|
||||
{
|
||||
$iterations = count($instances);
|
||||
|
||||
$this->startCapturing();
|
||||
|
||||
foreach ($instances as $instance) {
|
||||
call_user_func_array(array($instance, $methodName), $parameters);
|
||||
}
|
||||
|
||||
$baseProfile = $this->endCapturing(
|
||||
$iterations . ' calls to ' . $className . '#' . $methodName . ': %fms / %fKb'
|
||||
);
|
||||
$this->startCapturing();
|
||||
|
||||
foreach ($proxies as $proxy) {
|
||||
call_user_func_array(array($proxy, $methodName), $parameters);
|
||||
}
|
||||
|
||||
$proxyProfile = $this->endCapturing(
|
||||
$iterations . ' calls to proxied ' . $className . '#' . $methodName . ': %fms / %fKb'
|
||||
);
|
||||
$this->compareProfile($baseProfile, $proxyProfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @param object[] $instances
|
||||
* @param \ProxyManager\Proxy\LazyLoadingInterface[] $proxies
|
||||
* @param string $property
|
||||
*/
|
||||
protected function profilePropertyWrites($className, array $instances, array $proxies, $property)
|
||||
{
|
||||
$iterations = count($instances);
|
||||
|
||||
$this->startCapturing();
|
||||
|
||||
foreach ($instances as $instance) {
|
||||
$instance->$property = 'foo';
|
||||
}
|
||||
|
||||
$baseProfile = $this->endCapturing(
|
||||
$iterations . ' writes of ' . $className . '::' . $property . ': %fms / %fKb'
|
||||
);
|
||||
$this->startCapturing();
|
||||
|
||||
foreach ($proxies as $proxy) {
|
||||
$proxy->$property = 'foo';
|
||||
}
|
||||
|
||||
$proxyProfile = $this->endCapturing(
|
||||
$iterations . ' writes of proxied ' . $className . '::' . $property . ': %fms / %fKb'
|
||||
);
|
||||
$this->compareProfile($baseProfile, $proxyProfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @param object[] $instances
|
||||
* @param \ProxyManager\Proxy\LazyLoadingInterface[] $proxies
|
||||
* @param string $property
|
||||
*/
|
||||
protected function profilePropertyReads($className, array $instances, array $proxies, $property)
|
||||
{
|
||||
$iterations = count($instances);
|
||||
|
||||
$this->startCapturing();
|
||||
|
||||
foreach ($instances as $instance) {
|
||||
$instance->$property;
|
||||
}
|
||||
|
||||
$baseProfile = $this->endCapturing(
|
||||
$iterations . ' reads of ' . $className . '::' . $property . ': %fms / %fKb'
|
||||
);
|
||||
$this->startCapturing();
|
||||
|
||||
foreach ($proxies as $proxy) {
|
||||
$proxy->$property;
|
||||
}
|
||||
|
||||
$proxyProfile = $this->endCapturing(
|
||||
$iterations . ' reads of proxied ' . $className . '::' . $property . ': %fms / %fKb'
|
||||
);
|
||||
$this->compareProfile($baseProfile, $proxyProfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @param object[] $instances
|
||||
* @param \ProxyManager\Proxy\LazyLoadingInterface[] $proxies
|
||||
* @param string $property
|
||||
*/
|
||||
protected function profilePropertyIsset($className, array $instances, array $proxies, $property)
|
||||
{
|
||||
$iterations = count($instances);
|
||||
|
||||
$this->startCapturing();
|
||||
|
||||
foreach ($instances as $instance) {
|
||||
isset($instance->$property);
|
||||
}
|
||||
|
||||
$baseProfile = $this->endCapturing(
|
||||
$iterations . ' isset of ' . $className . '::' . $property . ': %fms / %fKb'
|
||||
);
|
||||
$this->startCapturing();
|
||||
|
||||
foreach ($proxies as $proxy) {
|
||||
isset($proxy->$property);
|
||||
}
|
||||
|
||||
$proxyProfile = $this->endCapturing(
|
||||
$iterations . ' isset of proxied ' . $className . '::' . $property . ': %fms / %fKb'
|
||||
);
|
||||
$this->compareProfile($baseProfile, $proxyProfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @param object[] $instances
|
||||
* @param \ProxyManager\Proxy\LazyLoadingInterface[] $proxies
|
||||
* @param string $property
|
||||
*/
|
||||
protected function profilePropertyUnset($className, array $instances, array $proxies, $property)
|
||||
{
|
||||
$iterations = count($instances);
|
||||
|
||||
$this->startCapturing();
|
||||
|
||||
foreach ($instances as $instance) {
|
||||
unset($instance->$property);
|
||||
}
|
||||
|
||||
$baseProfile = $this->endCapturing(
|
||||
$iterations . ' unset of ' . $className . '::' . $property . ': %fms / %fKb'
|
||||
);
|
||||
$this->startCapturing();
|
||||
|
||||
foreach ($proxies as $proxy) {
|
||||
unset($proxy->$property);
|
||||
}
|
||||
|
||||
$proxyProfile = $this->endCapturing(
|
||||
$iterations . ' unset of proxied ' . $className . '::' . $property . ': %fms / %fKb'
|
||||
);
|
||||
$this->compareProfile($baseProfile, $proxyProfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a proxy for the given class name, and retrieves its class name
|
||||
*
|
||||
* @param string $parentClassName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function generateProxy($parentClassName);
|
||||
}
|
||||
101
vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/BasePerformanceTest.php
vendored
Normal file
101
vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/BasePerformanceTest.php
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
namespace ProxyManagerTest\Functional;
|
||||
|
||||
use PHPUnit_Framework_TestCase;
|
||||
|
||||
/**
|
||||
* Base performance test logic
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @group Performance
|
||||
* @coversNothing
|
||||
*/
|
||||
abstract class BasePerformanceTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var float time when last capture was started
|
||||
*/
|
||||
private $startTime = 0;
|
||||
|
||||
/**
|
||||
* @var int bytes when last capture was started
|
||||
*/
|
||||
private $startMemory = 0;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
$header = "Performance test - " . get_called_class() . ":";
|
||||
|
||||
echo "\n\n" . str_repeat('=', strlen($header)) . "\n" . $header . "\n\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Start profiler snapshot
|
||||
*/
|
||||
protected function startCapturing()
|
||||
{
|
||||
$this->startMemory = memory_get_usage();
|
||||
$this->startTime = microtime(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Echo current profiler output
|
||||
*
|
||||
* @param string $messageTemplate
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function endCapturing($messageTemplate)
|
||||
{
|
||||
$time = microtime(true) - $this->startTime;
|
||||
$memory = memory_get_usage() - $this->startMemory;
|
||||
|
||||
if (gc_enable()) {
|
||||
gc_collect_cycles();
|
||||
}
|
||||
|
||||
echo sprintf($messageTemplate, $time, $memory / 1024) . "\n";
|
||||
|
||||
return array(
|
||||
'time' => $time,
|
||||
'memory' => $memory
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display comparison between two profiles
|
||||
*
|
||||
* @param array $baseProfile
|
||||
* @param array $proxyProfile
|
||||
*/
|
||||
protected function compareProfile(array $baseProfile, array $proxyProfile)
|
||||
{
|
||||
$baseMemory = max(1, $baseProfile['memory']);
|
||||
$timeOverhead = (($proxyProfile['time'] / $baseProfile['time']) - 1) * 100;
|
||||
$memoryOverhead = (($proxyProfile['memory'] / $baseMemory) - 1) * 100;
|
||||
|
||||
echo sprintf('Comparison time / memory: %.2f%% / %.2f%%', $timeOverhead, $memoryOverhead) . "\n\n";
|
||||
}
|
||||
}
|
||||
171
vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/FatalPreventionFunctionalTest.php
vendored
Normal file
171
vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/FatalPreventionFunctionalTest.php
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
namespace ProxyManagerTest\Functional;
|
||||
|
||||
use PHPUnit_Framework_TestCase;
|
||||
use PHPUnit_Util_PHP;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* Verifies that proxy-manager will not attempt to `eval()` code that will cause fatal errors
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @group Functional
|
||||
* @coversNothing
|
||||
*/
|
||||
class FatalPreventionFunctionalTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $template = <<<'PHP'
|
||||
<?php
|
||||
|
||||
require_once %s;
|
||||
|
||||
$className = %s;
|
||||
$generatedClass = new ProxyManager\Generator\ClassGenerator(uniqid('generated'));
|
||||
$generatorStrategy = new ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy();
|
||||
$classGenerator = new %s;
|
||||
$classSignatureGenerator = new ProxyManager\Signature\ClassSignatureGenerator(
|
||||
new ProxyManager\Signature\SignatureGenerator()
|
||||
);
|
||||
|
||||
try {
|
||||
$classGenerator->generate(new ReflectionClass($className), $generatedClass);
|
||||
$classSignatureGenerator->addSignature($generatedClass, array('eval tests'));
|
||||
$generatorStrategy->generate($generatedClass);
|
||||
} catch (ProxyManager\Exception\ExceptionInterface $e) {
|
||||
} catch (ReflectionException $e) {
|
||||
}
|
||||
|
||||
echo 'SUCCESS: ' . %s;
|
||||
PHP;
|
||||
|
||||
/**
|
||||
* Verifies that code generation and evaluation will not cause fatals with any given class
|
||||
*
|
||||
* @param string $generatorClass an instantiable class (no arguments) implementing
|
||||
* the {@see \ProxyManager\ProxyGenerator\ProxyGeneratorInterface}
|
||||
* @param string $className a valid (existing/autoloadable) class name
|
||||
*
|
||||
* @dataProvider getTestedClasses
|
||||
*/
|
||||
public function testCodeGeneration($generatorClass, $className)
|
||||
{
|
||||
if (defined('HHVM_VERSION')) {
|
||||
$this->markTestSkipped('HHVM is just too slow for this kind of test right now.');
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID < 50401) {
|
||||
$this->markTestSkipped('Can\'t run this test suite on php < 5.4.1');
|
||||
}
|
||||
|
||||
$runner = PHPUnit_Util_PHP::factory();
|
||||
|
||||
$code = sprintf(
|
||||
$this->template,
|
||||
var_export(realpath(__DIR__ . '/../../../vendor/autoload.php'), true),
|
||||
var_export($className, true),
|
||||
$generatorClass,
|
||||
var_export($className, true)
|
||||
);
|
||||
|
||||
$result = $runner->runJob($code, array('-n'));
|
||||
|
||||
if (('SUCCESS: ' . $className) !== $result['stdout']) {
|
||||
$this->fail(sprintf(
|
||||
"Crashed with class '%s' and generator '%s'.\n\nStdout:\n%s\nStderr:\n%s\nGenerated code:\n%s'",
|
||||
$generatorClass,
|
||||
$className,
|
||||
$result['stdout'],
|
||||
$result['stderr'],
|
||||
$code
|
||||
));
|
||||
}
|
||||
|
||||
$this->assertSame('SUCCESS: ' . $className, $result['stdout']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[][]
|
||||
*/
|
||||
public function getTestedClasses()
|
||||
{
|
||||
$that = $this;
|
||||
|
||||
return call_user_func_array(
|
||||
'array_merge',
|
||||
array_map(
|
||||
function ($generator) use ($that) {
|
||||
return array_map(
|
||||
function ($class) use ($generator) {
|
||||
return array($generator, $class);
|
||||
},
|
||||
$that->getProxyTestedClasses()
|
||||
);
|
||||
},
|
||||
array(
|
||||
'ProxyManager\\ProxyGenerator\\AccessInterceptorScopeLocalizerGenerator',
|
||||
'ProxyManager\\ProxyGenerator\\AccessInterceptorValueHolderGenerator',
|
||||
'ProxyManager\\ProxyGenerator\\LazyLoadingGhostGenerator',
|
||||
'ProxyManager\\ProxyGenerator\\LazyLoadingValueHolderGenerator',
|
||||
'ProxyManager\\ProxyGenerator\\NullObjectGenerator',
|
||||
'ProxyManager\\ProxyGenerator\\RemoteObjectGenerator',
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private (public only for PHP 5.3 compatibility)
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getProxyTestedClasses()
|
||||
{
|
||||
$skippedPaths = array(
|
||||
realpath(__DIR__ . '/../../src'),
|
||||
realpath(__DIR__ . '/../../vendor'),
|
||||
realpath(__DIR__ . '/../../tests/ProxyManagerTest'),
|
||||
);
|
||||
|
||||
return array_filter(
|
||||
get_declared_classes(),
|
||||
function ($className) use ($skippedPaths) {
|
||||
$reflectionClass = new ReflectionClass($className);
|
||||
$fileName = $reflectionClass->getFileName();
|
||||
|
||||
if (! $fileName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$realPath = realpath($fileName);
|
||||
|
||||
foreach ($skippedPaths as $skippedPath) {
|
||||
if (0 === strpos($realPath, $skippedPath)) {
|
||||
// skip classes defined within ProxyManager, vendor or the test suite
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
441
vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/LazyLoadingGhostFunctionalTest.php
vendored
Normal file
441
vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/LazyLoadingGhostFunctionalTest.php
vendored
Normal file
@@ -0,0 +1,441 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
namespace ProxyManagerTest\Functional;
|
||||
|
||||
use PHPUnit_Framework_TestCase;
|
||||
use PHPUnit_Framework_MockObject_MockObject as Mock;
|
||||
use ProxyManager\Generator\ClassGenerator;
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
|
||||
use ProxyManager\Proxy\GhostObjectInterface;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhostGenerator;
|
||||
use ProxyManagerTestAsset\BaseClass;
|
||||
use ProxyManagerTestAsset\ClassWithPublicArrayProperty;
|
||||
use ProxyManagerTestAsset\ClassWithPublicProperties;
|
||||
use ProxyManagerTestAsset\ClassWithProtectedProperties;
|
||||
use ProxyManagerTestAsset\ClassWithPrivateProperties;
|
||||
use ProxyManagerTestAsset\ClassWithSelfHint;
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* Tests for {@see \ProxyManager\ProxyGenerator\LazyLoadingGhostGenerator} produced objects
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @group Functional
|
||||
* @coversNothing
|
||||
*/
|
||||
class LazyLoadingGhostFunctionalTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCalls($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\GhostObjectInterface|BaseClass */
|
||||
$proxy = new $proxyName($this->createInitializer($className, $instance));
|
||||
|
||||
$this->assertFalse($proxy->isProxyInitialized());
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
|
||||
$this->assertTrue($proxy->isProxyInitialized());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCallsAfterUnSerialization($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\GhostObjectInterface|BaseClass */
|
||||
$proxy = unserialize(serialize(new $proxyName($this->createInitializer($className, $instance))));
|
||||
|
||||
$this->assertTrue($proxy->isProxyInitialized());
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCallsAfterCloning($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\GhostObjectInterface|BaseClass */
|
||||
$proxy = new $proxyName($this->createInitializer($className, $instance));
|
||||
$cloned = clone $proxy;
|
||||
|
||||
$this->assertTrue($cloned->isProxyInitialized());
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($cloned, $method), $params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyReadAccess($instance, $proxy, $publicProperty, $propertyValue)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\GhostObjectInterface */
|
||||
$this->assertSame($propertyValue, $proxy->$publicProperty);
|
||||
$this->assertTrue($proxy->isProxyInitialized());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyWriteAccess($instance, $proxy, $publicProperty)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\GhostObjectInterface */
|
||||
$newValue = uniqid();
|
||||
$proxy->$publicProperty = $newValue;
|
||||
|
||||
$this->assertTrue($proxy->isProxyInitialized());
|
||||
$this->assertSame($newValue, $proxy->$publicProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyExistence($instance, $proxy, $publicProperty)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\GhostObjectInterface */
|
||||
$this->assertSame(isset($instance->$publicProperty), isset($proxy->$publicProperty));
|
||||
$this->assertTrue($proxy->isProxyInitialized());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyAbsence($instance, $proxy, $publicProperty)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\GhostObjectInterface */
|
||||
$proxy->$publicProperty = null;
|
||||
$this->assertFalse(isset($proxy->$publicProperty));
|
||||
$this->assertTrue($proxy->isProxyInitialized());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyUnset($instance, $proxy, $publicProperty)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\GhostObjectInterface */
|
||||
|
||||
unset($proxy->$publicProperty);
|
||||
|
||||
$this->assertTrue($proxy->isProxyInitialized());
|
||||
$this->assertTrue(isset($instance->$publicProperty));
|
||||
$this->assertFalse(isset($proxy->$publicProperty));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that accessing a public property containing an array behaves like in a normal context
|
||||
*/
|
||||
public function testCanWriteToArrayKeysInPublicProperty()
|
||||
{
|
||||
$instance = new ClassWithPublicArrayProperty();
|
||||
$className = get_class($instance);
|
||||
$initializer = $this->createInitializer($className, $instance);
|
||||
$proxyName = $this->generateProxy($className);
|
||||
/* @var $proxy ClassWithPublicArrayProperty */
|
||||
$proxy = new $proxyName($initializer);
|
||||
|
||||
$proxy->arrayProperty['foo'] = 'bar';
|
||||
|
||||
$this->assertSame('bar', $proxy->arrayProperty['foo']);
|
||||
|
||||
$proxy->arrayProperty = array('tab' => 'taz');
|
||||
|
||||
$this->assertSame(array('tab' => 'taz'), $proxy->arrayProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that public properties retrieved via `__get` don't get modified in the object itself
|
||||
*/
|
||||
public function testWillNotModifyRetrievedPublicProperties()
|
||||
{
|
||||
$instance = new ClassWithPublicProperties();
|
||||
$className = get_class($instance);
|
||||
$initializer = $this->createInitializer($className, $instance);
|
||||
$proxyName = $this->generateProxy($className);
|
||||
/* @var $proxy ClassWithPublicProperties */
|
||||
$proxy = new $proxyName($initializer);
|
||||
$variable = $proxy->property0;
|
||||
|
||||
$this->assertSame('property0', $variable);
|
||||
|
||||
$variable = 'foo';
|
||||
|
||||
$this->assertSame('property0', $proxy->property0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that public properties references retrieved via `__get` modify in the object state
|
||||
*/
|
||||
public function testWillModifyByRefRetrievedPublicProperties()
|
||||
{
|
||||
$instance = new ClassWithPublicProperties();
|
||||
$className = get_class($instance);
|
||||
$initializer = $this->createInitializer($className, $instance);
|
||||
$proxyName = $this->generateProxy($className);
|
||||
/* @var $proxy ClassWithPublicProperties */
|
||||
$proxy = new $proxyName($initializer);
|
||||
$variable = & $proxy->property0;
|
||||
|
||||
$this->assertSame('property0', $variable);
|
||||
|
||||
$variable = 'foo';
|
||||
|
||||
$this->assertSame('foo', $proxy->property0);
|
||||
}
|
||||
|
||||
public function testKeepsInitializerWhenNotOverwitten()
|
||||
{
|
||||
$instance = new BaseClass();
|
||||
$proxyName = $this->generateProxy(get_class($instance));
|
||||
$initializer = function () {
|
||||
};
|
||||
/* @var $proxy \ProxyManager\Proxy\GhostObjectInterface */
|
||||
$proxy = new $proxyName($initializer);
|
||||
|
||||
$proxy->initializeProxy();
|
||||
|
||||
$this->assertSame($initializer, $proxy->getProxyInitializer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that public properties are not being initialized multiple times
|
||||
*/
|
||||
public function testKeepsInitializedPublicProperties()
|
||||
{
|
||||
$instance = new BaseClass();
|
||||
$proxyName = $this->generateProxy(get_class($instance));
|
||||
$initializer = function (BaseClass $proxy, $method, $parameters, & $initializer) {
|
||||
$initializer = null;
|
||||
$proxy->publicProperty = 'newValue';
|
||||
};
|
||||
/* @var $proxy \ProxyManager\Proxy\GhostObjectInterface|BaseClass */
|
||||
$proxy = new $proxyName($initializer);
|
||||
|
||||
$proxy->initializeProxy();
|
||||
$this->assertSame('newValue', $proxy->publicProperty);
|
||||
|
||||
$proxy->publicProperty = 'otherValue';
|
||||
|
||||
$proxy->initializeProxy();
|
||||
|
||||
$this->assertSame('otherValue', $proxy->publicProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that properties' default values are preserved
|
||||
*/
|
||||
public function testPublicPropertyDefaultWillBePreserved()
|
||||
{
|
||||
$instance = new ClassWithPublicProperties();
|
||||
$proxyName = $this->generateProxy(get_class($instance));
|
||||
/* @var $proxy ClassWithPublicProperties */
|
||||
$proxy = new $proxyName(function () {
|
||||
});
|
||||
|
||||
$this->assertSame('property0', $proxy->property0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that protected properties' default values are preserved
|
||||
*/
|
||||
public function testProtectedPropertyDefaultWillBePreserved()
|
||||
{
|
||||
$instance = new ClassWithProtectedProperties();
|
||||
$proxyName = $this->generateProxy(get_class($instance));
|
||||
/* @var $proxy ClassWithProtectedProperties */
|
||||
$proxy = new $proxyName(function () {
|
||||
});
|
||||
|
||||
// Check protected property via reflection
|
||||
$reflectionProperty = new ReflectionProperty($instance, 'property0');
|
||||
$reflectionProperty->setAccessible(true);
|
||||
|
||||
$this->assertSame('property0', $reflectionProperty->getValue($proxy));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that private properties' default values are preserved
|
||||
*/
|
||||
public function testPrivatePropertyDefaultWillBePreserved()
|
||||
{
|
||||
$instance = new ClassWithPrivateProperties();
|
||||
$proxyName = $this->generateProxy(get_class($instance));
|
||||
/* @var $proxy ClassWithPrivateProperties */
|
||||
$proxy = new $proxyName(function () {
|
||||
});
|
||||
|
||||
// Check protected property via reflection
|
||||
$reflectionProperty = new ReflectionProperty($instance, 'property0');
|
||||
$reflectionProperty->setAccessible(true);
|
||||
|
||||
$this->assertSame('property0', $reflectionProperty->getValue($proxy));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a proxy for the given class name, and retrieves its class name
|
||||
*
|
||||
* @param string $parentClassName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateProxy($parentClassName)
|
||||
{
|
||||
$generatedClassName = __NAMESPACE__ . '\\' . UniqueIdentifierGenerator::getIdentifier('Foo');
|
||||
$generator = new LazyLoadingGhostGenerator();
|
||||
$generatedClass = new ClassGenerator($generatedClassName);
|
||||
$strategy = new EvaluatingGeneratorStrategy();
|
||||
|
||||
$generator->generate(new ReflectionClass($parentClassName), $generatedClass);
|
||||
$strategy->generate($generatedClass);
|
||||
|
||||
return $generatedClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @param object $realInstance
|
||||
* @param Mock $initializerMatcher
|
||||
*
|
||||
* @return \Closure
|
||||
*/
|
||||
private function createInitializer($className, $realInstance, Mock $initializerMatcher = null)
|
||||
{
|
||||
if (null === $initializerMatcher) {
|
||||
$initializerMatcher = $this->getMock('stdClass', array('__invoke'));
|
||||
|
||||
$initializerMatcher
|
||||
->expects($this->once())
|
||||
->method('__invoke')
|
||||
->with(
|
||||
$this->logicalAnd(
|
||||
$this->isInstanceOf('ProxyManager\\Proxy\\GhostObjectInterface'),
|
||||
$this->isInstanceOf($className)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$initializerMatcher = $initializerMatcher ?: $this->getMock('stdClass', array('__invoke'));
|
||||
|
||||
return function (
|
||||
GhostObjectInterface $proxy,
|
||||
$method,
|
||||
$params,
|
||||
& $initializer
|
||||
) use (
|
||||
$initializerMatcher,
|
||||
$realInstance
|
||||
) {
|
||||
$initializer = null;
|
||||
$reflectionClass = new ReflectionClass($realInstance);
|
||||
|
||||
foreach ($reflectionClass->getProperties() as $property) {
|
||||
$property->setAccessible(true);
|
||||
$property->setValue($proxy, $property->getValue($realInstance));
|
||||
}
|
||||
|
||||
$initializerMatcher->__invoke($proxy, $method, $params);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a list of object | invoked method | parameters | expected result
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProxyMethods()
|
||||
{
|
||||
$selfHintParam = new ClassWithSelfHint();
|
||||
|
||||
$data = array(
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseClass',
|
||||
new BaseClass(),
|
||||
'publicMethod',
|
||||
array(),
|
||||
'publicMethodDefault'
|
||||
),
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseClass',
|
||||
new BaseClass(),
|
||||
'publicTypeHintedMethod',
|
||||
array(new \stdClass()),
|
||||
'publicTypeHintedMethodDefault'
|
||||
),
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseClass',
|
||||
new BaseClass(),
|
||||
'publicByReferenceMethod',
|
||||
array(),
|
||||
'publicByReferenceMethodDefault'
|
||||
),
|
||||
);
|
||||
|
||||
if (PHP_VERSION_ID >= 50401) {
|
||||
// PHP < 5.4.1 misbehaves, throwing strict standards, see https://bugs.php.net/bug.php?id=60573
|
||||
$data[] = array(
|
||||
'ProxyManagerTestAsset\\ClassWithSelfHint',
|
||||
new ClassWithSelfHint(),
|
||||
'selfHintMethod',
|
||||
array('parameter' => $selfHintParam),
|
||||
$selfHintParam
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates proxies and instances with a public property to feed to the property accessor methods
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPropertyAccessProxies()
|
||||
{
|
||||
$instance1 = new BaseClass();
|
||||
$proxyName1 = $this->generateProxy(get_class($instance1));
|
||||
$instance2 = new BaseClass();
|
||||
$proxyName2 = $this->generateProxy(get_class($instance2));
|
||||
|
||||
return array(
|
||||
array(
|
||||
$instance1,
|
||||
new $proxyName1($this->createInitializer('ProxyManagerTestAsset\\BaseClass', $instance1)),
|
||||
'publicProperty',
|
||||
'publicPropertyDefault',
|
||||
),
|
||||
array(
|
||||
$instance2,
|
||||
unserialize(
|
||||
serialize(new $proxyName2($this->createInitializer('ProxyManagerTestAsset\\BaseClass', $instance2)))
|
||||
),
|
||||
'publicProperty',
|
||||
'publicPropertyDefault',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
160
vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/LazyLoadingGhostPerformanceTest.php
vendored
Normal file
160
vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/LazyLoadingGhostPerformanceTest.php
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
namespace ProxyManagerTest\Functional;
|
||||
|
||||
use ProxyManager\Generator\ClassGenerator;
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
|
||||
use ProxyManager\Proxy\GhostObjectInterface;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingGhostGenerator;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* Tests for {@see \ProxyManager\ProxyGenerator\LazyLoadingGhostGenerator} produced objects
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @group Performance
|
||||
* @coversNothing
|
||||
*/
|
||||
class LazyLoadingGhostPerformanceTest extends BaseLazyLoadingPerformanceTest
|
||||
{
|
||||
/**
|
||||
* @outputBuffering
|
||||
* @dataProvider getTestedClasses
|
||||
*
|
||||
* @param string $className
|
||||
* @param array $methods
|
||||
* @param array $properties
|
||||
* @param \ReflectionProperty[] $reflectionProperties
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testProxyInstantiationPerformance(
|
||||
$className,
|
||||
array $methods,
|
||||
array $properties,
|
||||
array $reflectionProperties
|
||||
) {
|
||||
$proxyName = $this->generateProxy($className);
|
||||
$iterations = 20000;
|
||||
$instances = array();
|
||||
/* @var $proxies \ProxyManager\Proxy\GhostObjectInterface[] */
|
||||
$proxies = array();
|
||||
$realInstance = new $className();
|
||||
$initializer = function (
|
||||
GhostObjectInterface $proxy,
|
||||
$method,
|
||||
$params,
|
||||
& $initializer
|
||||
) use (
|
||||
$reflectionProperties,
|
||||
$realInstance
|
||||
) {
|
||||
$initializer = null;
|
||||
|
||||
foreach ($reflectionProperties as $reflectionProperty) {
|
||||
$reflectionProperty->setValue($proxy, $reflectionProperty->getValue($realInstance));
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
$this->startCapturing();
|
||||
|
||||
for ($i = 0; $i < $iterations; $i += 1) {
|
||||
$instances[] = new $className();
|
||||
}
|
||||
|
||||
$baseProfile = $this->endCapturing(
|
||||
'Instantiation for ' . $iterations . ' objects of type ' . $className . ': %fms / %fKb'
|
||||
);
|
||||
$this->startCapturing();
|
||||
|
||||
for ($i = 0; $i < $iterations; $i += 1) {
|
||||
$proxies[] = new $proxyName($initializer);
|
||||
}
|
||||
|
||||
$proxyProfile = $this->endCapturing(
|
||||
'Instantiation for ' . $iterations . ' proxies of type ' . $className . ': %fms / %fKb'
|
||||
);
|
||||
$this->compareProfile($baseProfile, $proxyProfile);
|
||||
$this->startCapturing();
|
||||
|
||||
foreach ($proxies as $proxy) {
|
||||
$proxy->initializeProxy();
|
||||
}
|
||||
|
||||
$this->endCapturing('Initialization of ' . $iterations . ' proxies of type ' . $className . ': %fms / %fKb');
|
||||
|
||||
foreach ($methods as $methodName => $parameters) {
|
||||
$this->profileMethodAccess($className, $instances, $proxies, $methodName, $parameters);
|
||||
}
|
||||
|
||||
foreach ($properties as $property) {
|
||||
$this->profilePropertyWrites($className, $instances, $proxies, $property);
|
||||
$this->profilePropertyReads($className, $instances, $proxies, $property);
|
||||
$this->profilePropertyIsset($className, $instances, $proxies, $property);
|
||||
$this->profilePropertyUnset($className, $instances, $proxies, $property);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTestedClasses()
|
||||
{
|
||||
$testedClasses = array(
|
||||
array('stdClass', array(), array()),
|
||||
array('ProxyManagerTestAsset\\BaseClass', array('publicMethod' => array()), array('publicProperty')),
|
||||
);
|
||||
|
||||
foreach ($testedClasses as $key => $testedClass) {
|
||||
$reflectionProperties = array();
|
||||
$reflectionClass = new ReflectionClass($testedClass[0]);
|
||||
|
||||
foreach ($reflectionClass->getProperties() as $property) {
|
||||
$property->setAccessible(true);
|
||||
|
||||
$reflectionProperties[$property->getName()] = $property;
|
||||
}
|
||||
|
||||
$testedClasses[$key][] = $reflectionProperties;
|
||||
}
|
||||
|
||||
return $testedClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function generateProxy($parentClassName)
|
||||
{
|
||||
$generatedClassName = __NAMESPACE__ . '\\' . UniqueIdentifierGenerator::getIdentifier('Foo');
|
||||
$generator = new LazyLoadingGhostGenerator();
|
||||
$generatedClass = new ClassGenerator($generatedClassName);
|
||||
$strategy = new EvaluatingGeneratorStrategy();
|
||||
|
||||
$generator->generate(new ReflectionClass($parentClassName), $generatedClass);
|
||||
$strategy->generate($generatedClass);
|
||||
|
||||
return $generatedClassName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
namespace ProxyManagerTest\Functional;
|
||||
|
||||
use PHPUnit_Framework_TestCase;
|
||||
use PHPUnit_Framework_MockObject_MockObject as Mock;
|
||||
use ProxyManager\Generator\ClassGenerator;
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
|
||||
use ProxyManager\Proxy\VirtualProxyInterface;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator;
|
||||
use ProxyManagerTestAsset\BaseClass;
|
||||
use ProxyManagerTestAsset\ClassWithPublicArrayProperty;
|
||||
use ProxyManagerTestAsset\ClassWithPublicProperties;
|
||||
use ProxyManagerTestAsset\ClassWithSelfHint;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* Tests for {@see \ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator} produced objects
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @group Functional
|
||||
* @coversNothing
|
||||
*/
|
||||
class LazyLoadingValueHolderFunctionalTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCalls($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */
|
||||
$proxy = new $proxyName($this->createInitializer($className, $instance));
|
||||
|
||||
$this->assertFalse($proxy->isProxyInitialized());
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
|
||||
$this->assertTrue($proxy->isProxyInitialized());
|
||||
$this->assertSame($instance, $proxy->getWrappedValueHolderValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCallsAfterUnSerialization($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */
|
||||
$proxy = unserialize(serialize(new $proxyName($this->createInitializer($className, $instance))));
|
||||
|
||||
$this->assertTrue($proxy->isProxyInitialized());
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
|
||||
$this->assertEquals($instance, $proxy->getWrappedValueHolderValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCallsAfterCloning($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */
|
||||
$proxy = new $proxyName($this->createInitializer($className, $instance));
|
||||
$cloned = clone $proxy;
|
||||
|
||||
$this->assertTrue($cloned->isProxyInitialized());
|
||||
$this->assertNotSame($proxy->getWrappedValueHolderValue(), $cloned->getWrappedValueHolderValue());
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($cloned, $method), $params));
|
||||
$this->assertEquals($instance, $cloned->getWrappedValueHolderValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyReadAccess($instance, $proxy, $publicProperty, $propertyValue)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */
|
||||
$this->assertSame($propertyValue, $proxy->$publicProperty);
|
||||
$this->assertTrue($proxy->isProxyInitialized());
|
||||
$this->assertEquals($instance, $proxy->getWrappedValueHolderValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyWriteAccess($instance, $proxy, $publicProperty)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */
|
||||
$newValue = uniqid();
|
||||
$proxy->$publicProperty = $newValue;
|
||||
|
||||
$this->assertTrue($proxy->isProxyInitialized());
|
||||
$this->assertSame($newValue, $proxy->$publicProperty);
|
||||
$this->assertSame($newValue, $proxy->getWrappedValueHolderValue()->$publicProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyExistence($instance, $proxy, $publicProperty)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */
|
||||
$this->assertSame(isset($instance->$publicProperty), isset($proxy->$publicProperty));
|
||||
$this->assertTrue($proxy->isProxyInitialized());
|
||||
$this->assertEquals($instance, $proxy->getWrappedValueHolderValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyAbsence($instance, $proxy, $publicProperty)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */
|
||||
$instance = $proxy->getWrappedValueHolderValue() ? $proxy->getWrappedValueHolderValue() : $instance;
|
||||
$instance->$publicProperty = null;
|
||||
$this->assertFalse(isset($proxy->$publicProperty));
|
||||
$this->assertTrue($proxy->isProxyInitialized());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyUnset($instance, $proxy, $publicProperty)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\VirtualProxyInterface|BaseClass */
|
||||
$instance = $proxy->getWrappedValueHolderValue() ? $proxy->getWrappedValueHolderValue() : $instance;
|
||||
unset($proxy->$publicProperty);
|
||||
|
||||
$this->assertTrue($proxy->isProxyInitialized());
|
||||
|
||||
$this->assertFalse(isset($instance->$publicProperty));
|
||||
$this->assertFalse(isset($proxy->$publicProperty));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that accessing a public property containing an array behaves like in a normal context
|
||||
*/
|
||||
public function testCanWriteToArrayKeysInPublicProperty()
|
||||
{
|
||||
$instance = new ClassWithPublicArrayProperty();
|
||||
$className = get_class($instance);
|
||||
$initializer = $this->createInitializer($className, $instance);
|
||||
$proxyName = $this->generateProxy($className);
|
||||
/* @var $proxy ClassWithPublicArrayProperty */
|
||||
$proxy = new $proxyName($initializer);
|
||||
|
||||
$proxy->arrayProperty['foo'] = 'bar';
|
||||
|
||||
$this->assertSame('bar', $proxy->arrayProperty['foo']);
|
||||
|
||||
$proxy->arrayProperty = array('tab' => 'taz');
|
||||
|
||||
$this->assertSame(array('tab' => 'taz'), $proxy->arrayProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that public properties retrieved via `__get` don't get modified in the object itself
|
||||
*/
|
||||
public function testWillNotModifyRetrievedPublicProperties()
|
||||
{
|
||||
$instance = new ClassWithPublicProperties();
|
||||
$className = get_class($instance);
|
||||
$initializer = $this->createInitializer($className, $instance);
|
||||
$proxyName = $this->generateProxy($className);
|
||||
/* @var $proxy ClassWithPublicProperties */
|
||||
$proxy = new $proxyName($initializer);
|
||||
$variable = $proxy->property0;
|
||||
|
||||
$this->assertSame('property0', $variable);
|
||||
|
||||
$variable = 'foo';
|
||||
|
||||
$this->assertSame('property0', $proxy->property0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that public properties references retrieved via `__get` modify in the object state
|
||||
*/
|
||||
public function testWillModifyByRefRetrievedPublicProperties()
|
||||
{
|
||||
$instance = new ClassWithPublicProperties();
|
||||
$className = get_class($instance);
|
||||
$initializer = $this->createInitializer($className, $instance);
|
||||
$proxyName = $this->generateProxy($className);
|
||||
/* @var $proxy ClassWithPublicProperties */
|
||||
$proxy = new $proxyName($initializer);
|
||||
$variable = & $proxy->property0;
|
||||
|
||||
$this->assertSame('property0', $variable);
|
||||
|
||||
$variable = 'foo';
|
||||
|
||||
$this->assertSame('foo', $proxy->property0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 16
|
||||
*
|
||||
* Verifies that initialization of a value holder proxy may happen multiple times
|
||||
*/
|
||||
public function testWillAllowMultipleProxyInitialization()
|
||||
{
|
||||
$proxyClass = $this->generateProxy('ProxyManagerTestAsset\\BaseClass');
|
||||
$counter = 0;
|
||||
$initializer = function (& $wrappedInstance) use (& $counter) {
|
||||
$wrappedInstance = new BaseClass();
|
||||
|
||||
$wrappedInstance->publicProperty = (string) ($counter += 1);
|
||||
};
|
||||
|
||||
/* @var $proxy BaseClass */
|
||||
$proxy = new $proxyClass($initializer);
|
||||
|
||||
$this->assertSame('1', $proxy->publicProperty);
|
||||
$this->assertSame('2', $proxy->publicProperty);
|
||||
$this->assertSame('3', $proxy->publicProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a proxy for the given class name, and retrieves its class name
|
||||
*
|
||||
* @param string $parentClassName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateProxy($parentClassName)
|
||||
{
|
||||
$generatedClassName = __NAMESPACE__ . '\\' . UniqueIdentifierGenerator::getIdentifier('Foo');
|
||||
$generator = new LazyLoadingValueHolderGenerator();
|
||||
$generatedClass = new ClassGenerator($generatedClassName);
|
||||
$strategy = new EvaluatingGeneratorStrategy();
|
||||
|
||||
$generator->generate(new ReflectionClass($parentClassName), $generatedClass);
|
||||
$strategy->generate($generatedClass);
|
||||
|
||||
return $generatedClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @param object $realInstance
|
||||
* @param Mock $initializerMatcher
|
||||
*
|
||||
* @return \Closure
|
||||
*/
|
||||
private function createInitializer($className, $realInstance, Mock $initializerMatcher = null)
|
||||
{
|
||||
if (null === $initializerMatcher) {
|
||||
$initializerMatcher = $this->getMock('stdClass', array('__invoke'));
|
||||
|
||||
$initializerMatcher
|
||||
->expects($this->once())
|
||||
->method('__invoke')
|
||||
->with(
|
||||
$this->logicalAnd(
|
||||
$this->isInstanceOf('ProxyManager\\Proxy\\VirtualProxyInterface'),
|
||||
$this->isInstanceOf($className)
|
||||
),
|
||||
$realInstance
|
||||
);
|
||||
}
|
||||
|
||||
$initializerMatcher = $initializerMatcher ?: $this->getMock('stdClass', array('__invoke'));
|
||||
|
||||
return function (
|
||||
& $wrappedObject,
|
||||
VirtualProxyInterface $proxy,
|
||||
$method,
|
||||
$params,
|
||||
& $initializer
|
||||
) use (
|
||||
$initializerMatcher,
|
||||
$realInstance
|
||||
) {
|
||||
$initializer = null;
|
||||
$wrappedObject = $realInstance;
|
||||
|
||||
$initializerMatcher->__invoke($proxy, $wrappedObject, $method, $params);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a list of object | invoked method | parameters | expected result
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProxyMethods()
|
||||
{
|
||||
$selfHintParam = new ClassWithSelfHint();
|
||||
|
||||
$data = array(
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseClass',
|
||||
new BaseClass(),
|
||||
'publicMethod',
|
||||
array(),
|
||||
'publicMethodDefault'
|
||||
),
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseClass',
|
||||
new BaseClass(),
|
||||
'publicTypeHintedMethod',
|
||||
array(new \stdClass()),
|
||||
'publicTypeHintedMethodDefault'
|
||||
),
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseClass',
|
||||
new BaseClass(),
|
||||
'publicByReferenceMethod',
|
||||
array(),
|
||||
'publicByReferenceMethodDefault'
|
||||
),
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseInterface',
|
||||
new BaseClass(),
|
||||
'publicMethod',
|
||||
array(),
|
||||
'publicMethodDefault'
|
||||
),
|
||||
);
|
||||
|
||||
if (PHP_VERSION_ID >= 50401) {
|
||||
// PHP < 5.4.1 misbehaves, throwing strict standards, see https://bugs.php.net/bug.php?id=60573
|
||||
$data[] = array(
|
||||
'ProxyManagerTestAsset\\ClassWithSelfHint',
|
||||
new ClassWithSelfHint(),
|
||||
'selfHintMethod',
|
||||
array('parameter' => $selfHintParam),
|
||||
$selfHintParam
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates proxies and instances with a public property to feed to the property accessor methods
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPropertyAccessProxies()
|
||||
{
|
||||
$instance1 = new BaseClass();
|
||||
$proxyName1 = $this->generateProxy(get_class($instance1));
|
||||
$instance2 = new BaseClass();
|
||||
$proxyName2 = $this->generateProxy(get_class($instance2));
|
||||
|
||||
return array(
|
||||
array(
|
||||
$instance1,
|
||||
new $proxyName1($this->createInitializer('ProxyManagerTestAsset\\BaseClass', $instance1)),
|
||||
'publicProperty',
|
||||
'publicPropertyDefault',
|
||||
),
|
||||
array(
|
||||
$instance2,
|
||||
unserialize(
|
||||
serialize(new $proxyName2($this->createInitializer('ProxyManagerTestAsset\\BaseClass', $instance2)))
|
||||
),
|
||||
'publicProperty',
|
||||
'publicPropertyDefault',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
namespace ProxyManagerTest\Functional;
|
||||
|
||||
use ProxyManager\Generator\ClassGenerator;
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
|
||||
use ProxyManager\Proxy\VirtualProxyInterface;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* Tests for {@see \ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator} produced objects
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @group Performance
|
||||
* @coversNothing
|
||||
*/
|
||||
class LazyLoadingValueHolderPerformanceTest extends BaseLazyLoadingPerformanceTest
|
||||
{
|
||||
/**
|
||||
* @outputBuffering
|
||||
* @dataProvider getTestedClasses
|
||||
*
|
||||
* @param string $className
|
||||
* @param array $methods
|
||||
* @param array $properties
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testProxyInstantiationPerformance($className, array $methods, array $properties)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
$iterations = 20000;
|
||||
$instances = array();
|
||||
/* @var $proxies \ProxyManager\Proxy\VirtualProxyInterface[] */
|
||||
$proxies = array();
|
||||
$initializer = function (
|
||||
& $valueHolder,
|
||||
VirtualProxyInterface $proxy,
|
||||
$method,
|
||||
$params,
|
||||
& $initializer
|
||||
) use ($className) {
|
||||
$initializer = null;
|
||||
$valueHolder = new $className();
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
$this->startCapturing();
|
||||
|
||||
for ($i = 0; $i < $iterations; $i += 1) {
|
||||
$instances[] = new $className();
|
||||
}
|
||||
|
||||
$baseProfile = $this->endCapturing(
|
||||
'Instantiation for ' . $iterations . ' objects of type ' . $className . ': %fms / %fKb'
|
||||
);
|
||||
$this->startCapturing();
|
||||
|
||||
for ($i = 0; $i < $iterations; $i += 1) {
|
||||
$proxies[] = new $proxyName($initializer);
|
||||
}
|
||||
|
||||
$proxyProfile = $this->endCapturing(
|
||||
'Instantiation for ' . $iterations . ' proxies of type ' . $className . ': %fms / %fKb'
|
||||
);
|
||||
$this->compareProfile($baseProfile, $proxyProfile);
|
||||
$this->startCapturing();
|
||||
|
||||
foreach ($proxies as $proxy) {
|
||||
$proxy->initializeProxy();
|
||||
}
|
||||
|
||||
$this->endCapturing('Initialization of ' . $iterations . ' proxies of type ' . $className . ': %fms / %fKb');
|
||||
|
||||
foreach ($methods as $methodName => $parameters) {
|
||||
$this->profileMethodAccess($className, $instances, $proxies, $methodName, $parameters);
|
||||
}
|
||||
|
||||
foreach ($properties as $property) {
|
||||
$this->profilePropertyWrites($className, $instances, $proxies, $property);
|
||||
$this->profilePropertyReads($className, $instances, $proxies, $property);
|
||||
$this->profilePropertyIsset($className, $instances, $proxies, $property);
|
||||
$this->profilePropertyUnset($className, $instances, $proxies, $property);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTestedClasses()
|
||||
{
|
||||
return array(
|
||||
array('stdClass', array(), array()),
|
||||
array('ProxyManagerTestAsset\\BaseClass', array('publicMethod' => array()), array('publicProperty')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function generateProxy($parentClassName)
|
||||
{
|
||||
$generatedClassName = __NAMESPACE__ . '\\' . UniqueIdentifierGenerator::getIdentifier('Foo');
|
||||
$generator = new LazyLoadingValueHolderGenerator();
|
||||
$generatedClass = new ClassGenerator($generatedClassName);
|
||||
$strategy = new EvaluatingGeneratorStrategy();
|
||||
|
||||
$generator->generate(new ReflectionClass($parentClassName), $generatedClass);
|
||||
$strategy->generate($generatedClass);
|
||||
|
||||
return $generatedClassName;
|
||||
}
|
||||
}
|
||||
123
vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/MultipleProxyGenerationTest.php
vendored
Normal file
123
vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/MultipleProxyGenerationTest.php
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
namespace ProxyManagerTest\Functional;
|
||||
|
||||
use PHPUnit_Framework_TestCase;
|
||||
use ProxyManager\Factory\AccessInterceptorScopeLocalizerFactory;
|
||||
use ProxyManager\Factory\AccessInterceptorValueHolderFactory;
|
||||
use ProxyManager\Factory\LazyLoadingGhostFactory;
|
||||
use ProxyManager\Factory\LazyLoadingValueHolderFactory;
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* Verifies that proxy factories don't conflict with each other when generating proxies
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @link https://github.com/Ocramius/ProxyManager/issues/10
|
||||
*
|
||||
* @group Functional
|
||||
* @group issue-10
|
||||
* @coversNothing
|
||||
*/
|
||||
class MultipleProxyGenerationTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Verifies that proxies generated from different factories will retain their specific implementation
|
||||
* and won't conflict
|
||||
*
|
||||
* @dataProvider getTestedClasses
|
||||
*/
|
||||
public function testCanGenerateMultipleDifferentProxiesForSameClass($className)
|
||||
{
|
||||
$skipScopeLocalizerTests = false;
|
||||
$ghostProxyFactory = new LazyLoadingGhostFactory();
|
||||
$virtualProxyFactory = new LazyLoadingValueHolderFactory();
|
||||
$accessInterceptorFactory = new AccessInterceptorValueHolderFactory();
|
||||
$accessInterceptorScopeLocalizerFactory = new AccessInterceptorScopeLocalizerFactory();
|
||||
$initializer = function () {
|
||||
};
|
||||
|
||||
$reflectionClass = new ReflectionClass($className);
|
||||
|
||||
if ((! method_exists('Closure', 'bind')) && $reflectionClass->getProperties(ReflectionProperty::IS_PRIVATE)) {
|
||||
$skipScopeLocalizerTests = true;
|
||||
}
|
||||
|
||||
$generated = array(
|
||||
$ghostProxyFactory->createProxy($className, $initializer),
|
||||
$virtualProxyFactory->createProxy($className, $initializer),
|
||||
$accessInterceptorFactory->createProxy(new $className()),
|
||||
);
|
||||
|
||||
if (! $skipScopeLocalizerTests) {
|
||||
$generated[] = $accessInterceptorScopeLocalizerFactory->createProxy(new $className());
|
||||
}
|
||||
|
||||
foreach ($generated as $key => $proxy) {
|
||||
$this->assertInstanceOf($className, $proxy);
|
||||
|
||||
foreach ($generated as $comparedKey => $comparedProxy) {
|
||||
if ($comparedKey === $key) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->assertNotSame(get_class($comparedProxy), get_class($proxy));
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertInstanceOf('ProxyManager\Proxy\GhostObjectInterface', $generated[0]);
|
||||
$this->assertInstanceOf('ProxyManager\Proxy\VirtualProxyInterface', $generated[1]);
|
||||
$this->assertInstanceOf('ProxyManager\Proxy\AccessInterceptorInterface', $generated[2]);
|
||||
$this->assertInstanceOf('ProxyManager\Proxy\ValueHolderInterface', $generated[2]);
|
||||
|
||||
if (! $skipScopeLocalizerTests) {
|
||||
$this->assertInstanceOf('ProxyManager\Proxy\AccessInterceptorInterface', $generated[3]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[][]
|
||||
*/
|
||||
public function getTestedClasses()
|
||||
{
|
||||
$data = array(
|
||||
array('ProxyManagerTestAsset\\BaseClass'),
|
||||
array('ProxyManagerTestAsset\\ClassWithMagicMethods'),
|
||||
array('ProxyManagerTestAsset\\ClassWithFinalMethods'),
|
||||
array('ProxyManagerTestAsset\\ClassWithFinalMagicMethods'),
|
||||
array('ProxyManagerTestAsset\\ClassWithByRefMagicMethods'),
|
||||
array('ProxyManagerTestAsset\\ClassWithMixedProperties'),
|
||||
array('ProxyManagerTestAsset\\ClassWithPrivateProperties'),
|
||||
array('ProxyManagerTestAsset\\ClassWithProtectedProperties'),
|
||||
array('ProxyManagerTestAsset\\ClassWithPublicProperties'),
|
||||
array('ProxyManagerTestAsset\\EmptyClass'),
|
||||
array('ProxyManagerTestAsset\\HydratedObject'),
|
||||
);
|
||||
|
||||
if (PHP_VERSION_ID >= 50401) {
|
||||
// PHP < 5.4.1 misbehaves, throwing strict standards, see https://bugs.php.net/bug.php?id=60573
|
||||
$data[] = array('ProxyManagerTestAsset\\ClassWithSelfHint');
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
223
vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/NullObjectFunctionalTest.php
vendored
Normal file
223
vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/NullObjectFunctionalTest.php
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
namespace ProxyManagerTest\Functional;
|
||||
|
||||
use PHPUnit_Framework_TestCase;
|
||||
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
|
||||
use ProxyManager\ProxyGenerator\NullObjectGenerator;
|
||||
use ProxyManagerTestAsset\BaseClass;
|
||||
use ProxyManagerTestAsset\ClassWithSelfHint;
|
||||
use ReflectionClass;
|
||||
use ProxyManager\Generator\ClassGenerator;
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
|
||||
/**
|
||||
* Tests for {@see \ProxyManager\ProxyGenerator\NullObjectGenerator} produced objects
|
||||
*
|
||||
* @author Vincent Blanchon <blanchon.vincent@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @group Functional
|
||||
* @coversNothing
|
||||
*/
|
||||
class NullObjectFunctionalTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCalls($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\NullObjectInterface */
|
||||
$proxy = new $proxyName();
|
||||
|
||||
$this->assertSame(null, call_user_func_array(array($proxy, $method), $params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCallsAfterUnSerialization($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
/* @var $proxy \ProxyManager\Proxy\NullObjectInterface */
|
||||
$proxy = unserialize(serialize(new $proxyName()));
|
||||
|
||||
$this->assertSame(null, call_user_func_array(array($proxy, $method), $params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testMethodCallsAfterCloning($className, $instance, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($className);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\NullObjectInterface */
|
||||
$proxy = new $proxyName();
|
||||
$cloned = clone $proxy;
|
||||
|
||||
$this->assertSame(null, call_user_func_array(array($cloned, $method), $params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyReadAccess($instance, $proxy, $publicProperty, $propertyValue)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\NullObjectInterface */
|
||||
$this->assertSame(null, $proxy->$publicProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyWriteAccess($instance, $proxy, $publicProperty)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\NullObjectInterface */
|
||||
$newValue = uniqid();
|
||||
$proxy->$publicProperty = $newValue;
|
||||
|
||||
$this->assertSame($newValue, $proxy->$publicProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyExistence($instance, $proxy, $publicProperty)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\NullObjectInterface */
|
||||
$this->assertSame(null, $proxy->$publicProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testPropertyUnset($instance, $proxy, $publicProperty)
|
||||
{
|
||||
/* @var $proxy \ProxyManager\Proxy\NullObjectInterface */
|
||||
unset($proxy->$publicProperty);
|
||||
|
||||
$this->assertTrue(isset($instance->$publicProperty));
|
||||
$this->assertFalse(isset($proxy->$publicProperty));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a proxy for the given class name, and retrieves its class name
|
||||
*
|
||||
* @param string $parentClassName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateProxy($parentClassName)
|
||||
{
|
||||
$generatedClassName = __NAMESPACE__ . '\\' . UniqueIdentifierGenerator::getIdentifier('Foo');
|
||||
$generator = new NullObjectGenerator();
|
||||
$generatedClass = new ClassGenerator($generatedClassName);
|
||||
$strategy = new EvaluatingGeneratorStrategy();
|
||||
|
||||
$generator->generate(new ReflectionClass($parentClassName), $generatedClass);
|
||||
$strategy->generate($generatedClass);
|
||||
|
||||
return $generatedClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a list of object | invoked method | parameters | expected result
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProxyMethods()
|
||||
{
|
||||
$selfHintParam = new ClassWithSelfHint();
|
||||
|
||||
$data = array(
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseClass',
|
||||
new BaseClass(),
|
||||
'publicMethod',
|
||||
array(),
|
||||
'publicMethodDefault'
|
||||
),
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseClass',
|
||||
new BaseClass(),
|
||||
'publicTypeHintedMethod',
|
||||
array('param' => new \stdClass()),
|
||||
'publicTypeHintedMethodDefault'
|
||||
),
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseClass',
|
||||
new BaseClass(),
|
||||
'publicByReferenceMethod',
|
||||
array(),
|
||||
'publicByReferenceMethodDefault'
|
||||
),
|
||||
array(
|
||||
'ProxyManagerTestAsset\\BaseInterface',
|
||||
new BaseClass(),
|
||||
'publicMethod',
|
||||
array(),
|
||||
'publicMethodDefault'
|
||||
),
|
||||
);
|
||||
|
||||
if (PHP_VERSION_ID >= 50401) {
|
||||
// PHP < 5.4.1 misbehaves, throwing strict standards, see https://bugs.php.net/bug.php?id=60573
|
||||
$data[] = array(
|
||||
'ProxyManagerTestAsset\\ClassWithSelfHint',
|
||||
new ClassWithSelfHint(),
|
||||
'selfHintMethod',
|
||||
array('parameter' => $selfHintParam),
|
||||
$selfHintParam
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates proxies and instances with a public property to feed to the property accessor methods
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPropertyAccessProxies()
|
||||
{
|
||||
$instance1 = new BaseClass();
|
||||
$proxyName1 = $this->generateProxy(get_class($instance1));
|
||||
$instance2 = new BaseClass();
|
||||
$proxyName2 = $this->generateProxy(get_class($instance2));
|
||||
|
||||
return array(
|
||||
array(
|
||||
$instance1,
|
||||
new $proxyName1($instance1),
|
||||
'publicProperty',
|
||||
'publicPropertyDefault',
|
||||
),
|
||||
array(
|
||||
$instance2,
|
||||
unserialize(serialize(new $proxyName2($instance2))),
|
||||
'publicProperty',
|
||||
'publicPropertyDefault',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
231
vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/RemoteObjectFunctionalTest.php
vendored
Normal file
231
vendor/ocramius/proxy-manager/tests/ProxyManagerTest/Functional/RemoteObjectFunctionalTest.php
vendored
Normal file
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license.
|
||||
*/
|
||||
|
||||
namespace ProxyManagerTest\Functional;
|
||||
|
||||
use PHPUnit_Framework_TestCase;
|
||||
use ProxyManager\Factory\RemoteObject\Adapter\JsonRpc as JsonRpcAdapter;
|
||||
use ProxyManager\Factory\RemoteObject\Adapter\XmlRpc as XmlRpcAdapter;
|
||||
use ProxyManager\Generator\ClassGenerator;
|
||||
use ProxyManager\Generator\Util\UniqueIdentifierGenerator;
|
||||
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
|
||||
use ProxyManager\ProxyGenerator\RemoteObjectGenerator;
|
||||
use ProxyManagerTestAsset\ClassWithSelfHint;
|
||||
use ProxyManagerTestAsset\RemoteProxy\Foo;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* Tests for {@see \ProxyManager\ProxyGenerator\RemoteObjectGenerator} produced objects
|
||||
*
|
||||
* @author Vincent Blanchon <blanchon.vincent@gmail.com>
|
||||
* @license MIT
|
||||
*
|
||||
* @group Functional
|
||||
* @coversNothing
|
||||
*/
|
||||
class RemoteObjectFunctionalTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @param mixed $expectedValue
|
||||
* @param string $method
|
||||
* @param array $params
|
||||
*
|
||||
* @return XmlRpcAdapter
|
||||
*/
|
||||
protected function getXmlRpcAdapter($expectedValue, $method, array $params)
|
||||
{
|
||||
$client = $this
|
||||
->getMockBuilder('Zend\Server\Client')
|
||||
->setMethods(array('call'))
|
||||
->getMock();
|
||||
|
||||
$client
|
||||
->expects($this->any())
|
||||
->method('call')
|
||||
->with($this->stringEndsWith($method), $params)
|
||||
->will($this->returnValue($expectedValue));
|
||||
|
||||
$adapter = new XmlRpcAdapter(
|
||||
$client,
|
||||
array(
|
||||
'ProxyManagerTestAsset\RemoteProxy\Foo.foo'
|
||||
=> 'ProxyManagerTestAsset\RemoteProxy\FooServiceInterface.foo'
|
||||
)
|
||||
);
|
||||
|
||||
return $adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $expectedValue
|
||||
* @param string $method
|
||||
* @param array $params
|
||||
*
|
||||
* @return JsonRpcAdapter
|
||||
*/
|
||||
protected function getJsonRpcAdapter($expectedValue, $method, array $params)
|
||||
{
|
||||
$client = $this
|
||||
->getMockBuilder('Zend\Server\Client')
|
||||
->setMethods(array('call'))
|
||||
->getMock();
|
||||
|
||||
$client
|
||||
->expects($this->any())
|
||||
->method('call')
|
||||
->with($this->stringEndsWith($method), $params)
|
||||
->will($this->returnValue($expectedValue));
|
||||
|
||||
$adapter = new JsonRpcAdapter(
|
||||
$client,
|
||||
array(
|
||||
'ProxyManagerTestAsset\RemoteProxy\Foo.foo'
|
||||
=> 'ProxyManagerTestAsset\RemoteProxy\FooServiceInterface.foo'
|
||||
)
|
||||
);
|
||||
|
||||
return $adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testXmlRpcMethodCalls($instanceOrClassname, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($instanceOrClassname);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\RemoteObjectInterface */
|
||||
$proxy = new $proxyName($this->getXmlRpcAdapter($expectedValue, $method, $params));
|
||||
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getProxyMethods
|
||||
*/
|
||||
public function testJsonRpcMethodCalls($instanceOrClassname, $method, $params, $expectedValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($instanceOrClassname);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\RemoteObjectInterface */
|
||||
$proxy = new $proxyName($this->getJsonRpcAdapter($expectedValue, $method, $params));
|
||||
|
||||
$this->assertSame($expectedValue, call_user_func_array(array($proxy, $method), $params));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPropertyAccessProxies
|
||||
*/
|
||||
public function testJsonRpcPropertyReadAccess($instanceOrClassname, $publicProperty, $propertyValue)
|
||||
{
|
||||
$proxyName = $this->generateProxy($instanceOrClassname);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\RemoteObjectInterface */
|
||||
$proxy = new $proxyName(
|
||||
$this->getJsonRpcAdapter($propertyValue, '__get', array($publicProperty))
|
||||
);
|
||||
|
||||
/* @var $proxy \ProxyManager\Proxy\NullObjectInterface */
|
||||
$this->assertSame($propertyValue, $proxy->$publicProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a proxy for the given class name, and retrieves its class name
|
||||
*
|
||||
* @param string $parentClassName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateProxy($parentClassName)
|
||||
{
|
||||
$generatedClassName = __NAMESPACE__ . '\\' . UniqueIdentifierGenerator::getIdentifier('Foo');
|
||||
$generator = new RemoteObjectGenerator();
|
||||
$generatedClass = new ClassGenerator($generatedClassName);
|
||||
$strategy = new EvaluatingGeneratorStrategy();
|
||||
|
||||
$generator->generate(new ReflectionClass($parentClassName), $generatedClass);
|
||||
$strategy->generate($generatedClass);
|
||||
|
||||
return $generatedClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a list of object | invoked method | parameters | expected result
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProxyMethods()
|
||||
{
|
||||
$selfHintParam = new ClassWithSelfHint();
|
||||
|
||||
$data = array(
|
||||
array(
|
||||
'ProxyManagerTestAsset\RemoteProxy\FooServiceInterface',
|
||||
'foo',
|
||||
array(),
|
||||
'bar remote'
|
||||
),
|
||||
array(
|
||||
'ProxyManagerTestAsset\RemoteProxy\Foo',
|
||||
'foo',
|
||||
array(),
|
||||
'bar remote'
|
||||
),
|
||||
array(
|
||||
new Foo(),
|
||||
'foo',
|
||||
array(),
|
||||
'bar remote'
|
||||
),
|
||||
array(
|
||||
'ProxyManagerTestAsset\RemoteProxy\BazServiceInterface',
|
||||
'baz',
|
||||
array('baz'),
|
||||
'baz remote'
|
||||
),
|
||||
);
|
||||
|
||||
if (PHP_VERSION_ID >= 50401) {
|
||||
// PHP < 5.4.1 misbehaves, throwing strict standards, see https://bugs.php.net/bug.php?id=60573
|
||||
$data[] = array(
|
||||
new ClassWithSelfHint(),
|
||||
'selfHintMethod',
|
||||
array($selfHintParam),
|
||||
$selfHintParam
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates proxies and instances with a public property to feed to the property accessor methods
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPropertyAccessProxies()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'ProxyManagerTestAsset\RemoteProxy\FooServiceInterface',
|
||||
'publicProperty',
|
||||
'publicProperty remote',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user