Skip to content
Browse files

Merge pull request #247 from doctrine/ProxyFactory

[DCOM-96] Refactor ProxyGenerator, introduce AbstractProxyFactory
  • Loading branch information...
2 parents 0cd52ed + 9c9c3c1 commit a5482b347530bb8522e355b399e5ff4983433a40 @beberlei beberlei committed Jan 26, 2013
View
1 .travis.yml
@@ -7,6 +7,7 @@ php:
- 5.3.3
- 5.3
- 5.4
+ - 5.5
before_script:
- composer --prefer-source --dev install
View
184 lib/Doctrine/Common/Proxy/AbstractProxyFactory.php
@@ -0,0 +1,184 @@
+<?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. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Proxy;
+
+use Doctrine\Common\Persistence\Mapping\ClassMetadataFactory;
+use Doctrine\Common\Proxy\Exception\InvalidArgumentException;
+use Doctrine\Common\Util\ClassUtils;
+use Doctrine\Common\Persistence\Mapping\ClassMetadata;
+
+/**
+ * Abstract factory for proxy objects.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+abstract class AbstractProxyFactory
+{
+ /**
+ * @var \Doctrine\Common\Persistence\Mapping\ClassMetadataFactory
+ */
+ private $metadataFactory;
+
+ /**
+ * @var \Doctrine\Common\Proxy\ProxyGenerator the proxy generator responsible for creating the proxy classes/files.
+ */
+ private $proxyGenerator;
+
+ /**
+ * @var bool Whether to automatically (re)generate proxy classes.
+ */
+ private $autoGenerate;
+
+ /**
+ * @var \Doctrine\Common\Proxy\ProxyDefinition[]
+ */
+ private $definitions = array();
+
+ /**
+ * @param \Doctrine\Common\Proxy\ProxyGenerator $proxyGenerator
+ * @param \Doctrine\Common\Persistence\Mapping\ClassMetadataFactory $metadataFactory
+ * @param bool $autoGenerate
+ */
+ public function __construct(ProxyGenerator $proxyGenerator, ClassMetadataFactory $metadataFactory, $autoGenerate)
+ {
+ $this->proxyGenerator = $proxyGenerator;
+ $this->metadataFactory = $metadataFactory;
+ $this->autoGenerate = $autoGenerate;
+ }
+
+ /**
+ * Gets a reference proxy instance for the entity of the given type and identified by
+ * the given identifier.
+ *
+ * @param string $className
+ * @param array $identifier
+ *
+ * @return \Doctrine\Common\Proxy\Proxy
+ */
+ public function getProxy($className, array $identifier)
+ {
+ $definition = isset($this->definitions[$className])
+ ? $this->definitions[$className]
+ : $this->getProxyDefinition($className);
+ $fqcn = $definition->proxyClassName;
+ $proxy = new $fqcn($definition->initializer, $definition->cloner);
+
+ foreach ($definition->identifierFields as $idField) {
+ $definition->reflectionFields[$idField]->setValue($proxy, $identifier[$idField]);
+ }
+
+ return $proxy;
+ }
+
+ /**
+ * Generates proxy classes for all given classes.
+ *
+ * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata[] $classes The classes (ClassMetadata instances)
+ * for which to generate proxies.
+ * @param string $proxyDir The target directory of the proxy classes. If not specified, the
+ * directory configured on the Configuration of the EntityManager used
+ * by this factory is used.
+ * @return int Number of generated proxies.
+ */
+ public function generateProxyClasses(array $classes, $proxyDir = null)
+ {
+ $generated = 0;
+
+ foreach ($classes as $class) {
+ if ($this->skipClass($class)) {
+ continue;
+ }
+
+ $proxyFileName = $this->proxyGenerator->getProxyFileName($class->getName(), $proxyDir);
+
+ $this->proxyGenerator->generateProxyClass($class, $proxyFileName);
+
+ $generated += 1;
+ }
+
+ return $generated;
+ }
+
+ /**
+ * Reset initialization/cloning logic for an un-initialized proxy
+ *
+ * @param \Doctrine\Common\Proxy\Proxy $proxy
+ *
+ * @return \Doctrine\Common\Proxy\Proxy
+ *
+ * @throws \Doctrine\Common\Proxy\Exception\InvalidArgumentException
+ */
+ public function resetUninitializedProxy(Proxy $proxy)
+ {
+ if ($proxy->__isInitialized()) {
+ throw InvalidArgumentException::unitializedProxyExpected($proxy);
+ }
+
+ $className = ClassUtils::getClass($proxy);
+ $definition = isset($this->definitions[$className])
+ ? $this->definitions[$className]
+ : $this->getProxyDefinition($className);
+
+ $proxy->__setInitializer($definition->initializer);
+ $proxy->__setCloner($definition->cloner);
+
+ return $proxy;
+ }
+
+ /**
+ * Get a proxy definition for the given class name.
+ *
+ * @return ProxyDefinition
+ */
+ private function getProxyDefinition($className)
+ {
+ $classMetadata = $this->metadataFactory->getMetadataFor($className);
+ $className = $classMetadata->getName(); // aliases and case sensitivity
+
+ $this->definitions[$className] = $this->createProxyDefinition($className);
+ $proxyClassName = $this->definitions[$className]->proxyClassName;
+
+ if ( ! class_exists($proxyClassName, false)) {
+ $fileName = $this->proxyGenerator->getProxyFileName($className);
+
+ if ($this->autoGenerate) {
+ $this->proxyGenerator->generateProxyClass($classMetadata);
+ }
+
+ require $fileName;
+ }
+
+ return $this->definitions[$className];
+ }
+
+ /**
+ * Determine if this class should be skipped during proxy generation.
+ *
+ * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $metadata
+ * @return bool
+ */
+ abstract protected function skipClass(ClassMetadata $metadata);
+
+ /**
+ * @return ProxyDefinition
+ */
+ abstract protected function createProxyDefinition($className);
+}
+
View
9 lib/Doctrine/Common/Proxy/Exception/InvalidArgumentException.php
@@ -19,6 +19,7 @@
namespace Doctrine\Common\Proxy\Exception;
+use Doctrine\Common\Persistence\Proxy;
use InvalidArgumentException as BaseInvalidArgumentException;
/**
@@ -68,6 +69,14 @@ public static function proxyNamespaceRequired()
}
/**
+ * @return self
+ */
+ public static function unitializedProxyExpected(Proxy $proxy)
+ {
+ return new self(sprintf('Provided proxy of type "%s" must not be initialized.', get_class($proxy)));
+ }
+
+ /**
* @param mixed $callback
*
* @return self
View
70 lib/Doctrine/Common/Proxy/ProxyDefinition.php
@@ -0,0 +1,70 @@
+<?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. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Proxy;
+
+/**
+ * Definition structure how to create a proxy.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class ProxyDefinition
+{
+ /**
+ * @var string
+ */
+ public $proxyClassName;
+
+ /**
+ * @var array
+ */
+ public $identifierFields;
+
+ /**
+ * @var \ReflectionProperty[]
+ */
+ public $reflectionFields;
+
+ /**
+ * @var callable
+ */
+ public $initializer;
+
+ /**
+ * @var callable
+ */
+ public $cloner;
+
+ /**
+ * @param string $proxyClassName
+ * @param array $identifierFields
+ * @param array $reflectionFields
+ * @param callable $initializer
+ * @param callable $cloner
+ */
+ public function __construct($proxyClassName, array $identifierFields, array $reflectionFields, $initializer, $cloner)
+ {
+ $this->proxyClassName = $proxyClassName;
+ $this->identifierFields = $identifierFields;
+ $this->reflectionFields = $reflectionFields;
+ $this->initializer = $initializer;
+ $this->cloner = $cloner;
+ }
+}
+
View
137 lib/Doctrine/Common/Proxy/ProxyGenerator.php
@@ -52,7 +52,10 @@ class ProxyGenerator
/**
* @var string[]|callable[] map of callables used to fill in placeholders set in the template
*/
- protected $placeholders = array();
+ protected $placeholders = array(
+ 'baseProxyInterface' => 'Doctrine\Common\Proxy\Proxy',
+ 'additionalProperties' => '',
+ );
/**
* @var string template used as a blueprint to generate proxies
@@ -64,7 +67,7 @@ class ProxyGenerator
/**
* DO NOT EDIT THIS FILE - IT WAS CREATED BY DOCTRINE\'S PROXY GENERATOR
*/
-class <proxyClassName> extends \<className> implements \<baseProxyInterface>
+class <proxyShortClassName> extends \<className> implements \<baseProxyInterface>
{
/**
* @var \Closure the callback responsible for loading properties in the proxy object. This callback is called with
@@ -210,35 +213,6 @@ public function __construct($proxyDirectory, $proxyNamespace)
$this->proxyDirectory = $proxyDirectory;
$this->proxyNamespace = $proxyNamespace;
-
- $this->setPlaceholders(array(
- '<namespace>' => array($this, 'generateNamespace'),
- '<proxyClassName>' => array($this, 'generateProxyShortClassName'),
- '<baseProxyInterface>' => 'Doctrine\Common\Proxy\Proxy',
- '<className>' => array($this, 'generateClassName'),
- '<additionalProperties>' => '',
- '<lazyPropertiesDefaults>' => array($this, 'generateLazyPropertiesDefaults'),
- '<constructorImpl>' => array($this, 'generateConstructorImpl'),
- '<magicGet>' => array($this, 'generateMagicGet'),
- '<magicSet>' => array($this, 'generateMagicSet'),
- '<magicIsset>' => array($this, 'generateMagicIsset'),
- '<sleepImpl>' => array($this, 'generateSleepImpl'),
- '<wakeupImpl>' => array($this, 'generateWakeupImpl'),
- '<cloneImpl>' => array($this, 'generateCloneImpl'),
- '<methods>' => array($this, 'generateMethods'),
- ));
- }
-
- /**
- * Set the placeholders to be replaced in the template
- *
- * @param string[]|callable[] $placeholders
- */
- public function setPlaceholders(array $placeholders)
- {
- foreach ($placeholders as $name => $value) {
- $this->setPlaceholder($name, $value);
- }
}
/**
@@ -269,15 +243,48 @@ public function setProxyClassTemplate($proxyClassTemplate)
}
/**
- * Generate the Proxy class name
+ * Generates a proxy class file.
*
- * @param string $originalClassName
+ * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class Metadata for the original class
+ * @param string $fileName Filename (full path) for the generated class
*
- * @return string the FQCN class name of the proxy. If the proxy does not exist, it is generated
+ * @throws UnexpectedValueException
*/
- public function getProxyClassName($originalClassName)
+ public function generateProxyClass(ClassMetadata $class, $fileName = null)
{
- return ClassUtils::generateProxyClassName($originalClassName, $this->proxyNamespace);
+ preg_match_all('(<([a-zA-Z]+)>)', $this->proxyClassTemplate, $placeholderMatches);
+
+ $placeholderMatches = array_combine($placeholderMatches[0], $placeholderMatches[1]);
+ $placeholders = array();
+
+ foreach ($placeholderMatches as $placeholder => $name) {
+ $placeholders[$placeholder] = isset($this->placeholders[$name])
+ ? $this->placeholders[$name]
+ : array($this, 'generate' . $name);
+ }
+
+ foreach ($placeholders as & $placeholder) {
+ if (is_callable($placeholder)) {
+ $placeholder = call_user_func($placeholder, $class);
+ }
+ }
+
+ $proxyCode = strtr($this->proxyClassTemplate, $placeholders);
+ $fileName = $fileName ?: $this->getProxyFileName($class->getName());
+ $parentDirectory = dirname($fileName);
+
+ if ( ! is_dir($parentDirectory) && (false === @mkdir($parentDirectory, 0775, true))) {
+ throw UnexpectedValueException::proxyDirectoryNotWritable();
+ }
+
+ if ( ! is_writable($parentDirectory)) {
+ throw UnexpectedValueException::proxyDirectoryNotWritable();
+ }
+
+ $tmpFileName = $fileName . '.' . uniqid('', true);
+
+ file_put_contents($tmpFileName, $proxyCode);
+ rename($tmpFileName, $fileName);
}
/**
@@ -287,7 +294,7 @@ public function getProxyClassName($originalClassName)
*
* @return string
*/
- public function generateProxyShortClassName(ClassMetadata $class)
+ private function generateProxyShortClassName(ClassMetadata $class)
{
$proxyClassName = ClassUtils::generateProxyClassName($class->getName(), $this->proxyNamespace);
$parts = explode('\\', strrev($proxyClassName), 2);
@@ -302,7 +309,7 @@ public function generateProxyShortClassName(ClassMetadata $class)
*
* @return string
*/
- public function generateNamespace(ClassMetadata $class)
+ private function generateNamespace(ClassMetadata $class)
{
$proxyClassName = ClassUtils::generateProxyClassName($class->getName(), $this->proxyNamespace);
$parts = explode('\\', strrev($proxyClassName), 2);
@@ -317,7 +324,7 @@ public function generateNamespace(ClassMetadata $class)
*
* @return string
*/
- public function generateClassName(ClassMetadata $class)
+ private function generateClassName(ClassMetadata $class)
{
return ltrim($class->getName(), '\\');
}
@@ -329,7 +336,7 @@ public function generateClassName(ClassMetadata $class)
*
* @return string
*/
- public function generateLazyPropertiesDefaults(ClassMetadata $class)
+ private function generateLazyPropertiesDefaults(ClassMetadata $class)
{
$lazyPublicProperties = $this->getLazyLoadedPublicProperties($class);
$values = array();
@@ -348,7 +355,7 @@ public function generateLazyPropertiesDefaults(ClassMetadata $class)
*
* @return string
*/
- public function generateConstructorImpl(ClassMetadata $class)
+ private function generateConstructorImpl(ClassMetadata $class)
{
$constructorImpl = <<<'EOT'
/**
@@ -383,7 +390,7 @@ public function __construct($initializer = null, $cloner = null)
*
* @return string
*/
- public function generateMagicGet(ClassMetadata $class)
+ private function generateMagicGet(ClassMetadata $class)
{
$lazyPublicProperties = array_keys($this->getLazyLoadedPublicProperties($class));
$hasParentGet = $class->getReflectionClass()->hasMethod('__get');
@@ -441,7 +448,7 @@ public function __get(\$name)
*
* @return string
*/
- public function generateMagicSet(ClassMetadata $class)
+ private function generateMagicSet(ClassMetadata $class)
{
$lazyPublicProperties = $this->getLazyLoadedPublicProperties($class);
$hasParentSet = $class->getReflectionClass()->hasMethod('__set');
@@ -498,7 +505,7 @@ public function __set(\$name, \$value)
*
* @return string
*/
- public function generateMagicIsset(ClassMetadata $class)
+ private function generateMagicIsset(ClassMetadata $class)
{
$lazyPublicProperties = array_keys($this->getLazyLoadedPublicProperties($class));
$hasParentIsset = $class->getReflectionClass()->hasMethod('__isset');
@@ -552,7 +559,7 @@ public function __isset(\$name)
*
* @return string
*/
- public function generateSleepImpl(ClassMetadata $class)
+ private function generateSleepImpl(ClassMetadata $class)
{
$hasParentSleep = $class->getReflectionClass()->hasMethod('__sleep');
$inheritDoc = $hasParentSleep ? '{@inheritDoc}' : '';
@@ -617,7 +624,7 @@ public function __sleep()
*
* @return string
*/
- public function generateWakeupImpl(ClassMetadata $class)
+ private function generateWakeupImpl(ClassMetadata $class)
{
$unsetPublicProperties = array();
$hasWakeup = $class->getReflectionClass()->hasMethod('__wakeup');
@@ -672,7 +679,7 @@ public function __wakeup()
*
* @return string
*/
- public function generateCloneImpl(ClassMetadata $class)
+ private function generateCloneImpl(ClassMetadata $class)
{
$hasParentClone = $class->getReflectionClass()->hasMethod('__clone');
$inheritDoc = $hasParentClone ? '{@inheritDoc}' : '';
@@ -696,7 +703,7 @@ public function __clone()
*
* @return string
*/
- public function generateMethods(ClassMetadata $class)
+ private function generateMethods(ClassMetadata $class)
{
$methods = '';
$methodNames = array();
@@ -822,40 +829,6 @@ public function getProxyFileName($className, $baseDirectory = null)
}
/**
- * Generates a proxy class file.
- *
- * @param \Doctrine\Common\Persistence\Mapping\ClassMetadata $class Metadata for the original class
- * @param string $fileName Filename (full path) for the generated class
- * @param string $file The proxy class template data
- *
- * @throws UnexpectedValueException
- */
- public function generateProxyClass(ClassMetadata $class, $fileName = null, $file = null)
- {
- $placeholders = array();
-
- foreach ($this->placeholders as $name => $placeholder) {
- $placeholders[$name] = is_callable($placeholder) ? call_user_func($placeholder, $class) : $placeholder;
- }
-
- $fileName = $fileName ?: $this->getProxyFileName($class->getName());
- $file = $file ? $file : $this->proxyClassTemplate;
- $file = strtr($file, $placeholders);
-
- $parentDirectory = dirname($fileName);
-
- if ( ! is_dir($parentDirectory) && (false === @mkdir($parentDirectory, 0775, true))) {
- throw UnexpectedValueException::proxyDirectoryNotWritable();
- } elseif ( ! is_writable($parentDirectory)) {
- throw UnexpectedValueException::proxyDirectoryNotWritable();
- }
-
- $tmpFileName = $fileName . '.' . uniqid('', true);
- file_put_contents($tmpFileName, $file);
- rename($tmpFileName, $fileName);
- }
-
- /**
* Check if the method is a short identifier getter.
*
* What does this mean? For proxy objects the identifier is already known,
View
118 tests/Doctrine/Tests/Common/Proxy/AbstractProxyFactoryTest.php
@@ -0,0 +1,118 @@
+<?php
+
+namespace Doctrine\Tests\Common\Proxy;
+
+use Doctrine\Tests\DoctrineTestCase;
+use Doctrine\Common\Proxy\ProxyDefinition;
+
+class AbstractProxyFactoryTest extends DoctrineTestCase
+{
+ public function testGenerateProxyClasses()
+ {
+ $metadata = $this->getMock('Doctrine\Common\Persistence\Mapping\ClassMetadata');
+ $proxyGenerator = $this->getMock('Doctrine\Common\Proxy\ProxyGenerator', array(), array(), '', false);
+
+ $proxyGenerator
+ ->expects($this->once())
+ ->method('getProxyFileName');
+ $proxyGenerator
+ ->expects($this->once())
+ ->method('generateProxyClass');
+
+ $metadataFactory = $this->getMock('Doctrine\Common\Persistence\Mapping\ClassMetadataFactory');
+ $proxyFactory = $this->getMockForAbstractClass(
+ 'Doctrine\Common\Proxy\AbstractProxyFactory',
+ array($proxyGenerator, $metadataFactory, true)
+ );
+
+ $proxyFactory
+ ->expects($this->any())
+ ->method('skipClass')
+ ->will($this->returnValue(false));
+
+ $generated = $proxyFactory->generateProxyClasses(array($metadata), sys_get_temp_dir());
+
+ $this->assertEquals(1, $generated, 'One proxy was generated');
+ }
+
+ public function testGetProxy()
+ {
+ $metadata = $this->getMock('Doctrine\Common\Persistence\Mapping\ClassMetadata');
+ $proxy = $this->getMock('Doctrine\Common\Proxy\Proxy');
+ $definition = new ProxyDefinition(get_class($proxy), array(), array(), null, null);
+ $proxyGenerator = $this->getMock('Doctrine\Common\Proxy\ProxyGenerator', array(), array(), '', false);
+ $metadataFactory = $this->getMock('Doctrine\Common\Persistence\Mapping\ClassMetadataFactory');
+
+ $metadataFactory
+ ->expects($this->once())
+ ->method('getMetadataFor')
+ ->will($this->returnValue($metadata));
+
+ $proxyFactory = $this->getMockForAbstractClass(
+ 'Doctrine\Common\Proxy\AbstractProxyFactory',
+ array($proxyGenerator, $metadataFactory, true)
+ );
+
+ $proxyFactory
+ ->expects($this->any())
+ ->method('createProxyDefinition')
+ ->will($this->returnValue($definition));
+
+ $generatedProxy = $proxyFactory->getProxy('Class', array('id' => 1));
+
+ $this->assertInstanceOf(get_class($proxy), $generatedProxy);
+ }
+
+ public function testResetUnitializedProxy()
+ {
+ $metadata = $this->getMock('Doctrine\Common\Persistence\Mapping\ClassMetadata');
+ $proxy = $this->getMock('Doctrine\Common\Proxy\Proxy');
+ $definition = new ProxyDefinition(get_class($proxy), array(), array(), null, null);
+ $proxyGenerator = $this->getMock('Doctrine\Common\Proxy\ProxyGenerator', array(), array(), '', false);
+ $metadataFactory = $this->getMock('Doctrine\Common\Persistence\Mapping\ClassMetadataFactory');
+
+ $metadataFactory
+ ->expects($this->once())
+ ->method('getMetadataFor')
+ ->will($this->returnValue($metadata));
+
+ $proxyFactory = $this->getMockForAbstractClass(
+ 'Doctrine\Common\Proxy\AbstractProxyFactory',
+ array($proxyGenerator, $metadataFactory, true)
+ );
+
+ $proxyFactory
+ ->expects($this->any())
+ ->method('createProxyDefinition')
+ ->will($this->returnValue($definition));
+
+ $proxy
+ ->expects($this->once())
+ ->method('__isInitialized')
+ ->will($this->returnValue(false));
+ $proxy
+ ->expects($this->once())
+ ->method('__setInitializer');
+ $proxy
+ ->expects($this->once())
+ ->method('__setCloner');
+
+ $proxyFactory->resetUninitializedProxy($proxy);
+ }
+
+ public function testDisallowsResettingInitializedProxy()
+ {
+ $proxyFactory = $this->getMockForAbstractClass('Doctrine\Common\Proxy\AbstractProxyFactory', array(), '', false);
+ $proxy = $this->getMock('Doctrine\Common\Proxy\Proxy');
+
+ $proxy
+ ->expects($this->any())
+ ->method('__isInitialized')
+ ->will($this->returnValue(true));
+
+ $this->setExpectedException('Doctrine\Common\Proxy\Exception\InvalidArgumentException');
+
+ $proxyFactory->resetUninitializedProxy($proxy);
+ }
+}
+

0 comments on commit a5482b3

Please sign in to comment.
Something went wrong with that request. Please try again.