canHydrateAnEntityViaSimpleDataLoading()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 41
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 23
c 1
b 0
f 1
nc 1
nop 0
dl 0
loc 41
rs 9.552
1
<?php
2
/**
3
 * Copyright (C) 2018 Gerrit Addiks.
4
 * This package (including this file) was released under the terms of the GPL-3.0.
5
 * You should have received a copy of the GNU General Public License along with this program.
6
 * If not, see <http://www.gnu.org/licenses/> or send me a mail so i can send you a copy.
7
 * @license GPL-3.0
8
 * @author Gerrit Addiks <[email protected]>
9
 */
10
11
namespace Addiks\RDMBundle\Tests;
12
13
use PHPUnit\Framework\TestCase;
14
use Symfony\Component\DependencyInjection\Container;
15
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
16
use Symfony\Component\Config\FileLocator;
17
use Addiks\RDMBundle\Doctrine\EventListener;
18
use Doctrine\ORM\Event\LifecycleEventArgs;
19
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
20
use Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs;
21
use Doctrine\ORM\EntityManagerInterface;
22
use Doctrine\Common\Annotations\Reader as AnnotationReader;
23
use Symfony\Component\HttpKernel\KernelInterface;
24
use Doctrine\ORM\Mapping\ClassMetadata;
25
use Doctrine\DBAL\Schema\Schema;
26
use Doctrine\DBAL\Schema\Table;
27
use Doctrine\ORM\Mapping\ClassMetadataFactory;
28
use Addiks\RDMBundle\Tests\Hydration\EntityExample;
29
use Doctrine\ORM\Configuration;
30
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
31
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
32
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
33
use Symfony\Component\DependencyInjection\ContainerBuilder;
34
use Psr\Cache\CacheItemPoolInterface;
35
use Addiks\RDMBundle\Mapping\Drivers\MappingDriverInterface;
36
use ReflectionClass;
37
use Doctrine\ORM\Mapping\Entity;
38
use Doctrine\Common\EventManager;
39
use ReflectionProperty;
40
use Doctrine\ORM\Mapping\Id;
41
use Doctrine\ORM\Mapping\Column;
42
use Psr\Cache\CacheItemInterface;
43
use Addiks\RDMBundle\Mapping\Annotation\Choice;
44
use Addiks\RDMBundle\Tests\Hydration\ServiceExample;
45
use Addiks\RDMBundle\Mapping\Annotation\Service;
46
use Addiks\RDMBundle\Exception\FailedRDMAssertionExceptionInterface;
47
use Doctrine\ORM\UnitOfWork;
48
use Doctrine\DBAL\Connection;
49
use Doctrine\DBAL\Statement;
50
use Doctrine\ORM\Query\Expr;
51
use Doctrine\DBAL\Query\QueryBuilder;
52
use Doctrine\ORM\Event\PostFlushEventArgs;
53
use Addiks\RDMBundle\Tests\ValueObjectExample;
54
use Addiks\RDMBundle\Mapping\Annotation\Call;
55
use Addiks\RDMBundle\Mapping\Annotation\RDMArray;
56
use Addiks\RDMBundle\Mapping\Annotation\RDMObject;
57
use Doctrine\DBAL\Platforms\AbstractPlatform;
58
59
/**
60
 * This is an integration-test that test's the bundle as a whole.
61
 * It loads all the service-definitions from the service.xml and attempts to interact with the whole object-graph as it
62
 * will be for the end-user. Mostly it just pretends to be doctrine, provides events to the event-listener and checks
63
 * that the expected things happened.
64
 */
65
final class IntegrationTest extends TestCase
66
{
67
68
    /**
69
     * @var Container
70
     */
71
    private $container;
72
73
    /**
74
     * @var EntityManagerInterface
75
     */
76
    private $entityManager;
77
78
    /**
79
     * @var AnnotationReader
80
     */
81
    private $annotationReader;
82
83
    /**
84
     * @var KernelInterface
85
     */
86
    private $kernel;
87
88
    /**
89
     * @var MappingDriver
90
     */
91
    private $doctrineMetadataDriver;
92
93
    /**
94
     * @var Configuration
95
     */
96
    private $doctrineConfiguration;
97
98
    /**
99
     * @var CacheItemPoolInterface
100
     */
101
    private $cacheItemPool;
102
103
    /**
104
     * @var XmlFileLoader
105
     */
106
    private $loader;
107
108
    public function setUp(): void
109
    {
110
        $this->container = new ContainerBuilder();
111
        $this->entityManager = $this->createMock(EntityManagerInterface::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(Doctri...anagerInterface::class) of type PHPUnit\Framework\MockObject\MockObject is incompatible with the declared type Doctrine\ORM\EntityManagerInterface of property $entityManager.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
112
        $this->annotationReader = $this->createMock(AnnotationReader::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(Doctri...otations\Reader::class) of type PHPUnit\Framework\MockObject\MockObject is incompatible with the declared type Doctrine\Common\Annotations\Reader of property $annotationReader.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
113
        $this->kernel = $this->createMock(KernelInterface::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(Symfon...KernelInterface::class) of type PHPUnit\Framework\MockObject\MockObject is incompatible with the declared type Symfony\Component\HttpKernel\KernelInterface of property $kernel.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
114
        $this->doctrineMetadataDriver = $this->createMock(MappingDriver::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(Doctri...r\MappingDriver::class) of type PHPUnit\Framework\MockObject\MockObject is incompatible with the declared type Doctrine\Persistence\Mapping\Driver\MappingDriver of property $doctrineMetadataDriver.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
115
        $this->doctrineConfiguration = $this->createMock(Configuration::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(Doctri...M\Configuration::class) of type PHPUnit\Framework\MockObject\MockObject is incompatible with the declared type Doctrine\ORM\Configuration of property $doctrineConfiguration.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
116
        $this->cacheItemPool = $this->createMock(CacheItemPoolInterface::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(Psr\Ca...emPoolInterface::class) of type PHPUnit\Framework\MockObject\MockObject is incompatible with the declared type Psr\Cache\CacheItemPoolInterface of property $cacheItemPool.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
117
118
        $this->entityManager->method('getConfiguration')->willReturn($this->doctrineConfiguration);
119
        $this->entityManager->method('getEventManager')->willReturn($this->createMock(EventManager::class));
120
        $this->entityManager->method('getMetadataFactory')->willReturn($this->createMock(ClassMetadataFactory::class));
121
122
        $this->cacheItemPool->method('getItem')->willReturn($this->createMock(CacheItemInterface::class));
123
124
        $this->container->set('kernel', $this->kernel);
125
        $this->container->set('doctrine.orm.entity_manager', $this->entityManager);
126
        $this->container->set('annotation_reader', $this->annotationReader);
127
        $this->container->set('cache.app', $this->cacheItemPool);
128
129
        $this->loader = new XmlFileLoader(
130
            $this->container,
131
            new FileLocator(__DIR__ . '/../Resources/config')
132
        );
133
    }
134
135
    /**
136
     * @test
137
     */
138
    public function willCreateTheNeededAdditionalSchema()
139
    {
140
        $annotationMap = array(
141
            'id' => [
142
                Id::class => new Id(),
143
                Column::class => $this->createColumn("id")
144
            ],
145
            'foo' => [
146
                Choice::class => $this->createChoice("lorem"),
147
            ],
148
            'bar' => [
149
                Choice::class => $this->createChoice(),
150
            ],
151
            'baz' => [],
152
        );
153
154
        $this->configureMockedAnnotationReader($this->annotationReader, $annotationMap);
155
156
        /** @var EventListener $eventListener */
157
        $eventListener = $this->spawnEventListener();
158
159
        $metadataFactory = new ClassMetadataFactory();
160
        $metadataFactory->setEntityManager($this->entityManager);
161
162
        /** @var ClassMetadata $classMetadata */
163
        $classMetadata = $metadataFactory->getMetadataFor(EntityExample::class);
164
165
        $classTable = new Table("some_table");
166
        $schema = new Schema([$classTable]);
167
168
        $eventListener->postGenerateSchemaTable(new GenerateSchemaTableEventArgs(
169
            $classMetadata,
170
            $schema,
171
            $classTable
172
        ));
173
174
        $this->assertTrue($classTable->hasColumn("lorem"));
175
        $this->assertTrue($classTable->hasColumn("bar"));
176
    }
177
178
    /**
179
     * @test
180
     */
181
    public function canHydrateAnEntityViaSimpleDataLoading()
182
    {
183
        $annotationMap = array(
184
            'id' => [
185
                Id::class => new Id(),
186
                Column::class => $this->createColumn("id")
187
            ],
188
            'foo' => [
189
                Service::class => $this->createService("a_service"),
190
            ],
191
            'bar' => [
192
                Service::class => $this->createService("b_service"),
193
            ],
194
            'baz' => [],
195
        );
196
197
        $this->configureMockedAnnotationReader($this->annotationReader, $annotationMap);
198
199
        /** @var EventListener $eventListener */
200
        $eventListener = $this->spawnEventListener();
201
202
        $metadataFactory = new ClassMetadataFactory();
203
        $metadataFactory->setEntityManager($this->entityManager);
204
205
        /** @var ClassMetadata $classMetadata */
206
        $classMetadata = $metadataFactory->getMetadataFor(EntityExample::class);
207
208
        $serviceA = new ServiceExample("lorem", 123);
209
        $serviceB = new ServiceExample("ipsum", 456);
210
211
        $entity = new EntityExample();
212
213
        $this->container->set('a_service', $serviceA);
214
        $this->container->set('b_service', $serviceB);
215
216
        $eventListener->loadClassMetadata(new LoadClassMetadataEventArgs($classMetadata, $this->entityManager));
217
218
        $eventListener->postLoad(new LifecycleEventArgs($entity, $this->entityManager));
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\ORM\Event\LifecycleEventArgs has been deprecated: This class will be removed in ORM 3.0. Use one of the dedicated classes instead. ( Ignorable by Annotation )

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

218
        $eventListener->postLoad(/** @scrutinizer ignore-deprecated */ new LifecycleEventArgs($entity, $this->entityManager));
Loading history...
219
220
        $this->assertSame($serviceA, $entity->foo);
221
        $this->assertSame($serviceB, $entity->bar);
222
    }
223
224
    /**
225
     * @test
226
     */
227
    public function willRecogniseFailedAssertions()
228
    {
229
        $annotationMap = array(
230
            'id' => [
231
                Id::class => new Id(),
232
                Column::class => $this->createColumn("id")
233
            ],
234
            'foo' => [
235
                Service::class => $this->createService("a_service"),
236
            ],
237
            'bar' => [
238
                Service::class => $this->createService("b_service"),
239
            ],
240
            'baz' => [],
241
        );
242
243
        $this->configureMockedAnnotationReader($this->annotationReader, $annotationMap);
244
245
        /** @var EventListener $eventListener */
246
        $eventListener = $this->spawnEventListener();
247
248
        $metadataFactory = new ClassMetadataFactory();
249
        $metadataFactory->setEntityManager($this->entityManager);
250
251
        /** @var ClassMetadata $classMetadata */
252
        $classMetadata = $metadataFactory->getMetadataFor(EntityExample::class);
253
254
        $serviceA = new ServiceExample("lorem", 123);
255
        $serviceB = new ServiceExample("ipsum", 456);
256
257
        $entity = new EntityExample();
258
        $entity->foo = $serviceA;
259
        $entity->bar = null;
260
261
        $this->container->set('a_service', $serviceA);
262
        $this->container->set('b_service', $serviceB);
263
264
        $eventListener->loadClassMetadata(new LoadClassMetadataEventArgs($classMetadata, $this->entityManager));
265
266
        $this->expectException(FailedRDMAssertionExceptionInterface::class);
267
268
        $eventListener->prePersist(new LifecycleEventArgs($entity, $this->entityManager));
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\ORM\Event\LifecycleEventArgs has been deprecated: This class will be removed in ORM 3.0. Use one of the dedicated classes instead. ( Ignorable by Annotation )

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

268
        $eventListener->prePersist(/** @scrutinizer ignore-deprecated */ new LifecycleEventArgs($entity, $this->entityManager));
Loading history...
269
    }
270
271
    /**
272
     * @test
273
     * @dataProvider dataProviderForCanStoreAdditionalData
274
     */
275
    public function canStoreAdditionalData(string $stability, bool $expectsUpdate): void
276
    {
277
        $annotationMap = array(
278
            'id' => [
279
                Id::class => new Id(),
280
                Column::class => $this->createColumn("id")
281
            ],
282
            'foo' => [
283
            ],
284
            'bar' => [
285
                Choice::class => $this->createChoice("bar_column", [
286
                    'a' => $this->createService("a_service"),
287
                    'b' => $this->createService("b_service"),
288
                ]),
289
            ],
290
            'baz' => [],
291
        );
292
293
        $this->configureMockedAnnotationReader($this->annotationReader, $annotationMap);
294
295
        /** @var EventListener $eventListener */
296
        $eventListener = $this->spawnEventListener();
297
298
        $metadataFactory = new ClassMetadataFactory();
299
        $metadataFactory->setEntityManager($this->entityManager);
300
301
        /** @var ClassMetadata $classMetadata */
302
        $classMetadata = $metadataFactory->getMetadataFor(EntityExample::class);
303
        $classMetadata->table = ['name' => 'some_table'];
304
305
        /** @var UnitOfWork $unitOfWork */
306
        $unitOfWork = $this->createMock(UnitOfWork::class);
307
308
        /** @var Connection $connection */
309
        $connection = $this->createMock(Connection::class);
310
311
        $this->entityManager->method("getUnitOfWork")->willReturn($unitOfWork);
0 ignored issues
show
Bug introduced by
The method method() does not exist on Doctrine\ORM\EntityManagerInterface. ( Ignorable by Annotation )

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

311
        $this->entityManager->/** @scrutinizer ignore-call */ 
312
                              method("getUnitOfWork")->willReturn($unitOfWork);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
312
        $this->entityManager->method("getConnection")->willReturn($connection);
313
        $this->entityManager->method("getClassMetadata")->will($this->returnValueMap([
314
            [EntityExample::class, $classMetadata]
315
        ]));
316
317
        $serviceA = new ServiceExample("lorem", 123);
318
        $serviceB = new ServiceExample("ipsum", 456);
319
320
        $entity = new EntityExample();
321
        $entity->foo = null;
322
        $entity->bar = $serviceA;
323
324
        $unitOfWork->method('getIdentityMap')->willReturn([
0 ignored issues
show
Bug introduced by
The method method() does not exist on Doctrine\ORM\UnitOfWork. ( Ignorable by Annotation )

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

324
        $unitOfWork->/** @scrutinizer ignore-call */ 
325
                     method('getIdentityMap')->willReturn([

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
325
            EntityExample::class => [
326
                $entity
327
            ]
328
        ]);
329
330
        $this->container->setParameter('addiks_rdm.data_loader.stability', $stability);
331
        $this->container->set('a_service', $serviceA);
332
        $this->container->set('b_service', $serviceB);
333
334
        if ($expectsUpdate) {
335
            $connection->expects($this->once())->method("update")->with(
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Doctrine\DBAL\Connection. ( Ignorable by Annotation )

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

335
            $connection->/** @scrutinizer ignore-call */ 
336
                         expects($this->once())->method("update")->with(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
336
                $this->equalTo("some_table"),
337
                $this->equalTo([
338
                    'bar_column' => 'a'
339
                ])
340
            );
341
        }
342
343
        $eventListener->loadClassMetadata(new LoadClassMetadataEventArgs($classMetadata, $this->entityManager));
344
345
        $eventListener->postFlush(new PostFlushEventArgs($this->entityManager));
346
    }
347
348
    public function dataProviderForCanStoreAdditionalData(): array
349
    {
350
        return [
351
            ["slow-and-stable", true],
352
            ["fast-and-unstable", false],
353
        ];
354
    }
355
356
    /**
357
     * @test
358
     */
359
    public function completesAWholeLifetime()
360
    {
361
        ### PREPARE
362
363
        /** @var UnitOfWork $unitOfWork */
364
        $unitOfWork = $this->createMock(UnitOfWork::class);
365
366
        /** @var Connection $connection */
367
        $connection = $this->createMock(Connection::class);
368
369
        /** @var QueryBuilder $queryBuilder */
370
        $queryBuilder = $this->createMock(QueryBuilder::class);
371
372
        /** @var Expr $expr */
373
        $expr = $this->createMock(Expr::class);
374
375
        /** @var Statement $statement */
376
        $statement = $this->createMock(Statement::class);
377
378
        /** @var mixed $annotationMap */
379
        $annotationMap = array(
380
            'id' => [
381
                Id::class => new Id(),
382
                Column::class => $this->createColumn("id")
383
            ],
384
            'foo' => [
385
                Choice::class => $this->createChoice("foo_column", [
386
                    'a' => $this->createService("a_service"),
387
                    'b' => $this->createService("b_service"),
388
                ]),
389
            ],
390
            'bar' => [
391
                Choice::class => $this->createChoice("bar_column", [
392
                    'a' => $this->createService("a_service"),
393
                    'b' => $this->createService("b_service"),
394
                ]),
395
            ],
396
            'baz' => [],
397
            'boo' => [
398
                RDMObject::class => $this->createObject(ValueObjectExample::class, [
399
                    'lorem' => $this->createColumn('lorem')
400
                ])
401
            ],
402
            'arr' => [
403
                RDMArray::class => $this->createArray([
404
                    'dolor' => $this->createColumn('dolor')
405
                ]),
406
            ]
407
        );
408
409
        $this->configureMockedAnnotationReader($this->annotationReader, $annotationMap);
410
411
        /** @var EventListener $eventListener */
412
        $eventListener = $this->spawnEventListener();
413
414
        $metadataFactory = new ClassMetadataFactory();
415
        $metadataFactory->setEntityManager($this->entityManager);
416
417
        /** @var ClassMetadata $classMetadata */
418
        $classMetadata = $metadataFactory->getMetadataFor(EntityExample::class);
419
        $classMetadata->identifier = ['id'];
420
        $classMetadata->fieldMappings = ['id' => ['columnName' => 'id']];
421
        $classMetadata->table = ['name' => 'some_table'];
422
423
        $this->entityManager->method("getUnitOfWork")->willReturn($unitOfWork);
424
        $this->entityManager->method("getConnection")->willReturn($connection);
425
        $this->entityManager->method("getClassMetadata")->will($this->returnValueMap([
426
            [EntityExample::class, $classMetadata]
427
        ]));
428
429
        /** @var AbstractPlatform $platform */
430
        $platform = $this->createMock(AbstractPlatform::class);
431
432
        $connection->method('getDatabasePlatform')->willReturn($platform);
0 ignored issues
show
Bug introduced by
The method method() does not exist on Doctrine\DBAL\Connection. ( Ignorable by Annotation )

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

432
        $connection->/** @scrutinizer ignore-call */ 
433
                     method('getDatabasePlatform')->willReturn($platform);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
433
        $connection->method('createQueryBuilder')->willReturn($queryBuilder);
434
435
        $queryBuilder->method('expr')->willReturn($expr);
0 ignored issues
show
Bug introduced by
The method method() does not exist on Doctrine\DBAL\Query\QueryBuilder. ( Ignorable by Annotation )

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

435
        $queryBuilder->/** @scrutinizer ignore-call */ 
436
                       method('expr')->willReturn($expr);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
436
        $queryBuilder->method('execute')->willReturn($statement);
437
438
        $queryBuilder->method('from');
439
        $queryBuilder->method('andWhere');
440
        $queryBuilder->method('addSelect');
441
442
        $statement->method("fetch")->willReturn([
0 ignored issues
show
Bug introduced by
The method method() does not exist on Doctrine\DBAL\Statement. ( Ignorable by Annotation )

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

442
        $statement->/** @scrutinizer ignore-call */ 
443
                    method("fetch")->willReturn([

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
443
            'foo_column' => null,
444
            'bar_column' => 'a',
445
            'lorem' => 'ipsum',
446
            'dolor' => 'sit amet'
447
        ]);
448
449
        $classTable = new Table("some_table");
450
        $schema = new Schema([$classTable]);
451
452
        $serviceA = new ServiceExample("lorem", 123);
453
        $serviceB = new ServiceExample("ipsum", 456);
454
455
        $this->container->set('a_service', $serviceA);
456
        $this->container->set('b_service', $serviceB);
457
458
        ### EXECUTE
459
460
        $eventListener->loadClassMetadata(new LoadClassMetadataEventArgs(
461
            $classMetadata,
462
            $this->entityManager
463
        ));
464
465
        $eventListener->postGenerateSchemaTable(new GenerateSchemaTableEventArgs(
466
            $classMetadata,
467
            $schema,
468
            $classTable
469
        ));
470
471
        $this->assertTrue($classTable->hasColumn("foo_column"));
472
        $this->assertTrue($classTable->hasColumn("bar_column"));
473
        $this->assertTrue($classTable->hasColumn("lorem"));
474
        $this->assertTrue($classTable->hasColumn("dolor"));
475
476
        $entity = new EntityExample();
477
        $entity->id = 123;
478
        $entity->foo = null;
479
        $entity->bar = $serviceA;
480
481
        $eventListener->prePersist(new LifecycleEventArgs(
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\ORM\Event\LifecycleEventArgs has been deprecated: This class will be removed in ORM 3.0. Use one of the dedicated classes instead. ( Ignorable by Annotation )

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

481
        $eventListener->prePersist(/** @scrutinizer ignore-deprecated */ new LifecycleEventArgs(
Loading history...
482
            $entity,
483
            $this->entityManager
484
        ));
485
486
        $unitOfWork->method('getIdentityMap')->willReturn([
487
            EntityExample::class => [
488
                $entity
489
            ]
490
        ]);
491
492
        $eventListener->postFlush(new PostFlushEventArgs(
493
            $this->entityManager
494
        ));
495
496
        $loadedEntity = new EntityExample();
497
        $loadedEntity->id = 123;
498
        $loadedEntity->foo = null;
499
        $loadedEntity->bar = null;
500
501
        $eventListener->postLoad(new LifecycleEventArgs(
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\ORM\Event\LifecycleEventArgs has been deprecated: This class will be removed in ORM 3.0. Use one of the dedicated classes instead. ( Ignorable by Annotation )

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

501
        $eventListener->postLoad(/** @scrutinizer ignore-deprecated */ new LifecycleEventArgs(
Loading history...
502
            $loadedEntity,
503
            $this->entityManager
504
        ));
505
506
        $this->assertSame($serviceA, $loadedEntity->bar);
507
        $this->assertTrue($loadedEntity->getBoo() instanceof ValueObjectExample);
508
        $this->assertEquals("ipsum", $loadedEntity->getBoo()->lorem);
509
        $this->assertEquals("sit amet", $loadedEntity->arr['dolor']);
510
    }
511
512
    private function spawnEventListener(): EventListener
513
    {
514
        # The test-method may replace the doctrineMetadataDriver, so redefine the return-value of getMetadataDriverImpl
515
        $this->doctrineConfiguration->method('getMetadataDriverImpl')->willReturn($this->doctrineMetadataDriver);
0 ignored issues
show
Bug introduced by
The method method() does not exist on Doctrine\ORM\Configuration. ( Ignorable by Annotation )

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

515
        $this->doctrineConfiguration->/** @scrutinizer ignore-call */ 
516
                                      method('getMetadataDriverImpl')->willReturn($this->doctrineMetadataDriver);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
516
517
        $this->loader->load('services.xml');
518
519
        /** @var MappingDriverInterface $mappingDriver */
520
        $mappingDriver = $this->container->get("addiks_rdm.mapping.driver");
521
522
        $this->assertInstanceOf(MappingDriverInterface::class, $mappingDriver);
523
524
        /** @var EventListener $eventListener */
525
        $eventListener = $this->container->get("addiks_rdm.listener");
526
527
        $this->assertInstanceOf(EventListener::class, $eventListener);
528
529
        return $eventListener;
530
    }
531
532
    private function configureMockedAnnotationReader(AnnotationReader $annotationReader, array $annotationMap)
533
    {
534
        $annotationReader->method('getClassAnnotations')->will($this->returnCallback(
0 ignored issues
show
Bug introduced by
The method method() does not exist on Doctrine\Common\Annotations\Reader. It seems like you code against a sub-type of Doctrine\Common\Annotations\Reader such as Doctrine\Common\Annotations\IndexedReader. ( Ignorable by Annotation )

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

534
        $annotationReader->/** @scrutinizer ignore-call */ 
535
                           method('getClassAnnotations')->will($this->returnCallback(
Loading history...
535
            function (ReflectionClass $reflectionClass) {
536
                if ($reflectionClass->getName() === EntityExample::class) {
537
                    return [new Entity()];
538
                }
539
            }
540
        ));
541
542
        $annotationReader->method('getPropertyAnnotation')->will($this->returnCallback(
543
            function (ReflectionProperty $reflectionProperty, string $annotationName) use ($annotationMap) {
544
                /** @var ReflectionClass $reflectionClass */
545
                $reflectionClass = $reflectionProperty->getDeclaringClass();
546
547
                if ($reflectionClass->getName() === EntityExample::class) {
548
                    if (isset($annotationMap[$reflectionProperty->getName()])) {
549
                        $annotationMap = $annotationMap[$reflectionProperty->getName()];
550
                    }
551
552
                    if (isset($annotationMap[$annotationName])) {
553
                        return $annotationMap[$annotationName];
554
                    }
555
                }
556
            }
557
        ));
558
559
        $annotationReader->method('getPropertyAnnotations')->will($this->returnCallback(
560
            function (ReflectionProperty $reflectionProperty) use ($annotationMap) {
561
                /** @var ReflectionClass $reflectionClass */
562
                $reflectionClass = $reflectionProperty->getDeclaringClass();
563
564
                if ($reflectionClass->getName() === EntityExample::class) {
565
                    if (isset($annotationMap[$reflectionProperty->getName()])) {
566
                        return array_values($annotationMap[$reflectionProperty->getName()]);
567
568
                    } else {
569
                        return [];
570
                    }
571
                }
572
            }
573
        ));
574
575
        $annotationDriver = new AnnotationDriver($this->annotationReader);
576
577
        $this->doctrineMetadataDriver = new MappingDriverChain();
578
        $this->doctrineMetadataDriver->addDriver($annotationDriver, "Addiks\\RDMBundle\\Tests");
579
580
    }
581
582
    private function createColumn(string $columnName): Column
583
    {
584
        $column = new Column();
585
        $column->name = $columnName;
586
587
        return $column;
588
    }
589
590
    private function createService(string $id): Service
591
    {
592
        $service = new Service();
593
        $service->id = $id;
594
595
        return $service;
596
    }
597
598
    private function createObject(
599
        string $className,
600
        array $fields,
601
        Call $factory = null,
602
        Call $serialize = null
603
    ): RDMObject {
604
        $object = new RDMObject();
605
        $object->{"class"} = $className;
606
        $object->fields = $fields;
607
        $object->factory = $factory;
608
        $object->serialize = $serialize;
609
610
        return $object;
611
    }
612
613
    private function createChoice(string $columnName = null, array $choices = array()): Choice
614
    {
615
        $choice = new Choice();
616
        $choice->column = $columnName;
617
        $choice->choices = $choices;
618
619
        return $choice;
620
    }
621
622
    private function createArray(array $entries): RDMArray
623
    {
624
        $array = new RDMArray();
625
        $array->entries = $entries;
626
627
        return $array;
628
    }
629
630
}
631