From 66f377fb12c2048a73b7f195a27f3fac49d57445 Mon Sep 17 00:00:00 2001 From: piccoloprincipe Date: Fri, 17 Jul 2009 12:43:37 +0000 Subject: [PATCH] [2.0] extended tests for proxy class generation --- .../ORM/Proxy/ProxyClassGenerator.php | 44 +++++++------- .../ORM/Proxy/ProxyClassGeneratorTest.php | 59 ++++++++++++++++--- 2 files changed, 73 insertions(+), 30 deletions(-) diff --git a/lib/Doctrine/ORM/Proxy/ProxyClassGenerator.php b/lib/Doctrine/ORM/Proxy/ProxyClassGenerator.php index 538034ba5..d15b668b3 100644 --- a/lib/Doctrine/ORM/Proxy/ProxyClassGenerator.php +++ b/lib/Doctrine/ORM/Proxy/ProxyClassGenerator.php @@ -58,24 +58,26 @@ class ProxyClassGenerator * Generates a reference proxy class. * This is a proxy for an object which we have the id for retrieval. * - * @param string $className - * @param string $proxyClassName - * @param string $fileName + * @param string $originalClassName + * @return string name of the proxy class */ - public function generateReferenceProxyClass($className) + public function generateReferenceProxyClass($originalClassName) { - $class = $this->_em->getClassMetadata($className); - $proxyClassName = str_replace('\\', '_', $className) . 'RProxy'; + $proxyClassName = str_replace('\\', '_', $originalClassName) . 'RProxy'; + //$proxyClassName = $originalClassName . 'RProxy'; + $proxyFullyQualifiedClassName = self::$_ns . $proxyClassName; - if ( ! class_exists($proxyClassName, false)) { - $this->_em->getMetadataFactory()->setMetadataFor(self::$_ns . $proxyClassName, $class); - $fileName = $this->_cacheDir . $proxyClassName . '.g.php'; + if (class_exists($proxyFullyQualifiedClassName, false)) { + return $proxyFullyQualifiedClassName; + } + + $class = $this->_em->getClassMetadata($originalClassName); + $this->_em->getMetadataFactory()->setMetadataFor($proxyFullyQualifiedClassName, $class); + $fileName = $this->_cacheDir . $proxyClassName . '.g.php'; - if (file_exists($fileName)) { - require $fileName; - $proxyClassName = '\\' . self::$_ns . $proxyClassName; - return $proxyClassName; - } + if (file_exists($fileName)) { + require $fileName; + return $proxyFullyQualifiedClassName; } $file = self::$_proxyClassTemplate; @@ -87,7 +89,7 @@ class ProxyClassGenerator '', '' ); $replacements = array( - $proxyClassName, $className, $methods, $sleepImpl + $proxyClassName, $originalClassName, $methods, $sleepImpl ); $file = str_replace($placeholders, $replacements, $file); @@ -95,9 +97,7 @@ class ProxyClassGenerator file_put_contents($fileName, $file); require $fileName; - $proxyClassName = '\\' . self::$_ns . $proxyClassName; - - return $proxyClassName; + return $proxyFullyQualifiedClassName; } protected function _generateMethods(ClassMetadata $class) @@ -172,12 +172,12 @@ class ProxyClassGenerator * This is a proxy class for an object which we have the association where * it is involved, but no primary key to retrieve it. * - * @param string $className + * @param string $originalClassName * @param string $proxyClassName */ - public function generateAssociationProxyClass($className, $proxyClassName) + public function generateAssociationProxyClass($originalClassName, $proxyClassName) { - $class = $this->_em->getClassMetadata($className); + $class = $this->_em->getClassMetadata($originalClassName); $file = self::$_assocProxyClassTemplate; $methods = ''; @@ -231,7 +231,7 @@ class ProxyClassGenerator '', '' ); $replacements = array( - $proxyClassName, $className, $methods, $sleepImpl + $proxyClassName, $originalClassName, $methods, $sleepImpl ); $file = str_replace($placeholders, $replacements, $file); diff --git a/tests/Doctrine/Tests/ORM/Proxy/ProxyClassGeneratorTest.php b/tests/Doctrine/Tests/ORM/Proxy/ProxyClassGeneratorTest.php index 62460d3dd..dca11547e 100644 --- a/tests/Doctrine/Tests/ORM/Proxy/ProxyClassGeneratorTest.php +++ b/tests/Doctrine/Tests/ORM/Proxy/ProxyClassGeneratorTest.php @@ -9,6 +9,7 @@ use Doctrine\Tests\Models\ECommerce\ECommerceCart; use Doctrine\Tests\Models\ECommerce\ECommerceCustomer; use Doctrine\Tests\Models\ECommerce\ECommerceFeature; use Doctrine\Tests\Models\ECommerce\ECommerceShipping; +use Doctrine\ORM\Persisters\StandardEntityPersister; require_once __DIR__ . '/../../TestInit.php'; @@ -59,15 +60,57 @@ class ProxyClassGeneratorTest extends \Doctrine\Tests\OrmTestCase $this->assertTrue(is_subclass_of($proxyClass, '\Doctrine\Tests\Models\ECommerce\ECommerceCart')); } - public function _testGenerateProxiesWhichForwardsToTheModelWithTheGivenIdentifier() + public function testAllowsIdempotentCreationOfProxyClass() { - $feature = new ECommerceFeature; - $feature->setDescription('An interesting feature'); - $this->_emMock->save($feature); - $id = $feature->getId(); - $this->_emMock->clear(); + $proxyClass = $this->_generator->generateReferenceProxyClass('Doctrine\Tests\Models\ECommerce\ECommerceFeature'); + $theSameProxyClass = $this->_generator->generateReferenceProxyClass('Doctrine\Tests\Models\ECommerce\ECommerceFeature'); + $this->assertEquals($proxyClass, $theSameProxyClass); + } - $proxy = $this->_generator->generateReferenceProxyClass('Doctrine\Tests\Models\ECommerce\ECommerceFeature', 1); - $this->assertEquals('An interesting feature', $proxy->getDescription()); + public function testCreatesClassesThatRequirePersisterInTheConstructor() + { + $proxyClass = $this->_generator->generateReferenceProxyClass('Doctrine\Tests\Models\ECommerce\ECommerceFeature'); + $proxy = new $proxyClass($this->_getMockPersister(), null); + } + + public function testCreatesClassesThatDelegateLoadingToThePersister() + { + $identifier = array('id' => 42); + $proxyClass = $this->_generator->generateReferenceProxyClass('Doctrine\Tests\Models\ECommerce\ECommerceFeature'); + $persister = $this->_getMockPersister(); + $proxy = new $proxyClass($persister, $identifier); + $persister->expects($this->any()) + ->method('load') + ->with($this->equalTo($identifier), $this->isInstanceOf($proxyClass)); + $proxy->getDescription(); + } + + public function testCreatesClassesThatExecutesLoadingOnlyOnce() + { + $identifier = array('id' => 42); + $proxyClass = $this->_generator->generateReferenceProxyClass('Doctrine\Tests\Models\ECommerce\ECommerceFeature'); + $persister = $this->_getMockPersister(); + $proxy = new $proxyClass($persister, $identifier); + $persister->expects($this->once()) + ->method('load') + ->with($this->equalTo($identifier), $this->isInstanceOf($proxyClass)); + $proxy->getId(); + $proxy->getDescription(); + } + + /** + * @expectedException PHPUnit_Framework_Error + */ + public function testRespectsMethodsParametersTypeHinting() + { + $proxyClass = $this->_generator->generateReferenceProxyClass('Doctrine\Tests\Models\ECommerce\ECommerceFeature'); + $proxy = new $proxyClass($this->_getMockPersister(), null); + $proxy->setProduct(array('invalid parameter')); + } + + protected function _getMockPersister() + { + $persister = $this->getMock('Doctrine\ORM\Persisters\StandardEntityPersister', array('load'), array(), '', false); + return $persister; } }