GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( d68f0e...658fac )
by Ross
14s queued 12s
created

AbstractEntityRepositoryLargeTest   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 341
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 161
dl 0
loc 341
rs 9.1199
c 0
b 0
f 0
wmc 41

27 Methods

Rating   Name   Duplication   Size   Complexity  
A find() 0 5 1
A findAll() 0 5 1
A setup() 0 9 1
A getRepository() 0 4 1
A generateAndSaveTestEntities() 0 8 2
A itCanRunAllTheBasicMethods() 0 13 1
A sortCollectionById() 0 9 2
A getGetterForType() 0 9 2
A arrayContainsEntity() 0 9 3
A findOneBy() 0 18 2
A get() 0 5 1
A findBy() 0 8 2
A getClassName() 0 5 1
A matching() 0 13 2
A getWillThrowAnExceptionIfNothingIsFound() 0 4 1
A addAssocEntities() 0 7 2
A createNamedQuery() 0 7 1
A createQueryBuilder() 0 4 1
A testCount() 0 5 2
A clear() 0 7 1
A getRandomOneBy() 0 15 3
A itCanUseEntitiesInDql() 0 16 1
A collectionContainsEntity() 0 9 3
A getRandomBy() 0 7 1
A getOneBy() 0 17 1
A getOneByWillThrowAnExceptionIfNothingIsFound() 0 6 1
A createResultSetMappingBuilder() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like AbstractEntityRepositoryLargeTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AbstractEntityRepositoryLargeTest, and based on these observations, apply Extract Interface, too.

1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta\Tests\Large\C\Entity\Repositories;
4
5
use Doctrine\Common\Collections\Collection;
6
use Doctrine\Common\Collections\Criteria;
7
use Doctrine\Common\Collections\Expr\Comparison;
8
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\EntityInterface;
9
use EdmondsCommerce\DoctrineStaticMeta\Entity\Repositories\AbstractEntityRepository;
10
use EdmondsCommerce\DoctrineStaticMeta\Entity\Repositories\RepositoryFactory;
11
use EdmondsCommerce\DoctrineStaticMeta\Entity\Savers\EntitySaver;
12
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityDebugDumper;
13
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityGenerator\TestEntityGenerator;
14
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityGenerator\TestEntityGeneratorFactory;
15
use EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException;
16
use EdmondsCommerce\DoctrineStaticMeta\MappingHelper;
17
use EdmondsCommerce\DoctrineStaticMeta\Tests\Assets\AbstractLargeTest;
18
use EdmondsCommerce\DoctrineStaticMeta\Tests\Assets\AbstractTest;
19
use EdmondsCommerce\DoctrineStaticMeta\Tests\Assets\TestCodeGenerator;
20
21
/**
22
 * @see     https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/working-with-objects.html#querying
23
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
24
 * @SuppressWarnings(PHPMD.ExcessivePublicCount)
25
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
26
 * @large
27
 * @covers  \EdmondsCommerce\DoctrineStaticMeta\Entity\Repositories\AbstractEntityRepository
28
 */
29
class AbstractEntityRepositoryLargeTest extends AbstractLargeTest
30
{
31
    public const WORK_DIR = AbstractTest::VAR_PATH . '/'
32
                            . self::TEST_TYPE_LARGE . '/AbstractEntityRepositoryLargeTest';
33
34
    private const PERSON_ENTITY_FQN = self::TEST_ENTITIES_ROOT_NAMESPACE . TestCodeGenerator::TEST_ENTITY_PERSON;
35
36
    private const NUM_ENTITIES_QUICK = 2;
37
38
    private const NUM_ENTITIES_FULL = 10;
39
40
    protected static $buildOnce = true;
41
42
    private $generatedEntities = [];
43
    /**
44
     * @var AbstractEntityRepository
45
     */
46
    private $repository;
47
    /**
48
     * @var TestEntityGenerator $entityGenerator
49
     */
50
    private $entityGenerator;
51
52
    public function setup()
53
    {
54
        parent::setUp();
55
        $this->generateTestCode();
56
        $this->setupCopiedWorkDirAndCreateDatabase();
57
        $this->repository      = $this->getRepository();
58
        $this->entityGenerator = $this->container->get(TestEntityGeneratorFactory::class)
59
                                                 ->createForEntityFqn($this->getCopiedFqn(self::PERSON_ENTITY_FQN));
60
        $this->generateAndSaveTestEntities();
61
    }
62
63
    protected function getRepository(): AbstractEntityRepository
64
    {
65
        return $this->container->get(RepositoryFactory::class)
66
                               ->getRepository($this->getCopiedFqn(self::PERSON_ENTITY_FQN));
67
    }
68
69
    protected function generateAndSaveTestEntities(): void
70
    {
71
        $this->generatedEntities = $this->entityGenerator->generateEntities(
72
            $this->isQuickTests() ? self::NUM_ENTITIES_QUICK : self::NUM_ENTITIES_FULL
73
        );
74
75
        $saver = new EntitySaver($this->getEntityManager());
76
        $saver->saveAll($this->generatedEntities);
77
    }
78
79
    /**
80
     * @test
81
     */
82
    public function itCanRunAllTheBasicMethods(): void
83
    {
84
        $this->find();
85
        $this->get();
86
        $this->findAll();
87
        $this->findBy();
88
        $this->findOneBy();
89
        $this->matching();
90
        $this->createQueryBuilder();
91
        $this->createResultSetMappingBuilder();
92
        $this->get();
93
        $this->getOneBy();
94
        $this->getClassName();
95
    }
96
97
    private function find(): void
98
    {
99
        $expected = $this->generatedEntities[array_rand($this->generatedEntities)];
100
        $actual   = $this->repository->find($expected->getId());
101
        self::assertSame($expected, $actual);
102
    }
103
104
    private function get(): void
105
    {
106
        $expected = $this->generatedEntities[array_rand($this->generatedEntities)];
107
        $actual   = $this->repository->get($expected->getId());
108
        self::assertSame($expected, $actual);
109
    }
110
111
    private function findAll(): void
112
    {
113
        $expected = $this->sortCollectionById($this->generatedEntities);
114
        $actual   = $this->sortCollectionById($this->repository->findAll());
115
        self::assertEquals($expected, $actual);
116
    }
117
118
    private function sortCollectionById(array $collection): array
119
    {
120
        $return = [];
121
        foreach ($collection as $item) {
122
            $return[(string)$item->getId()] = $item;
123
        }
124
        ksort($return);
125
126
        return $return;
127
    }
128
129
    private function findBy(): void
130
    {
131
        foreach (MappingHelper::COMMON_TYPES as $property) {
132
            $entity   = current($this->generatedEntities);
133
            $getter   = $this->getGetterForType($property);
134
            $criteria = [$property => $entity->$getter()];
135
            $actual   = $this->repository->findBy($criteria);
136
            self::assertTrue($this->arrayContainsEntity($entity, $actual));
137
        }
138
    }
139
140
    protected function getGetterForType(string $type): string
141
    {
142
        $ucType = ucfirst($type);
143
        $getter = "get$ucType";
144
        if (MappingHelper::TYPE_BOOLEAN === $type) {
145
            $getter = "is$ucType";
146
        }
147
148
        return $getter;
149
    }
150
151
    protected function arrayContainsEntity(EntityInterface $expectedEntity, array $array): bool
152
    {
153
        foreach ($array as $entity) {
154
            if ($entity->getId() === $expectedEntity->getId()) {
155
                return true;
156
            }
157
        }
158
159
        return false;
160
    }
161
162
    private function findOneBy(): void
163
    {
164
        foreach (MappingHelper::COMMON_TYPES as $property) {
165
            $entity   = current($this->generatedEntities);
166
            $getter   = $this->getGetterForType($property);
167
            $value    = $entity->$getter();
168
            $criteria = [
169
                $property => $value,
170
                'id'      => $entity->getId(),
171
            ];
172
            $actual   = $this->repository->findOneBy($criteria);
173
            self::assertEquals(
174
                $entity,
175
                $actual,
176
                'Failed finding one expected entity (ID' . $entity->getId() . ') with $criteria: '
177
                . "\n" . var_export($criteria, true)
178
                . "\n and \$actual: "
179
                . "\n" . (new EntityDebugDumper())->dump($actual, $this->getEntityManager())
0 ignored issues
show
Bug introduced by
It seems like $actual can also be of type null; however, parameter $entity of EdmondsCommerce\Doctrine...tityDebugDumper::dump() does only seem to accept EdmondsCommerce\Doctrine...erfaces\EntityInterface, maybe add an additional type check? ( Ignorable by Annotation )

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

179
                . "\n" . (new EntityDebugDumper())->dump(/** @scrutinizer ignore-type */ $actual, $this->getEntityManager())
Loading history...
180
            );
181
        }
182
    }
183
184
    private function matching(): void
185
    {
186
        foreach (MappingHelper::COMMON_TYPES as $property) {
187
            $entity   = current($this->generatedEntities);
188
            $getter   = $this->getGetterForType($property);
189
            $value    = $entity->$getter();
190
            $criteria = new Criteria();
191
            $criteria->where(new Comparison($property, '=', $value));
192
//            $criteria->andWhere(new Comparison('id', '=', $entity->getId()));
193
            $actual = $this->repository->matching($criteria);
194
            self::assertTrue(
195
                $this->collectionContainsEntity($entity, $actual),
196
                "Failed finding entity by criteria $property = $value"
197
            );
198
        }
199
    }
200
201
    protected function collectionContainsEntity(EntityInterface $expectedEntity, Collection $collection): bool
202
    {
203
        foreach ($collection->getIterator() as $entity) {
204
            if ($entity->getId()->toString() === $expectedEntity->getId()->toString()) {
205
                return true;
206
            }
207
        }
208
209
        return false;
210
    }
211
212
    private function createQueryBuilder(): void
213
    {
214
        $this->repository->createQueryBuilder('foo');
215
        self::assertTrue(true);
216
    }
217
218
    private function createResultSetMappingBuilder(): void
219
    {
220
        $this->repository->createResultSetMappingBuilder('foo');
221
        self::assertTrue(true);
222
    }
223
224
    private function getOneBy(): void
225
    {
226
        $entity   = current($this->generatedEntities);
227
        $getter   = $this->getGetterForType(MappingHelper::TYPE_STRING);
228
        $value    = $entity->$getter();
229
        $criteria = [
230
            MappingHelper::TYPE_STRING => $value,
231
            'id'                       => $entity->getId(),
232
        ];
233
        $actual   = $this->repository->findOneBy($criteria);
234
        self::assertEquals(
235
            $entity,
236
            $actual,
237
            'Failed finding one expected entity (ID' . $entity->getId() . ') with $criteria: '
238
            . "\n" . var_export($criteria, true)
239
            . "\n and \$actual: "
240
            . "\n" . (new EntityDebugDumper())->dump($actual, $this->getEntityManager())
0 ignored issues
show
Bug introduced by
It seems like $actual can also be of type null; however, parameter $entity of EdmondsCommerce\Doctrine...tityDebugDumper::dump() does only seem to accept EdmondsCommerce\Doctrine...erfaces\EntityInterface, maybe add an additional type check? ( Ignorable by Annotation )

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

240
            . "\n" . (new EntityDebugDumper())->dump(/** @scrutinizer ignore-type */ $actual, $this->getEntityManager())
Loading history...
241
        );
242
    }
243
244
    /**
245
     * @test
246
     */
247
    public function itCanUseEntitiesInDql(): void
248
    {
249
        $this->addAssocEntities();
250
        $queryBuilder = $this->repository->createQueryBuilder('fetch');
251
        $queryBuilder->where('fetch.attributesAddress IS NOT NULL');
252
253
        $person      = $queryBuilder->getQuery()->execute()[0];
254
        $address     = $person->getAttributesAddress();
255
        $secondQuery = $this->repository->createQueryBuilder('second');
256
        $secondQuery->where('second.attributesAddress = :address');
257
        $secondQuery->setParameter('address', $address);
258
        $query        = $secondQuery->getQuery();
259
        $secondPerson = $query->execute();
260
        self::assertNotEmpty($secondPerson);
261
262
        self::assertSame($address->getId()->toString(), $secondPerson[0]->getAttributesAddress()->getId()->toString());
263
    }
264
265
    private function addAssocEntities(): void
266
    {
267
        foreach ($this->generatedEntities as $entity) {
268
            $this->entityGenerator->addAssociationEntities($entity);
269
        }
270
        $saver = new EntitySaver($this->getEntityManager());
271
        $saver->saveAll($this->generatedEntities);
272
    }
273
274
    /**
275
     * @test
276
     */
277
    public function getWillThrowAnExceptionIfNothingIsFound(): void
278
    {
279
        $this->expectException(DoctrineStaticMetaException::class);
280
        $this->repository->get(time());
281
    }
282
283
    /**
284
     * @test
285
     */
286
    public function getOneByWillThrowAnExceptionIfNothingIsFound(): void
287
    {
288
        $property = MappingHelper::TYPE_STRING;
289
        $criteria = [$property => 'not-a-real-vaule'];
290
        $this->expectException(\RuntimeException::class);
291
        $this->repository->getOneBy($criteria);
292
    }
293
294
    /**
295
     * @test
296
     */
297
    public function getClassName(): void
298
    {
299
        self::assertSame(
300
            ltrim($this->getCopiedFqn(self::PERSON_ENTITY_FQN), '\\'),
301
            $this->repository->getClassName()
302
        );
303
    }
304
305
    /**
306
     * @test
307
     */
308
    public function createNamedQuery(): void
309
    {
310
        $this->markTestIncomplete(
311
            'Need to add a named query for a test entity somehow in the meta data before we can test this'
312
        );
313
        $this->repository->createNamedQuery('foo');
314
        self::assertTrue(true);
315
    }
316
317
    /**
318
     * @test
319
     */
320
    public function clear(): void
321
    {
322
        $this->repository->clear();
323
        $map = $this->getEntityManager()->getUnitOfWork()->getIdentityMap();
324
        self::assertSame(
325
            [],
326
            $map[ltrim($this->getCopiedFqn(self::PERSON_ENTITY_FQN), '\\')]
327
        );
328
    }
329
330
    /**
331
     */
332
    public function testCount(): void
333
    {
334
        self::assertSame(
335
            $this->isQuickTests() ? self::NUM_ENTITIES_QUICK : self::NUM_ENTITIES_FULL,
336
            $this->repository->count([])
337
        );
338
    }
339
340
    /**
341
     * @test
342
     */
343
    public function getRandomBy(): void
344
    {
345
        $criteria = [];
346
        $result   = $this->repository->getRandomBy($criteria);
347
        self::assertCount(1, $result);
348
        $result = $this->repository->getRandomBy($criteria, 2);
349
        self::assertCount(2, $result);
350
    }
351
352
    /**
353
     * @test
354
     */
355
    public function getRandomOneBy(): void
356
    {
357
        $criteria = [];
358
        $tries    = 0;
359
        $maxTries = 3;
360
        while ($tries++ < $maxTries) {
361
            $rand1 = $this->repository->getRandomOneBy($criteria);
362
            $rand2 = $this->repository->getRandomOneBy($criteria);
363
            if ($rand1 !== $rand2) {
364
                self::assertTrue(true);
365
366
                return;
367
            }
368
        }
369
        $this->fail('Failed pulling out two random entities that were not the same');
370
    }
371
}
372