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 (#45)
by joseph
02:37
created

AbstractTest.php$0 ➔ qaGeneratedCode()   B

Complexity

Conditions 4

Size

Total Lines 61

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
dl 0
loc 61
rs 8.9392
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta;
4
5
use Composer\Autoload\ClassLoader;
6
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\CodeHelper;
7
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Command\AbstractCommand;
8
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\AbstractGenerator;
9
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\EntityGenerator;
10
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\FieldGenerator;
11
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\RelationsGenerator;
12
use EdmondsCommerce\DoctrineStaticMeta\GeneratedCode\GeneratedCodeTest;
13
use EdmondsCommerce\DoctrineStaticMeta\Schema\Database;
14
use EdmondsCommerce\DoctrineStaticMeta\Schema\Schema;
15
use EdmondsCommerce\PHPQA\Constants;
16
use Overtrue\PHPLint\Linter;
17
use PHPUnit\Framework\TestCase;
18
use Symfony\Component\Filesystem\Filesystem;
19
20
/**
21
 * Class AbstractTest
22
 *
23
 * @package EdmondsCommerce\DoctrineStaticMeta
24
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
25
 */
26
abstract class AbstractTest extends TestCase
27
{
28
    public const VAR_PATH                    = __DIR__.'/../var/testOutput';
29
    public const WORK_DIR                    = 'override me';
30
    public const TEST_PROJECT_ROOT_NAMESPACE = 'My\\Test\\Project';
31
32
    /**
33
     * The absolute path to the Entities folder, eg:
34
     * /var/www/vhosts/doctrine-static-meta/var/{testWorkDir}/Entities
35
     *
36
     * @var string
37
     */
38
    protected $entitiesPath = '';
39
40
    /**
41
     * The absolute path to the EntityRelations folder, eg:
42
     * /var/www/vhosts/doctrine-static-meta/var/{testWorkDir}/Entity/Relations
43
     *
44
     * @var string
45
     */
46
    protected $entityRelationsPath = '';
47
48
    /**
49
     * @var Container
50
     */
51
    protected $container;
52
53
    /**
54
     * @var Filesystem
55
     */
56
    protected $filesystem;
57
58
59
    /**
60
     * Prepare working directory, ensure its empty, create entities folder and set up env variables
61
     *
62
     * The order of these actions is critical
63
     */
64
    public function setup()
65
    {
66
        $this->entitiesPath = static::WORK_DIR
67
                              .'/'.AbstractCommand::DEFAULT_SRC_SUBFOLDER
68
                              .'/'.AbstractGenerator::ENTITIES_FOLDER_NAME;
69
        $this->getFileSystem()->mkdir($this->entitiesPath);
70
        $this->entitiesPath        = realpath($this->entitiesPath);
71
        $this->entityRelationsPath = static::WORK_DIR
72
                                     .'/'.AbstractCommand::DEFAULT_SRC_SUBFOLDER
73
                                     .'/'.AbstractGenerator::ENTITY_RELATIONS_FOLDER_NAME;
74
        $this->getFileSystem()->mkdir($this->entityRelationsPath);
75
        $this->entityRelationsPath = realpath($this->entityRelationsPath);
76
        $this->setupContainer();
77
        $this->clearWorkDir();
78
        $this->extendAutoloader();
79
    }
80
81
    /**
82
     * @throws Exception\ConfigException
83
     * @throws Exception\DoctrineStaticMetaException
84
     * @SuppressWarnings(PHPMD.Superglobals)
85
     * @SuppressWarnings(PHPMD.StaticAccess)
86
     */
87
    protected function setupContainer()
88
    {
89
        SimpleEnv::setEnv(Config::getProjectRootDirectory().'/.env');
90
        $testConfig                                       = $_SERVER;
91
        $testConfig[ConfigInterface::PARAM_ENTITIES_PATH] = $this->entitiesPath;
92
        $testConfig[ConfigInterface::PARAM_DB_NAME]       .= '_test';
93
        $testConfig[ConfigInterface::PARAM_DEVMODE]       = true;
94
        $this->container                                  = new Container();
95
        $this->container->buildSymfonyContainer($testConfig);
96
        $this->container->get(Database::class)->drop(true)->create(true);
97
    }
98
99
100
    /**
101
     * Accesses the standard Composer autoloader
102
     *
103
     * Extends the class and also providing an entry point for xdebugging
104
     *
105
     * Extends this with a PSR4 root for our WORK_DIR
106
     **/
107
    protected function extendAutoloader()
108
    {
109
        $loader = new class extends ClassLoader
110
        {
111
            public function loadClass($class)
112
            {
113
                if (false === strpos($class, AbstractTest::TEST_PROJECT_ROOT_NAMESPACE)) {
114
                    return false;
115
                }
116
                $found = parent::loadClass($class);
117
                if (\in_array(gettype($found), ['boolean', 'NULL'], true)) {
118
                    //good spot to set a break point ;)
119
                    return false;
120
                }
121
122
                return true;
123
            }
124
        };
125
        $loader->addPsr4(
126
            static::TEST_PROJECT_ROOT_NAMESPACE.'\\',
127
            static::WORK_DIR.'/'.AbstractCommand::DEFAULT_SRC_SUBFOLDER
128
        );
129
        $loader->register();
130
    }
131
132
    protected function clearWorkDir()
133
    {
134
        if (static::WORK_DIR === self::WORK_DIR) {
0 ignored issues
show
introduced by
The condition static::WORK_DIR === self::WORK_DIR is always true.
Loading history...
135
            throw new \RuntimeException(
136
                "You must set a `const WORK_DIR=AbstractTest::VAR_PATH.'/folderName/';` in your test class"
137
            );
138
        }
139
        $this->getFileSystem()->mkdir(static::WORK_DIR);
140
        $this->emptyDirectory(static::WORK_DIR);
141
        if (empty($this->entitiesPath)) {
142
            throw new \RuntimeException('$this->entitiesPath path is empty');
143
        }
144
        $this->getFileSystem()->mkdir($this->entitiesPath);
145
    }
146
147
    protected function getFileSystem(): Filesystem
148
    {
149
        if (null === $this->filesystem) {
150
            $this->filesystem = (null !== $this->container)
151
                ? $this->container->get(Filesystem::class)
152
                : new Filesystem();
153
        }
154
155
        return $this->filesystem;
156
    }
157
158
    protected function emptyDirectory(string $path)
159
    {
160
        $fileSystem = $this->getFileSystem();
161
        $fileSystem->remove($path);
162
        $fileSystem->mkdir($path);
163
    }
164
165
    protected function assertNoMissedReplacements(string $createdFile)
166
    {
167
        $createdFile = $this->container->get(CodeHelper::class)->resolvePath($createdFile);
168
        $this->assertFileExists($createdFile);
169
        $contents = file_get_contents($createdFile);
170
        $this->assertNotContains(
171
            'template',
172
            $contents,
173
            'Found the word "template" (case insensitive) in the created file '.$createdFile,
174
            true
175
        );
176
    }
177
178
    protected function assertFileContains(string $createdFile, string $needle)
179
    {
180
        $createdFile = $this->container->get(CodeHelper::class)->resolvePath($createdFile);
181
        $this->assertFileExists($createdFile);
182
        $contents = file_get_contents($createdFile);
183
        $this->assertContains(
184
            $needle,
185
            $contents,
186
            "Missing '$needle' in file '$createdFile'"
187
        );
188
    }
189
190
    protected function getEntityGenerator(): EntityGenerator
191
    {
192
        /**
193
         * @var EntityGenerator $entityGenerator
194
         */
195
        $entityGenerator = $this->container->get(EntityGenerator::class);
196
        $entityGenerator->setPathToProjectRoot(static::WORK_DIR)
197
                        ->setProjectRootNamespace(static::TEST_PROJECT_ROOT_NAMESPACE);
198
199
        return $entityGenerator;
200
    }
201
202
    protected function getRelationsGenerator(): RelationsGenerator
203
    {
204
        /**
205
         * @var RelationsGenerator $relationsGenerator
206
         */
207
        $relationsGenerator = $this->container->get(RelationsGenerator::class);
208
        $relationsGenerator->setPathToProjectRoot(static::WORK_DIR)
209
                           ->setProjectRootNamespace(static::TEST_PROJECT_ROOT_NAMESPACE);
210
211
        return $relationsGenerator;
212
    }
213
214
    protected function getFieldGenerator(): FieldGenerator
215
    {
216
        /**
217
         * @var FieldGenerator $fieldGenerator
218
         */
219
        $fieldGenerator = $this->container->get(FieldGenerator::class);
220
        $fieldGenerator->setPathToProjectRoot(static::WORK_DIR)
221
                       ->setProjectRootNamespace(static::TEST_PROJECT_ROOT_NAMESPACE);
222
223
        return $fieldGenerator;
224
    }
225
226
    protected function getSchema(): Schema
227
    {
228
        return $this->container->get(Schema::class);
229
    }
230
231
    /**
232
     * @SuppressWarnings(PHPMD.Superglobals)
233
     */
234
    public function qaGeneratedCode(): bool
235
    {
236
        if (isset($_SERVER[Constants::QA_QUICK_TESTS_KEY])
237
            && (int)$_SERVER[Constants::QA_QUICK_TESTS_KEY] === Constants::QA_QUICK_TESTS_ENABLED
238
        ) {
239
            return true;
240
        }
241
        //lint
242
        $path       = static::WORK_DIR;
243
        $exclude    = ['vendor'];
244
        $extensions = ['php'];
245
246
        $linter  = new Linter($path, $exclude, $extensions);
247
        $lint    = $linter->lint([], false);
248
        $message = str_replace($path, '', print_r($lint, true));
249
        $this->assertEmpty($lint, "\n\nPHP Syntax Errors in $path\n\n$message\n\n");
250
251
        $phpstanNamespace  = static::TEST_PROJECT_ROOT_NAMESPACE.'\\\\';
252
        $phpstanFolder     = static::WORK_DIR.'/'.AbstractCommand::DEFAULT_SRC_SUBFOLDER;
253
        $phpstanAutoLoader = '<?php declare(strict_types=1);
254
require __DIR__."/../../../vendor/autoload.php";
255
256
use Composer\Autoload\ClassLoader;
257
258
$loader = new class extends ClassLoader
259
        {
260
            public function loadClass($class)
261
            {
262
                if (false === strpos($class, "'.AbstractTest::TEST_PROJECT_ROOT_NAMESPACE.'")) {
263
                    return false;
264
                }
265
                $found = parent::loadClass($class);
266
                if (\in_array(gettype($found), [\'boolean\', \'NULL\'], true)) {
267
                    //good spot to set a break point ;)
268
                    return false;
269
                }
270
271
                return true;
272
            }
273
        };
274
        $loader->addPsr4(
275
            "'.$phpstanNamespace.'","'.$phpstanFolder.'"
276
        );
277
        $loader->register();
278
';
279
        file_put_contents(static::WORK_DIR.'/phpstan-autoloader.php', $phpstanAutoLoader);
280
281
282
        exec(
283
            GeneratedCodeTest::BASH_PHPNOXDEBUG_FUNCTION
284
            ."\n\nphpNoXdebug bin/phpstan.phar analyse $path/src -l7 -a "
285
            .static::WORK_DIR.'/phpstan-autoloader.php 2>&1',
286
            $output,
287
            $exitCode
288
        );
289
        if (0 !== $exitCode) {
290
            $this->fail('PHPStan errors found in generated code at '.$path
291
                        .':'."\n\n".implode("\n", $output));
292
        }
293
294
        return true;
295
    }
296
}
297