Completed
Push — master ( 22ecc2...971c40 )
by Marco
14:47
created

ClassMetadataTest::testInlineEmbeddable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 7
nc 1
nop 0
1
<?php
2
3
namespace Doctrine\Tests\ORM\Mapping;
4
5
use Doctrine\Common\Persistence\Mapping\RuntimeReflectionService;
6
use Doctrine\Common\Persistence\Mapping\StaticReflectionService;
7
use Doctrine\ORM\Events;
8
use Doctrine\ORM\Mapping\ClassMetadata;
9
use Doctrine\ORM\Mapping\DefaultNamingStrategy;
10
use Doctrine\ORM\Mapping\MappingException;
11
use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
12
use Doctrine\Tests\Models\CMS;
13
use Doctrine\Tests\Models\Company\CompanyContract;
14
use Doctrine\Tests\Models\CustomType\CustomTypeParent;
15
use Doctrine\Tests\Models\DDC117\DDC117Article;
16
use Doctrine\Tests\Models\DDC117\DDC117ArticleDetails;
17
use Doctrine\Tests\Models\DDC6412\DDC6412File;
18
use Doctrine\Tests\Models\DDC964\DDC964Admin;
19
use Doctrine\Tests\Models\DDC964\DDC964Guest;
20
use Doctrine\Tests\Models\Routing\RoutingLeg;
21
use Doctrine\Tests\OrmTestCase;
22
use DoctrineGlobal_Article;
23
24
require_once __DIR__ . '/../../Models/Global/GlobalNamespaceModel.php';
25
26
class ClassMetadataTest extends OrmTestCase
27
{
28
    public function testClassMetadataInstanceSerialization()
29
    {
30
        $cm = new ClassMetadata(CMS\CmsUser::class);
31
        $cm->initializeReflection(new RuntimeReflectionService());
32
33
        // Test initial state
34
        $this->assertTrue(count($cm->getReflectionProperties()) == 0);
35
        $this->assertInstanceOf('ReflectionClass', $cm->reflClass);
36
        $this->assertEquals(CMS\CmsUser::class, $cm->name);
37
        $this->assertEquals(CMS\CmsUser::class, $cm->rootEntityName);
38
        $this->assertEquals([], $cm->subClasses);
39
        $this->assertEquals([], $cm->parentClasses);
40
        $this->assertEquals(ClassMetadata::INHERITANCE_TYPE_NONE, $cm->inheritanceType);
41
42
        // Customize state
43
        $cm->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE);
44
        $cm->setSubclasses(["One", "Two", "Three"]);
45
        $cm->setParentClasses(["UserParent"]);
46
        $cm->setCustomRepositoryClass("UserRepository");
47
        $cm->setDiscriminatorColumn(['name' => 'disc', 'type' => 'integer']);
48
        $cm->mapOneToOne(['fieldName' => 'phonenumbers', 'targetEntity' => 'CmsAddress', 'mappedBy' => 'foo']);
49
        $cm->markReadOnly();
50
        $cm->addNamedQuery(['name' => 'dql', 'query' => 'foo']);
51
        $this->assertEquals(1, count($cm->associationMappings));
52
53
        $serialized = serialize($cm);
54
        $cm = unserialize($serialized);
55
        $cm->wakeupReflection(new RuntimeReflectionService());
56
57
        // Check state
58
        $this->assertTrue(count($cm->getReflectionProperties()) > 0);
59
        $this->assertEquals('Doctrine\Tests\Models\CMS', $cm->namespace);
60
        $this->assertInstanceOf(\ReflectionClass::class, $cm->reflClass);
61
        $this->assertEquals(CMS\CmsUser::class, $cm->name);
62
        $this->assertEquals('UserParent', $cm->rootEntityName);
63
        $this->assertEquals([CMS\One::class, CMS\Two::class, CMS\Three::class], $cm->subClasses);
64
        $this->assertEquals(['UserParent'], $cm->parentClasses);
65
        $this->assertEquals(CMS\UserRepository::class, $cm->customRepositoryClassName);
66
        $this->assertEquals(['name' => 'disc', 'type' => 'integer', 'fieldName' => 'disc'], $cm->discriminatorColumn);
67
        $this->assertTrue($cm->associationMappings['phonenumbers']['type'] == ClassMetadata::ONE_TO_ONE);
68
        $this->assertEquals(1, count($cm->associationMappings));
69
        $oneOneMapping = $cm->getAssociationMapping('phonenumbers');
70
        $this->assertTrue($oneOneMapping['fetch'] == ClassMetadata::FETCH_LAZY);
71
        $this->assertEquals('phonenumbers', $oneOneMapping['fieldName']);
72
        $this->assertEquals(CMS\CmsAddress::class, $oneOneMapping['targetEntity']);
73
        $this->assertTrue($cm->isReadOnly);
74
        $this->assertEquals(['dql' => ['name'=>'dql','query'=>'foo','dql'=>'foo']], $cm->namedQueries);
75
    }
76
77
    public function testFieldIsNullable()
78
    {
79
        $cm = new ClassMetadata(CMS\CmsUser::class);
80
        $cm->initializeReflection(new RuntimeReflectionService());
81
82
        // Explicit Nullable
83
        $cm->mapField(['fieldName' => 'status', 'nullable' => true, 'type' => 'string', 'length' => 50]);
84
        $this->assertTrue($cm->isNullable('status'));
85
86
        // Explicit Not Nullable
87
        $cm->mapField(['fieldName' => 'username', 'nullable' => false, 'type' => 'string', 'length' => 50]);
88
        $this->assertFalse($cm->isNullable('username'));
89
90
        // Implicit Not Nullable
91
        $cm->mapField(['fieldName' => 'name', 'type' => 'string', 'length' => 50]);
92
        $this->assertFalse($cm->isNullable('name'), "By default a field should not be nullable.");
93
    }
94
95
    /**
96
     * @group DDC-115
97
     */
98
    public function testMapAssociationInGlobalNamespace()
99
    {
100
        require_once __DIR__."/../../Models/Global/GlobalNamespaceModel.php";
101
102
        $cm = new ClassMetadata('DoctrineGlobal_Article');
103
        $cm->initializeReflection(new RuntimeReflectionService());
104
        $cm->mapManyToMany(
105
            [
106
            'fieldName' => 'author',
107
            'targetEntity' => 'DoctrineGlobal_User',
108
            'joinTable' => [
109
                'name' => 'bar',
110
                'joinColumns' => [['name' => 'bar_id', 'referencedColumnName' => 'id']],
111
                'inverseJoinColumns' => [['name' => 'baz_id', 'referencedColumnName' => 'id']],
112
            ],
113
            ]
114
        );
115
116
        $this->assertEquals("DoctrineGlobal_User", $cm->associationMappings['author']['targetEntity']);
117
    }
118
119
    public function testMapManyToManyJoinTableDefaults()
120
    {
121
        $cm = new ClassMetadata(CMS\CmsUser::class);
122
        $cm->initializeReflection(new RuntimeReflectionService());
123
        $cm->mapManyToMany(
124
            [
125
            'fieldName' => 'groups',
126
            'targetEntity' => 'CmsGroup'
127
            ]
128
        );
129
130
        $assoc = $cm->associationMappings['groups'];
131
        $this->assertEquals(
132
            [
133
            'name' => 'cmsuser_cmsgroup',
134
            'joinColumns' => [['name' => 'cmsuser_id', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE']],
135
            'inverseJoinColumns' => [['name' => 'cmsgroup_id', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE']]
136
            ], $assoc['joinTable']);
137
        $this->assertTrue($assoc['isOnDeleteCascade']);
138
    }
139
140
    public function testSerializeManyToManyJoinTableCascade()
141
    {
142
        $cm = new ClassMetadata(CMS\CmsUser::class);
143
        $cm->initializeReflection(new RuntimeReflectionService());
144
        $cm->mapManyToMany(
145
            [
146
            'fieldName' => 'groups',
147
            'targetEntity' => 'CmsGroup'
148
            ]
149
        );
150
151
        /* @var $assoc \Doctrine\ORM\Mapping\ManyToMany */
152
        $assoc = $cm->associationMappings['groups'];
153
        $assoc = unserialize(serialize($assoc));
154
155
        $this->assertTrue($assoc['isOnDeleteCascade']);
156
    }
157
158
    /**
159
     * @group DDC-115
160
     */
161
    public function testSetDiscriminatorMapInGlobalNamespace()
162
    {
163
        require_once __DIR__."/../../Models/Global/GlobalNamespaceModel.php";
164
165
        $cm = new ClassMetadata('DoctrineGlobal_User');
166
        $cm->initializeReflection(new RuntimeReflectionService());
167
        $cm->setDiscriminatorMap(['descr' => 'DoctrineGlobal_Article', 'foo' => 'DoctrineGlobal_User']);
168
169
        $this->assertEquals("DoctrineGlobal_Article", $cm->discriminatorMap['descr']);
170
        $this->assertEquals("DoctrineGlobal_User", $cm->discriminatorMap['foo']);
171
    }
172
173
    /**
174
     * @group DDC-115
175
     */
176
    public function testSetSubClassesInGlobalNamespace()
177
    {
178
        require_once __DIR__."/../../Models/Global/GlobalNamespaceModel.php";
179
180
        $cm = new ClassMetadata('DoctrineGlobal_User');
181
        $cm->initializeReflection(new RuntimeReflectionService());
182
        $cm->setSubclasses(['DoctrineGlobal_Article']);
183
184
        $this->assertEquals("DoctrineGlobal_Article", $cm->subClasses[0]);
185
    }
186
187
    /**
188
     * @group DDC-268
189
     */
190
    public function testSetInvalidVersionMapping_ThrowsException()
191
    {
192
        $field = [];
193
        $field['fieldName'] = 'foo';
194
        $field['type'] = 'string';
195
196
        $cm = new ClassMetadata(CMS\CmsUser::class);
197
        $cm->initializeReflection(new RuntimeReflectionService());
198
199
        $this->expectException(\Doctrine\ORM\Mapping\MappingException::class);
200
        $cm->setVersionMapping($field);
201
    }
202
203
    public function testGetSingleIdentifierFieldName_MultipleIdentifierEntity_ThrowsException()
204
    {
205
        $cm = new ClassMetadata(CMS\CmsUser::class);
206
        $cm->initializeReflection(new RuntimeReflectionService());
207
        $cm->isIdentifierComposite  = true;
208
209
        $this->expectException(\Doctrine\ORM\Mapping\MappingException::class);
210
        $cm->getSingleIdentifierFieldName();
211
    }
212
213
    public function testGetSingleIdentifierFieldName_NoIdEntity_ThrowsException()
214
    {
215
        $cm = new ClassMetadata(DDC6412File::class);
216
        $cm->initializeReflection(new RuntimeReflectionService());
217
218
        $this->expectException(\Doctrine\ORM\Mapping\MappingException::class);
219
        $cm->getSingleIdentifierFieldName();
220
    }
221
222
    public function testDuplicateAssociationMappingException()
223
    {
224
        $cm = new ClassMetadata(CMS\CmsUser::class);
225
        $cm->initializeReflection(new RuntimeReflectionService());
226
227
        $a1 = ['fieldName' => 'foo', 'sourceEntity' => 'stdClass', 'targetEntity' => 'stdClass', 'mappedBy' => 'foo'];
228
        $a2 = ['fieldName' => 'foo', 'sourceEntity' => 'stdClass', 'targetEntity' => 'stdClass', 'mappedBy' => 'foo'];
229
230
        $cm->addInheritedAssociationMapping($a1);
231
        $this->expectException(\Doctrine\ORM\Mapping\MappingException::class);
232
        $cm->addInheritedAssociationMapping($a2);
233
    }
234
235
    public function testDuplicateColumnName_ThrowsMappingException()
236
    {
237
        $cm = new ClassMetadata(CMS\CmsUser::class);
238
        $cm->initializeReflection(new RuntimeReflectionService());
239
240
        $cm->mapField(['fieldName' => 'name', 'columnName' => 'name']);
241
242
        $this->expectException(\Doctrine\ORM\Mapping\MappingException::class);
243
        $cm->mapField(['fieldName' => 'username', 'columnName' => 'name']);
244
    }
245
246
    public function testDuplicateColumnName_DiscriminatorColumn_ThrowsMappingException()
247
    {
248
        $cm = new ClassMetadata(CMS\CmsUser::class);
249
        $cm->initializeReflection(new RuntimeReflectionService());
250
251
        $cm->mapField(['fieldName' => 'name', 'columnName' => 'name']);
252
253
        $this->expectException(\Doctrine\ORM\Mapping\MappingException::class);
254
        $cm->setDiscriminatorColumn(['name' => 'name']);
255
    }
256
257
    public function testDuplicateColumnName_DiscriminatorColumn2_ThrowsMappingException()
258
    {
259
        $cm = new ClassMetadata(CMS\CmsUser::class);
260
        $cm->initializeReflection(new RuntimeReflectionService());
261
262
        $cm->setDiscriminatorColumn(['name' => 'name']);
263
264
        $this->expectException(\Doctrine\ORM\Mapping\MappingException::class);
265
        $cm->mapField(['fieldName' => 'name', 'columnName' => 'name']);
266
    }
267
268
    public function testDuplicateFieldAndAssociationMapping1_ThrowsException()
269
    {
270
        $cm = new ClassMetadata(CMS\CmsUser::class);
271
        $cm->initializeReflection(new RuntimeReflectionService());
272
273
        $cm->mapField(['fieldName' => 'name', 'columnName' => 'name']);
274
275
        $this->expectException(\Doctrine\ORM\Mapping\MappingException::class);
276
        $cm->mapOneToOne(['fieldName' => 'name', 'targetEntity' => 'CmsUser']);
277
    }
278
279
    public function testDuplicateFieldAndAssociationMapping2_ThrowsException()
280
    {
281
        $cm = new ClassMetadata(CMS\CmsUser::class);
282
        $cm->initializeReflection(new RuntimeReflectionService());
283
284
        $cm->mapOneToOne(['fieldName' => 'name', 'targetEntity' => 'CmsUser']);
285
286
        $this->expectException(\Doctrine\ORM\Mapping\MappingException::class);
287
        $cm->mapField(['fieldName' => 'name', 'columnName' => 'name']);
288
    }
289
290
    /**
291
     * @group DDC-1224
292
     */
293
    public function testGetTemporaryTableNameSchema()
294
    {
295
        $cm = new ClassMetadata(CMS\CmsUser::class);
296
        $cm->initializeReflection(new RuntimeReflectionService());
297
298
        $cm->setTableName('foo.bar');
299
300
        $this->assertEquals('foo_bar_id_tmp', $cm->getTemporaryIdTableName());
301
    }
302
303
    public function testDefaultTableName()
304
    {
305
        $cm = new ClassMetadata(CMS\CmsUser::class);
306
        $cm->initializeReflection(new RuntimeReflectionService());
307
308
        // When table's name is not given
309
        $primaryTable = [];
310
        $cm->setPrimaryTable($primaryTable);
311
312
        $this->assertEquals('CmsUser', $cm->getTableName());
313
        $this->assertEquals('CmsUser', $cm->table['name']);
314
315
        $cm = new ClassMetadata(CMS\CmsAddress::class);
316
        $cm->initializeReflection(new RuntimeReflectionService());
317
        // When joinTable's name is not given
318
        $cm->mapManyToMany(
319
            [
320
                'fieldName' => 'user',
321
                'targetEntity' => 'CmsUser',
322
                'inversedBy' => 'users',
323
                'joinTable' => [
324
                    'joinColumns' => [['referencedColumnName' => 'id']],
325
                    'inverseJoinColumns' => [['referencedColumnName' => 'id']]
326
                ]
327
            ]
328
        );
329
        $this->assertEquals('cmsaddress_cmsuser', $cm->associationMappings['user']['joinTable']['name']);
330
    }
331
332
    public function testDefaultJoinColumnName()
333
    {
334
        $cm = new ClassMetadata(CMS\CmsAddress::class);
335
        $cm->initializeReflection(new RuntimeReflectionService());
336
337
        // this is really dirty, but it's the simplest way to test whether
338
        // joinColumn's name will be automatically set to user_id
339
        $cm->mapOneToOne(
340
            [
341
            'fieldName' => 'user',
342
            'targetEntity' => 'CmsUser',
343
            'joinColumns' => [['referencedColumnName' => 'id']]
344
            ]
345
        );
346
        $this->assertEquals('user_id', $cm->associationMappings['user']['joinColumns'][0]['name']);
347
348
        $cm = new ClassMetadata(CMS\CmsAddress::class);
349
        $cm->initializeReflection(new RuntimeReflectionService());
350
        $cm->mapManyToMany(
351
            [
352
            'fieldName' => 'user',
353
            'targetEntity' => 'CmsUser',
354
            'inversedBy' => 'users',
355
            'joinTable' => [
356
                    'name' => 'user_CmsUser',
357
                    'joinColumns' => [['referencedColumnName' => 'id']],
358
                    'inverseJoinColumns' => [['referencedColumnName' => 'id']]
359
                ]
360
            ]
361
        );
362
        $this->assertEquals('cmsaddress_id', $cm->associationMappings['user']['joinTable']['joinColumns'][0]['name']);
363
        $this->assertEquals('cmsuser_id', $cm->associationMappings['user']['joinTable']['inverseJoinColumns'][0]['name']);
364
    }
365
366
    /**
367
     * @group DDC-559
368
     */
369
    public function testUnderscoreNamingStrategyDefaults()
370
    {
371
        $namingStrategy     = new UnderscoreNamingStrategy(CASE_UPPER);
372
        $oneToOneMetadata   = new ClassMetadata(CMS\CmsAddress::class, $namingStrategy);
373
        $manyToManyMetadata = new ClassMetadata(CMS\CmsAddress::class, $namingStrategy);
374
375
        $oneToOneMetadata->mapOneToOne(
376
            [
377
            'fieldName'     => 'user',
378
            'targetEntity'  => 'CmsUser'
379
            ]
380
        );
381
382
        $manyToManyMetadata->mapManyToMany(
383
            [
384
            'fieldName'     => 'user',
385
            'targetEntity'  => 'CmsUser'
386
            ]
387
        );
388
389
        $this->assertEquals(['USER_ID'=>'ID'], $oneToOneMetadata->associationMappings['user']['sourceToTargetKeyColumns']);
390
        $this->assertEquals(['USER_ID'=>'USER_ID'], $oneToOneMetadata->associationMappings['user']['joinColumnFieldNames']);
391
        $this->assertEquals(['ID'=>'USER_ID'], $oneToOneMetadata->associationMappings['user']['targetToSourceKeyColumns']);
392
393
        $this->assertEquals('USER_ID', $oneToOneMetadata->associationMappings['user']['joinColumns'][0]['name']);
394
        $this->assertEquals('ID', $oneToOneMetadata->associationMappings['user']['joinColumns'][0]['referencedColumnName']);
395
396
397
        $this->assertEquals('CMS_ADDRESS_CMS_USER', $manyToManyMetadata->associationMappings['user']['joinTable']['name']);
398
399
        $this->assertEquals(['CMS_ADDRESS_ID','CMS_USER_ID'], $manyToManyMetadata->associationMappings['user']['joinTableColumns']);
400
        $this->assertEquals(['CMS_ADDRESS_ID'=>'ID'], $manyToManyMetadata->associationMappings['user']['relationToSourceKeyColumns']);
401
        $this->assertEquals(['CMS_USER_ID'=>'ID'], $manyToManyMetadata->associationMappings['user']['relationToTargetKeyColumns']);
402
403
        $this->assertEquals('CMS_ADDRESS_ID', $manyToManyMetadata->associationMappings['user']['joinTable']['joinColumns'][0]['name']);
404
        $this->assertEquals('CMS_USER_ID', $manyToManyMetadata->associationMappings['user']['joinTable']['inverseJoinColumns'][0]['name']);
405
406
        $this->assertEquals('ID', $manyToManyMetadata->associationMappings['user']['joinTable']['joinColumns'][0]['referencedColumnName']);
407
        $this->assertEquals('ID', $manyToManyMetadata->associationMappings['user']['joinTable']['inverseJoinColumns'][0]['referencedColumnName']);
408
409
410
        $cm = new ClassMetadata('DoctrineGlobal_Article', $namingStrategy);
411
        $cm->mapManyToMany(['fieldName' => 'author', 'targetEntity' => CMS\CmsUser::class]);
412
        $this->assertEquals('DOCTRINE_GLOBAL_ARTICLE_CMS_USER', $cm->associationMappings['author']['joinTable']['name']);
413
    }
414
415
    /**
416
     * @group DDC-886
417
     */
418
    public function testSetMultipleIdentifierSetsComposite()
419
    {
420
        $cm = new ClassMetadata(CMS\CmsUser::class);
421
        $cm->initializeReflection(new RuntimeReflectionService());
422
423
        $cm->mapField(['fieldName' => 'name']);
424
        $cm->mapField(['fieldName' => 'username']);
425
426
        $cm->setIdentifier(['name', 'username']);
427
        $this->assertTrue($cm->isIdentifierComposite);
428
    }
429
430
    /**
431
     * @group DDC-944
432
     */
433
    public function testMappingNotFound()
434
    {
435
        $cm = new ClassMetadata(CMS\CmsUser::class);
436
        $cm->initializeReflection(new RuntimeReflectionService());
437
438
        $this->expectException(MappingException::class);
439
        $this->expectExceptionMessage("No mapping found for field 'foo' on class '" . CMS\CmsUser::class . "'.");
440
441
        $cm->getFieldMapping('foo');
442
    }
443
444
    /**
445
     * @group DDC-961
446
     */
447
    public function testJoinTableMappingDefaults()
448
    {
449
        $cm = new ClassMetadata('DoctrineGlobal_Article');
450
        $cm->initializeReflection(new RuntimeReflectionService());
451
452
        $cm->mapManyToMany(['fieldName' => 'author', 'targetEntity' => CMS\CmsUser::class]);
453
454
        $this->assertEquals('doctrineglobal_article_cmsuser', $cm->associationMappings['author']['joinTable']['name']);
455
    }
456
457
    /**
458
     * @group DDC-117
459
     */
460
    public function testMapIdentifierAssociation()
461
    {
462
        $cm = new ClassMetadata(DDC117ArticleDetails::class);
463
        $cm->initializeReflection(new RuntimeReflectionService());
464
465
        $cm->mapOneToOne(
466
            [
467
            'fieldName' => 'article',
468
            'id' => true,
469
            'targetEntity' => DDC117Article::class,
470
            'joinColumns' => [],
471
            ]
472
        );
473
474
        $this->assertTrue($cm->containsForeignIdentifier, "Identifier Association should set 'containsForeignIdentifier' boolean flag.");
475
        $this->assertEquals(["article"], $cm->identifier);
476
    }
477
478
    /**
479
     * @group DDC-117
480
     */
481
    public function testOrphanRemovalIdentifierAssociation()
482
    {
483
        $cm = new ClassMetadata(DDC117ArticleDetails::class);
484
        $cm->initializeReflection(new RuntimeReflectionService());
485
486
        $this->expectException(MappingException::class);
487
        $this->expectExceptionMessage('The orphan removal option is not allowed on an association that');
488
489
        $cm->mapOneToOne(
490
            [
491
            'fieldName' => 'article',
492
            'id' => true,
493
            'targetEntity' => DDC117Article::class,
494
            'orphanRemoval' => true,
495
            'joinColumns' => [],
496
            ]
497
        );
498
    }
499
500
    /**
501
     * @group DDC-117
502
     */
503
    public function testInverseIdentifierAssociation()
504
    {
505
        $cm = new ClassMetadata(DDC117ArticleDetails::class);
506
        $cm->initializeReflection(new RuntimeReflectionService());
507
508
        $this->expectException(MappingException::class);
509
        $this->expectExceptionMessage('An inverse association is not allowed to be identifier in');
510
511
        $cm->mapOneToOne(
512
            [
513
            'fieldName' => 'article',
514
            'id' => true,
515
            'mappedBy' => 'details', // INVERSE!
516
            'targetEntity' => DDC117Article::class,
517
            'joinColumns' => [],
518
            ]
519
        );
520
    }
521
522
    /**
523
     * @group DDC-117
524
     */
525
    public function testIdentifierAssociationManyToMany()
526
    {
527
        $cm = new ClassMetadata(DDC117ArticleDetails::class);
528
        $cm->initializeReflection(new RuntimeReflectionService());
529
530
        $this->expectException(MappingException::class);
531
        $this->expectExceptionMessage('Many-to-many or one-to-many associations are not allowed to be identifier in');
532
533
        $cm->mapManyToMany(
534
            [
535
            'fieldName' => 'article',
536
            'id' => true,
537
            'targetEntity' => DDC117Article::class,
538
            'joinColumns' => [],
539
            ]
540
        );
541
    }
542
543
    /**
544
     * @group DDC-996
545
     */
546
    public function testEmptyFieldNameThrowsException()
547
    {
548
        $this->expectException(MappingException::class);
549
        $this->expectExceptionMessage("The field or association mapping misses the 'fieldName' attribute in entity '" . CMS\CmsUser::class . "'.");
550
551
        $cm = new ClassMetadata(CMS\CmsUser::class);
552
        $cm->initializeReflection(new RuntimeReflectionService());
553
554
        $cm->mapField(['fieldName' => '']);
555
    }
556
557
    public function testRetrievalOfNamedQueries()
558
    {
559
        $cm = new ClassMetadata(CMS\CmsUser::class);
560
        $cm->initializeReflection(new RuntimeReflectionService());
561
562
563
        $this->assertEquals(0, count($cm->getNamedQueries()));
564
565
        $cm->addNamedQuery(
566
            [
567
            'name'  => 'userById',
568
            'query' => 'SELECT u FROM __CLASS__ u WHERE u.id = ?1'
569
            ]
570
        );
571
572
        $this->assertEquals(1, count($cm->getNamedQueries()));
573
    }
574
575
    /**
576
     * @group DDC-1663
577
     */
578
    public function testRetrievalOfResultSetMappings()
579
    {
580
        $cm = new ClassMetadata(CMS\CmsUser::class);
581
        $cm->initializeReflection(new RuntimeReflectionService());
582
583
584
        $this->assertEquals(0, count($cm->getSqlResultSetMappings()));
585
586
        $cm->addSqlResultSetMapping(
587
            [
588
            'name'      => 'find-all',
589
            'entities'  => [
590
                [
591
                    'entityClass'   => CMS\CmsUser::class,
592
                ],
593
            ],
594
            ]
595
        );
596
597
        $this->assertEquals(1, count($cm->getSqlResultSetMappings()));
598
    }
599
600
    public function testExistanceOfNamedQuery()
601
    {
602
        $cm = new ClassMetadata(CMS\CmsUser::class);
603
        $cm->initializeReflection(new RuntimeReflectionService());
604
605
606
        $cm->addNamedQuery(
607
            [
608
            'name'  => 'all',
609
            'query' => 'SELECT u FROM __CLASS__ u'
610
            ]
611
        );
612
613
        $this->assertTrue($cm->hasNamedQuery('all'));
614
        $this->assertFalse($cm->hasNamedQuery('userById'));
615
    }
616
617
    /**
618
     * @group DDC-1663
619
     */
620
    public function testRetrieveOfNamedNativeQuery()
621
    {
622
        $cm = new ClassMetadata(CMS\CmsUser::class);
623
        $cm->initializeReflection(new RuntimeReflectionService());
624
625
        $cm->addNamedNativeQuery(
626
            [
627
            'name'              => 'find-all',
628
            'query'             => 'SELECT * FROM cms_users',
629
            'resultSetMapping'  => 'result-mapping-name',
630
            'resultClass'       => CMS\CmsUser::class,
631
            ]
632
        );
633
634
        $cm->addNamedNativeQuery(
635
            [
636
            'name'              => 'find-by-id',
637
            'query'             => 'SELECT * FROM cms_users WHERE id = ?',
638
            'resultClass'       => '__CLASS__',
639
            'resultSetMapping'  => 'result-mapping-name',
640
            ]
641
        );
642
643
        $mapping = $cm->getNamedNativeQuery('find-all');
644
        $this->assertEquals('SELECT * FROM cms_users', $mapping['query']);
645
        $this->assertEquals('result-mapping-name', $mapping['resultSetMapping']);
646
        $this->assertEquals(CMS\CmsUser::class, $mapping['resultClass']);
647
648
        $mapping = $cm->getNamedNativeQuery('find-by-id');
649
        $this->assertEquals('SELECT * FROM cms_users WHERE id = ?', $mapping['query']);
650
        $this->assertEquals('result-mapping-name', $mapping['resultSetMapping']);
651
        $this->assertEquals(CMS\CmsUser::class, $mapping['resultClass']);
652
    }
653
654
    /**
655
     * @group DDC-1663
656
     */
657
    public function testRetrieveOfSqlResultSetMapping()
658
    {
659
        $cm = new ClassMetadata(CMS\CmsUser::class);
660
        $cm->initializeReflection(new RuntimeReflectionService());
661
662
        $cm->addSqlResultSetMapping(
663
            [
664
            'name'      => 'find-all',
665
            'entities'  => [
666
                [
667
                    'entityClass'   => '__CLASS__',
668
                    'fields'        => [
669
                        [
670
                            'name'  => 'id',
671
                            'column'=> 'id'
672
                        ],
673
                        [
674
                            'name'  => 'name',
675
                            'column'=> 'name'
676
                        ]
677
                    ]
678
                ],
679
                [
680
                    'entityClass'   => CMS\CmsEmail::class,
681
                    'fields'        => [
682
                        [
683
                            'name'  => 'id',
684
                            'column'=> 'id'
685
                        ],
686
                        [
687
                            'name'  => 'email',
688
                            'column'=> 'email'
689
                        ]
690
                    ]
691
                ]
692
            ],
693
            'columns'   => [
694
                [
695
                    'name' => 'scalarColumn'
696
                ]
697
            ]
698
            ]
699
        );
700
701
        $mapping = $cm->getSqlResultSetMapping('find-all');
702
703
        $this->assertEquals(CMS\CmsUser::class, $mapping['entities'][0]['entityClass']);
704
        $this->assertEquals(['name'=>'id','column'=>'id'], $mapping['entities'][0]['fields'][0]);
705
        $this->assertEquals(['name'=>'name','column'=>'name'], $mapping['entities'][0]['fields'][1]);
706
707
        $this->assertEquals(CMS\CmsEmail::class, $mapping['entities'][1]['entityClass']);
708
        $this->assertEquals(['name'=>'id','column'=>'id'], $mapping['entities'][1]['fields'][0]);
709
        $this->assertEquals(['name'=>'email','column'=>'email'], $mapping['entities'][1]['fields'][1]);
710
711
        $this->assertEquals('scalarColumn', $mapping['columns'][0]['name']);
712
    }
713
714
    /**
715
     * @group DDC-1663
716
     */
717
    public function testExistanceOfSqlResultSetMapping()
718
    {
719
        $cm = new ClassMetadata(CMS\CmsUser::class);
720
        $cm->initializeReflection(new RuntimeReflectionService());
721
722
        $cm->addSqlResultSetMapping(
723
            [
724
            'name'      => 'find-all',
725
            'entities'  => [
726
                [
727
                    'entityClass'   => CMS\CmsUser::class,
728
                ],
729
            ],
730
            ]
731
        );
732
733
        $this->assertTrue($cm->hasSqlResultSetMapping('find-all'));
734
        $this->assertFalse($cm->hasSqlResultSetMapping('find-by-id'));
735
    }
736
737
    /**
738
     * @group DDC-1663
739
     */
740
    public function testExistanceOfNamedNativeQuery()
741
    {
742
        $cm = new ClassMetadata(CMS\CmsUser::class);
743
        $cm->initializeReflection(new RuntimeReflectionService());
744
745
746
        $cm->addNamedNativeQuery(
747
            [
748
            'name'              => 'find-all',
749
            'query'             => 'SELECT * FROM cms_users',
750
            'resultClass'       => CMS\CmsUser::class,
751
            'resultSetMapping'  => 'result-mapping-name'
752
            ]
753
        );
754
755
        $this->assertTrue($cm->hasNamedNativeQuery('find-all'));
756
        $this->assertFalse($cm->hasNamedNativeQuery('find-by-id'));
757
    }
758
759
    public function testRetrieveOfNamedQuery()
760
    {
761
        $cm = new ClassMetadata(CMS\CmsUser::class);
762
        $cm->initializeReflection(new RuntimeReflectionService());
763
764
765
        $cm->addNamedQuery(
766
            [
767
            'name'  => 'userById',
768
            'query' => 'SELECT u FROM __CLASS__ u WHERE u.id = ?1'
769
            ]
770
        );
771
772
        $this->assertEquals('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1', $cm->getNamedQuery('userById'));
773
    }
774
775
    /**
776
     * @group DDC-1663
777
     */
778
    public function testRetrievalOfNamedNativeQueries()
779
    {
780
        $cm = new ClassMetadata(CMS\CmsUser::class);
781
        $cm->initializeReflection(new RuntimeReflectionService());
782
783
        $this->assertEquals(0, count($cm->getNamedNativeQueries()));
784
785
        $cm->addNamedNativeQuery(
786
            [
787
            'name'              => 'find-all',
788
            'query'             => 'SELECT * FROM cms_users',
789
            'resultClass'       => CMS\CmsUser::class,
790
            'resultSetMapping'  => 'result-mapping-name'
791
            ]
792
        );
793
794
        $this->assertEquals(1, count($cm->getNamedNativeQueries()));
795
    }
796
797
    /**
798
     * @group DDC-2451
799
     */
800
    public function testSerializeEntityListeners()
801
    {
802
        $metadata = new ClassMetadata(CompanyContract::class);
803
804
        $metadata->initializeReflection(new RuntimeReflectionService());
805
        $metadata->addEntityListener(Events::prePersist, 'CompanyContractListener', 'prePersistHandler');
806
        $metadata->addEntityListener(Events::postPersist, 'CompanyContractListener', 'postPersistHandler');
807
808
        $serialize   = serialize($metadata);
809
        $unserialize = unserialize($serialize);
810
811
        $this->assertEquals($metadata->entityListeners, $unserialize->entityListeners);
812
    }
813
814
    /**
815
     * @expectedException \Doctrine\ORM\Mapping\MappingException
816
     * @expectedExceptionMessage Query named "userById" in "Doctrine\Tests\Models\CMS\CmsUser" was already declared, but it must be declared only once
817
     */
818
    public function testNamingCollisionNamedQueryShouldThrowException()
819
    {
820
        $cm = new ClassMetadata(CMS\CmsUser::class);
821
        $cm->initializeReflection(new RuntimeReflectionService());
822
823
        $cm->addNamedQuery(
824
            [
825
            'name'  => 'userById',
826
            'query' => 'SELECT u FROM __CLASS__ u WHERE u.id = ?1'
827
            ]
828
        );
829
830
        $cm->addNamedQuery(
831
            [
832
            'name'  => 'userById',
833
            'query' => 'SELECT u FROM __CLASS__ u WHERE u.id = ?1'
834
            ]
835
        );
836
    }
837
838
    /**
839
     * @group DDC-1663
840
     *
841
     * @expectedException \Doctrine\ORM\Mapping\MappingException
842
     * @expectedExceptionMessage Query named "find-all" in "Doctrine\Tests\Models\CMS\CmsUser" was already declared, but it must be declared only once
843
     */
844
    public function testNamingCollisionNamedNativeQueryShouldThrowException()
845
    {
846
        $cm = new ClassMetadata(CMS\CmsUser::class);
847
        $cm->initializeReflection(new RuntimeReflectionService());
848
849
        $cm->addNamedNativeQuery(
850
            [
851
            'name'              => 'find-all',
852
            'query'             => 'SELECT * FROM cms_users',
853
            'resultClass'       => CMS\CmsUser::class,
854
            'resultSetMapping'  => 'result-mapping-name'
855
            ]
856
        );
857
858
        $cm->addNamedNativeQuery(
859
            [
860
            'name'              => 'find-all',
861
            'query'             => 'SELECT * FROM cms_users',
862
            'resultClass'       => CMS\CmsUser::class,
863
            'resultSetMapping'  => 'result-mapping-name'
864
            ]
865
        );
866
    }
867
868
    /**
869
     * @group DDC-1663
870
     *
871
     * @expectedException \Doctrine\ORM\Mapping\MappingException
872
     * @expectedExceptionMessage Result set mapping named "find-all" in "Doctrine\Tests\Models\CMS\CmsUser" was already declared, but it must be declared only once
873
     */
874
    public function testNamingCollisionSqlResultSetMappingShouldThrowException()
875
    {
876
        $cm = new ClassMetadata(CMS\CmsUser::class);
877
        $cm->initializeReflection(new RuntimeReflectionService());
878
879
        $cm->addSqlResultSetMapping(
880
            [
881
            'name'      => 'find-all',
882
            'entities'  => [
883
                [
884
                    'entityClass'   => CMS\CmsUser::class,
885
                ],
886
            ],
887
            ]
888
        );
889
890
        $cm->addSqlResultSetMapping(
891
            [
892
            'name'      => 'find-all',
893
            'entities'  => [
894
                [
895
                    'entityClass'   => CMS\CmsUser::class,
896
                ],
897
            ],
898
            ]
899
        );
900
    }
901
902
    /**
903
     * @group DDC-1068
904
     */
905
    public function testClassCaseSensitivity()
906
    {
907
        $user = new CMS\CmsUser();
908
        $cm = new ClassMetadata(strtoupper(CMS\CmsUser::class));
909
        $cm->initializeReflection(new RuntimeReflectionService());
910
911
        $this->assertEquals(CMS\CmsUser::class, $cm->name);
912
    }
913
914
    /**
915
     * @group DDC-659
916
     */
917
    public function testLifecycleCallbackNotFound()
918
    {
919
        $cm = new ClassMetadata(CMS\CmsUser::class);
920
        $cm->initializeReflection(new RuntimeReflectionService());
921
        $cm->addLifecycleCallback('notfound', 'postLoad');
922
923
        $this->expectException(MappingException::class);
924
        $this->expectExceptionMessage("Entity '" . CMS\CmsUser::class . "' has no method 'notfound' to be registered as lifecycle callback.");
925
926
        $cm->validateLifecycleCallbacks(new RuntimeReflectionService());
927
    }
928
929
    /**
930
     * @group ImproveErrorMessages
931
     */
932
    public function testTargetEntityNotFound()
933
    {
934
        $cm = new ClassMetadata(CMS\CmsUser::class);
935
        $cm->initializeReflection(new RuntimeReflectionService());
936
        $cm->mapManyToOne(['fieldName' => 'address', 'targetEntity' => 'UnknownClass']);
937
938
        $this->expectException(MappingException::class);
939
        $this->expectExceptionMessage("The target-entity Doctrine\\Tests\\Models\\CMS\\UnknownClass cannot be found in '" . CMS\CmsUser::class . "#address'.");
940
941
        $cm->validateAssociations();
942
    }
943
944
    /**
945
     * @group DDC-1663
946
     *
947
     * @expectedException \Doctrine\ORM\Mapping\MappingException
948
     * @expectedExceptionMessage Query name on entity class 'Doctrine\Tests\Models\CMS\CmsUser' is not defined.
949
     */
950
    public function testNameIsMandatoryForNamedQueryMappingException()
951
    {
952
        $cm = new ClassMetadata(CMS\CmsUser::class);
953
        $cm->initializeReflection(new RuntimeReflectionService());
954
        $cm->addNamedQuery(
955
            [
956
            'query' => 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u',
957
            ]
958
        );
959
    }
960
961
    /**
962
     * @group DDC-1663
963
     *
964
     * @expectedException \Doctrine\ORM\Mapping\MappingException
965
     * @expectedExceptionMessage Query name on entity class 'Doctrine\Tests\Models\CMS\CmsUser' is not defined.
966
     */
967
    public function testNameIsMandatoryForNameNativeQueryMappingException()
968
    {
969
        $cm = new ClassMetadata(CMS\CmsUser::class);
970
        $cm->initializeReflection(new RuntimeReflectionService());
971
        $cm->addNamedQuery(
972
            [
973
            'query'             => 'SELECT * FROM cms_users',
974
            'resultClass'       => CMS\CmsUser::class,
975
            'resultSetMapping'  => 'result-mapping-name'
976
            ]
977
        );
978
    }
979
980
    /**
981
     * @group DDC-1663
982
     *
983
     * @expectedException \Doctrine\ORM\Mapping\MappingException
984
     * @expectedExceptionMessage Result set mapping named "find-all" in "Doctrine\Tests\Models\CMS\CmsUser requires a entity class name.
985
     */
986
    public function testNameIsMandatoryForEntityNameSqlResultSetMappingException()
987
    {
988
        $cm = new ClassMetadata(CMS\CmsUser::class);
989
        $cm->initializeReflection(new RuntimeReflectionService());
990
        $cm->addSqlResultSetMapping(
991
            [
992
            'name'      => 'find-all',
993
            'entities'  => [
994
                [
995
                    'fields' => []
996
                ]
997
            ],
998
            ]
999
        );
1000
    }
1001
1002
    /**
1003
     * @expectedException \Doctrine\ORM\Mapping\MappingException
1004
     * @expectedExceptionMessage Discriminator column name on entity class 'Doctrine\Tests\Models\CMS\CmsUser' is not defined.
1005
     */
1006
    public function testNameIsMandatoryForDiscriminatorColumnsMappingException()
1007
    {
1008
        $cm = new ClassMetadata(CMS\CmsUser::class);
1009
        $cm->initializeReflection(new RuntimeReflectionService());
1010
        $cm->setDiscriminatorColumn([]);
1011
    }
1012
1013
    /**
1014
     * @group DDC-984
1015
     * @group DDC-559
1016
     * @group DDC-1575
1017
     */
1018
    public function testFullyQualifiedClassNameShouldBeGivenToNamingStrategy()
1019
    {
1020
        $namingStrategy     = new MyNamespacedNamingStrategy();
1021
        $addressMetadata    = new ClassMetadata(CMS\CmsAddress::class, $namingStrategy);
1022
        $articleMetadata    = new ClassMetadata(DoctrineGlobal_Article::class, $namingStrategy);
1023
        $routingMetadata    = new ClassMetadata(RoutingLeg::class, $namingStrategy);
1024
1025
        $addressMetadata->initializeReflection(new RuntimeReflectionService());
1026
        $articleMetadata->initializeReflection(new RuntimeReflectionService());
1027
        $routingMetadata->initializeReflection(new RuntimeReflectionService());
1028
1029
        $addressMetadata->mapManyToMany(
1030
            [
1031
            'fieldName'     => 'user',
1032
            'targetEntity'  => 'CmsUser'
1033
            ]
1034
        );
1035
1036
        $articleMetadata->mapManyToMany(
1037
            [
1038
            'fieldName'     => 'author',
1039
            'targetEntity'  => CMS\CmsUser::class
1040
            ]
1041
        );
1042
1043
        $this->assertEquals('routing_routingleg', $routingMetadata->table['name']);
1044
        $this->assertEquals('cms_cmsaddress_cms_cmsuser', $addressMetadata->associationMappings['user']['joinTable']['name']);
1045
        $this->assertEquals('doctrineglobal_article_cms_cmsuser', $articleMetadata->associationMappings['author']['joinTable']['name']);
1046
    }
1047
1048
    /**
1049
     * @group DDC-984
1050
     * @group DDC-559
1051
     */
1052
    public function testFullyQualifiedClassNameShouldBeGivenToNamingStrategyPropertyToColumnName()
1053
    {
1054
        $namingStrategy = new MyPrefixNamingStrategy();
1055
        $metadata       = new ClassMetadata(CMS\CmsAddress::class, $namingStrategy);
1056
1057
        $metadata->initializeReflection(new RuntimeReflectionService());
1058
1059
        $metadata->mapField(['fieldName'=>'country']);
1060
        $metadata->mapField(['fieldName'=>'city']);
1061
1062
        $this->assertEquals($metadata->fieldNames, [
1063
            'cmsaddress_country'   => 'country',
1064
            'cmsaddress_city'      => 'city'
1065
        ]
1066
        );
1067
    }
1068
1069
    /**
1070
     * @group DDC-1746
1071
     */
1072
    public function testInvalidCascade()
1073
    {
1074
        $cm = new ClassMetadata(CMS\CmsUser::class);
1075
        $cm->initializeReflection(new RuntimeReflectionService());
1076
1077
        $this->expectException(MappingException::class);
1078
        $this->expectExceptionMessage("You have specified invalid cascade options for " . CMS\CmsUser::class . "::\$address: 'invalid'; available options: 'remove', 'persist', 'refresh', 'merge', and 'detach'");
1079
1080
        $cm->mapManyToOne(['fieldName' => 'address', 'targetEntity' => 'UnknownClass', 'cascade' => ['invalid']]);
1081
     }
1082
1083
    /**
1084
     * @group DDC-964
1085
     * @expectedException        Doctrine\ORM\Mapping\MappingException
1086
     * @expectedExceptionMessage Invalid field override named 'invalidPropertyName' for class 'Doctrine\Tests\Models\DDC964\DDC964Admin
1087
     */
1088
    public function testInvalidPropertyAssociationOverrideNameException()
1089
    {
1090
        $cm = new ClassMetadata(DDC964Admin::class);
1091
        $cm->initializeReflection(new RuntimeReflectionService());
1092
        $cm->mapManyToOne(['fieldName' => 'address', 'targetEntity' => 'DDC964Address']);
1093
1094
        $cm->setAssociationOverride('invalidPropertyName', []);
1095
    }
1096
1097
    /**
1098
     * @group DDC-964
1099
     * @expectedException        Doctrine\ORM\Mapping\MappingException
1100
     * @expectedExceptionMessage Invalid field override named 'invalidPropertyName' for class 'Doctrine\Tests\Models\DDC964\DDC964Guest'.
1101
     */
1102
    public function testInvalidPropertyAttributeOverrideNameException()
1103
    {
1104
        $cm = new ClassMetadata(DDC964Guest::class);
1105
        $cm->initializeReflection(new RuntimeReflectionService());
1106
        $cm->mapField(['fieldName' => 'name']);
1107
1108
        $cm->setAttributeOverride('invalidPropertyName', []);
1109
    }
1110
1111
    /**
1112
     * @group DDC-964
1113
     * @expectedException        Doctrine\ORM\Mapping\MappingException
1114
     * @expectedExceptionMessage The column type of attribute 'name' on class 'Doctrine\Tests\Models\DDC964\DDC964Guest' could not be changed.
1115
     */
1116
    public function testInvalidOverrideAttributeFieldTypeException()
1117
    {
1118
        $cm = new ClassMetadata(DDC964Guest::class);
1119
        $cm->initializeReflection(new RuntimeReflectionService());
1120
        $cm->mapField(['fieldName' => 'name', 'type'=>'string']);
1121
1122
        $cm->setAttributeOverride('name', ['type'=>'date']);
1123
    }
1124
1125
    /**
1126
     * @group DDC-1955
1127
     *
1128
     * @expectedException        Doctrine\ORM\Mapping\MappingException
1129
     * @expectedExceptionMessage Entity Listener "\InvalidClassName" declared on "Doctrine\Tests\Models\CMS\CmsUser" not found.
1130
     */
1131
    public function testInvalidEntityListenerClassException()
1132
    {
1133
        $cm = new ClassMetadata(CMS\CmsUser::class);
1134
        $cm->initializeReflection(new RuntimeReflectionService());
1135
1136
        $cm->addEntityListener(Events::postLoad, '\InvalidClassName', 'postLoadHandler');
1137
    }
1138
1139
    /**
1140
     * @group DDC-1955
1141
     *
1142
     * @expectedException        Doctrine\ORM\Mapping\MappingException
1143
     * @expectedExceptionMessage Entity Listener "\Doctrine\Tests\Models\Company\CompanyContractListener" declared on "Doctrine\Tests\Models\CMS\CmsUser" has no method "invalidMethod".
1144
     */
1145
    public function testInvalidEntityListenerMethodException()
1146
    {
1147
        $cm = new ClassMetadata(CMS\CmsUser::class);
1148
        $cm->initializeReflection(new RuntimeReflectionService());
1149
1150
        $cm->addEntityListener(Events::postLoad, '\Doctrine\Tests\Models\Company\CompanyContractListener', 'invalidMethod');
1151
    }
1152
1153
    public function testManyToManySelfReferencingNamingStrategyDefaults()
1154
    {
1155
        $cm = new ClassMetadata(CustomTypeParent::class);
1156
        $cm->initializeReflection(new RuntimeReflectionService());
1157
        $cm->mapManyToMany(
1158
            [
1159
                'fieldName' => 'friendsWithMe',
1160
                'targetEntity' => 'CustomTypeParent'
1161
            ]
1162
        );
1163
1164
        $this->assertEquals(
1165
            [
1166
                'name' => 'customtypeparent_customtypeparent',
1167
                'joinColumns' => [['name' => 'customtypeparent_source', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE']],
1168
                'inverseJoinColumns' => [['name' => 'customtypeparent_target', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE']],
1169
            ],
1170
            $cm->associationMappings['friendsWithMe']['joinTable']
1171
        );
1172
        $this->assertEquals(['customtypeparent_source', 'customtypeparent_target'], $cm->associationMappings['friendsWithMe']['joinTableColumns']);
1173
        $this->assertEquals(['customtypeparent_source' => 'id'], $cm->associationMappings['friendsWithMe']['relationToSourceKeyColumns']);
1174
        $this->assertEquals(['customtypeparent_target' => 'id'], $cm->associationMappings['friendsWithMe']['relationToTargetKeyColumns']);
1175
    }
1176
1177
    /**
1178
     * @group DDC-2608
1179
     */
1180
    public function testSetSequenceGeneratorThrowsExceptionWhenSequenceNameIsMissing()
1181
    {
1182
        $cm = new ClassMetadata(CMS\CmsUser::class);
1183
        $cm->initializeReflection(new RuntimeReflectionService());
1184
1185
        $this->expectException(\Doctrine\ORM\Mapping\MappingException::class);
1186
        $cm->setSequenceGeneratorDefinition([]);
1187
    }
1188
1189
    /**
1190
     * @group DDC-2662
1191
     */
1192
    public function testQuotedSequenceName()
1193
    {
1194
        $cm = new ClassMetadata(CMS\CmsUser::class);
1195
        $cm->initializeReflection(new RuntimeReflectionService());
1196
1197
        $cm->setSequenceGeneratorDefinition(['sequenceName' => '`foo`']);
1198
1199
        $this->assertEquals(['sequenceName' => 'foo', 'quoted' => true], $cm->sequenceGeneratorDefinition);
1200
    }
1201
1202
    /**
1203
     * @group DDC-2700
1204
     */
1205
    public function testIsIdentifierMappedSuperClass()
1206
    {
1207
        $class = new ClassMetadata(DDC2700MappedSuperClass::class);
1208
1209
        $this->assertFalse($class->isIdentifier('foo'));
1210
    }
1211
1212
    /**
1213
     * @group DDC-3120
1214
     */
1215
    public function testCanInstantiateInternalPhpClassSubclass()
1216
    {
1217
        $classMetadata = new ClassMetadata(MyArrayObjectEntity::class);
1218
1219
        $this->assertInstanceOf(MyArrayObjectEntity::class, $classMetadata->newInstance());
1220
    }
1221
1222
    /**
1223
     * @group DDC-3120
1224
     */
1225
    public function testCanInstantiateInternalPhpClassSubclassFromUnserializedMetadata()
1226
    {
1227
        /* @var $classMetadata ClassMetadata */
1228
        $classMetadata = unserialize(serialize(new ClassMetadata(MyArrayObjectEntity::class)));
1229
1230
        $classMetadata->wakeupReflection(new RuntimeReflectionService());
1231
1232
        $this->assertInstanceOf(MyArrayObjectEntity::class, $classMetadata->newInstance());
1233
    }
1234
1235
    public function testWakeupReflectionWithEmbeddableAndStaticReflectionService()
1236
    {
1237
        $classMetadata = new ClassMetadata(TestEntity1::class);
1238
1239
        $classMetadata->mapEmbedded(
1240
            [
1241
            'fieldName'    => 'test',
1242
            'class'        => TestEntity1::class,
1243
            'columnPrefix' => false,
1244
            ]
1245
        );
1246
1247
        $field = [
1248
            'fieldName' => 'test.embeddedProperty',
1249
            'type' => 'string',
1250
            'originalClass' => TestEntity1::class,
1251
            'declaredField' => 'test',
1252
            'originalField' => 'embeddedProperty'
1253
        ];
1254
1255
        $classMetadata->mapField($field);
1256
        $classMetadata->wakeupReflection(new StaticReflectionService());
1257
1258
        $this->assertEquals(['test' => null, 'test.embeddedProperty' => null], $classMetadata->getReflectionProperties());
1259
    }
1260
1261
    public function testGetColumnNamesWithGivenFieldNames()
1262
    {
1263
        $metadata = new ClassMetadata(CMS\CmsUser::class);
1264
        $metadata->initializeReflection(new RuntimeReflectionService());
1265
1266
        $metadata->mapField(['fieldName' => 'status', 'type' => 'string', 'columnName' => 'foo']);
1267
        $metadata->mapField(['fieldName' => 'username', 'type' => 'string', 'columnName' => 'bar']);
1268
        $metadata->mapField(['fieldName' => 'name', 'type' => 'string', 'columnName' => 'baz']);
1269
1270
        self::assertSame(['foo', 'baz'], $metadata->getColumnNames(['status', 'name']));
1271
    }
1272
1273
    /**
1274
     * @group DDC-6460
1275
     */
1276
    public function testInlineEmbeddable()
1277
    {
1278
        $classMetadata = new ClassMetadata(TestEntity1::class);
1279
1280
        $classMetadata->mapEmbedded(
1281
            [
1282
                'fieldName'    => 'test',
1283
                'class'        => TestEntity1::class,
1284
                'columnPrefix' => false,
1285
            ]
1286
        );
1287
1288
        $this->assertTrue($classMetadata->hasField('test'));
1289
    }
1290
}
1291
1292
/**
1293
 * @MappedSuperclass
1294
 */
1295
class DDC2700MappedSuperClass
1296
{
1297
    /** @Column */
1298
    private $foo;
1299
}
1300
1301
class MyNamespacedNamingStrategy extends DefaultNamingStrategy
1302
{
1303
    /**
1304
     * {@inheritdoc}
1305
     */
1306
    public function classToTableName($className)
1307
    {
1308
        if (strpos($className, '\\') !== false) {
1309
            $className = str_replace('\\', '_', str_replace('Doctrine\Tests\Models\\', '', $className));
1310
        }
1311
1312
        return strtolower($className);
1313
    }
1314
}
1315
1316
class MyPrefixNamingStrategy extends DefaultNamingStrategy
1317
{
1318
    /**
1319
     * {@inheritdoc}
1320
     */
1321
    public function propertyToColumnName($propertyName, $className = null)
1322
    {
1323
        return strtolower($this->classToTableName($className)) . '_' . $propertyName;
1324
    }
1325
}
1326
1327
class MyArrayObjectEntity extends \ArrayObject
1328
{
1329
}
1330