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 ( a48bd8...83d092 )
by joseph
16:18 queued 18s
created

AbstractTest::createEntity()

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
nc 1
nop 2
dl 0
loc 3
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta\Tests\Assets;
4
5
use Composer\Autoload\ClassLoader;
6
use Doctrine\Common\Cache\CacheProvider;
7
use Doctrine\ORM\EntityManagerInterface;
8
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Action\CreateDtosForAllEntitiesAction;
9
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\CodeHelper;
10
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Command\AbstractCommand;
11
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\AbstractGenerator;
12
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\Embeddable\ArchetypeEmbeddableGenerator;
13
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\Embeddable\EntityEmbeddableSetter;
14
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\EntityGenerator;
15
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\Field\EntityFieldSetter;
16
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\Field\FieldGenerator;
17
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\FindAndReplaceHelper;
18
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\RelationsGenerator;
19
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\NamespaceHelper;
20
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\PathHelper;
21
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\UnusedRelationsRemover;
22
use EdmondsCommerce\DoctrineStaticMeta\Config;
23
use EdmondsCommerce\DoctrineStaticMeta\ConfigInterface;
24
use EdmondsCommerce\DoctrineStaticMeta\Container;
25
use EdmondsCommerce\DoctrineStaticMeta\Entity\DataTransferObjects\DtoFactory;
26
use EdmondsCommerce\DoctrineStaticMeta\Entity\Factory\EntityFactory;
27
use EdmondsCommerce\DoctrineStaticMeta\Entity\Factory\EntityFactoryInterface;
28
use EdmondsCommerce\DoctrineStaticMeta\Entity\Fields\Factories\UuidFactory;
29
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\DataTransferObjectInterface;
30
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\EntityInterface;
31
use EdmondsCommerce\DoctrineStaticMeta\Entity\Repositories\RepositoryFactory;
32
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityDebugDumper;
33
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityGenerator\TestEntityGeneratorFactory;
34
use EdmondsCommerce\DoctrineStaticMeta\Schema\Schema;
35
use EdmondsCommerce\DoctrineStaticMeta\SimpleEnv;
36
use EdmondsCommerce\PHPQA\Constants;
37
use PHPUnit\Framework\TestCase;
38
use Symfony\Component\Filesystem\Filesystem;
39
40
/**
41
 * Class AbstractTest
42
 *
43
 * @package EdmondsCommerce\DoctrineStaticMeta
44
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
45
 * @SuppressWarnings(PHPMD.NumberOfChildren)
46
 * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
47
 */
48
abstract class AbstractTest extends TestCase
49
{
50
    public const TEST_TYPE_SMALL              = 'Small';
51
    public const TEST_TYPE_MEDIUM             = 'Medium';
52
    public const TEST_TYPE_LARGE              = 'Large';
53
    public const VAR_PATH                     = __DIR__ . '/../../var/testOutput/';
54
    public const WORK_DIR                     = 'override me';
55
    public const TEST_PROJECT_ROOT_NAMESPACE  = 'My\\Test\\Project';
56
    public const TEST_ENTITIES_ROOT_NAMESPACE = self::TEST_PROJECT_ROOT_NAMESPACE . '\\' .
57
                                                AbstractGenerator::ENTITIES_FOLDER_NAME;
58
    protected static $buildOnce = false;
59
    protected static $built     = false;
60
    /**
61
     * @var Container
62
     */
63
    protected static $containerStaticRef;
64
    /**
65
     * The absolute path to the Entities folder, eg:
66
     * /var/www/vhosts/doctrine-static-meta/var/{testWorkDir}/Entities
67
     *
68
     * @var string
69
     */
70
    protected $entitiesPath = '';
71
    /**
72
     * The absolute path to the EntityRelations folder, eg:
73
     * /var/www/vhosts/doctrine-static-meta/var/{testWorkDir}/Entity/Relations
74
     *
75
     * @var string
76
     */
77
    protected $entityRelationsPath = '';
78
    /**
79
     * @var Container
80
     */
81
    protected $container;
82
    /**
83
     * @var Filesystem
84
     */
85
    protected $filesystem;
86
    /**
87
     * @var string|null
88
     */
89
    protected $copiedWorkDir;
90
    /**
91
     * @var string|null
92
     */
93
    protected $copiedRootNamespace;
94
95
    /**
96
     * Ensure built steps are set to false when test class is instantiated
97
     */
98
    public static function setUpBeforeClass()
99
    {
100
        self::$built   = false;
101
        static::$built = false;
102
    }
103
104
    public static function tearDownAfterClass()
105
    {
106
        if (!(self::$containerStaticRef instanceof Container)) {
0 ignored issues
show
introduced by
self::containerStaticRef is always a sub-type of EdmondsCommerce\DoctrineStaticMeta\Container.
Loading history...
107
            return;
108
        }
109
        $entityManager = static::$containerStaticRef->get(EntityManagerInterface::class);
110
        $connection    = $entityManager->getConnection();
111
112
        $entityManager->close();
113
        $connection->close();
114
        static::$containerStaticRef = null;
115
    }
116
117
    /**
118
     * Prepare working directory, ensure its empty, create entities folder and set up env variables
119
     *
120
     * The order of these actions is critical
121
     */
122
    public function setUp()
123
    {
124
        if (false !== stripos(static::WORK_DIR, self::WORK_DIR)) {
125
            throw new \RuntimeException(
126
                "You must set a `public const WORK_DIR=AbstractTest::VAR_PATH.'/'"
127
                . ".self::TEST_TYPE.'/folderName/';` in your test class"
128
            );
129
        }
130
        if (false === strpos(static::WORK_DIR, '/' . static::TEST_TYPE_SMALL)
131
            && false === strpos(static::WORK_DIR, '/' . static::TEST_TYPE_MEDIUM)
132
            && false === strpos(static::WORK_DIR, '/' . static::TEST_TYPE_LARGE)
133
        ) {
134
            throw new \RuntimeException(
135
                'Your WORK_DIR is missing the test type, should look like: '
136
                . "`public const WORK_DIR=AbstractTest::VAR_PATH.'/'"
137
                . ".self::TEST_TYPE_(SMALL|MEDIUM|LARGE).'/folderName/';` in your test class"
138
            );
139
        }
140
        $this->copiedWorkDir       = null;
141
        $this->copiedRootNamespace = null;
142
        $this->entitiesPath        = static::WORK_DIR
143
                                     . '/' . AbstractCommand::DEFAULT_SRC_SUBFOLDER
144
                                     . '/' . AbstractGenerator::ENTITIES_FOLDER_NAME;
145
        $this->entityRelationsPath = static::WORK_DIR
146
                                     . '/' . AbstractCommand::DEFAULT_SRC_SUBFOLDER
147
                                     . '/' . AbstractGenerator::ENTITY_RELATIONS_FOLDER_NAME;
148
        $this->clearWorkDir();
149
        $this->setupContainer($this->entitiesPath);
150
        $this->clearCache();
151
        $this->extendAutoloader(
152
            static::TEST_PROJECT_ROOT_NAMESPACE . '\\',
153
            static::WORK_DIR
154
        );
155
    }
156
157
    protected function clearWorkDir(): void
158
    {
159
        if (true === static::$buildOnce && true === static::$built) {
160
            $this->entitiesPath = $this->getRealPath($this->entitiesPath);
161
162
            return;
163
        }
164
        $this->getFileSystem()->mkdir(static::WORK_DIR);
165
        $this->emptyDirectory(static::WORK_DIR);
166
        $this->getFileSystem()->mkdir($this->entitiesPath);
167
        $this->entitiesPath = $this->getRealPath($this->entitiesPath);
168
169
        $this->getFileSystem()->mkdir($this->entityRelationsPath);
170
        $this->entityRelationsPath = realpath($this->entityRelationsPath);
171
    }
172
173
    protected function getRealPath(string $path)
174
    {
175
        $realpath = realpath($path);
176
        if (false === $realpath) {
177
            throw new \RuntimeException('Failed getting realpath for path: ' . $path);
178
        }
179
180
        return $realpath;
181
    }
182
183
    protected function getFileSystem(): Filesystem
184
    {
185
        if (null === $this->filesystem) {
186
            $this->filesystem = new Filesystem();
187
        }
188
189
        return $this->filesystem;
190
    }
191
192
    protected function emptyDirectory(string $path): void
193
    {
194
        $fileSystem = $this->getFileSystem();
195
        $fileSystem->remove($path);
196
        $fileSystem->mkdir($path);
197
    }
198
199
    /**
200
     * @param string $entitiesPath
201
     *
202
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\ConfigException
203
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
204
     * @SuppressWarnings(PHPMD.Superglobals)
205
     * @SuppressWarnings(PHPMD.StaticAccess)
206
     */
207
    protected function setupContainer(string $entitiesPath): void
208
    {
209
        SimpleEnv::setEnv(Config::getProjectRootDirectory() . '/.env');
210
        $testConfig                                               = $_SERVER;
211
        $testConfig[ConfigInterface::PARAM_ENTITIES_PATH]         = $entitiesPath;
212
        $testConfig[ConfigInterface::PARAM_DB_NAME]               .= '_test';
213
        $testConfig[ConfigInterface::PARAM_DEVMODE]               = true;
214
        $testConfig[ConfigInterface::PARAM_FILESYSTEM_CACHE_PATH] = static::WORK_DIR . '/cache/dsm';
215
        $this->container                                          = new Container();
216
        $this->container->buildSymfonyContainer($testConfig);
217
        static::$containerStaticRef = $this->container;
218
    }
219
220
    /**
221
     * Clear the Doctrine Cache
222
     *
223
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
224
     */
225
    protected function clearCache(): void
226
    {
227
        $cache = $this->getEntityManager()
228
                      ->getConfiguration()
229
                      ->getMetadataCacheImpl();
230
        if ($cache instanceof CacheProvider) {
231
            $cache->deleteAll();
232
        }
233
    }
234
235
    /**
236
     * @return EntityManagerInterface
237
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
238
     */
239
    protected function getEntityManager(): EntityManagerInterface
240
    {
241
        return $this->container->get(EntityManagerInterface::class);
242
    }
243
244
    /**
245
     * Accesses the standard Composer autoloader
246
     *
247
     * Extends the class and also providing an entry point for xdebugging
248
     *
249
     * Extends this with a PSR4 root for our WORK_DIR
250
     *
251
     * @param string $namespace
252
     * @param string $path
253
     *
254
     * @throws \ReflectionException
255
     */
256
    protected function extendAutoloader(string $namespace, string $path): void
257
    {
258
        //Unregister any previously set extension first
259
        $registered = \spl_autoload_functions();
260
        foreach ($registered as $loader) {
261
            if ($loader instanceof \Closure) {
262
                continue;
263
            }
264
            if ((new  \ts\Reflection\ReflectionClass(\get_class($loader[0])))->isAnonymous()) {
265
                \spl_autoload_unregister($loader);
266
            }
267
        }
268
        //Then build a new extension and register it
269
        $namespace  = rtrim($namespace, '\\') . '\\';
270
        $testLoader = new class($namespace) extends ClassLoader
271
        {
272
            /**
273
             * @var string
274
             */
275
            protected $namespace;
276
277
            public function __construct(string $namespace)
278
            {
279
                $this->namespace = $namespace;
280
            }
281
282
            public function loadClass($class)
283
            {
284
                if (false === strpos($class, $this->namespace)) {
285
                    return false;
286
                }
287
                $found = parent::loadClass($class);
288
                if (false === $found || null === $found) {
0 ignored issues
show
introduced by
The condition null === $found is always false.
Loading history...
289
                    //good point to set a breakpoint
290
                    return $found;
291
                }
292
293
                return $found;
294
            }
295
        };
296
        $testLoader->addPsr4($namespace, $path . '/src', true);
297
        $testLoader->addPsr4($namespace, $path . '/tests', true);
298
        $testLoader->register();
299
    }
300
301
    /**
302
     * Run QA tools against the generated code
303
     *
304
     * Can specify a custom namespace root if required
305
     *
306
     * Will run:
307
     *
308
     * - PHP linting
309
     * - PHPStan
310
     *
311
     * @SuppressWarnings(PHPMD.Superglobals)
312
     * @param null|string $namespaceRoot
313
     *
314
     * @return bool
315
     */
316
    public function qaGeneratedCode(?string $namespaceRoot = null): bool
317
    {
318
        if ($this->isQuickTests()) {
319
            self::assertTrue(true);
320
321
            return true;
322
        }
323
        $workDir       = static::WORK_DIR;
324
        $namespaceRoot = trim($namespaceRoot ?? static::TEST_PROJECT_ROOT_NAMESPACE, '\\');
325
        if (null !== $this->copiedRootNamespace) {
326
            $workDir       = $this->copiedWorkDir;
327
            $namespaceRoot = trim($this->copiedRootNamespace, '\\');
328
        }
329
        static $codeValidator;
330
        if (null === $codeValidator) {
331
            $codeValidator = new CodeValidator();
332
        }
333
        $errors = $codeValidator($workDir, $namespaceRoot);
334
        self::assertNull($errors);
335
336
        return true;
337
    }
338
339
    /**
340
     * @return bool
341
     * @SuppressWarnings(PHPMD.Superglobals)
342
     */
343
    protected function isQuickTests(): bool
344
    {
345
        if (isset($_SERVER[Constants::QA_QUICK_TESTS_KEY])
346
            && (int)$_SERVER[Constants::QA_QUICK_TESTS_KEY] === Constants::QA_QUICK_TESTS_ENABLED
347
        ) {
348
            return true;
349
        }
350
351
        return false;
352
    }
353
354
    protected function getUuidFactory(): UuidFactory
355
    {
356
        return $this->container->get(UuidFactory::class);
357
    }
358
359
    protected function generateTestCode(): void
360
    {
361
        if (false === static::$built) {
362
            $this->getTestCodeGenerator()
363
                 ->copyTo(static::WORK_DIR);
364
            static::$built = true;
365
        }
366
    }
367
368
    protected function getTestCodeGenerator(): TestCodeGenerator
369
    {
370
        return $this->container->get(TestCodeGenerator::class);
371
    }
372
373
    protected function recreateDtos(): void
374
    {
375
        /**
376
         * @var CreateDtosForAllEntitiesAction $dtoAction
377
         */
378
        $dtoAction = $this->container->get(CreateDtosForAllEntitiesAction::class);
379
        $dtoAction->setProjectRootNamespace($this->copiedRootNamespace)
0 ignored issues
show
Bug introduced by
It seems like $this->copiedRootNamespace can also be of type null; however, parameter $projectRootNamespace of EdmondsCommerce\Doctrine...tProjectRootNamespace() does only seem to accept string, 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

379
        $dtoAction->setProjectRootNamespace(/** @scrutinizer ignore-type */ $this->copiedRootNamespace)
Loading history...
380
                  ->setProjectRootDirectory($this->copiedWorkDir)
0 ignored issues
show
Bug introduced by
It seems like $this->copiedWorkDir can also be of type null; however, parameter $projectRootDirectory of EdmondsCommerce\Doctrine...tProjectRootDirectory() does only seem to accept string, 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

380
                  ->setProjectRootDirectory(/** @scrutinizer ignore-type */ $this->copiedWorkDir)
Loading history...
381
                  ->run();
382
    }
383
384
    protected function tearDown()
385
    {
386
        $entityManager = $this->getEntityManager();
387
        $connection    = $entityManager->getConnection();
388
389
        $entityManager->close();
390
        $connection->close();
391
    }
392
393
    protected function getRepositoryFactory(): RepositoryFactory
394
    {
395
        return $this->container->get(RepositoryFactory::class);
396
    }
397
398
    protected function getNamespaceHelper(): NamespaceHelper
399
    {
400
        return $this->container->get(NamespaceHelper::class);
401
    }
402
403
    protected function dump(EntityInterface $entity): string
404
    {
405
        return (new EntityDebugDumper())->dump($entity, $this->getEntityManager());
406
    }
407
408
    /**
409
     * If PHP loads any files whilst generating, then subsequent changes to those files will not have any effect
410
     *
411
     * To resolve this, we need to clone the copied code into a new namespace before running it
412
     *
413
     * We only allow copying to a new work dir once per test run, different extras must be used
414
     *
415
     * @return string $copiedWorkDir
416
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
417
     * @throws \ReflectionException
418
     */
419
    protected function setupCopiedWorkDir(): string
420
    {
421
        $copiedNamespaceRoot       = $this->getCopiedNamespaceRoot();
422
        $this->copiedWorkDir       = rtrim(static::WORK_DIR, '/') . 'Copies/' . $copiedNamespaceRoot . '/';
423
        $this->entitiesPath        = $this->copiedWorkDir . '/src/Entities/';
424
        $this->copiedRootNamespace = $copiedNamespaceRoot;
425
        if (is_dir($this->copiedWorkDir)) {
426
            throw new \RuntimeException(
427
                'The Copied WorkDir ' . $this->copiedWorkDir . ' Already Exists'
428
            );
429
        }
430
        if (is_dir($this->copiedWorkDir)) {
431
            $this->getFileSystem()->remove($this->copiedWorkDir);
432
        }
433
        $codeCopier = new CodeCopier(
434
            $this->getFileSystem(),
435
            $this->container->get(FindAndReplaceHelper::class)
436
        );
437
        $codeCopier->copy(
438
            static::WORK_DIR,
439
            $this->copiedWorkDir,
440
            self::TEST_PROJECT_ROOT_NAMESPACE,
441
            $copiedNamespaceRoot
442
        );
443
        $this->extendAutoloader(
444
            $this->copiedRootNamespace . '\\',
445
            $this->copiedWorkDir
446
        );
447
        $this->clearCache();
448
449
        return $this->copiedWorkDir;
450
    }
451
452
    /**
453
     * Get the namespace root to use in a copied work dir
454
     *
455
     * @return string
456
     * @throws \ReflectionException
457
     */
458
    protected function getCopiedNamespaceRoot(): string
459
    {
460
        $name          = ucwords($this->getName());
461
        $namespaceName = preg_replace('%[^a-z]+%i', '_', $name);
462
463
        return (new  \ts\Reflection\ReflectionClass(static::class))->getShortName() . '_' . $namespaceName . '_';
464
    }
465
466
    /**
467
     * When working with a copied work dir, use this function to translate the FQN of any Entities etc
468
     *
469
     * This will replace both the raw TestCodeGenerator root namespace and the test level root namespace
470
     *
471
     * @param string $fqn
472
     *
473
     * @return string
474
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
475
     * @throws \ReflectionException
476
     */
477
    protected function getCopiedFqn(string $fqn): string
478
    {
479
        $copiedNamespaceRoot = $this->getCopiedNamespaceRoot();
480
481
        $currentRootRemoved = \str_replace(
482
            static::TEST_PROJECT_ROOT_NAMESPACE,
483
            '',
484
            $fqn
485
        );
486
        $currentRootRemoved = ltrim(
487
            $currentRootRemoved,
488
            '\\'
489
        );
490
491
        return $this->container
492
            ->get(NamespaceHelper::class)
493
            ->tidy('\\' . $copiedNamespaceRoot . '\\' . $currentRootRemoved);
494
    }
495
496
    /**
497
     * @return bool
498
     * @SuppressWarnings(PHPMD.Superglobals)
499
     */
500
    protected function isTravis(): bool
501
    {
502
        return isset($_SERVER['TRAVIS']);
503
    }
504
505
    protected function getEntityEmbeddableSetter(): EntityEmbeddableSetter
506
    {
507
        $setter = $this->container->get(EntityEmbeddableSetter::class);
508
        $setter->setPathToProjectRoot($this->copiedWorkDir ?? static::WORK_DIR);
509
        $setter->setProjectRootNamespace($this->copiedRootNamespace ?? self::TEST_PROJECT_ROOT_NAMESPACE);
510
511
        return $setter;
512
    }
513
514
    /**
515
     * @return ArchetypeEmbeddableGenerator
516
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
517
     */
518
    protected function getArchetypeEmbeddableGenerator(): ArchetypeEmbeddableGenerator
519
    {
520
        /**
521
         * @var ArchetypeEmbeddableGenerator $generator
522
         */
523
        $generator = $this->container->get(ArchetypeEmbeddableGenerator::class);
524
        $generator->setProjectRootNamespace(static::TEST_PROJECT_ROOT_NAMESPACE)
525
                  ->setPathToProjectRoot(static::WORK_DIR);
526
527
        return $generator;
528
    }
529
530
    protected function assertNoMissedReplacements(string $createdFile, array $checkFor = []): void
531
    {
532
        $createdFile = $this->getPathHelper()->resolvePath($createdFile);
533
        self::assertFileExists($createdFile);
534
        $contents   = file_get_contents($createdFile);
535
        $checkFor[] = 'template';
536
        foreach ($checkFor as $check) {
537
            self::assertNotRegExp(
538
                '%[^a-z]' . $check . '[^a-z]%i',
539
                $contents,
540
                'Found the word "' . $check . '" (case insensitive) in the created file ' . $createdFile
541
            );
542
        }
543
    }
544
545
    protected function getPathHelper(): PathHelper
546
    {
547
        return $this->container->get(PathHelper::class);
548
    }
549
550
    protected function getTestEntityGeneratorFactory(): TestEntityGeneratorFactory
551
    {
552
        return $this->container->get(TestEntityGeneratorFactory::class);
553
    }
554
555
    protected function assertFileContains(string $createdFile, string $needle): void
556
    {
557
        $createdFile = $this->getPathHelper()->resolvePath($createdFile);
558
        self::assertFileExists($createdFile);
559
        $contents = file_get_contents($createdFile);
560
        self::assertContains(
561
            $needle,
562
            $contents,
563
            "Missing '$needle' in file '$createdFile'"
564
        );
565
    }
566
567
    protected function getEntityGenerator(): EntityGenerator
568
    {
569
        /**
570
         * @var EntityGenerator $entityGenerator
571
         */
572
        $entityGenerator = $this->container->get(EntityGenerator::class);
573
        $entityGenerator->setPathToProjectRoot($this->copiedWorkDir ?? static::WORK_DIR)
574
                        ->setProjectRootNamespace($this->copiedRootNamespace ?? static::TEST_PROJECT_ROOT_NAMESPACE);
575
576
        return $entityGenerator;
577
    }
578
579
    protected function getRelationsGenerator(): RelationsGenerator
580
    {
581
        /**
582
         * @var RelationsGenerator $relationsGenerator
583
         */
584
        $relationsGenerator = $this->container->get(RelationsGenerator::class);
585
        $relationsGenerator->setPathToProjectRoot($this->copiedWorkDir ?? static::WORK_DIR)
586
                           ->setProjectRootNamespace($this->copiedRootNamespace ?? static::TEST_PROJECT_ROOT_NAMESPACE);
587
588
        return $relationsGenerator;
589
    }
590
591
    protected function getFieldGenerator(): FieldGenerator
592
    {
593
        /**
594
         * @var \EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\Field\FieldGenerator $fieldGenerator
595
         */
596
        $fieldGenerator = $this->container->get(FieldGenerator::class);
597
        $fieldGenerator->setPathToProjectRoot($this->copiedWorkDir ?? static::WORK_DIR)
598
                       ->setProjectRootNamespace($this->copiedRootNamespace ?? static::TEST_PROJECT_ROOT_NAMESPACE);
599
600
        return $fieldGenerator;
601
    }
602
603
    protected function getFieldSetter(): EntityFieldSetter
604
    {
605
        $fieldSetter = $this->container->get(EntityFieldSetter::class);
606
        $fieldSetter->setPathToProjectRoot($this->copiedWorkDir ?? static::WORK_DIR)
607
                    ->setProjectRootNamespace($this->copiedRootNamespace ?? static::TEST_PROJECT_ROOT_NAMESPACE);
608
609
        return $fieldSetter;
610
    }
611
612
    protected function getSchema(): Schema
613
    {
614
        return $this->container->get(Schema::class);
615
    }
616
617
    protected function getCodeHelper(): CodeHelper
618
    {
619
        return $this->container->get(CodeHelper::class);
620
    }
621
622
    protected function getUnusedRelationsRemover(): UnusedRelationsRemover
623
    {
624
        return $this->container->get(UnusedRelationsRemover::class);
625
    }
626
627
    protected function createEntity(string $entityFqn, DataTransferObjectInterface $dto = null): EntityInterface
628
    {
629
        return $this->getEntityFactory()->create($entityFqn, $dto);
630
    }
631
632
    protected function getEntityFactory(): EntityFactoryInterface
633
    {
634
        $factory = $this->container->get(EntityFactory::class);
635
        $factory->setEntityManager($this->getEntityManager());
636
637
        return $factory;
638
    }
639
640
    protected function getEntityDtoFactory(): DtoFactory
641
    {
642
        return $this->container->get(DtoFactory::class);
643
    }
644
}
645