MappedSuperclassRelated1
last analyzed

Complexity

Total Complexity 0

Size/Duplication

Total Lines 2
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 2
c 0
b 0
f 0
wmc 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\ORM\Mapping;
6
7
use Doctrine\ORM\Annotation as ORM;
8
use Doctrine\ORM\EntityRepository;
9
use Doctrine\ORM\Mapping\ClassMetadataFactory;
10
use Doctrine\ORM\Mapping\GeneratorType;
11
use Doctrine\ORM\Mapping\MappingException;
12
use Doctrine\ORM\Mapping\TransientMetadata;
13
use Doctrine\Tests\Models\DDC869\DDC869ChequePayment;
14
use Doctrine\Tests\Models\DDC869\DDC869CreditCardPayment;
15
use Doctrine\Tests\Models\DDC869\DDC869Payment;
16
use Doctrine\Tests\Models\DDC869\DDC869PaymentRepository;
17
use Doctrine\Tests\OrmTestCase;
18
use function iterator_to_array;
19
20
class BasicInheritanceMappingTest extends OrmTestCase
21
{
22
    /** @var ClassMetadataFactory */
23
    private $cmf;
24
25
    /**
26
     * {@inheritDoc}
27
     */
28
    protected function setUp() : void
29
    {
30
        $this->cmf = new ClassMetadataFactory();
31
32
        $this->cmf->setEntityManager($this->getTestEntityManager());
33
    }
34
35
    public function testGetMetadataForTransientClassThrowsException() : void
36
    {
37
        $this->expectException(MappingException::class);
38
39
        $this->cmf->getMetadataFor(TransientBaseClass::class);
40
    }
41
42
    public function testGetMetadataForSubclassWithTransientBaseClass() : void
43
    {
44
        $class = $this->cmf->getMetadataFor(EntitySubClass::class);
45
46
        self::assertEmpty($class->getSubClasses());
47
        self::assertCount(0, $class->getAncestorsIterator());
48
49
        self::assertNotNull($class->getProperty('id'));
50
        self::assertNotNull($class->getProperty('name'));
51
    }
52
53
    public function testGetMetadataForSubclassWithMappedSuperclass() : void
54
    {
55
        $class = $this->cmf->getMetadataFor(EntitySubClass2::class);
56
57
        self::assertEmpty($class->getSubClasses());
58
        self::assertCount(0, $class->getAncestorsIterator());
59
60
        self::assertNotNull($class->getProperty('id'));
61
        self::assertNotNull($class->getProperty('name'));
62
        self::assertNotNull($class->getProperty('mapped1'));
63
        self::assertNotNull($class->getProperty('mapped2'));
64
65
        self::assertTrue($class->isInheritedProperty('mapped1'));
66
        self::assertTrue($class->isInheritedProperty('mapped2'));
67
68
        self::assertNotNull($class->getProperty('transient'));
69
        self::assertInstanceOf(TransientMetadata::class, $class->getProperty('transient'));
70
71
        self::assertArrayHasKey('mappedRelated1', iterator_to_array($class->getPropertiesIterator()));
72
    }
73
74
    /**
75
     * @group DDC-869
76
     */
77
    public function testGetMetadataForSubclassWithMappedSuperclassWithRepository() : void
78
    {
79
        $class = $this->cmf->getMetadataFor(DDC869CreditCardPayment::class);
80
81
        self::assertEquals($class->getCustomRepositoryClassName(), DDC869PaymentRepository::class);
82
83
        self::assertNotNull($class->getProperty('id'));
84
        self::assertNotNull($class->getProperty('value'));
85
        self::assertNotNull($class->getProperty('creditCardNumber'));
86
87
        $class = $this->cmf->getMetadataFor(DDC869ChequePayment::class);
88
89
        self::assertEquals($class->getCustomRepositoryClassName(), DDC869PaymentRepository::class);
90
91
        self::assertNotNull($class->getProperty('id'));
92
        self::assertNotNull($class->getProperty('value'));
93
        self::assertNotNull($class->getProperty('serialNumber'));
94
95
        // override repositoryClass
96
        $class = $this->cmf->getMetadataFor(SubclassWithRepository::class);
97
98
        self::assertEquals($class->getCustomRepositoryClassName(), EntityRepository::class);
99
100
        self::assertNotNull($class->getProperty('id'));
101
        self::assertNotNull($class->getProperty('value'));
102
    }
103
104
    /**
105
     * @group DDC-1203
106
     */
107
    public function testUnmappedSuperclassInHierarchy() : void
108
    {
109
        $class = $this->cmf->getMetadataFor(HierarchyD::class);
110
111
        self::assertNotNull($class->getProperty('id'));
112
        self::assertNotNull($class->getProperty('a'));
113
        self::assertNotNull($class->getProperty('d'));
114
    }
115
116
    /**
117
     * @group DDC-1204
118
     */
119
    public function testUnmappedEntityInHierarchy() : void
120
    {
121
        $this->expectException(MappingException::class);
122
        $this->expectExceptionMessage(
123
            'Entity \'Doctrine\Tests\ORM\Mapping\HierarchyBEntity\' has to be part of the discriminator map'
124
            . ' of \'Doctrine\Tests\ORM\Mapping\HierarchyBase\' to be properly mapped in the inheritance hierarchy.'
125
            . ' Alternatively you can make \'Doctrine\Tests\ORM\Mapping\HierarchyBEntity\' an abstract class to'
126
            . ' avoid this exception from occurring.'
127
        );
128
129
        $this->cmf->getMetadataFor(HierarchyE::class);
130
    }
131
132
    /**
133
     * @group DDC-1204
134
     * @group DDC-1203
135
     */
136
    public function testMappedSuperclassWithId() : void
137
    {
138
        $class = $this->cmf->getMetadataFor(SuperclassEntity::class);
139
140
        self::assertNotNull($class->getProperty('id'));
141
    }
142
143
    /**
144
     * @group DDC-1156
145
     * @group DDC-1218
146
     */
147
    public function testGeneratedValueFromMappedSuperclass() : void
148
    {
149
        /** @var ClassMetadata $class */
150
        $class = $this->cmf->getMetadataFor(SuperclassEntity::class);
151
152
        $valueGenerator = $class->getProperty('id')->getValueGenerator();
153
154
        self::assertSame(GeneratorType::SEQUENCE, $valueGenerator->getType());
155
        self::assertEquals('foo', $valueGenerator->getGenerator()->getSequenceName());
156
        self::assertEquals(1, $valueGenerator->getGenerator()->getAllocationSize());
157
    }
158
159
    /**
160
     * @group DDC-1156
161
     * @group DDC-1218
162
     */
163
    public function testSequenceDefinitionInHierarchyWithSandwichMappedSuperclass() : void
164
    {
165
        /** @var ClassMetadata $class */
166
        $class = $this->cmf->getMetadataFor(HierarchyD::class);
167
168
        $valueGenerator = $class->getProperty('id')->getValueGenerator();
169
170
        self::assertSame(GeneratorType::SEQUENCE, $valueGenerator->getType());
171
        self::assertEquals('foo', $valueGenerator->getGenerator()->getSequenceName());
172
        self::assertEquals(1, $valueGenerator->getGenerator()->getAllocationSize());
173
    }
174
175
    /**
176
     * @group DDC-1156
177
     * @group DDC-1218
178
     */
179
    public function testMultipleMappedSuperclasses() : void
180
    {
181
        /** @var ClassMetadata $class */
182
        $class = $this->cmf->getMetadataFor(MediumSuperclassEntity::class);
183
184
        $valueGenerator = $class->getProperty('id')->getValueGenerator();
185
186
        self::assertSame(GeneratorType::SEQUENCE, $valueGenerator->getType());
187
        self::assertEquals('foo', $valueGenerator->getGenerator()->getSequenceName());
188
        self::assertEquals(1, $valueGenerator->getGenerator()->getAllocationSize());
189
    }
190
}
191
192
class TransientBaseClass
193
{
194
    private $transient1;
0 ignored issues
show
introduced by
The private property $transient1 is not used, and could be removed.
Loading history...
195
    private $transient2;
0 ignored issues
show
introduced by
The private property $transient2 is not used, and could be removed.
Loading history...
196
}
197
198
/** @ORM\Entity */
199
class EntitySubClass extends TransientBaseClass
200
{
201
    /** @ORM\Id @ORM\Column(type="integer") */
202
    private $id;
0 ignored issues
show
introduced by
The private property $id is not used, and could be removed.
Loading history...
203
    /** @ORM\Column(type="string") */
204
    private $name;
0 ignored issues
show
introduced by
The private property $name is not used, and could be removed.
Loading history...
205
}
206
207
/** @ORM\MappedSuperclass */
208
class MappedSuperclassBase
209
{
210
    /** @ORM\Column(type="integer") */
211
    private $mapped1;
0 ignored issues
show
introduced by
The private property $mapped1 is not used, and could be removed.
Loading history...
212
    /** @ORM\Column(type="string") */
213
    private $mapped2;
0 ignored issues
show
introduced by
The private property $mapped2 is not used, and could be removed.
Loading history...
214
    /**
215
     * @ORM\OneToOne(targetEntity=MappedSuperclassRelated1::class)
216
     * @ORM\JoinColumn(name="related1_id", referencedColumnName="id")
217
     */
218
    private $mappedRelated1;
0 ignored issues
show
introduced by
The private property $mappedRelated1 is not used, and could be removed.
Loading history...
219
    private $transient;
0 ignored issues
show
introduced by
The private property $transient is not used, and could be removed.
Loading history...
220
}
221
class MappedSuperclassRelated1
222
{
223
}
224
225
/** @ORM\Entity */
226
class EntitySubClass2 extends MappedSuperclassBase
227
{
228
    /** @ORM\Id @ORM\Column(type="integer") */
229
    private $id;
230
    /** @ORM\Column(type="string") */
231
    private $name;
232
}
233
234
/**
235
 * @ORM\MappedSuperclass
236
 */
237
class MappedSuperclassBaseIndex
238
{
239
    /** @ORM\Column(type="string") */
240
    private $mapped1;
241
    /** @ORM\Column(type="string") */
242
    private $mapped2;
243
}
244
245
/** @ORM\Entity @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(name="IDX_NAME_INDEX",columns={"name"})}) */
246
class EntityIndexSubClass extends MappedSuperclassBaseIndex
247
{
248
    /** @ORM\Id @ORM\Column(type="integer") */
249
    private $id;
250
    /** @ORM\Column(type="string") */
251
    private $name;
252
}
253
254
/**
255
 * @ORM\Entity
256
 * @ORM\InheritanceType("SINGLE_TABLE")
257
 * @ORM\DiscriminatorColumn(name="type", type="string", length=20)
258
 * @ORM\DiscriminatorMap({
259
 *     "c"   = HierarchyC::class,
260
 *     "d"   = HierarchyD::class,
261
 *     "e"   = HierarchyE::class
262
 * })
263
 */
264
abstract class HierarchyBase
265
{
266
    /**
267
     * @ORM\Column(type="integer") @ORM\Id @ORM\GeneratedValue(strategy="SEQUENCE")
268
     * @ORM\SequenceGenerator(sequenceName="foo")
269
     *
270
     * @var int
271
     */
272
    public $id;
273
}
274
275
/** @ORM\MappedSuperclass */
276
abstract class HierarchyASuperclass extends HierarchyBase
277
{
278
    /** @ORM\Column(type="string") */
279
    public $a;
280
}
281
282
/** @ORM\Entity */
283
class HierarchyBEntity extends HierarchyBase
284
{
285
    /** @ORM\Column(type="string") */
286
    public $b;
287
}
288
289
/** @ORM\Entity */
290
class HierarchyC extends HierarchyBase
291
{
292
    /** @ORM\Column(type="string") */
293
    public $c;
294
}
295
296
/** @ORM\Entity */
297
class HierarchyD extends HierarchyASuperclass
298
{
299
    /** @ORM\Column(type="string") */
300
    public $d;
301
}
302
303
/** @ORM\Entity */
304
class HierarchyE extends HierarchyBEntity
305
{
306
    /** @ORM\Column(type="string") */
307
    public $e;
308
}
309
310
/** @ORM\Entity */
311
class SuperclassEntity extends SuperclassBase
312
{
313
}
314
315
/** @ORM\MappedSuperclass */
316
abstract class SuperclassBase
317
{
318
    /**
319
     * @ORM\Column(type="integer") @ORM\Id @ORM\GeneratedValue(strategy="SEQUENCE")
320
     * @ORM\SequenceGenerator(sequenceName="foo")
321
     */
322
    public $id;
323
}
324
325
/** @ORM\MappedSuperclass */
326
abstract class MediumSuperclassBase extends SuperclassBase
327
{
328
}
329
330
/** @ORM\Entity */
331
class MediumSuperclassEntity extends MediumSuperclassBase
332
{
333
}
334
335
/** @ORM\Entity(repositoryClass = "Doctrine\ORM\EntityRepository") */
336
class SubclassWithRepository extends DDC869Payment
337
{
338
}
339