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 ( 0a6f96...b0c756 )
by Ross
12s queued 10s
created

GeneratedCodeTest::assertNoUncommitedChanges()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 0
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta\GeneratedCode;
4
5
use Doctrine\Common\Inflector\Inflector;
6
use EdmondsCommerce\DoctrineStaticMeta\AbstractTest;
7
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Command\GenerateFieldCommand;
8
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\AbstractGenerator;
9
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\FieldGenerator;
10
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\RelationsGenerator;
11
use EdmondsCommerce\DoctrineStaticMeta\Config;
12
use EdmondsCommerce\DoctrineStaticMeta\ConfigInterface;
13
use EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException;
14
use EdmondsCommerce\DoctrineStaticMeta\MappingHelper;
15
use EdmondsCommerce\PHPQA\Constants;
16
17
/**
18
 * Class GeneratedCodeTest
19
 *
20
 * @package EdmondsCommerce\DoctrineStaticMeta\GeneratedCode
21
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
22
 */
23
class GeneratedCodeTest extends AbstractTest
24
{
25
    public const TEST_PROJECT_ROOT_NAMESPACE = 'My\\GeneratedCodeTest\\Project';
26
27
    public const TEST_ENTITY_NAMESPACE_BASE = self::TEST_PROJECT_ROOT_NAMESPACE
28
                                              .'\\'.AbstractGenerator::ENTITIES_FOLDER_NAME;
29
30
    public const TEST_FIELD_TRAIT_NAMESPACE = self::TEST_FIELD_NAMESPACE_BASE.'\\Traits\\';
31
32
    public const TEST_ENTITY_PERSON        = self::TEST_ENTITY_NAMESPACE_BASE.'\\Person';
33
    public const TEST_ENTITY_ADDRESS       = self::TEST_ENTITY_NAMESPACE_BASE.'\\Attributes\\Address';
34
    public const TEST_ENTITY_EMAIL         = self::TEST_ENTITY_NAMESPACE_BASE.'\\Attributes\\Email';
35
    public const TEST_ENTITY_COMPANY       = self::TEST_ENTITY_NAMESPACE_BASE.'\\Company';
36
    public const TEST_ENTITY_DIRECTOR      = self::TEST_ENTITY_NAMESPACE_BASE.'\\Company\\Director';
37
    public const TEST_ENTITY_ORDER         = self::TEST_ENTITY_NAMESPACE_BASE.'\\Order';
38
    public const TEST_ENTITY_ORDER_ADDRESS = self::TEST_ENTITY_NAMESPACE_BASE.'\\Order\\Address';
39
40
    public const TEST_ENTITY_NAME_SPACING_COMPANY        = self::TEST_ENTITY_NAMESPACE_BASE.'\\Company';
41
    public const TEST_ENTITY_NAME_SPACING_SOME_CLIENT    = self::TEST_ENTITY_NAMESPACE_BASE.'\\Some\\Client';
42
    public const TEST_ENTITY_NAME_SPACING_ANOTHER_CLIENT = self::TEST_ENTITY_NAMESPACE_BASE.'\\Another\\Client';
43
44
    public const TEST_ENTITIES = [
45
        self::TEST_ENTITY_PERSON,
46
        self::TEST_ENTITY_ADDRESS,
47
        self::TEST_ENTITY_EMAIL,
48
        self::TEST_ENTITY_COMPANY,
49
        self::TEST_ENTITY_DIRECTOR,
50
        self::TEST_ENTITY_ORDER,
51
        self::TEST_ENTITY_ORDER_ADDRESS,
52
        self::TEST_ENTITY_NAME_SPACING_COMPANY,
53
        self::TEST_ENTITY_NAME_SPACING_SOME_CLIENT,
54
        self::TEST_ENTITY_NAME_SPACING_ANOTHER_CLIENT,
55
    ];
56
57
    public const TEST_RELATIONS = [
58
        [self::TEST_ENTITY_PERSON, RelationsGenerator::HAS_UNIDIRECTIONAL_MANY_TO_ONE, self::TEST_ENTITY_ADDRESS],
59
        [self::TEST_ENTITY_PERSON, RelationsGenerator::HAS_ONE_TO_MANY, self::TEST_ENTITY_EMAIL],
60
        [self::TEST_ENTITY_COMPANY, RelationsGenerator::HAS_MANY_TO_MANY, self::TEST_ENTITY_DIRECTOR],
61
        [self::TEST_ENTITY_COMPANY, RelationsGenerator::HAS_ONE_TO_MANY, self::TEST_ENTITY_ADDRESS],
62
        [self::TEST_ENTITY_COMPANY, RelationsGenerator::HAS_UNIDIRECTIONAL_ONE_TO_MANY, self::TEST_ENTITY_EMAIL],
63
        [self::TEST_ENTITY_DIRECTOR, RelationsGenerator::HAS_ONE_TO_ONE, self::TEST_ENTITY_PERSON],
64
        [self::TEST_ENTITY_ORDER, RelationsGenerator::HAS_MANY_TO_ONE, self::TEST_ENTITY_PERSON],
65
        [self::TEST_ENTITY_ORDER, RelationsGenerator::HAS_ONE_TO_MANY, self::TEST_ENTITY_ORDER_ADDRESS],
66
        [self::TEST_ENTITY_ORDER_ADDRESS, RelationsGenerator::HAS_UNIDIRECTIONAL_ONE_TO_ONE, self::TEST_ENTITY_ADDRESS],
67
        [
68
            self::TEST_ENTITY_NAME_SPACING_COMPANY,
69
            RelationsGenerator::HAS_ONE_TO_MANY,
70
            self::TEST_ENTITY_NAME_SPACING_SOME_CLIENT,
71
        ],
72
        [
73
            self::TEST_ENTITY_NAME_SPACING_COMPANY,
74
            RelationsGenerator::HAS_ONE_TO_MANY,
75
            self::TEST_ENTITY_NAME_SPACING_ANOTHER_CLIENT,
76
        ],
77
    ];
78
79
    public const TEST_FIELD_NAMESPACE_BASE = self::TEST_PROJECT_ROOT_NAMESPACE.'\\Entity\\Fields';
80
81
    public const UNIQUEABLE_FIELD_TYPES = [
82
        MappingHelper::TYPE_INTEGER,
83
        MappingHelper::TYPE_STRING,
84
    ];
85
86
    protected function assertWeCheckAllPossibleRelationTypes()
87
    {
88
        $included = $toTest = [];
89
        foreach (RelationsGenerator::HAS_TYPES as $hasType) {
90
            if (0 === \strpos($hasType, RelationsGenerator::PREFIX_INVERSE)) {
91
                continue;
92
            }
93
            $toTest[$hasType] = true;
94
        }
95
        \ksort($toTest);
96
        foreach (self::TEST_RELATIONS as $relation) {
97
            $included[$relation[1]] = true;
98
        }
99
        \ksort($included);
100
        $missing = \array_diff(\array_keys($toTest), \array_keys($included));
101
        $this->assertEmpty(
102
            $missing,
103
            'We are not testing all relation types - '
104
            .'these ones have not been included: '
105
            .print_r($missing, true)
106
        );
107
    }
108
109
    public const BASH_PHPNOXDEBUG_FUNCTION = <<<'BASH'
110
function phpNoXdebug {
111
    debugMode="off"
112
    if [[ "$-" == *x* ]]
113
    then
114
        debugMode='on'
115
    fi
116
    if [[ "$debugMode" == "on" ]]
117
    then
118
        set +x
119
    fi
120
    local returnCode;
121
    local temporaryPath="$(mktemp -t php.XXXX).ini"
122
    # Using awk to ensure that files ending without newlines do not lead to configuration error
123
    /usr/bin/php -i | grep "\.ini" | grep -o -e '\(/[a-z0-9._-]\+\)\+\.ini' | grep -v xdebug \
124
        | xargs awk 'FNR==1{print ""}1' > "$temporaryPath"
125
    #Run PHP with temp config with no xdebug, display errors on stderr
126
    set +e
127
    /usr/bin/php -n -c "$temporaryPath" "$@"    
128
    returnCode=$?
129
    set -e
130
    rm -f "$temporaryPath"
131
    if [[ "$debugMode" == "on" ]]
132
    then
133
        set -x
134
    fi
135
    return ${returnCode};    
136
}
137
138
BASH;
139
    /**
140
     * @var string
141
     */
142
    private $workDir;
143
144
    /**
145
     * We need to check for uncommited changes in the main project. If there are, then the generated code tests will
146
     * not get them as it works by cloning this repo via the filesystem
147
     */
148
    protected function assertNoUncommitedChanges()
149
    {
150
        if ($this->isTravis()) {
151
            return;
152
        }
153
        exec("git status | grep -E 'nothing to commit, working .*? clean' ", $output, $exitCode);
154
        if (0 !== $exitCode) {
155
            $this->fail(
156
                'uncommitted changes detected in this project, '
157
                .'there is no point running the generated code test as it will not have your uncommitted changes.'
158
                ."\n\n".implode("\n", $output)
159
            );
160
        }
161
    }
162
163
    /**
164
     * @throws \Exception
165
     * @throws \Psr\Container\ContainerExceptionInterface
166
     * @throws \Psr\Container\NotFoundExceptionInterface
167
     * @SuppressWarnings(PHPMD.Superglobals)
168
     * @SuppressWarnings(PHPMD.StaticAccess)
169
     */
170
    public function setup()
171
    {
172
        if (isset($_SERVER[Constants::QA_QUICK_TESTS_KEY])
173
            && (int)$_SERVER[Constants::QA_QUICK_TESTS_KEY] === Constants::QA_QUICK_TESTS_ENABLED
174
        ) {
175
            return;
176
        }
177
        $this->assertNoUncommitedChanges();
178
        $this->workDir      = $this->isTravis() ?
179
            AbstractTest::VAR_PATH.'/GeneratedCodeTest'
180
            : sys_get_temp_dir().'/dsm/test-project';
181
        $this->entitiesPath = $this->workDir.'/src/Entities';
182
        $this->getFileSystem()->mkdir($this->workDir);
183
        $this->emptyDirectory($this->workDir);
184
        $this->getFileSystem()->mkdir($this->entitiesPath);
185
        $this->setupContainer();
186
        $this->initRebuildFile();
187
        $this->setupGeneratedDb();
188
        $this->initComposerAndInstall();
189
        $fileSystem = $this->getFileSystem();
190
        $fileSystem->mkdir(
191
            [
192
                $this->workDir.'/tests/',
193
                $this->workDir.'/cache/Proxies',
194
                $this->workDir.'/cache/qa',
195
                $this->workDir.'/qaConfig',
196
            ]
197
        );
198
        $fileSystem->copy(
199
            __DIR__.'/../../qaConfig/phpunit.xml',
200
            $this->workDir.'/qaConfig/phpunit.xml'
201
        );
202
        $fileSystem->symlink($this->workDir.'/qaConfig/phpunit.xml', $this->workDir.'/phpunit.xml');
203
        $fileSystem->copy(
204
            __DIR__.'/../../qaConfig/phpunit-with-coverage.xml',
205
            $this->workDir.'/qaConfig/phpunit-with-coverage.xml'
206
        );
207
        $fileSystem->copy(__DIR__.'/../../cli-config.php', $this->workDir.'/cli-config.php');
208
        file_put_contents($this->workDir.'/README.md', '#Generated Code');
209
210
        $this->addToRebuildFile(self::BASH_PHPNOXDEBUG_FUNCTION);
211
212
        $entities            = $this->generateEntities();
213
        $standardFieldEntity = $this->generateStandardFieldEntity();
214
        $this->generateRelations();
215
        $this->generateFields();
216
        $this->setFields(
217
            $entities,
218
            $this->getFieldFqns()
219
        );
220
        $this->setFields(
221
            [$standardFieldEntity],
222
            FieldGenerator::STANDARD_FIELDS
223
        );
224
    }
225
226
    protected function initRebuildFile()
227
    {
228
        $bash =
229
            <<<'BASH'
230
#!/usr/bin/env bash
231
readonly DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )";
232
cd "$DIR";
233
set -e
234
set -u
235
set -o pipefail
236
standardIFS="$IFS"
237
IFS=$'\n\t'
238
echo "
239
===========================================
240
$(hostname) $0 $@
241
===========================================
242
"
243
# Error Handling
244
backTraceExit () {
245
    local err=$?
246
    set +o xtrace
247
    local code="${1:-1}"
248
    printf "\n\nError in ${BASH_SOURCE[1]}:${BASH_LINENO[0]}. '${BASH_COMMAND}'\n\n exited with status: \n\n$err\n\n"
249
    # Print out the stack trace described by $function_stack
250
    if [ ${#FUNCNAME[@]} -gt 2 ]
251
    then
252
        echo "Call tree:"
253
        for ((i=1;i<${#FUNCNAME[@]}-1;i++))
254
        do
255
            echo " $i: ${BASH_SOURCE[$i+1]}:${BASH_LINENO[$i]} ${FUNCNAME[$i]}(...)"
256
        done
257
    fi
258
    echo "Exiting with status ${code}"
259
    exit "${code}"
260
}
261
trap 'backTraceExit' ERR
262
set -o errtrace
263
# Error Handling Ends
264
265
echo "clearing out generated code"
266
rm -rf src/* tests/*
267
268
echo "preparing empty Entities directory"
269
mkdir src/Entities
270
271
echo "making sure we have the latest version of code"
272
(cd vendor/edmondscommerce/doctrine-static-meta && git pull)
273
274
BASH;
275
        if (!$this->isTravis()) {
276
            $bash .= self::BASH_PHPNOXDEBUG_FUNCTION;
277
        }
278
        file_put_contents(
279
            $this->workDir.'/rebuild.bash',
280
            "\n\n".$bash
281
        );
282
    }
283
284
285
286
    /**
287
     * @return string Generated Database Name
288
     * @throws \Exception
289
     * @throws \Psr\Container\ContainerExceptionInterface
290
     * @throws \Psr\Container\NotFoundExceptionInterface
291
     */
292
    protected function setupGeneratedDb(): string
293
    {
294
        $dbHost = $this->container->get(Config::class)->get(ConfigInterface::PARAM_DB_HOST);
295
        $dbUser = $this->container->get(Config::class)->get(ConfigInterface::PARAM_DB_USER);
296
        $dbPass = $this->container->get(Config::class)->get(ConfigInterface::PARAM_DB_PASS);
297
        $dbName = $this->container->get(Config::class)->get(ConfigInterface::PARAM_DB_NAME);
298
        $link   = mysqli_connect($dbHost, $dbUser, $dbPass);
299
        if (!$link) {
0 ignored issues
show
introduced by
$link is of type mysqli, thus it always evaluated to true.
Loading history...
300
            throw new DoctrineStaticMetaException('Failed getting connection in '.__METHOD__);
301
        }
302
        $generatedDbName = $dbName.'_generated';
303
        mysqli_query($link, "DROP DATABASE IF EXISTS $generatedDbName");
304
        mysqli_query($link, "CREATE DATABASE $generatedDbName 
305
        CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci");
306
        mysqli_close($link);
307
308
        $rebuildBash = <<<BASH
309
echo "Dropping and creating the DB $generatedDbName"        
310
mysql -u $dbUser -p$dbPass -h $dbHost -e "DROP DATABASE IF EXISTS $generatedDbName";
311
mysql -u $dbUser -p$dbPass -h $dbHost -e "CREATE DATABASE $generatedDbName 
312
CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci";
313
BASH;
314
        $this->addToRebuildFile($rebuildBash);
315
        file_put_contents(
316
            $this->workDir.'/.env',
317
            <<<EOF
318
export dbUser="{$dbUser}"
319
export dbPass="{$dbPass}"
320
export dbHost="{$dbHost}"
321
export dbName="$generatedDbName"
322
EOF
323
        );
324
325
        return $generatedDbName;
326
    }
327
328
    /**
329
     * @param string $bash
330
     *
331
     * @return bool
332
     * @throws \Exception
333
     */
334
    protected function addToRebuildFile(string $bash): bool
335
    {
336
        $result = file_put_contents(
337
            $this->workDir.'/rebuild.bash',
338
            "\n\n".$bash."\n\n",
339
            FILE_APPEND
340
        );
341
        if (!$result) {
342
            throw new \RuntimeException('Failed writing to rebuild file');
343
        }
344
345
        return true;
346
    }
347
348
    protected function initComposerAndInstall()
349
    {
350
        $vcsPath = realpath(__DIR__.'/../../');
351
352
        $composerJson = <<<'JSON'
353
{
354
  "require": {
355
    "edmondscommerce/doctrine-static-meta": "dev-%s"
356
  },
357
  "repositories": [
358
    {
359
      "type": "vcs",
360
      "url": "%s"
361
    },
362
    {
363
      "type": "vcs",
364
      "url": "https://github.com/edmondscommerce/Faker.git"
365
    }
366
  ],
367
  "minimum-stability": "dev",
368
  "require-dev": {
369
    "fzaninotto/faker": "dev-dsm-patches@dev",
370
    "edmondscommerce/phpqa": "dev-master@dev"
371
  },
372
  "autoload": {
373
    "psr-4": {
374
      "My\\GeneratedCodeTest\\Project\\": [
375
        "src/"
376
      ]
377
    }
378
  },
379
  "autoload-dev": {
380
    "psr-4": {
381
      "My\\GeneratedCodeTest\\Project\\": [
382
        "tests/"
383
      ]
384
    }
385
  },
386
  "config": {
387
    "bin-dir": "bin",
388
    "preferred-install": {
389
      "edmondscommerce/*": "source",
390
      "fzaninotto/faker": "source",
391
      "*": "dist"
392
    },
393
    "optimize-autoloader": true
394
  }
395
}
396
JSON;
397
398
        $gitCurrentBranchName = trim(shell_exec("git branch | grep '*' | cut -d ' ' -f 2"));
399
        file_put_contents(
400
            $this->workDir.'/composer.json',
401
            sprintf($composerJson, $gitCurrentBranchName, $vcsPath)
402
        );
403
404
        $phpCmd   = $this->isTravis() ? 'php' : 'phpNoXdebug';
405
        $bashCmds = <<<BASH
406
           
407
$phpCmd $(which composer) install \
408
    --prefer-dist
409
410
$phpCmd $(which composer) dump-autoload --optimize
411
412
BASH;
413
        $this->execBash($bashCmds);
414
    }
415
416
    /**
417
     * Runs bash with strict error handling and verbose logging
418
     *
419
     * Will ensure the phpNoXdebugFunction is available and will CD into the correct directory before running commands
420
     *
421
     * Asserts that the command returns with an exit code of 0
422
     *
423
     * Appends to the rebuild file allowing easy rerunning of the commmands in the test project
424
     *
425
     * @param string $bashCmds
426
     *
427
     * @throws \Exception
428
     */
429
    protected function execBash(string $bashCmds)
430
    {
431
        fwrite(STDERR, "\n\t# Executing:\n\t$bashCmds");
432
        $startTime = microtime(true);
433
434
        $fullCmds = '';
435
        if (!$this->isTravis()) {
436
            $fullCmds .= "\n".self::BASH_PHPNOXDEBUG_FUNCTION."\n\n";
437
        }
438
        $fullCmds .= "set -xe;\n";
439
        $fullCmds .= "cd {$this->workDir};\n";
440
        #$fullCmds .= "exec 2>&1;\n";
441
        $fullCmds .= "$bashCmds\n";
442
443
        $output   = [];
444
        $exitCode = 0;
445
        exec($fullCmds, $output, $exitCode);
446
447
        if (0 !== $exitCode) {
448
            throw new \RuntimeException(
449
                "Error running bash commands:\n\nOutput:\n----------\n\n"
450
                .implode("\n", $output)
451
                ."\n\nCommands:\n----------\n"
452
                .str_replace(
453
                    "\n",
454
                    "\n\t",
455
                    "\n$bashCmds"
456
                )."\n\n"
457
            );
458
        }
459
460
        $seconds = round(microtime(true) - $startTime, 2);
461
        fwrite(STDERR, "\n\t\t#Completed in $seconds seconds\n");
462
    }
463
464
    protected function generateEntity(string $entityFqn)
465
    {
466
        $namespace   = self::TEST_PROJECT_ROOT_NAMESPACE;
467
        $doctrineCmd = <<<DOCTRINE
468
 dsm:generate:entity \
469
    --project-root-namespace="{$namespace}" \
470
    --entity-fully-qualified-name="{$entityFqn}"
471
DOCTRINE;
472
        $this->execDoctrine($doctrineCmd);
473
    }
474
475
    protected function generateUuidEntity(string $entityFqn)
476
    {
477
        $namespace   = self::TEST_PROJECT_ROOT_NAMESPACE;
478
        $doctrineCmd = <<<DOCTRINE
479
 dsm:generate:entity \
480
    --project-root-namespace="{$namespace}" \
481
    --entity-fully-qualified-name="{$entityFqn}" \
482
    --uuid-primary-key
483
DOCTRINE;
484
        $this->execDoctrine($doctrineCmd);
485
    }
486
487
    /**
488
     * @param string $propertyName
489
     * @param string $type
490
     * @param bool   $isNullable
491
     * @param bool   $isUnique
492
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
493
     */
494
    protected function generateField(
495
        string $propertyName,
496
        string $type,
497
        bool $isNullable = true,
498
        bool $isUnique = false
499
    ) {
500
        $namespace   = self::TEST_PROJECT_ROOT_NAMESPACE;
501
        $doctrineCmd = <<<DOCTRINE
502
 dsm:generate:field \
503
    --project-root-path="{$this->workDir}" \
504
    --project-root-namespace="{$namespace}" \
505
    --field-fully-qualified-name="{$propertyName}" \
506
    --field-property-doctrine-type="{$type}"
507
DOCTRINE;
508
        if (false === $isNullable) {
509
            $doctrineCmd .= ' --'.GenerateFieldCommand::OPT_NOT_NULLABLE;
510
        }
511
        if (true === $isUnique) {
512
            $doctrineCmd .= ' --'.GenerateFieldCommand::OPT_IS_UNIQUE;
513
        }
514
        $this->execDoctrine($doctrineCmd);
515
    }
516
517
    protected function setField(string $entityFqn, string $fieldFqn)
518
    {
519
        $namespace   = self::TEST_PROJECT_ROOT_NAMESPACE;
520
        $doctrineCmd = <<<DOCTRINE
521
 dsm:set:field \
522
    --project-root-path="{$this->workDir}" \
523
    --project-root-namespace="{$namespace}" \
524
    --entity="{$entityFqn}" \
525
    --field="{$fieldFqn}"
526
DOCTRINE;
527
        $this->execDoctrine($doctrineCmd);
528
    }
529
530
    protected function execDoctrine(string $doctrineCmds)
531
    {
532
        $phpCmd  = $this->isTravis() ? 'php' : 'phpNoXdebug';
533
        $bash    = <<<BASH
534
$phpCmd bin/doctrine $doctrineCmds    
535
BASH;
536
        $error   = false;
537
        $message = '';
538
        try {
539
            $this->execBash($bash);
540
        } catch (\RuntimeException $e) {
541
            $this->addToRebuildFile("\n\nexit 0;\n\n#The command below failed...\n\n");
542
            $error   = true;
543
            $message = $e->getMessage();
544
        }
545
        $this->addToRebuildFile($bash);
546
        $this->assertFalse($error, $message);
547
    }
548
549
    protected function setRelation(string $entity1, string $type, string $entity2)
550
    {
551
        $namespace = self::TEST_PROJECT_ROOT_NAMESPACE;
552
        $this->execDoctrine(
553
            <<<DOCTRINE
554
dsm:set:relation \
555
    --project-root-path="{$this->workDir}" \
556
    --project-root-namespace="{$namespace}" \
557
    --entity1="{$entity1}" \
558
    --hasType="{$type}" \
559
    --entity2="{$entity2}"    
560
DOCTRINE
561
        );
562
    }
563
564
    /**
565
     * @SuppressWarnings(PHPMD.Superglobals)
566
     * @throws \Exception
567
     */
568
    public function testRunTests()
569
    {
570
        $this->assertWeCheckAllPossibleRelationTypes();
571
        if (isset($_SERVER[Constants::QA_QUICK_TESTS_KEY])
572
            && (int)$_SERVER[Constants::QA_QUICK_TESTS_KEY] === Constants::QA_QUICK_TESTS_ENABLED
573
        ) {
574
            $this->markTestSkipped('Quick tests is enabled');
575
        }
576
        /** @lang bash */
577
        $bashCmds = <<<BASH
578
579
set +x
580
581
echo "
582
583
--------------------------------------------------
584
STARTS Running Tests In {$this->workDir}
585
--------------------------------------------------
586
587
"
588
589
#Prevent the retry tool dialogue etc
590
export CI=true
591
592
bash -x bin/qa
593
594
echo "
595
596
--------------------------------------------------
597
DONE Running Tests In {$this->workDir}
598
--------------------------------------------------
599
600
"
601
set -x
602
BASH;
603
        $this->execBash($bashCmds);
604
    }
605
606
    /**
607
     * Generate all test entities
608
     *
609
     * @return array
610
     */
611
    protected function generateEntities(): array
612
    {
613
        foreach (self::TEST_ENTITIES as $entityFqn) {
614
            $this->generateEntity($entityFqn);
615
        }
616
617
        return self::TEST_ENTITIES;
618
    }
619
620
    /**
621
     * @return string
622
     */
623
    protected function generateStandardFieldEntity(): string
624
    {
625
        $entityFqn = self::TEST_ENTITY_NAMESPACE_BASE.'\\Standard\\Field';
626
        $this->generateUuidEntity($entityFqn);
627
628
        return $entityFqn;
629
    }
630
631
    /**
632
     * Generate all test relations
633
     *
634
     * @return void
635
     */
636
    protected function generateRelations(): void
637
    {
638
        foreach (self::TEST_RELATIONS as $relation) {
639
            $this->setRelation(...$relation);
0 ignored issues
show
Bug introduced by
The call to EdmondsCommerce\Doctrine...CodeTest::setRelation() has too few arguments starting with type. ( Ignorable by Annotation )

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

639
            $this->/** @scrutinizer ignore-call */ 
640
                   setRelation(...$relation);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
640
        }
641
    }
642
643
    /**
644
     * Generate one field per common type
645
     *
646
     * @return void
647
     */
648
    protected function generateFields(): void
649
    {
650
        foreach (MappingHelper::COMMON_TYPES as $type) {
651
            $fieldFqn = self::TEST_FIELD_TRAIT_NAMESPACE.'\\'.$type;
652
            $this->generateField($fieldFqn, $type);
653
        }
654
        foreach (self::UNIQUEABLE_FIELD_TYPES as $uniqueableType) {
655
            $fieldFqn = self::TEST_FIELD_TRAIT_NAMESPACE.'\\Unique'.ucwords($uniqueableType);
656
            $this->generateField($fieldFqn, $uniqueableType, true, true);
657
        }
658
    }
659
660
    /**
661
     * Set each field type on each entity type
662
     *
663
     * @param array $entities
664
     * @param array $fields
665
     *
666
     * @return void
667
     */
668
    protected function setFields(array $entities, array $fields): void
669
    {
670
        foreach ($entities as $entityFqn) {
671
            foreach ($fields as $fieldFqn) {
672
                $this->setField($entityFqn, $fieldFqn);
673
            }
674
        }
675
    }
676
677
    /**
678
     * @return array
679
     * @SuppressWarnings(PHPMD.StaticAccess)
680
     */
681
    protected function getFieldFqns(): array
682
    {
683
        $fieldFqns = [];
684
        foreach (MappingHelper::COMMON_TYPES as $type) {
685
            $fieldFqns[] = self::TEST_FIELD_TRAIT_NAMESPACE.Inflector::classify($type).'FieldTrait';
686
        }
687
        foreach (self::UNIQUEABLE_FIELD_TYPES as $type) {
688
            $fieldFqns[] = self::TEST_FIELD_TRAIT_NAMESPACE.Inflector::classify('unique_'.$type).'FieldTrait';
689
        }
690
691
        return $fieldFqns;
692
    }
693
}
694