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 (#166)
by Ross
06:42
created

TestCodeGenerator::emptyDir()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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