Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / doctrine / orm / tests / Doctrine / Tests / ORM / Mapping / ClassMetadataFactoryTest.php
1 <?php
2
3 namespace Doctrine\Tests\ORM\Mapping;
4
5 use Doctrine\Tests\Mocks\MetadataDriverMock;
6 use Doctrine\Tests\Mocks\EntityManagerMock;
7 use Doctrine\Tests\Mocks\ConnectionMock;
8 use Doctrine\Tests\Mocks\DriverMock;
9 use Doctrine\ORM\Mapping\ClassMetadata;
10 use Doctrine\Common\EventManager;
11 use Doctrine\ORM\Mapping\ClassMetadataFactory;
12
13 require_once __DIR__ . '/../../TestInit.php';
14
15 class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
16 {
17     public function testGetMetadataForSingleClass()
18     {
19         $mockDriver = new MetadataDriverMock();
20         $entityManager = $this->_createEntityManager($mockDriver);
21
22         $conn = $entityManager->getConnection();
23         $mockPlatform = $conn->getDatabasePlatform();
24         $mockPlatform->setPrefersSequences(true);
25         $mockPlatform->setPrefersIdentityColumns(false);
26
27         $cm1 = $this->_createValidClassMetadata();
28
29         // SUT
30         $cmf = new \Doctrine\ORM\Mapping\ClassMetadataFactory();
31         $cmf->setEntityManager($entityManager);
32         $cmf->setMetadataFor($cm1->name, $cm1);
33
34         // Prechecks
35         $this->assertEquals(array(), $cm1->parentClasses);
36         $this->assertEquals(ClassMetadata::INHERITANCE_TYPE_NONE, $cm1->inheritanceType);
37         $this->assertTrue($cm1->hasField('name'));
38         $this->assertEquals(2, count($cm1->associationMappings));
39         $this->assertEquals(ClassMetadata::GENERATOR_TYPE_AUTO, $cm1->generatorType);
40         $this->assertEquals('group', $cm1->table['name']);
41
42         // Go
43         $cmMap1 = $cmf->getMetadataFor($cm1->name);
44
45         $this->assertSame($cm1, $cmMap1);
46         $this->assertEquals('group', $cmMap1->table['name']);
47         $this->assertTrue($cmMap1->table['quoted']);
48         $this->assertEquals(array(), $cmMap1->parentClasses);
49         $this->assertTrue($cmMap1->hasField('name'));
50     }
51
52     public function testGetMetadataFor_ReturnsLoadedCustomIdGenerator()
53     {
54         $cm1 = $this->_createValidClassMetadata();
55         $cm1->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_CUSTOM);
56         $cm1->customGeneratorDefinition = array(
57             "class" => "Doctrine\Tests\ORM\Mapping\CustomIdGenerator");
58         $cmf = $this->_createTestFactory();
59         $cmf->setMetadataForClass($cm1->name, $cm1);
60
61         $actual = $cmf->getMetadataFor($cm1->name);
62
63         $this->assertEquals(ClassMetadata::GENERATOR_TYPE_CUSTOM,
64             $actual->generatorType);
65         $this->assertInstanceOf("Doctrine\Tests\ORM\Mapping\CustomIdGenerator",
66             $actual->idGenerator);
67     }
68
69     public function testGetMetadataFor_ThrowsExceptionOnUnknownCustomGeneratorClass()
70     {
71         $cm1 = $this->_createValidClassMetadata();
72         $cm1->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_CUSTOM);
73         $cm1->customGeneratorDefinition = array("class" => "NotExistingGenerator");
74         $cmf = $this->_createTestFactory();
75         $cmf->setMetadataForClass($cm1->name, $cm1);
76         $this->setExpectedException("Doctrine\ORM\ORMException");
77
78         $actual = $cmf->getMetadataFor($cm1->name);
79     }
80
81     public function testGetMetadataFor_ThrowsExceptionOnMissingCustomGeneratorDefinition()
82     {
83         $cm1 = $this->_createValidClassMetadata();
84         $cm1->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_CUSTOM);
85         $cmf = $this->_createTestFactory();
86         $cmf->setMetadataForClass($cm1->name, $cm1);
87         $this->setExpectedException("Doctrine\ORM\ORMException");
88
89         $actual = $cmf->getMetadataFor($cm1->name);
90     }
91
92     public function testHasGetMetadata_NamespaceSeperatorIsNotNormalized()
93     {
94         require_once __DIR__."/../../Models/Global/GlobalNamespaceModel.php";
95
96         $metadataDriver = $this->createAnnotationDriver(array(__DIR__ . '/../../Models/Global/'));
97
98         $entityManager = $this->_createEntityManager($metadataDriver);
99
100         $mf = $entityManager->getMetadataFactory();
101         $m1 = $mf->getMetadataFor("DoctrineGlobal_Article");
102         $h1 = $mf->hasMetadataFor("DoctrineGlobal_Article");
103         $h2 = $mf->hasMetadataFor("\DoctrineGlobal_Article");
104         $m2 = $mf->getMetadataFor("\DoctrineGlobal_Article");
105
106         $this->assertNotSame($m1, $m2);
107         $this->assertFalse($h2);
108         $this->assertTrue($h1);
109     }
110
111     /**
112      * @group DDC-1512
113      */
114     public function testIsTransient()
115     {
116         $cmf = new ClassMetadataFactory();
117         $driver = $this->getMock('Doctrine\Common\Persistence\Mapping\Driver\MappingDriver');
118         $driver->expects($this->at(0))
119                ->method('isTransient')
120                ->with($this->equalTo('Doctrine\Tests\Models\CMS\CmsUser'))
121                ->will($this->returnValue(true));
122         $driver->expects($this->at(1))
123                ->method('isTransient')
124                ->with($this->equalTo('Doctrine\Tests\Models\CMS\CmsArticle'))
125                ->will($this->returnValue(false));
126
127         $em = $this->_createEntityManager($driver);
128
129         $this->assertTrue($em->getMetadataFactory()->isTransient('Doctrine\Tests\Models\CMS\CmsUser'));
130         $this->assertFalse($em->getMetadataFactory()->isTransient('Doctrine\Tests\Models\CMS\CmsArticle'));
131     }
132
133     /**
134      * @group DDC-1512
135      */
136     public function testIsTransientEntityNamespace()
137     {
138         $cmf = new ClassMetadataFactory();
139         $driver = $this->getMock('Doctrine\Common\Persistence\Mapping\Driver\MappingDriver');
140         $driver->expects($this->at(0))
141                ->method('isTransient')
142                ->with($this->equalTo('Doctrine\Tests\Models\CMS\CmsUser'))
143                ->will($this->returnValue(true));
144         $driver->expects($this->at(1))
145                ->method('isTransient')
146                ->with($this->equalTo('Doctrine\Tests\Models\CMS\CmsArticle'))
147                ->will($this->returnValue(false));
148
149         $em = $this->_createEntityManager($driver);
150         $em->getConfiguration()->addEntityNamespace('CMS', 'Doctrine\Tests\Models\CMS');
151
152         $this->assertTrue($em->getMetadataFactory()->isTransient('CMS:CmsUser'));
153         $this->assertFalse($em->getMetadataFactory()->isTransient('CMS:CmsArticle'));
154     }
155
156     public function testAddDefaultDiscriminatorMap()
157     {
158         $cmf = new ClassMetadataFactory();
159         $driver = $this->createAnnotationDriver(array(__DIR__ . '/../../Models/JoinedInheritanceType/'));
160         $em = $this->_createEntityManager($driver);
161         $cmf->setEntityManager($em);
162
163         $rootMetadata = $cmf->getMetadataFor('Doctrine\Tests\Models\JoinedInheritanceType\RootClass');
164         $childMetadata = $cmf->getMetadataFor('Doctrine\Tests\Models\JoinedInheritanceType\ChildClass');
165         $anotherChildMetadata = $cmf->getMetadataFor('Doctrine\Tests\Models\JoinedInheritanceType\AnotherChildClass');
166         $rootDiscriminatorMap = $rootMetadata->discriminatorMap;
167         $childDiscriminatorMap = $childMetadata->discriminatorMap;
168         $anotherChildDiscriminatorMap = $anotherChildMetadata->discriminatorMap;
169
170         $rootClass = 'Doctrine\Tests\Models\JoinedInheritanceType\RootClass';
171         $childClass = 'Doctrine\Tests\Models\JoinedInheritanceType\ChildClass';
172         $anotherChildClass = 'Doctrine\Tests\Models\JoinedInheritanceType\AnotherChildClass';
173
174         $rootClassKey = array_search($rootClass, $rootDiscriminatorMap);
175         $childClassKey = array_search($childClass, $rootDiscriminatorMap);
176         $anotherChildClassKey = array_search($anotherChildClass, $rootDiscriminatorMap);
177
178         $this->assertEquals('rootclass', $rootClassKey);
179         $this->assertEquals('childclass', $childClassKey);
180         $this->assertEquals('anotherchildclass', $anotherChildClassKey);
181
182         $this->assertEquals($childDiscriminatorMap, $rootDiscriminatorMap);
183         $this->assertEquals($anotherChildDiscriminatorMap, $rootDiscriminatorMap);
184
185         // ClassMetadataFactory::addDefaultDiscriminatorMap shouldn't be called again, because the
186         // discriminator map is already cached
187         $cmf = $this->getMock('Doctrine\ORM\Mapping\ClassMetadataFactory', array('addDefaultDiscriminatorMap'));
188         $cmf->setEntityManager($em);
189         $cmf->expects($this->never())
190             ->method('addDefaultDiscriminatorMap');
191
192         $rootMetadata = $cmf->getMetadataFor('Doctrine\Tests\Models\JoinedInheritanceType\RootClass');
193     }
194
195     protected function _createEntityManager($metadataDriver)
196     {
197         $driverMock = new DriverMock();
198         $config = new \Doctrine\ORM\Configuration();
199         $config->setProxyDir(__DIR__ . '/../../Proxies');
200         $config->setProxyNamespace('Doctrine\Tests\Proxies');
201         $eventManager = new EventManager();
202         $conn = new ConnectionMock(array(), $driverMock, $config, $eventManager);
203         $mockDriver = new MetadataDriverMock();
204         $config->setMetadataDriverImpl($metadataDriver);
205
206         return EntityManagerMock::create($conn, $config, $eventManager);
207     }
208
209     /**
210      * @return ClassMetadataFactoryTestSubject
211      */
212     protected function _createTestFactory()
213     {
214         $mockDriver = new MetadataDriverMock();
215         $entityManager = $this->_createEntityManager($mockDriver);
216         $cmf = new ClassMetadataFactoryTestSubject();
217         $cmf->setEntityManager($entityManager);
218         return $cmf;
219     }
220
221     /**
222      * @param string $class
223      * @return ClassMetadata
224      */
225     protected function _createValidClassMetadata()
226     {
227         // Self-made metadata
228         $cm1 = new ClassMetadata('Doctrine\Tests\ORM\Mapping\TestEntity1');
229         $cm1->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
230         $cm1->setPrimaryTable(array('name' => '`group`'));
231         // Add a mapped field
232         $cm1->mapField(array('fieldName' => 'name', 'type' => 'varchar'));
233         // Add a mapped field
234         $cm1->mapField(array('fieldName' => 'id', 'type' => 'integer', 'id' => true));
235         // and a mapped association
236         $cm1->mapOneToOne(array('fieldName' => 'other', 'targetEntity' => 'TestEntity1', 'mappedBy' => 'this'));
237         // and an association on the owning side
238         $joinColumns = array(
239             array('name' => 'other_id', 'referencedColumnName' => 'id')
240         );
241         $cm1->mapOneToOne(array('fieldName' => 'association', 'targetEntity' => 'TestEntity1', 'joinColumns' => $joinColumns));
242         // and an id generator type
243         $cm1->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_AUTO);
244         return $cm1;
245     }
246
247     /**
248     * @group DDC-1845
249     */
250     public function testQuoteMetadata()
251     {
252         $cmf    = new ClassMetadataFactory();
253         $driver = $this->createAnnotationDriver(array(__DIR__ . '/../../Models/Quote/'));
254         $em     = $this->_createEntityManager($driver);
255         $cmf->setEntityManager($em);
256
257
258         $userMetadata       = $cmf->getMetadataFor('Doctrine\Tests\Models\Quote\User');
259         $phoneMetadata      = $cmf->getMetadataFor('Doctrine\Tests\Models\Quote\Phone');
260         $groupMetadata      = $cmf->getMetadataFor('Doctrine\Tests\Models\Quote\Group');
261         $addressMetadata    = $cmf->getMetadataFor('Doctrine\Tests\Models\Quote\Address');
262
263
264         // Phone Class Metadata
265         $this->assertTrue($phoneMetadata->fieldMappings['number']['quoted']);
266         $this->assertEquals('phone-number', $phoneMetadata->fieldMappings['number']['columnName']);
267
268         $user = $phoneMetadata->associationMappings['user'];
269         $this->assertTrue($user['joinColumns'][0]['quoted']);
270         $this->assertEquals('user-id', $user['joinColumns'][0]['name']);
271         $this->assertEquals('user-id', $user['joinColumns'][0]['referencedColumnName']);
272
273
274
275         // User Group Metadata
276         $this->assertTrue($groupMetadata->fieldMappings['id']['quoted']);
277         $this->assertTrue($groupMetadata->fieldMappings['name']['quoted']);
278
279         $this->assertEquals('user-id', $userMetadata->fieldMappings['id']['columnName']);
280         $this->assertEquals('user-name', $userMetadata->fieldMappings['name']['columnName']);
281
282         $user = $groupMetadata->associationMappings['parent'];
283         $this->assertTrue($user['joinColumns'][0]['quoted']);
284         $this->assertEquals('parent-id', $user['joinColumns'][0]['name']);
285         $this->assertEquals('group-id', $user['joinColumns'][0]['referencedColumnName']);
286
287         
288         // Address Class Metadata
289         $this->assertTrue($addressMetadata->fieldMappings['id']['quoted']);
290         $this->assertTrue($addressMetadata->fieldMappings['zip']['quoted']);
291
292         $this->assertEquals('address-id', $addressMetadata->fieldMappings['id']['columnName']);
293         $this->assertEquals('address-zip', $addressMetadata->fieldMappings['zip']['columnName']);
294
295         $user = $addressMetadata->associationMappings['user'];
296         $this->assertTrue($user['joinColumns'][0]['quoted']);
297         $this->assertEquals('user-id', $user['joinColumns'][0]['name']);
298         $this->assertEquals('user-id', $user['joinColumns'][0]['referencedColumnName']);
299
300
301
302         // User Class Metadata
303         $this->assertTrue($userMetadata->fieldMappings['id']['quoted']);
304         $this->assertTrue($userMetadata->fieldMappings['name']['quoted']);
305         
306         $this->assertEquals('user-id', $userMetadata->fieldMappings['id']['columnName']);
307         $this->assertEquals('user-name', $userMetadata->fieldMappings['name']['columnName']);
308
309         
310         $address = $userMetadata->associationMappings['address'];
311         $this->assertTrue($address['joinColumns'][0]['quoted']);
312         $this->assertEquals('address-id', $address['joinColumns'][0]['name']);
313         $this->assertEquals('address-id', $address['joinColumns'][0]['referencedColumnName']);
314
315         $groups = $userMetadata->associationMappings['groups'];
316         $this->assertTrue($groups['joinTable']['quoted']);
317         $this->assertTrue($groups['joinTable']['joinColumns'][0]['quoted']);
318         $this->assertEquals('quote-users-groups', $groups['joinTable']['name']);
319         $this->assertEquals('user-id', $groups['joinTable']['joinColumns'][0]['name']);
320         $this->assertEquals('user-id', $groups['joinTable']['joinColumns'][0]['referencedColumnName']);
321
322         $this->assertTrue($groups['joinTable']['inverseJoinColumns'][0]['quoted']);
323         $this->assertEquals('group-id', $groups['joinTable']['inverseJoinColumns'][0]['name']);
324         $this->assertEquals('group-id', $groups['joinTable']['inverseJoinColumns'][0]['referencedColumnName']);
325     }
326 }
327
328 /* Test subject class with overriden factory method for mocking purposes */
329 class ClassMetadataFactoryTestSubject extends \Doctrine\ORM\Mapping\ClassMetadataFactory
330 {
331     private $mockMetadata = array();
332     private $requestedClasses = array();
333
334     /** @override */
335     protected function newClassMetadataInstance($className)
336     {
337         $this->requestedClasses[] = $className;
338         if ( ! isset($this->mockMetadata[$className])) {
339             throw new InvalidArgumentException("No mock metadata found for class $className.");
340         }
341         return $this->mockMetadata[$className];
342     }
343
344     public function setMetadataForClass($className, $metadata)
345     {
346         $this->mockMetadata[$className] = $metadata;
347     }
348
349     public function getRequestedClasses()
350     {
351         return $this->requestedClasses;
352     }
353 }
354
355 class TestEntity1
356 {
357     private $id;
358     private $name;
359     private $other;
360     private $association;
361 }
362
363 class CustomIdGenerator extends \Doctrine\ORM\Id\AbstractIdGenerator
364 {
365     public function generate(\Doctrine\ORM\EntityManager $em, $entity)
366     {
367     }
368 }