Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / doctrine / orm / tests / Doctrine / Tests / ORM / Mapping / ClassMetadataTest.php
1 <?php
2
3 namespace Doctrine\Tests\ORM\Mapping;
4
5 use Doctrine\ORM\Mapping\ClassMetadata;
6 use Doctrine\ORM\Events;
7
8 require_once __DIR__ . '/../../TestInit.php';
9 require_once __DIR__ . '/../../Models/Global/GlobalNamespaceModel.php';
10
11 class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
12 {
13     public function testClassMetadataInstanceSerialization()
14     {
15         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
16         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
17
18         // Test initial state
19         $this->assertTrue(count($cm->getReflectionProperties()) == 0);
20         $this->assertInstanceOf('ReflectionClass', $cm->reflClass);
21         $this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $cm->name);
22         $this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $cm->rootEntityName);
23         $this->assertEquals(array(), $cm->subClasses);
24         $this->assertEquals(array(), $cm->parentClasses);
25         $this->assertEquals(ClassMetadata::INHERITANCE_TYPE_NONE, $cm->inheritanceType);
26
27         // Customize state
28         $cm->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE);
29         $cm->setSubclasses(array("One", "Two", "Three"));
30         $cm->setParentClasses(array("UserParent"));
31         $cm->setCustomRepositoryClass("UserRepository");
32         $cm->setDiscriminatorColumn(array('name' => 'disc', 'type' => 'integer'));
33         $cm->mapOneToOne(array('fieldName' => 'phonenumbers', 'targetEntity' => 'CmsAddress', 'mappedBy' => 'foo'));
34         $cm->markReadOnly();
35         $cm->addNamedQuery(array('name' => 'dql', 'query' => 'foo'));
36         $this->assertEquals(1, count($cm->associationMappings));
37
38         $serialized = serialize($cm);
39         $cm = unserialize($serialized);
40         $cm->wakeupReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
41
42         // Check state
43         $this->assertTrue(count($cm->getReflectionProperties()) > 0);
44         $this->assertEquals('Doctrine\Tests\Models\CMS', $cm->namespace);
45         $this->assertInstanceOf('ReflectionClass', $cm->reflClass);
46         $this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $cm->name);
47         $this->assertEquals('UserParent', $cm->rootEntityName);
48         $this->assertEquals(array('Doctrine\Tests\Models\CMS\One', 'Doctrine\Tests\Models\CMS\Two', 'Doctrine\Tests\Models\CMS\Three'), $cm->subClasses);
49         $this->assertEquals(array('UserParent'), $cm->parentClasses);
50         $this->assertEquals('Doctrine\Tests\Models\CMS\UserRepository', $cm->customRepositoryClassName);
51         $this->assertEquals(array('name' => 'disc', 'type' => 'integer', 'fieldName' => 'disc'), $cm->discriminatorColumn);
52         $this->assertTrue($cm->associationMappings['phonenumbers']['type'] == ClassMetadata::ONE_TO_ONE);
53         $this->assertEquals(1, count($cm->associationMappings));
54         $oneOneMapping = $cm->getAssociationMapping('phonenumbers');
55         $this->assertTrue($oneOneMapping['fetch'] == ClassMetadata::FETCH_LAZY);
56         $this->assertEquals('phonenumbers', $oneOneMapping['fieldName']);
57         $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddress', $oneOneMapping['targetEntity']);
58         $this->assertTrue($cm->isReadOnly);
59         $this->assertEquals(array('dql' => array('name'=>'dql','query'=>'foo','dql'=>'foo')), $cm->namedQueries);
60     }
61
62     public function testFieldIsNullable()
63     {
64         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
65         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
66
67         // Explicit Nullable
68         $cm->mapField(array('fieldName' => 'status', 'nullable' => true, 'type' => 'string', 'length' => 50));
69         $this->assertTrue($cm->isNullable('status'));
70
71         // Explicit Not Nullable
72         $cm->mapField(array('fieldName' => 'username', 'nullable' => false, 'type' => 'string', 'length' => 50));
73         $this->assertFalse($cm->isNullable('username'));
74
75         // Implicit Not Nullable
76         $cm->mapField(array('fieldName' => 'name', 'type' => 'string', 'length' => 50));
77         $this->assertFalse($cm->isNullable('name'), "By default a field should not be nullable.");
78     }
79
80     /**
81      * @group DDC-115
82      */
83     public function testMapAssocationInGlobalNamespace()
84     {
85         require_once __DIR__."/../../Models/Global/GlobalNamespaceModel.php";
86
87         $cm = new ClassMetadata('DoctrineGlobal_Article');
88         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
89         $cm->mapManyToMany(array(
90             'fieldName' => 'author',
91             'targetEntity' => 'DoctrineGlobal_User',
92             'joinTable' => array(
93                 'name' => 'bar',
94                 'joinColumns' => array(array('name' => 'bar_id', 'referencedColumnName' => 'id')),
95                 'inverseJoinColumns' => array(array('name' => 'baz_id', 'referencedColumnName' => 'id')),
96             ),
97         ));
98
99         $this->assertEquals("DoctrineGlobal_User", $cm->associationMappings['author']['targetEntity']);
100     }
101
102     public function testMapManyToManyJoinTableDefaults()
103     {
104         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
105         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
106         $cm->mapManyToMany(
107             array(
108             'fieldName' => 'groups',
109             'targetEntity' => 'CmsGroup'
110         ));
111
112         $assoc = $cm->associationMappings['groups'];
113         //$this->assertInstanceOf('Doctrine\ORM\Mapping\ManyToManyMapping', $assoc);
114         $this->assertEquals(array(
115             'name' => 'cmsuser_cmsgroup',
116             'joinColumns' => array(array('name' => 'cmsuser_id', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE')),
117             'inverseJoinColumns' => array(array('name' => 'cmsgroup_id', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE'))
118         ), $assoc['joinTable']);
119         $this->assertTrue($assoc['isOnDeleteCascade']);
120     }
121
122     public function testSerializeManyToManyJoinTableCascade()
123     {
124         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
125         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
126         $cm->mapManyToMany(
127             array(
128             'fieldName' => 'groups',
129             'targetEntity' => 'CmsGroup'
130         ));
131
132         /* @var $assoc \Doctrine\ORM\Mapping\ManyToManyMapping */
133         $assoc = $cm->associationMappings['groups'];
134         $assoc = unserialize(serialize($assoc));
135
136         $this->assertTrue($assoc['isOnDeleteCascade']);
137     }
138
139     /**
140      * @group DDC-115
141      */
142     public function testSetDiscriminatorMapInGlobalNamespace()
143     {
144         require_once __DIR__."/../../Models/Global/GlobalNamespaceModel.php";
145
146         $cm = new ClassMetadata('DoctrineGlobal_User');
147         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
148         $cm->setDiscriminatorMap(array('descr' => 'DoctrineGlobal_Article', 'foo' => 'DoctrineGlobal_User'));
149
150         $this->assertEquals("DoctrineGlobal_Article", $cm->discriminatorMap['descr']);
151         $this->assertEquals("DoctrineGlobal_User", $cm->discriminatorMap['foo']);
152     }
153
154     /**
155      * @group DDC-115
156      */
157     public function testSetSubClassesInGlobalNamespace()
158     {
159         require_once __DIR__."/../../Models/Global/GlobalNamespaceModel.php";
160
161         $cm = new ClassMetadata('DoctrineGlobal_User');
162         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
163         $cm->setSubclasses(array('DoctrineGlobal_Article'));
164
165         $this->assertEquals("DoctrineGlobal_Article", $cm->subClasses[0]);
166     }
167
168     /**
169      * @group DDC-268
170      */
171     public function testSetInvalidVersionMapping_ThrowsException()
172     {
173         $field = array();
174         $field['fieldName'] = 'foo';
175         $field['type'] = 'string';
176
177         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
178         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
179
180         $this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
181         $cm->setVersionMapping($field);
182     }
183
184     public function testGetSingleIdentifierFieldName_MultipleIdentifierEntity_ThrowsException()
185     {
186         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
187         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
188         $cm->isIdentifierComposite  = true;
189
190         $this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
191         $cm->getSingleIdentifierFieldName();
192     }
193
194     public function testDuplicateAssociationMappingException()
195     {
196         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
197         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
198
199         $a1 = array('fieldName' => 'foo', 'sourceEntity' => 'stdClass', 'targetEntity' => 'stdClass', 'mappedBy' => 'foo');
200         $a2 = array('fieldName' => 'foo', 'sourceEntity' => 'stdClass', 'targetEntity' => 'stdClass', 'mappedBy' => 'foo');
201
202         $cm->addInheritedAssociationMapping($a1);
203         $this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
204         $cm->addInheritedAssociationMapping($a2);
205     }
206
207     public function testDuplicateColumnName_ThrowsMappingException()
208     {
209         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
210         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
211
212         $cm->mapField(array('fieldName' => 'name', 'columnName' => 'name'));
213
214         $this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
215         $cm->mapField(array('fieldName' => 'username', 'columnName' => 'name'));
216     }
217
218     public function testDuplicateColumnName_DiscriminatorColumn_ThrowsMappingException()
219     {
220         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
221         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
222
223         $cm->mapField(array('fieldName' => 'name', 'columnName' => 'name'));
224
225         $this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
226         $cm->setDiscriminatorColumn(array('name' => 'name'));
227     }
228
229     public function testDuplicateColumnName_DiscriminatorColumn2_ThrowsMappingException()
230     {
231         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
232         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
233
234         $cm->setDiscriminatorColumn(array('name' => 'name'));
235
236         $this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
237         $cm->mapField(array('fieldName' => 'name', 'columnName' => 'name'));
238     }
239
240     public function testDuplicateFieldAndAssocationMapping1_ThrowsException()
241     {
242         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
243         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
244
245         $cm->mapField(array('fieldName' => 'name', 'columnName' => 'name'));
246
247         $this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
248         $cm->mapOneToOne(array('fieldName' => 'name', 'targetEntity' => 'CmsUser'));
249     }
250
251     public function testDuplicateFieldAndAssocationMapping2_ThrowsException()
252     {
253         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
254         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
255
256         $cm->mapOneToOne(array('fieldName' => 'name', 'targetEntity' => 'CmsUser'));
257
258         $this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
259         $cm->mapField(array('fieldName' => 'name', 'columnName' => 'name'));
260     }
261
262     /**
263      * @group DDC-1224
264      */
265     public function testGetTemporaryTableNameSchema()
266     {
267         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
268         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
269
270         $cm->setTableName('foo.bar');
271
272         $this->assertEquals('foo_bar_id_tmp', $cm->getTemporaryIdTableName());
273     }
274
275     public function testDefaultTableName()
276     {
277         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
278         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
279
280         // When table's name is not given
281         $primaryTable = array();
282         $cm->setPrimaryTable($primaryTable);
283
284         $this->assertEquals('CmsUser', $cm->getTableName());
285         $this->assertEquals('CmsUser', $cm->table['name']);
286
287         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
288         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
289         // When joinTable's name is not given
290         $cm->mapManyToMany(array(
291             'fieldName' => 'user',
292             'targetEntity' => 'CmsUser',
293             'inversedBy' => 'users',
294             'joinTable' => array('joinColumns' => array(array('referencedColumnName' => 'id')),
295                                  'inverseJoinColumns' => array(array('referencedColumnName' => 'id')))));
296         $this->assertEquals('cmsaddress_cmsuser', $cm->associationMappings['user']['joinTable']['name']);
297     }
298
299     public function testDefaultJoinColumnName()
300     {
301         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
302         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
303
304         // this is really dirty, but it's the simpliest way to test whether
305         // joinColumn's name will be automatically set to user_id
306         $cm->mapOneToOne(array(
307             'fieldName' => 'user',
308             'targetEntity' => 'CmsUser',
309             'joinColumns' => array(array('referencedColumnName' => 'id'))));
310         $this->assertEquals('user_id', $cm->associationMappings['user']['joinColumns'][0]['name']);
311
312         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
313         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
314         $cm->mapManyToMany(array(
315             'fieldName' => 'user',
316             'targetEntity' => 'CmsUser',
317             'inversedBy' => 'users',
318             'joinTable' => array('name' => 'user_CmsUser',
319                                 'joinColumns' => array(array('referencedColumnName' => 'id')),
320                                 'inverseJoinColumns' => array(array('referencedColumnName' => 'id')))));
321         $this->assertEquals('cmsaddress_id', $cm->associationMappings['user']['joinTable']['joinColumns'][0]['name']);
322         $this->assertEquals('cmsuser_id', $cm->associationMappings['user']['joinTable']['inverseJoinColumns'][0]['name']);
323     }
324
325     /**
326      * @group DDC-559
327      */
328     public function testUnderscoreNamingStrategyDefaults()
329     {
330         $namingStrategy     = new \Doctrine\ORM\Mapping\UnderscoreNamingStrategy(CASE_UPPER);
331         $oneToOneMetadata   = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress', $namingStrategy);
332         $manyToManyMetadata = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress', $namingStrategy);
333
334         $oneToOneMetadata->mapOneToOne(array(
335             'fieldName'     => 'user',
336             'targetEntity'  => 'CmsUser'
337         ));
338
339         $manyToManyMetadata->mapManyToMany(array(
340             'fieldName'     => 'user',
341             'targetEntity'  => 'CmsUser'
342         ));
343         
344         $this->assertEquals(array('USER_ID'=>'ID'), $oneToOneMetadata->associationMappings['user']['sourceToTargetKeyColumns']);
345         $this->assertEquals(array('USER_ID'=>'USER_ID'), $oneToOneMetadata->associationMappings['user']['joinColumnFieldNames']);
346         $this->assertEquals(array('ID'=>'USER_ID'), $oneToOneMetadata->associationMappings['user']['targetToSourceKeyColumns']);
347
348         $this->assertEquals('USER_ID', $oneToOneMetadata->associationMappings['user']['joinColumns'][0]['name']);
349         $this->assertEquals('ID', $oneToOneMetadata->associationMappings['user']['joinColumns'][0]['referencedColumnName']);
350
351         
352         $this->assertEquals('CMS_ADDRESS_CMS_USER', $manyToManyMetadata->associationMappings['user']['joinTable']['name']);
353
354         $this->assertEquals(array('CMS_ADDRESS_ID','CMS_USER_ID'), $manyToManyMetadata->associationMappings['user']['joinTableColumns']);
355         $this->assertEquals(array('CMS_ADDRESS_ID'=>'ID'), $manyToManyMetadata->associationMappings['user']['relationToSourceKeyColumns']);
356         $this->assertEquals(array('CMS_USER_ID'=>'ID'), $manyToManyMetadata->associationMappings['user']['relationToTargetKeyColumns']);
357
358         $this->assertEquals('CMS_ADDRESS_ID', $manyToManyMetadata->associationMappings['user']['joinTable']['joinColumns'][0]['name']);
359         $this->assertEquals('CMS_USER_ID', $manyToManyMetadata->associationMappings['user']['joinTable']['inverseJoinColumns'][0]['name']);
360
361         $this->assertEquals('ID', $manyToManyMetadata->associationMappings['user']['joinTable']['joinColumns'][0]['referencedColumnName']);
362         $this->assertEquals('ID', $manyToManyMetadata->associationMappings['user']['joinTable']['inverseJoinColumns'][0]['referencedColumnName']);
363
364
365         $cm = new ClassMetadata('DoctrineGlobal_Article', $namingStrategy);
366         $cm->mapManyToMany(array('fieldName' => 'author', 'targetEntity' => 'Doctrine\Tests\Models\CMS\CmsUser'));
367         $this->assertEquals('DOCTRINE_GLOBAL_ARTICLE_CMS_USER', $cm->associationMappings['author']['joinTable']['name']);
368     }
369
370     /**
371      * @group DDC-886
372      */
373     public function testSetMultipleIdentifierSetsComposite()
374     {
375         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
376         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
377
378         $cm->mapField(array('fieldName' => 'name'));
379         $cm->mapField(array('fieldName' => 'username'));
380
381         $cm->setIdentifier(array('name', 'username'));
382         $this->assertTrue($cm->isIdentifierComposite);
383     }
384
385     /**
386      * @group DDC-944
387      */
388     public function testMappingNotFound()
389     {
390         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
391         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
392
393         $this->setExpectedException('Doctrine\ORM\Mapping\MappingException', "No mapping found for field 'foo' on class 'Doctrine\Tests\Models\CMS\CmsUser'.");
394         $cm->getFieldMapping('foo');
395     }
396
397     /**
398      * @group DDC-961
399      */
400     public function testJoinTableMappingDefaults()
401     {
402         $cm = new ClassMetadata('DoctrineGlobal_Article');
403         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
404
405         $cm->mapManyToMany(array('fieldName' => 'author', 'targetEntity' => 'Doctrine\Tests\Models\CMS\CmsUser'));
406
407         $this->assertEquals('doctrineglobal_article_cmsuser', $cm->associationMappings['author']['joinTable']['name']);
408     }
409
410     /**
411      * @group DDC-117
412      */
413     public function testMapIdentifierAssociation()
414     {
415         $cm = new ClassMetadata('Doctrine\Tests\Models\DDC117\DDC117ArticleDetails');
416         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
417
418         $cm->mapOneToOne(array(
419             'fieldName' => 'article',
420             'id' => true,
421             'targetEntity' => 'Doctrine\Tests\Models\DDC117\DDC117Article',
422             'joinColumns' => array(),
423         ));
424
425         $this->assertTrue($cm->containsForeignIdentifier, "Identifier Association should set 'containsForeignIdentifier' boolean flag.");
426         $this->assertEquals(array("article"), $cm->identifier);
427     }
428
429     /**
430      * @group DDC-117
431      */
432     public function testOrphanRemovalIdentifierAssociation()
433     {
434         $cm = new ClassMetadata('Doctrine\Tests\Models\DDC117\DDC117ArticleDetails');
435         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
436
437         $this->setExpectedException('Doctrine\ORM\Mapping\MappingException', 'The orphan removal option is not allowed on an association that');
438         $cm->mapOneToOne(array(
439             'fieldName' => 'article',
440             'id' => true,
441             'targetEntity' => 'Doctrine\Tests\Models\DDC117\DDC117Article',
442             'orphanRemoval' => true,
443             'joinColumns' => array(),
444         ));
445     }
446
447     /**
448      * @group DDC-117
449      */
450     public function testInverseIdentifierAssocation()
451     {
452         $cm = new ClassMetadata('Doctrine\Tests\Models\DDC117\DDC117ArticleDetails');
453         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
454
455
456         $this->setExpectedException('Doctrine\ORM\Mapping\MappingException', 'An inverse association is not allowed to be identifier in');
457         $cm->mapOneToOne(array(
458             'fieldName' => 'article',
459             'id' => true,
460             'mappedBy' => 'details', // INVERSE!
461             'targetEntity' => 'Doctrine\Tests\Models\DDC117\DDC117Article',
462             'joinColumns' => array(),
463         ));
464     }
465
466     /**
467      * @group DDC-117
468      */
469     public function testIdentifierAssocationManyToMany()
470     {
471         $cm = new ClassMetadata('Doctrine\Tests\Models\DDC117\DDC117ArticleDetails');
472         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
473
474
475         $this->setExpectedException('Doctrine\ORM\Mapping\MappingException', 'Many-to-many or one-to-many associations are not allowed to be identifier in');
476         $cm->mapManyToMany(array(
477             'fieldName' => 'article',
478             'id' => true,
479             'targetEntity' => 'Doctrine\Tests\Models\DDC117\DDC117Article',
480             'joinColumns' => array(),
481         ));
482     }
483
484     /**
485      * @group DDC-996
486      */
487     public function testEmptyFieldNameThrowsException()
488     {
489         $this->setExpectedException('Doctrine\ORM\Mapping\MappingException',
490             "The field or association mapping misses the 'fieldName' attribute in entity 'Doctrine\Tests\Models\CMS\CmsUser'.");
491         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
492         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
493
494         $cm->mapField(array('fieldName' => ''));
495     }
496
497     public function testRetrievalOfNamedQueries()
498     {
499         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
500         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
501
502
503         $this->assertEquals(0, count($cm->getNamedQueries()));
504
505         $cm->addNamedQuery(array(
506             'name'  => 'userById',
507             'query' => 'SELECT u FROM __CLASS__ u WHERE u.id = ?1'
508         ));
509
510         $this->assertEquals(1, count($cm->getNamedQueries()));
511     }
512
513     /**
514      * @group DDC-1663
515      */
516     public function testRetrievalOfResultSetMappings()
517     {
518         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
519         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
520
521
522         $this->assertEquals(0, count($cm->getSqlResultSetMappings()));
523
524         $cm->addSqlResultSetMapping(array(
525             'name'      => 'find-all',
526             'entities'  => array(
527                 array(
528                     'entityClass'   => 'Doctrine\Tests\Models\CMS\CmsUser',
529                 ),
530             ),
531         ));
532
533         $this->assertEquals(1, count($cm->getSqlResultSetMappings()));
534     }
535
536     public function testExistanceOfNamedQuery()
537     {
538         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
539         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
540
541
542         $cm->addNamedQuery(array(
543             'name'  => 'all',
544             'query' => 'SELECT u FROM __CLASS__ u'
545         ));
546
547         $this->assertTrue($cm->hasNamedQuery('all'));
548         $this->assertFalse($cm->hasNamedQuery('userById'));
549     }
550
551     /**
552      * @group DDC-1663
553      */
554     public function testRetrieveOfNamedNativeQuery()
555     {
556         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
557         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
558
559         $cm->addNamedNativeQuery(array(
560             'name'              => 'find-all',
561             'query'             => 'SELECT * FROM cms_users',
562             'resultSetMapping'  => 'result-mapping-name',
563             'resultClass'       => 'Doctrine\Tests\Models\CMS\CmsUser',
564         ));
565
566         $cm->addNamedNativeQuery(array(
567             'name'              => 'find-by-id',
568             'query'             => 'SELECT * FROM cms_users WHERE id = ?',
569             'resultClass'       => '__CLASS__',
570             'resultSetMapping'  => 'result-mapping-name',
571         ));
572
573         $mapping = $cm->getNamedNativeQuery('find-all');
574         $this->assertEquals('SELECT * FROM cms_users', $mapping['query']);
575         $this->assertEquals('result-mapping-name', $mapping['resultSetMapping']);
576         $this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $mapping['resultClass']);
577
578         $mapping = $cm->getNamedNativeQuery('find-by-id');
579         $this->assertEquals('SELECT * FROM cms_users WHERE id = ?', $mapping['query']);
580         $this->assertEquals('result-mapping-name', $mapping['resultSetMapping']);
581         $this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $mapping['resultClass']);
582     }
583
584     /**
585      * @group DDC-1663
586      */
587     public function testRetrieveOfSqlResultSetMapping()
588     {
589         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
590         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
591
592         $cm->addSqlResultSetMapping(array(
593             'name'      => 'find-all',
594             'entities'  => array(
595                 array(
596                     'entityClass'   => '__CLASS__',
597                     'fields'        => array(
598                         array(
599                             'name'  => 'id',
600                             'column'=> 'id'
601                         ),
602                         array(
603                             'name'  => 'name',
604                             'column'=> 'name'
605                         )
606                     )
607                 ),
608                 array(
609                     'entityClass'   => 'Doctrine\Tests\Models\CMS\CmsEmail',
610                     'fields'        => array(
611                         array(
612                             'name'  => 'id',
613                             'column'=> 'id'
614                         ),
615                         array(
616                             'name'  => 'email',
617                             'column'=> 'email'
618                         )
619                     )
620                 )
621             ),
622             'columns'   => array(
623                 array(
624                     'name' => 'scalarColumn'
625                 )
626             )
627         ));
628
629         $mapping = $cm->getSqlResultSetMapping('find-all');
630
631         $this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $mapping['entities'][0]['entityClass']);
632         $this->assertEquals(array('name'=>'id','column'=>'id'), $mapping['entities'][0]['fields'][0]);
633         $this->assertEquals(array('name'=>'name','column'=>'name'), $mapping['entities'][0]['fields'][1]);
634
635         $this->assertEquals('Doctrine\Tests\Models\CMS\CmsEmail', $mapping['entities'][1]['entityClass']);
636         $this->assertEquals(array('name'=>'id','column'=>'id'), $mapping['entities'][1]['fields'][0]);
637         $this->assertEquals(array('name'=>'email','column'=>'email'), $mapping['entities'][1]['fields'][1]);
638
639         $this->assertEquals('scalarColumn', $mapping['columns'][0]['name']);
640     }
641
642     /**
643      * @group DDC-1663
644      */
645     public function testExistanceOfSqlResultSetMapping()
646     {
647         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
648         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
649
650         $cm->addSqlResultSetMapping(array(
651             'name'      => 'find-all',
652             'entities'  => array(
653                 array(
654                     'entityClass'   => 'Doctrine\Tests\Models\CMS\CmsUser',
655                 ),
656             ),
657         ));
658
659         $this->assertTrue($cm->hasSqlResultSetMapping('find-all'));
660         $this->assertFalse($cm->hasSqlResultSetMapping('find-by-id'));
661     }
662
663     /**
664      * @group DDC-1663
665      */
666     public function testExistanceOfNamedNativeQuery()
667     {
668         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
669         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
670
671
672         $cm->addNamedNativeQuery(array(
673             'name'              => 'find-all',
674             'query'             => 'SELECT * FROM cms_users',
675             'resultClass'       => 'Doctrine\Tests\Models\CMS\CmsUser',
676             'resultSetMapping'  => 'result-mapping-name'
677         ));
678
679         $this->assertTrue($cm->hasNamedNativeQuery('find-all'));
680         $this->assertFalse($cm->hasNamedNativeQuery('find-by-id'));
681     }
682
683     public function testRetrieveOfNamedQuery()
684     {
685         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
686         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
687
688
689         $cm->addNamedQuery(array(
690             'name'  => 'userById',
691             'query' => 'SELECT u FROM __CLASS__ u WHERE u.id = ?1'
692         ));
693
694         $this->assertEquals('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1', $cm->getNamedQuery('userById'));
695     }
696
697     /**
698      * @group DDC-1663
699      */
700     public function testRetrievalOfNamedNativeQueries()
701     {
702         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
703         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
704
705         $this->assertEquals(0, count($cm->getNamedNativeQueries()));
706
707         $cm->addNamedNativeQuery(array(
708             'name'              => 'find-all',
709             'query'             => 'SELECT * FROM cms_users',
710             'resultClass'       => 'Doctrine\Tests\Models\CMS\CmsUser',
711             'resultSetMapping'  => 'result-mapping-name'
712         ));
713
714         $this->assertEquals(1, count($cm->getNamedNativeQueries()));
715     }
716
717     /**
718      * @expectedException \Doctrine\ORM\Mapping\MappingException
719      * @expectedExceptionMessage Query named "userById" in "Doctrine\Tests\Models\CMS\CmsUser" was already declared, but it must be declared only once
720      */
721     public function testNamingCollisionNamedQueryShouldThrowException()
722     {
723         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
724         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
725
726         $cm->addNamedQuery(array(
727             'name'  => 'userById',
728             'query' => 'SELECT u FROM __CLASS__ u WHERE u.id = ?1'
729         ));
730
731         $cm->addNamedQuery(array(
732             'name'  => 'userById',
733             'query' => 'SELECT u FROM __CLASS__ u WHERE u.id = ?1'
734         ));
735     }
736
737     /**
738      * @group DDC-1663
739      *
740      * @expectedException \Doctrine\ORM\Mapping\MappingException
741      * @expectedExceptionMessage Query named "find-all" in "Doctrine\Tests\Models\CMS\CmsUser" was already declared, but it must be declared only once
742      */
743     public function testNamingCollisionNamedNativeQueryShouldThrowException()
744     {
745         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
746         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
747
748         $cm->addNamedNativeQuery(array(
749             'name'              => 'find-all',
750             'query'             => 'SELECT * FROM cms_users',
751             'resultClass'       => 'Doctrine\Tests\Models\CMS\CmsUser',
752             'resultSetMapping'  => 'result-mapping-name'
753         ));
754
755         $cm->addNamedNativeQuery(array(
756             'name'              => 'find-all',
757             'query'             => 'SELECT * FROM cms_users',
758             'resultClass'       => 'Doctrine\Tests\Models\CMS\CmsUser',
759             'resultSetMapping'  => 'result-mapping-name'
760         ));
761     }
762
763     /**
764      * @group DDC-1663
765      *
766      * @expectedException \Doctrine\ORM\Mapping\MappingException
767      * @expectedExceptionMessage Result set mapping named "find-all" in "Doctrine\Tests\Models\CMS\CmsUser" was already declared, but it must be declared only once
768      */
769     public function testNamingCollisionSqlResultSetMappingShouldThrowException()
770     {
771         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
772         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
773         
774         $cm->addSqlResultSetMapping(array(
775             'name'      => 'find-all',
776             'entities'  => array(
777                 array(
778                     'entityClass'   => 'Doctrine\Tests\Models\CMS\CmsUser',
779                 ),
780             ),
781         ));
782
783         $cm->addSqlResultSetMapping(array(
784             'name'      => 'find-all',
785             'entities'  => array(
786                 array(
787                     'entityClass'   => 'Doctrine\Tests\Models\CMS\CmsUser',
788                 ),
789             ),
790         ));
791     }
792
793     /**
794      * @group DDC-1068
795      */
796     public function testClassCaseSensitivity()
797     {
798         $user = new \Doctrine\Tests\Models\CMS\CmsUser();
799         $cm = new ClassMetadata('DOCTRINE\TESTS\MODELS\CMS\CMSUSER');
800         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
801
802         $this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $cm->name);
803     }
804
805     /**
806      * @group DDC-659
807      */
808     public function testLifecycleCallbackNotFound()
809     {
810         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
811         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
812         $cm->addLifecycleCallback('notfound', 'postLoad');
813
814         $this->setExpectedException("Doctrine\ORM\Mapping\MappingException", "Entity 'Doctrine\Tests\Models\CMS\CmsUser' has no method 'notfound' to be registered as lifecycle callback.");
815         $cm->validateLifecycleCallbacks(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
816     }
817
818     /**
819      * @group ImproveErrorMessages
820      */
821     public function testTargetEntityNotFound()
822     {
823         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
824         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
825         $cm->mapManyToOne(array('fieldName' => 'address', 'targetEntity' => 'UnknownClass'));
826
827         $this->setExpectedException("Doctrine\ORM\Mapping\MappingException", "The target-entity Doctrine\Tests\Models\CMS\UnknownClass cannot be found in 'Doctrine\Tests\Models\CMS\CmsUser#address'.");
828         $cm->validateAssocations();
829     }
830
831     /**
832      * @group DDC-1663
833      *
834      * @expectedException \Doctrine\ORM\Mapping\MappingException
835      * @expectedExceptionMessage Query name on entity class 'Doctrine\Tests\Models\CMS\CmsUser' is not defined.
836      */
837     public function testNameIsMandatoryForNamedQueryMappingException()
838     {
839         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
840         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
841         $cm->addNamedQuery(array(
842             'query' => 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u',
843         ));
844     }
845
846     /**
847      * @group DDC-1663
848      *
849      * @expectedException \Doctrine\ORM\Mapping\MappingException
850      * @expectedExceptionMessage Query name on entity class 'Doctrine\Tests\Models\CMS\CmsUser' is not defined.
851      */
852     public function testNameIsMandatoryForNameNativeQueryMappingException()
853     {
854         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
855         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
856         $cm->addNamedQuery(array(
857             'query'             => 'SELECT * FROM cms_users',
858             'resultClass'       => 'Doctrine\Tests\Models\CMS\CmsUser',
859             'resultSetMapping'  => 'result-mapping-name'
860         ));
861     }
862
863     /**
864      * @group DDC-1663
865      *
866      * @expectedException \Doctrine\ORM\Mapping\MappingException
867      * @expectedExceptionMessage Result set mapping named "find-all" in "Doctrine\Tests\Models\CMS\CmsUser requires a entity class name.
868      */
869     public function testNameIsMandatoryForEntityNameSqlResultSetMappingException()
870     {
871         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
872         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
873         $cm->addSqlResultSetMapping(array(
874             'name'      => 'find-all',
875             'entities'  => array(
876                 array(
877                     'fields' => array()
878                 )
879             ),
880         ));
881     }
882
883     /**
884      * @expectedException \Doctrine\ORM\Mapping\MappingException
885      * @expectedExceptionMessage Discriminator column name on entity class 'Doctrine\Tests\Models\CMS\CmsUser' is not defined.
886      */
887     public function testNameIsMandatoryForDiscriminatorColumnsMappingException()
888     {
889         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
890         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
891         $cm->setDiscriminatorColumn(array());
892     }
893
894     /**
895      * @group DDC-984
896      * @group DDC-559
897      * @group DDC-1575
898      */
899     public function testFullyQualifiedClassNameShouldBeGivenToNamingStrategy()
900     {
901         $namingStrategy     = new MyNamespacedNamingStrategy();
902         $addressMetadata    = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress', $namingStrategy);
903         $articleMetadata    = new ClassMetadata('DoctrineGlobal_Article', $namingStrategy);
904         $routingMetadata    = new ClassMetadata('Doctrine\Tests\Models\Routing\RoutingLeg',$namingStrategy);
905
906         $addressMetadata->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
907         $articleMetadata->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
908         $routingMetadata->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
909
910         $addressMetadata->mapManyToMany(array(
911             'fieldName'     => 'user',
912             'targetEntity'  => 'CmsUser'
913         ));
914
915         $articleMetadata->mapManyToMany(array(
916             'fieldName'     => 'author',
917             'targetEntity'  => 'Doctrine\Tests\Models\CMS\CmsUser'
918         ));
919
920         $this->assertEquals('routing_routingleg', $routingMetadata->table['name']);
921         $this->assertEquals('cms_cmsaddress_cms_cmsuser', $addressMetadata->associationMappings['user']['joinTable']['name']);
922         $this->assertEquals('doctrineglobal_article_cms_cmsuser', $articleMetadata->associationMappings['author']['joinTable']['name']);
923     }
924
925     /**
926      * @group DDC-1746
927      */
928     public function testInvalidCascade()
929     {
930         $cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
931         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
932
933         $this->setExpectedException("Doctrine\ORM\Mapping\MappingException", "You have specified invalid cascade options for Doctrine\Tests\Models\CMS\CmsUser::\$address: 'invalid'; available options: 'remove', 'persist', 'refresh', 'merge', and 'detach'");
934
935
936         $cm->mapManyToOne(array('fieldName' => 'address', 'targetEntity' => 'UnknownClass', 'cascade' => array('invalid')));
937      }
938
939     /**
940      * @group DDC-964
941      * @expectedException        Doctrine\ORM\Mapping\MappingException
942      * @expectedExceptionMessage Invalid field override named 'invalidPropertyName' for class 'Doctrine\Tests\Models\DDC964\DDC964Admin
943      */
944     public function testInvalidPropertyAssociationOverrideNameException()
945     {
946         $cm = new ClassMetadata('Doctrine\Tests\Models\DDC964\DDC964Admin');
947         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
948         $cm->mapManyToOne(array('fieldName' => 'address', 'targetEntity' => 'DDC964Address'));
949
950         $cm->setAssociationOverride('invalidPropertyName', array());
951     }
952
953     /**
954      * @group DDC-964
955      * @expectedException        Doctrine\ORM\Mapping\MappingException
956      * @expectedExceptionMessage Invalid field override named 'invalidPropertyName' for class 'Doctrine\Tests\Models\DDC964\DDC964Guest'.
957      */
958     public function testInvalidPropertyAttributeOverrideNameException()
959     {
960         $cm = new ClassMetadata('Doctrine\Tests\Models\DDC964\DDC964Guest');
961         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
962         $cm->mapField(array('fieldName' => 'name'));
963
964         $cm->setAttributeOverride('invalidPropertyName', array());
965     }
966
967     /**
968      * @group DDC-964
969      * @expectedException        Doctrine\ORM\Mapping\MappingException
970      * @expectedExceptionMessage The column type of attribute 'name' on class 'Doctrine\Tests\Models\DDC964\DDC964Guest' could not be changed.
971      */
972     public function testInvalidOverrideAttributeFieldTypeException()
973     {
974         $cm = new ClassMetadata('Doctrine\Tests\Models\DDC964\DDC964Guest');
975         $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
976         $cm->mapField(array('fieldName' => 'name', 'type'=>'string'));
977
978         $cm->setAttributeOverride('name', array('type'=>'date'));
979     }
980 }
981
982 class MyNamespacedNamingStrategy extends \Doctrine\ORM\Mapping\DefaultNamingStrategy
983 {
984     /**
985      * {@inheritdoc}
986      */
987     public function classToTableName($className)
988     {
989         if (strpos($className, '\\') !== false) {
990             $className = str_replace('\\', '_', str_replace('Doctrine\Tests\Models\\', '', $className));
991         }
992
993         return strtolower($className);
994     }
995 }