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
Pull Request — master (#224)
by joseph
23:03
created

TestCodeGenerator::updateLargePropertiesEntity()

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
nc 2
nop 0
dl 0
loc 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace EdmondsCommerce\DoctrineStaticMeta\Tests\Assets;
6
7
use Composer\Autoload\ClassLoader;
8
use EdmondsCommerce\DoctrineStaticMeta\Builder\Builder;
9
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Creation\Src\Entity\Fields\Traits\FieldTraitCreator;
10
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\AbstractGenerator;
11
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\FindAndReplaceHelper;
12
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\RelationsGenerator;
13
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\NamespaceHelper;
14
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\PostProcessor\FileOverrider;
15
use EdmondsCommerce\DoctrineStaticMeta\Entity\Embeddable\Traits\Attribute\HasWeightEmbeddableTrait;
16
use EdmondsCommerce\DoctrineStaticMeta\Entity\Embeddable\Traits\Financial\HasMoneyEmbeddableTrait;
17
use EdmondsCommerce\DoctrineStaticMeta\Entity\Embeddable\Traits\Geo\HasAddressEmbeddableTrait;
18
use EdmondsCommerce\DoctrineStaticMeta\Entity\Embeddable\Traits\Identity\HasFullNameEmbeddableTrait;
19
use EdmondsCommerce\DoctrineStaticMeta\Entity\Fields\Traits\String\EmailAddressFieldTrait;
20
use EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException;
21
use EdmondsCommerce\DoctrineStaticMeta\MappingHelper;
22
use ReflectionException;
23
use RuntimeException;
24
use Symfony\Component\Filesystem\Filesystem;
25
26
use function spl_autoload_functions;
27
use function spl_autoload_unregister;
28
29
/**
30
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
31
 */
32
class TestCodeGenerator
33
{
34
35
    public const   TEST_PROJECT_ROOT_NAMESPACE = 'Test\\Code\\Generator';
36
    public const   TEST_ENTITY_NAMESPACE_BASE  = '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME;
37
    private const  TEST_FIELD_NAMESPACE_BASE   = '\\Entity\\Fields';
38
    private const  TEST_FIELD_FQN_BASE         = self::TEST_FIELD_NAMESPACE_BASE . '\\Traits';
39
40
    public const TEST_ENTITY_PERSON                      = '\\Person';
41
    public const TEST_ENTITY_ATTRIBUTES_ADDRESS          = '\\Attributes\\Address';
42
    public const TEST_ENTITY_EMAIL                       = '\\Attributes\\Email';
43
    public const TEST_ENTITY_COMPANY                     = '\\Company';
44
    public const TEST_ENTITY_DIRECTOR                    = '\\Company\\Director';
45
    public const TEST_ENTITY_ORDER                       = '\\Order';
46
    public const TEST_ENTITY_ORDER_ADDRESS               = '\\Order\\Address';
47
    public const TEST_ENTITY_NAME_SPACING_SOME_CLIENT    = '\\Some\\Client';
48
    public const TEST_ENTITY_NAME_SPACING_ANOTHER_CLIENT = '\\Another\\Deeply\\Nested\\Client';
49
    public const TEST_ENTITY_LARGE_DATA                  = '\\Large\\Data';
50
    public const TEST_ENTITY_LARGE_PROPERTIES            = '\\Large\\Property';
51
    public const TEST_ENTITY_LARGE_RELATIONS             = '\\Large\\Relation';
52
    public const TEST_ENTITY_ALL_ARCHETYPE_FIELDS        = '\\All\\StandardLibraryFields\\TestEntity';
53
    public const TEST_ENTITY_ALL_EMBEDDABLES             = '\\AllEmbeddable';
54
    public const TEST_ENTITY_SIMPLE                      = '\\Simple';
55
    public const TEST_ENTITY_CUSTOM_RELATION             = '\\CustomRelation';
56
57
    public const TEST_ENTITIES = [
58
        self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_PERSON,
59
        self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ATTRIBUTES_ADDRESS,
60
        self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_EMAIL,
61
        self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_COMPANY,
62
        self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_DIRECTOR,
63
        self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ORDER,
64
        self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ORDER_ADDRESS,
65
        self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_NAME_SPACING_SOME_CLIENT,
66
        self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_NAME_SPACING_ANOTHER_CLIENT,
67
        self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_DATA,
68
        self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_PROPERTIES,
69
        self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS,
70
        self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ALL_ARCHETYPE_FIELDS,
71
        self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ALL_EMBEDDABLES,
72
        self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_SIMPLE,
73
        self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_CUSTOM_RELATION
74
    ];
75
76
77
    private const TEST_RELATIONS = [
78
        [
79
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_PERSON,
80
            RelationsGenerator::HAS_UNIDIRECTIONAL_MANY_TO_ONE,
81
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ATTRIBUTES_ADDRESS,
82
            false,
83
        ],
84
        [
85
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_PERSON,
86
            RelationsGenerator::HAS_ONE_TO_MANY,
87
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_EMAIL,
88
            false,
89
        ],
90
        [
91
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_COMPANY,
92
            RelationsGenerator::HAS_REQUIRED_MANY_TO_MANY,
93
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_DIRECTOR,
94
            true,
95
        ],
96
        [
97
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_COMPANY,
98
            RelationsGenerator::HAS_REQUIRED_ONE_TO_MANY,
99
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ATTRIBUTES_ADDRESS,
100
            false,
101
        ],
102
        [
103
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_COMPANY,
104
            RelationsGenerator::HAS_REQUIRED_UNIDIRECTIONAL_ONE_TO_MANY,
105
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_EMAIL,
106
            false,
107
        ],
108
        [
109
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_DIRECTOR,
110
            RelationsGenerator::HAS_REQUIRED_ONE_TO_ONE,
111
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_PERSON,
112
            false,
113
        ],
114
        [
115
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ORDER,
116
            RelationsGenerator::HAS_REQUIRED_UNIDIRECTIONAL_MANY_TO_ONE,
117
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_PERSON,
118
            false,
119
        ],
120
        [
121
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ORDER,
122
            RelationsGenerator::HAS_REQUIRED_ONE_TO_MANY,
123
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ORDER_ADDRESS,
124
            true,
125
        ],
126
        [
127
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ORDER_ADDRESS,
128
            RelationsGenerator::HAS_REQUIRED_UNIDIRECTIONAL_ONE_TO_ONE,
129
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ATTRIBUTES_ADDRESS,
130
            false,
131
        ],
132
        [
133
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_COMPANY,
134
            RelationsGenerator::HAS_ONE_TO_ONE,
135
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_NAME_SPACING_SOME_CLIENT,
136
            false,
137
        ],
138
        [
139
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_COMPANY,
140
            RelationsGenerator::HAS_ONE_TO_ONE,
141
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_NAME_SPACING_ANOTHER_CLIENT,
142
            false,
143
        ],
144
        [
145
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS,
146
            RelationsGenerator::HAS_UNIDIRECTIONAL_MANY_TO_ONE,
147
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ATTRIBUTES_ADDRESS,
148
            false,
149
        ],
150
        [
151
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS,
152
            RelationsGenerator::HAS_REQUIRED_ONE_TO_MANY,
153
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_EMAIL,
154
            false,
155
        ],
156
        [
157
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS,
158
            RelationsGenerator::HAS_MANY_TO_MANY,
159
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_DIRECTOR,
160
            false,
161
        ],
162
        [
163
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS,
164
            RelationsGenerator::HAS_REQUIRED_UNIDIRECTIONAL_ONE_TO_MANY,
165
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_DATA,
166
            false,
167
        ],
168
        [
169
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS,
170
            RelationsGenerator::HAS_ONE_TO_ONE,
171
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_PERSON,
172
            false,
173
        ],
174
        [
175
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS,
176
            RelationsGenerator::HAS_REQUIRED_MANY_TO_ONE,
177
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_PROPERTIES,
178
            true,
179
        ],
180
        [
181
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS,
182
            RelationsGenerator::HAS_ONE_TO_MANY,
183
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_ORDER_ADDRESS,
184
            false,
185
        ],
186
        [
187
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_LARGE_RELATIONS,
188
            RelationsGenerator::HAS_REQUIRED_UNIDIRECTIONAL_ONE_TO_ONE,
189
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_COMPANY,
190
            false,
191
        ],
192
        [
193
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_CUSTOM_RELATION,
194
            RelationsGenerator::HAS_REQUIRED_UNIDIRECTIONAL_ONE_TO_ONE,
195
            self::TEST_ENTITY_NAMESPACE_BASE . self::TEST_ENTITY_COMPANY,
196
            false,
197
        ]
198
    ];
199
200
    private const LARGE_DATA_FIELDS = [
201
        self::TEST_FIELD_FQN_BASE . '\\Large\\Data\\LargeDataOne',
202
        self::TEST_FIELD_FQN_BASE . '\\Large\\Data\\LargeDataTwo',
203
        self::TEST_FIELD_FQN_BASE . '\\Large\\Data\\LargeDataThree',
204
        self::TEST_FIELD_FQN_BASE . '\\Large\\Data\\LargeDataFour',
205
    ];
206
207
    private const LARGE_PROPERTIES_FIELDS = [
208
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData001',
209
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData002',
210
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData003',
211
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData004',
212
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData005',
213
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData006',
214
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData007',
215
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData008',
216
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData009',
217
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData010',
218
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData011',
219
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData012',
220
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData013',
221
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData014',
222
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData015',
223
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData016',
224
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData017',
225
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData018',
226
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData019',
227
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData020',
228
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData021',
229
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData022',
230
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData023',
231
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData024',
232
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData025',
233
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData026',
234
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData027',
235
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData028',
236
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData029',
237
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData030',
238
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData031',
239
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData032',
240
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData033',
241
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData034',
242
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData035',
243
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData036',
244
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData037',
245
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData038',
246
        self::TEST_FIELD_FQN_BASE . '\\Large\\Properties\\LargeData039',
247
    ];
248
249
    private const  BUILD_DIR                      = AbstractTest::VAR_PATH . '/../testCode';
250
    private const  BUILD_DIR_TMP_B1               = AbstractTest::VAR_PATH . '/../testCodeTmp1';
251
    private const  BUILD_DIR_TMP_B2               = AbstractTest::VAR_PATH . '/../testCodeTmp2';
252
    private const  TEST_PROJECT_ROOT_NAMESPACE_B1 = self::TEST_PROJECT_ROOT_NAMESPACE . '\\Tmp1';
253
    private const  TEST_ENTITY_NAMESPACE_BASE_B1  = self::TEST_PROJECT_ROOT_NAMESPACE_B1 .
254
                                                    self::TEST_ENTITY_NAMESPACE_BASE;
255
    private const  TEST_PROJECT_ROOT_NAMESPACE_B2 = self::TEST_PROJECT_ROOT_NAMESPACE . '\\Tmp2';
256
    private const  BUILD_HASH_FILE                = self::BUILD_DIR . '/.buildHash';
257
258
    /**
259
     * @var Builder
260
     */
261
    protected $builder;
262
    /**
263
     * @var Filesystem
264
     */
265
    protected $filesystem;
266
    /**
267
     * @var FindAndReplaceHelper
268
     */
269
    protected $findAndReplaceHelper;
270
    /**
271
     * @var CodeCopier
272
     */
273
    private $codeCopier;
274
    /**
275
     * @var NamespaceHelper
276
     */
277
    private $namespaceHelper;
278
279
    public function __construct(
280
        Builder $builder,
281
        Filesystem $filesystem,
282
        FindAndReplaceHelper $findAndReplaceHelper,
283
        NamespaceHelper $namespaceHelper
284
    ) {
285
        $this->builder         = $builder;
286
        $this->filesystem      = $filesystem;
287
        $this->codeCopier      = new CodeCopier($this->filesystem, $findAndReplaceHelper);
288
        $this->namespaceHelper = $namespaceHelper;
289
        $this->initBuildDir();
290
        $this->buildOnce();
291
    }
292
293
    private function initBuildDir(): void
294
    {
295
296
        if (!is_dir(self::BUILD_DIR)) {
297
            $this->filesystem->mkdir(self::BUILD_DIR);
298
        }
299
    }
300
301
    private function applyOverrides(): void
302
    {
303
        $overrider = new FileOverrider(
304
            self::BUILD_DIR,
305
            '../../tests/Assets/overrides'
306
        );
307
        $invalidOverrides = $overrider->getInvalidOverrides();
308
        if ($invalidOverrides !== []) {
309
            throw new RuntimeException('Invaild Overrides: ' . \ts\print_r($invalidOverrides, true));
310
        }
311
        $overrider->applyOverrides();
312
    }
313
314
    private function buildOnce(): void
315
    {
316
        if ($this->isBuilt()) {
317
            return;
318
        }
319
        $this->firstBuild();
320
        $this->secondBuild();
321
        $this->applyOverrides();
322
        $this->filesystem->remove(self::BUILD_DIR_TMP_B1);
323
        $this->filesystem->remove(self::BUILD_DIR_TMP_B2);
324
        $this->setBuildHash();
325
    }
326
327
    /**
328
     * Check that a file exists in the build directory which contains the md5 hash of this class.
329
     *
330
     * This means that if we update this class, the hash changes and the built files are invalid and will be nuked
331
     *
332
     * @return bool
333
     */
334
    private function isBuilt(): bool
335
    {
336
        return file_exists(self::BUILD_HASH_FILE) && $this->validateBuildHash();
337
    }
338
339
    private function validateBuildHash(): bool
340
    {
341
        return md5(\ts\file_get_contents(__FILE__)) === \ts\file_get_contents(self::BUILD_HASH_FILE);
342
    }
343
344
    private function firstBuild(): void
345
    {
346
        $this->emptyDir(self::BUILD_DIR_TMP_B1);
347
        $this->builder->setProjectRootNamespace(self::TEST_PROJECT_ROOT_NAMESPACE_B1)
348
                      ->setPathToProjectRoot(self::BUILD_DIR_TMP_B1);
349
        $this->filesystem->remove(self::BUILD_DIR_TMP_B1);
350
        $this->filesystem->mkdir(self::BUILD_DIR_TMP_B1);
351
        $this->extendAutoloader(self::TEST_PROJECT_ROOT_NAMESPACE_B1, self::BUILD_DIR_TMP_B1);
352
        $fields = $this->buildCommonTypeFields();
353
        $this->buildEntitiesAndAssignCommonFields($fields);
354
        $this->updateLargeDataEntity();
355
        $this->updateLargePropertiesEntity();
356
        $this->addArchetypeFieldsToEntities();
357
        $this->updateEmailEntity();
358
        $this->updateAllEmbeddablesEntity();
359
        $this->setRelations();
360
        $this->resetAutoloader();
361
    }
362
363
    private function emptyDir(string $path): void
364
    {
365
        $this->filesystem->remove($path);
366
        $this->filesystem->mkdir($path);
367
    }
368
369
    private function extendAutoloader(string $namespace, string $buildDir): void
370
    {
371
        $testLoader = new class ($namespace) extends ClassLoader
372
        {
373
            /**
374
             * @var string
375
             */
376
            protected $namespace;
377
378
            public function __construct(string $namespace)
379
            {
380
                $this->namespace = $namespace;
381
            }
382
383
            public function loadClass($class)
384
            {
385
                if (false === strpos($class, $this->namespace)) {
386
                    return false;
387
                }
388
                $found = parent::loadClass($class);
389
                if (false === $found || null === $found) {
0 ignored issues
show
introduced by
The condition null === $found is always false.
Loading history...
390
                    //good point to set a breakpoint
391
                    return $found;
392
                }
393
394
                return $found;
395
            }
396
        };
397
        $testLoader->addPsr4($namespace . '\\', $buildDir . '/src', true);
398
        $testLoader->addPsr4($namespace . '\\', $buildDir . '/tests', true);
399
        $testLoader->register();
400
    }
401
402
    /**
403
     * Build the fields and return an array of Field Trait FQNs
404
     *
405
     * @return array|string[]
406
     * @throws DoctrineStaticMetaException
407
     * @throws ReflectionException
408
     */
409
    private function buildCommonTypeFields(): array
410
    {
411
        $fields         = [];
412
        $fieldGenerator = $this->builder->getFieldGenerator();
413
414
        foreach (MappingHelper::COMMON_TYPES as $type) {
415
            $fields[] = $fieldGenerator->generateField(
416
                self::TEST_PROJECT_ROOT_NAMESPACE_B1
417
                . self::TEST_FIELD_FQN_BASE . '\\' . ucwords($type) . FieldTraitCreator::SUFFIX,
418
                $type
419
            );
420
        }
421
422
        return $fields;
423
    }
424
425
    private function buildEntitiesAndAssignCommonFields(array $fields): void
426
    {
427
428
        $entityGenerator = $this->builder->getEntityGenerator();
429
        $fieldSetter     = $this->builder->getFieldSetter();
430
431
        foreach (self::TEST_ENTITIES as $entityFqn) {
432
            $entityGenerator->generateEntity(self::TEST_PROJECT_ROOT_NAMESPACE_B1 . $entityFqn);
433
            foreach ($fields as $fieldFqn) {
434
                $fieldSetter->setEntityHasField(
435
                    self::TEST_PROJECT_ROOT_NAMESPACE_B1 . $entityFqn,
436
                    $fieldFqn
437
                );
438
            }
439
        }
440
    }
441
442
    private function updateLargeDataEntity(): void
443
    {
444
        $fieldGenerator = $this->builder->getFieldGenerator();
445
        $fieldSetter    = $this->builder->getFieldSetter();
446
        foreach (self::LARGE_DATA_FIELDS as $field) {
447
            $fieldSetter->setEntityHasField(
448
                self::TEST_ENTITY_NAMESPACE_BASE_B1 . self::TEST_ENTITY_LARGE_DATA,
449
                $fieldGenerator->generateField(
450
                    self::TEST_PROJECT_ROOT_NAMESPACE_B1 . $field,
451
                    MappingHelper::TYPE_TEXT
452
                )
453
            );
454
        }
455
    }
456
457
    private function updateLargePropertiesEntity(): void
458
    {
459
        $fieldGenerator = $this->builder->getFieldGenerator();
460
        $fieldSetter    = $this->builder->getFieldSetter();
461
        foreach (self::LARGE_PROPERTIES_FIELDS as $field) {
462
            $fieldSetter->setEntityHasField(
463
                self::TEST_ENTITY_NAMESPACE_BASE_B1 . self::TEST_ENTITY_LARGE_DATA,
464
                $fieldGenerator->generateField(
465
                    self::TEST_PROJECT_ROOT_NAMESPACE_B1 . $field,
466
                    MappingHelper::TYPE_BOOLEAN
467
                )
468
            );
469
        }
470
    }
471
472
    private function addArchetypeFieldsToEntities(): void
473
    {
474
        $archetypeFqns = $this->namespaceHelper->getAllArchetypeFieldFqns();
475
        $fieldSetter   = $this->builder->getFieldSetter();
476
        foreach ($archetypeFqns as $archetypeFieldFqn) {
477
            $fieldSetter->setEntityHasField(
478
                self::TEST_ENTITY_NAMESPACE_BASE_B1 . self::TEST_ENTITY_ALL_ARCHETYPE_FIELDS,
479
                $archetypeFieldFqn
480
            );
481
        }
482
    }
483
484
485
    private function updateEmailEntity(): void
486
    {
487
        $emailEntityFqn = self::TEST_ENTITY_NAMESPACE_BASE_B1 . self::TEST_ENTITY_EMAIL;
488
        $this->builder->getFieldSetter()->setEntityHasField($emailEntityFqn, EmailAddressFieldTrait::class);
489
    }
490
491
    private function updateAllEmbeddablesEntity(): void
492
    {
493
        $this->builder->setEmbeddablesToEntity(
494
            self::TEST_ENTITY_NAMESPACE_BASE_B1 . self::TEST_ENTITY_ALL_EMBEDDABLES,
495
            [
496
                HasMoneyEmbeddableTrait::class,
497
                HasAddressEmbeddableTrait::class,
498
                HasFullNameEmbeddableTrait::class,
499
                HasWeightEmbeddableTrait::class,
500
            ]
501
        );
502
    }
503
504
    private function setRelations(): void
505
    {
506
        $relationsGenerator = $this->builder->getRelationsGenerator();
507
        foreach (self::TEST_RELATIONS as $relation) {
508
            $relationsGenerator->setEntityHasRelationToEntity(
509
                self::TEST_PROJECT_ROOT_NAMESPACE_B1 . $relation[0],
510
                (string)$relation[1],
511
                self::TEST_PROJECT_ROOT_NAMESPACE_B1 . $relation[2],
512
                (bool)$relation[3]
513
            );
514
        }
515
    }
516
517
    private function resetAutoloader(): void
518
    {
519
        $registered = spl_autoload_functions();
520
        $loader     = array_pop($registered);
521
        spl_autoload_unregister($loader);
522
    }
523
524
    private function secondBuild(): void
525
    {
526
        $this->emptyDir(self::BUILD_DIR_TMP_B2);
527
        $this->codeCopier->copy(
528
            self::BUILD_DIR_TMP_B1,
529
            self::BUILD_DIR_TMP_B2,
530
            self::TEST_PROJECT_ROOT_NAMESPACE_B1,
531
            self::TEST_PROJECT_ROOT_NAMESPACE_B2
532
        );
533
        $this->createCustomDataFiller();
534
        $this->extendAutoloader(self::TEST_PROJECT_ROOT_NAMESPACE_B2, self::BUILD_DIR_TMP_B2);
535
        $this->builder->setPathToProjectRoot(self::BUILD_DIR_TMP_B2)
536
                      ->setProjectRootNamespace(self::TEST_PROJECT_ROOT_NAMESPACE_B2)
537
                      ->finaliseBuild();
538
        $this->emptyDir(self::BUILD_DIR);
539
        $this->codeCopier->copy(
540
            self::BUILD_DIR_TMP_B2,
541
            self::BUILD_DIR,
542
            self::TEST_PROJECT_ROOT_NAMESPACE_B2,
543
            self::TEST_PROJECT_ROOT_NAMESPACE
544
        );
545
    }
546
547
    private function createCustomDataFiller(): void
548
    {
549
550
        $dataFiller = <<<'PHP'
551
<?php declare(strict_types=1);
552
553
namespace Test\Code\Generator\Assets\Entity\FakerDataFillers;
554
555
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\NamespaceHelper;
556
use EdmondsCommerce\DoctrineStaticMeta\DoctrineStaticMeta;
557
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\DataTransferObjectInterface;
558
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityGenerator\FakerDataFiller;
559
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityGenerator\FakerDataFillerFactory;
560
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityGenerator\FakerDataFillerInterface;
561
use Test\Code\Generator\Entity\DataTransferObjects\SimpleDto;
562
563
class SimpleFakerDataFiller implements FakerDataFillerInterface
564
{
565
    /**
566
     * @var FakerDataFiller
567
     */
568
    private $wrappedFiller;
569
570
    public function __construct(
571
        FakerDataFillerFactory $fakerDataFillerFactory,
572
        DoctrineStaticMeta $testedEntityDsm,
573
        NamespaceHelper $namespaceHelper,
574
        array $fakerDataProviderClasses,
575
        ?float $seed = null
576
    ) {
577
        $this->wrappedFiller =
578
            new FakerDataFiller(
579
                $fakerDataFillerFactory,
580
                $testedEntityDsm,
581
                $namespaceHelper,
582
                $fakerDataProviderClasses,
583
                $seed
584
            );
585
    }
586
587
    public function updateDtoWithFakeData(DataTransferObjectInterface $dto): void
588
    {
589
        $this->wrappedFiller->updateDtoWithFakeData($dto);
590
        $this->updateDtoWithKnownData($dto);
591
    }
592
    
593
    public function update(DataTransferObjectInterface $dto, $isRootDto = false): void
594
    {
595
        $this->wrappedFiller->update($dto, $isRootDto);
596
        $this->updateDtoWithKnownData($dto);
597
    }
598
    
599
    private function updateDtoWithKnownData(DataTransferObjectInterface $dto): void
600
    {
601
        if (!$dto instanceof SimpleDto) {
602
            throw new \RuntimeException(sprintf('Expected %s got %s', SimpleDto::class, get_class($dto)));
603
        }
604
        $dto->setString('Set from a custom Faker Data Filler');
605
    }
606
}
607
PHP;
608
        $dirPath    = self::BUILD_DIR_TMP_B2 . '/tests/Assets/Entity/FakerDataFillers/';
609
        $filePath   = $dirPath . 'SimpleFakerDataFiller.php';
610
        if (!is_dir($dirPath)) {
611
            mkdir($dirPath);
612
        }
613
        \ts\file_put_contents($filePath, $dataFiller);
614
    }
615
616
    private function setBuildHash(): void
617
    {
618
        \ts\file_put_contents(self::BUILD_HASH_FILE, md5(\ts\file_get_contents(__FILE__)));
619
    }
620
621
    public function copyTo(
622
        string $destinationPath,
623
        string $replaceNamespace = AbstractTest::TEST_PROJECT_ROOT_NAMESPACE
624
    ): void {
625
        $this->codeCopier->copy(
626
            self::BUILD_DIR,
627
            $destinationPath,
628
            self::TEST_PROJECT_ROOT_NAMESPACE,
629
            $replaceNamespace
630
        );
631
    }
632
}
633