Failed Conditions
Push — master ( a3e53b...559253 )
by Guilherme
14:58
created

Tests/ORM/Mapping/AnnotationDriverTest.php (1 issue)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\ORM\Mapping;
6
7
use Doctrine\Common\Annotations\AnnotationException;
8
use Doctrine\ORM\Annotation as ORM;
9
use Doctrine\ORM\Mapping\ClassMetadata;
10
use Doctrine\ORM\Mapping\ClassMetadataFactory;
11
use Doctrine\ORM\Mapping\MappingException;
12
use Doctrine\Tests\Models\CMS\CmsUser;
13
use Doctrine\Tests\Models\DDC1872\DDC1872ExampleEntityWithoutOverride;
14
use Doctrine\Tests\Models\DDC1872\DDC1872ExampleEntityWithOverride;
15
use Doctrine\Tests\Models\DirectoryTree\Directory;
16
use Doctrine\Tests\Models\DirectoryTree\File;
17
use Doctrine\Tests\Models\ECommerce\ECommerceCart;
18
use function iterator_to_array;
19
20
class AnnotationDriverTest extends AbstractMappingDriverTest
21
{
22
    /**
23
     * @group DDC-268
24
     */
25
    public function testLoadMetadataForNonEntityThrowsException() : void
26
    {
27
        $mappingDriver = $this->loadDriver();
28
29
        $this->expectException(MappingException::class);
30
31
        $mappingDriver->loadMetadataForClass('stdClass', null, $this->metadataBuildingContext);
32
    }
33
34
    /**
35
     * @expectedException \Doctrine\ORM\Cache\Exception\CacheException
36
     * @expectedExceptionMessage Entity association field "Doctrine\Tests\ORM\Mapping\AnnotationSLC#foo" not configured as part of the second-level cache.
37
     */
38
    public function testFailingSecondLevelCacheAssociation() : void
39
    {
40
        $mappingDriver = $this->loadDriver();
41
42
        $mappingDriver->loadMetadataForClass(AnnotationSLC::class, null, $this->metadataBuildingContext);
43
    }
44
45
    /**
46
     * @group DDC-268
47
     */
48
    public function testColumnWithMissingTypeDefaultsToString() : void
49
    {
50
        $mappingDriver = $this->loadDriver();
51
52
        $cm = $mappingDriver->loadMetadataForClass(ColumnWithoutType::class, null, $this->metadataBuildingContext);
53
54
        self::assertNotNull($cm->getProperty('id'));
55
56
        $idProperty = $cm->getProperty('id');
57
58
        self::assertEquals('string', $idProperty->getTypeName());
59
    }
60
61
    /**
62
     * @group DDC-318
63
     */
64
    public function testGetAllClassNamesIsIdempotent() : void
65
    {
66
        $annotationDriver = $this->loadDriverForCMSModels();
67
        $original         = $annotationDriver->getAllClassNames();
68
69
        $annotationDriver = $this->loadDriverForCMSModels();
70
        $afterTestReset   = $annotationDriver->getAllClassNames();
71
72
        self::assertEquals($original, $afterTestReset);
73
    }
74
75
    /**
76
     * @group DDC-318
77
     */
78
    public function testGetAllClassNamesIsIdempotentEvenWithDifferentDriverInstances() : void
79
    {
80
        $annotationDriver = $this->loadDriverForCMSModels();
81
        $original         = $annotationDriver->getAllClassNames();
82
83
        $annotationDriver = $this->loadDriverForCMSModels();
84
        $afterTestReset   = $annotationDriver->getAllClassNames();
85
86
        self::assertEquals($original, $afterTestReset);
87
    }
88
89
    /**
90
     * @group DDC-318
91
     */
92
    public function testGetAllClassNamesReturnsAlreadyLoadedClassesIfAppropriate() : void
93
    {
94
        $this->ensureIsLoaded(CmsUser::class);
95
96
        $annotationDriver = $this->loadDriverForCMSModels();
97
        $classes          = $annotationDriver->getAllClassNames();
98
99
        self::assertContains(CmsUser::class, $classes);
100
    }
101
102
    /**
103
     * @group DDC-318
104
     */
105
    public function testGetClassNamesReturnsOnlyTheAppropriateClasses() : void
106
    {
107
        $this->ensureIsLoaded(ECommerceCart::class);
108
109
        $annotationDriver = $this->loadDriverForCMSModels();
110
        $classes          = $annotationDriver->getAllClassNames();
111
112
        self::assertNotContains(ECommerceCart::class, $classes);
113
    }
114
115
    protected function loadDriverForCMSModels()
116
    {
117
        $annotationDriver = $this->loadDriver();
118
        $annotationDriver->addPaths([__DIR__ . '/../../Models/CMS/']);
119
120
        return $annotationDriver;
121
    }
122
123
    protected function loadDriver()
124
    {
125
        return $this->createAnnotationDriver();
126
    }
127
128
    protected function ensureIsLoaded($entityClassName)
129
    {
130
        new $entityClassName();
131
    }
132
133
    /**
134
     * @group DDC-671
135
     *
136
     * Entities for this test are in AbstractMappingDriverTest
137
     */
138
    public function testJoinTablesWithMappedSuperclassForAnnotationDriver() : void
139
    {
140
        $annotationDriver = $this->loadDriver();
141
        $annotationDriver->addPaths([__DIR__ . '/../../Models/DirectoryTree/']);
142
143
        $em = $this->getTestEntityManager();
144
        $em->getConfiguration()->setMetadataDriverImpl($annotationDriver);
145
        $factory = new ClassMetadataFactory();
146
        $factory->setEntityManager($em);
147
148
        $classPage = $factory->getMetadataFor(File::class);
149
        self::assertArrayHasKey('parentDirectory', iterator_to_array($classPage->getPropertiesIterator()));
150
        self::assertEquals(File::class, $classPage->getProperty('parentDirectory')->getSourceEntity());
0 ignored issues
show
The method getSourceEntity() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\EmbeddedMetadata or Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

150
        self::assertEquals(File::class, $classPage->getProperty('parentDirectory')->/** @scrutinizer ignore-call */ getSourceEntity());
Loading history...
151
152
        $classDirectory = $factory->getMetadataFor(Directory::class);
153
        self::assertArrayHasKey('parentDirectory', iterator_to_array($classDirectory->getPropertiesIterator()));
154
        self::assertEquals(Directory::class, $classDirectory->getProperty('parentDirectory')->getSourceEntity());
155
    }
156
157
    /**
158
     * @group DDC-945
159
     */
160
    public function testInvalidMappedSuperClassWithManyToManyAssociation() : void
161
    {
162
        $annotationDriver = $this->loadDriver();
163
164
        $em = $this->getTestEntityManager();
165
        $em->getConfiguration()->setMetadataDriverImpl($annotationDriver);
166
        $factory = new ClassMetadataFactory();
167
        $factory->setEntityManager($em);
168
169
        $this->expectException(MappingException::class);
170
        $this->expectExceptionMessage(
171
            'It is illegal to put an inverse side one-to-many or many-to-many association on ' .
172
            "mapped superclass 'Doctrine\Tests\ORM\Mapping\InvalidMappedSuperClass#users'"
173
        );
174
175
        $factory->getMetadataFor(UsingInvalidMappedSuperClass::class);
176
    }
177
178
    /**
179
     * @group DDC-1034
180
     */
181
    public function testInheritanceSkipsParentLifecycleCallbacks() : void
182
    {
183
        $annotationDriver = $this->loadDriver();
184
185
        $em = $this->getTestEntityManager();
186
        $em->getConfiguration()->setMetadataDriverImpl($annotationDriver);
187
        $factory = new ClassMetadataFactory();
188
        $factory->setEntityManager($em);
189
190
        $cm = $factory->getMetadataFor(AnnotationChild::class);
191
        self::assertEquals(['postLoad' => ['postLoad'], 'preUpdate' => ['preUpdate']], $cm->lifecycleCallbacks);
192
193
        $cm = $factory->getMetadataFor(AnnotationParent::class);
194
        self::assertEquals(['postLoad' => ['postLoad'], 'preUpdate' => ['preUpdate']], $cm->lifecycleCallbacks);
195
    }
196
197
    /**
198
     * @group DDC-1156
199
     */
200
    public function testMappedSuperclassInMiddleOfInheritanceHierarchy() : void
201
    {
202
        $annotationDriver = $this->loadDriver();
203
204
        $em = $this->getTestEntityManager();
205
        $em->getConfiguration()->setMetadataDriverImpl($annotationDriver);
206
207
        $factory = new ClassMetadataFactory();
208
        $factory->setEntityManager($em);
209
210
        self::assertInstanceOf(ClassMetadata::class, $factory->getMetadataFor(ChildEntity::class));
211
    }
212
213
    public function testInvalidFetchOptionThrowsException() : void
214
    {
215
        $annotationDriver = $this->loadDriver();
216
217
        $em = $this->getTestEntityManager();
218
        $em->getConfiguration()->setMetadataDriverImpl($annotationDriver);
219
        $factory = new ClassMetadataFactory();
220
        $factory->setEntityManager($em);
221
222
        $this->expectException(AnnotationException::class);
223
        $this->expectExceptionMessage('[Enum Error] Attribute "fetch" of @Doctrine\ORM\Annotation\OneToMany declared on property Doctrine\Tests\ORM\Mapping\InvalidFetchOption::$collection accept only [LAZY, EAGER, EXTRA_LAZY], but got eager.');
224
225
        $factory->getMetadataFor(InvalidFetchOption::class);
226
    }
227
228
    public function testAttributeOverridesMappingWithTrait() : void
229
    {
230
        $factory = $this->createClassMetadataFactory();
231
232
        $metadataWithoutOverride = $factory->getMetadataFor(DDC1872ExampleEntityWithoutOverride::class);
233
        $metadataWithOverride    = $factory->getMetadataFor(DDC1872ExampleEntityWithOverride::class);
234
235
        self::assertNotNull($metadataWithoutOverride->getProperty('foo'));
236
        self::assertNotNull($metadataWithOverride->getProperty('foo'));
237
238
        $fooPropertyWithoutOverride = $metadataWithoutOverride->getProperty('foo');
239
        $fooPropertyWithOverride    = $metadataWithOverride->getProperty('foo');
240
241
        self::assertEquals('trait_foo', $fooPropertyWithoutOverride->getColumnName());
242
        self::assertEquals('foo_overridden', $fooPropertyWithOverride->getColumnName());
243
244
        $barPropertyWithoutOverride = $metadataWithoutOverride->getProperty('bar');
245
        $barPropertyWithOverride    = $metadataWithOverride->getProperty('bar');
246
247
        $barPropertyWithoutOverrideFirstJoinColumn = $barPropertyWithoutOverride->getJoinColumns()[0];
248
        $barPropertyWithOverrideFirstJoinColumn    = $barPropertyWithOverride->getJoinColumns()[0];
249
250
        self::assertEquals('example_trait_bar_id', $barPropertyWithoutOverrideFirstJoinColumn->getColumnName());
251
        self::assertEquals('example_entity_overridden_bar_id', $barPropertyWithOverrideFirstJoinColumn->getColumnName());
252
    }
253
}
254
255
/**
256
 * @ORM\MappedSuperclass
257
 */
258
class InvalidMappedSuperClass
259
{
260
    /** @ORM\ManyToMany(targetEntity=CmsUser::class, mappedBy="invalid") */
261
    private $users;
262
}
263
264
/**
265
 * @ORM\Entity
266
 */
267
class UsingInvalidMappedSuperClass extends InvalidMappedSuperClass
268
{
269
    /** @ORM\Id @ORM\Column(type="integer") @ORM\GeneratedValue */
270
    private $id;
271
}
272
273
/**
274
 * @ORM\Entity
275
 */
276
class ColumnWithoutType
277
{
278
    /** @ORM\Id @ORM\Column */
279
    public $id;
280
}
281
282
/**
283
 * @ORM\Entity
284
 * @ORM\InheritanceType("JOINED")
285
 * @ORM\DiscriminatorMap({"parent" = AnnotationParent::class, "child" = AnnotationChild::class})
286
 * @ORM\HasLifecycleCallbacks
287
 */
288
class AnnotationParent
289
{
290
    /** @ORM\Id @ORM\Column(type="integer") @ORM\GeneratedValue */
291
    private $id;
292
293
    /**
294
     * @ORM\PostLoad
295
     */
296
    public function postLoad()
297
    {
298
    }
299
300
    /**
301
     * @ORM\PreUpdate
302
     */
303
    public function preUpdate()
304
    {
305
    }
306
}
307
308
/**
309
 * @ORM\Entity
310
 * @ORM\HasLifecycleCallbacks
311
 */
312
class AnnotationChild extends AnnotationParent
313
{
314
}
315
316
/**
317
 * @ORM\Entity
318
 * @ORM\InheritanceType("SINGLE_TABLE")
319
 * @ORM\DiscriminatorMap({"s"=SuperEntity::class, "c"=ChildEntity::class})
320
 */
321
class SuperEntity
322
{
323
    /** @ORM\Id @ORM\Column(type="string") */
324
    private $id;
325
}
326
327
/**
328
 * @ORM\MappedSuperclass
329
 */
330
class MiddleMappedSuperclass extends SuperEntity
331
{
332
    /** @ORM\Column(type="string") */
333
    private $name;
334
}
335
336
/**
337
 * @ORM\Entity
338
 */
339
class ChildEntity extends MiddleMappedSuperclass
340
{
341
    /** @ORM\Column(type="string") */
342
    private $text;
343
}
344
345
/**
346
 * @ORM\Entity
347
 */
348
class InvalidFetchOption
349
{
350
    /** @ORM\OneToMany(targetEntity=CmsUser::class, fetch="eager") */
351
    private $collection;
352
}
353
354
/**
355
 * @ORM\Entity
356
 * @ORM\Cache
357
 */
358
class AnnotationSLC
359
{
360
    /**
361
     * @ORM\Id
362
     * @ORM\ManyToOne(targetEntity=AnnotationSLCFoo::class)
363
     */
364
    public $foo;
365
}
366
/**
367
 * @ORM\Entity
368
 */
369
class AnnotationSLCFoo
370
{
371
    /** @ORM\Column(type="string") */
372
    public $id;
373
}
374