ProxyClassGeneratorTest.php 6.18 KB
Newer Older
1 2
<?php

3
namespace Doctrine\Tests\ORM\Proxy;
4

5
use Doctrine\ORM\Proxy\ProxyFactory;
6 7
use Doctrine\Tests\Mocks\ConnectionMock;
use Doctrine\Tests\Mocks\EntityManagerMock;
8
use Doctrine\Tests\Mocks\UnitOfWorkMock;
9 10 11
use Doctrine\Tests\Models\ECommerce\ECommerceCart;
use Doctrine\Tests\Models\ECommerce\ECommerceCustomer;
use Doctrine\Tests\Models\ECommerce\ECommerceFeature;
12
use Doctrine\Tests\Models\ECommerce\ECommerceProduct;
13 14 15 16 17 18
use Doctrine\Tests\Models\ECommerce\ECommerceShipping;

require_once __DIR__ . '/../../TestInit.php';

/**
 * Test the proxy generator. Its work is generating on-the-fly subclasses of a given model, which implement the Proxy pattern.
19
 * @author Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
20
 */
21
class ProxyClassGeneratorTest extends \Doctrine\Tests\OrmTestCase
22 23
{
    private $_connectionMock;
24
    private $_uowMock;
25
    private $_emMock;
26 27 28 29

    /**
     * @var \Doctrine\ORM\Proxy\ProxyFactory
     */
30
    private $_proxyFactory;
31 32 33 34 35 36
    
    protected function setUp()
    {
        parent::setUp();
        $this->_connectionMock = new ConnectionMock(array(), new \Doctrine\Tests\Mocks\DriverMock());
        $this->_emMock = EntityManagerMock::create($this->_connectionMock);
37 38 39 40
        $this->_uowMock = new UnitOfWorkMock($this->_emMock);
        $this->_emMock->setUnitOfWork($this->_uowMock);
        // SUT
        $this->_proxyFactory = new ProxyFactory($this->_emMock, __DIR__ . '/generated', 'Proxies', true);
41 42 43 44 45 46 47 48 49 50 51
    }
    
    protected function tearDown()
    {
        foreach (new \DirectoryIterator(__DIR__ . '/generated') as $file) {
            if (strstr($file->getFilename(), '.php')) {
                unlink($file->getPathname());
            }
        }
    }

52
    public function testReferenceProxyDelegatesLoadingToThePersister()
53 54
    {
        $identifier = array('id' => 42);
55
        $proxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureProxy';
56
        $persister = $this->_getMockPersister();
57 58
        $this->_uowMock->setEntityPersister('Doctrine\Tests\Models\ECommerce\ECommerceFeature', $persister);
        
59
        $proxy = $this->_proxyFactory->getProxy('Doctrine\Tests\Models\ECommerce\ECommerceFeature', $identifier);
60
        
61
        $persister->expects($this->atLeastOnce())
62 63
                  ->method('load')
                  ->with($this->equalTo($identifier), $this->isInstanceOf($proxyClass));
64
        
65 66
        $proxy->getDescription();
    }
67

68
    public function testReferenceProxyExecutesLoadingOnlyOnce()
69 70
    {
        $identifier = array('id' => 42);
71
        $proxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureProxy';
72
        $persister = $this->_getMockPersister();
73
        $this->_uowMock->setEntityPersister('Doctrine\Tests\Models\ECommerce\ECommerceFeature', $persister);
74
        $proxy = $this->_proxyFactory->getProxy('Doctrine\Tests\Models\ECommerce\ECommerceFeature', $identifier);
75
        $persister->expects($this->atLeastOnce())
76 77 78 79 80 81
                  ->method('load')
                  ->with($this->equalTo($identifier), $this->isInstanceOf($proxyClass));
        $proxy->getId();
        $proxy->getDescription();
    }

82
    public function testReferenceProxyRespectsMethodsParametersTypeHinting()
83
    {
84
        $proxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureProxy';
85 86
        $persister = $this->_getMockPersister();
        $this->_uowMock->setEntityPersister('Doctrine\Tests\Models\ECommerce\ECommerceFeature', $persister);
87
        $proxy = $this->_proxyFactory->getProxy('Doctrine\Tests\Models\ECommerce\ECommerceFeature', null);
88 89 90 91 92 93
        
        $method = new \ReflectionMethod(get_class($proxy), 'setProduct');
        $params = $method->getParameters();
        
        $this->assertEquals(1, count($params));
        $this->assertEquals('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $params[0]->getClass()->getName());
94 95
    }

96 97
    public function testCreatesAssociationProxyAsSubclassOfTheOriginalOne()
    {
98
        $proxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureProxy';
99
        $this->assertTrue(is_subclass_of($proxyClass, 'Doctrine\Tests\Models\ECommerce\ECommerceFeature'));
100 101 102 103 104
    }


    public function testAllowsConcurrentCreationOfBothProxyTypes()
    {
105
        $referenceProxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureProxy';
106
        $associationProxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureAProxy';
107 108 109
        $this->assertNotEquals($referenceProxyClass, $associationProxyClass);
    }

110
    public function testNonNamespacedProxyGeneration()
111
    {
112 113 114 115 116 117 118 119 120 121 122 123 124 125
        require_once dirname(__FILE__)."/fixtures/NonNamespacedProxies.php";

        $className = "\DoctrineOrmTestEntity";
        $proxyName = "DoctrineOrmTestEntityProxy";
        $classMetadata = new \Doctrine\ORM\Mapping\ClassMetadata($className);
        $classMetadata->mapField(array('fieldName' => 'id', 'type' => 'integer'));
        $classMetadata->setIdentifier(array('id'));

        $this->_proxyFactory->generateProxyClasses(array($classMetadata));

        $classCode = file_get_contents(dirname(__FILE__)."/generated/".$proxyName.".php");
        
        $this->assertNotContains("class DoctrineOrmTestEntityProxy extends \\\\DoctrineOrmTestEntity", $classCode);
        $this->assertContains("class DoctrineOrmTestEntityProxy extends \\DoctrineOrmTestEntity", $classCode);
126
    }
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141

    public function testClassWithSleepProxyGeneration()
    {
        $className = "\Doctrine\Tests\ORM\Proxy\SleepClass";
        $proxyName = "DoctrineTestsORMProxySleepClassProxy";
        $classMetadata = new \Doctrine\ORM\Mapping\ClassMetadata($className);
        $classMetadata->mapField(array('fieldName' => 'id', 'type' => 'integer'));
        $classMetadata->setIdentifier(array('id'));

        $this->_proxyFactory->generateProxyClasses(array($classMetadata));

        $classCode = file_get_contents(dirname(__FILE__)."/generated/".$proxyName.".php");

        $this->assertEquals(1, substr_count($classCode, 'function __sleep'));
    }
142 143 144 145 146 147
    
    protected function _getMockPersister()
    {
        $persister = $this->getMock('Doctrine\ORM\Persisters\StandardEntityPersister', array('load'), array(), '', false, false, false);
        return $persister;
    }
148
}
149 150 151 152 153 154 155 156 157 158

class SleepClass
{
    public $id;

    public function __sleep()
    {
        return array('id');
    }
}