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

AbstractTest::qaGeneratedCode()

Size

Total Lines 65
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 30
nc 5
nop 0
dl 0
loc 65
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
     * @return bool
83
     * @SuppressWarnings(PHPMD.Superglobals)
84
     */
85
    protected function isTravis(): bool
86
    {
87
        return isset($_SERVER['TRAVIS']);
88
    }
89
90
    /**
91
     * @throws Exception\ConfigException
92
     * @throws Exception\DoctrineStaticMetaException
93
     * @SuppressWarnings(PHPMD.Superglobals)
94
     * @SuppressWarnings(PHPMD.StaticAccess)
95
     */
96
    protected function setupContainer()
97
    {
98
        SimpleEnv::setEnv(Config::getProjectRootDirectory().'/.env');
99
        $testConfig                                       = $_SERVER;
100
        $testConfig[ConfigInterface::PARAM_ENTITIES_PATH] = $this->entitiesPath;
101
        $testConfig[ConfigInterface::PARAM_DB_NAME]       .= '_test';
102
        $testConfig[ConfigInterface::PARAM_DEVMODE]       = true;
103
        $this->container                                  = new Container();
104
        $this->container->buildSymfonyContainer($testConfig);
105
        $this->container->get(Database::class)->drop(true)->create(true);
106
    }
107
108
109
    /**
110
     * Accesses the standard Composer autoloader
111
     *
112
     * Extends the class and also providing an entry point for xdebugging
113
     *
114
     * Extends this with a PSR4 root for our WORK_DIR
115
     **/
116
    protected function extendAutoloader()
117
    {
118
        $loader = new class extends ClassLoader
119
        {
120
            public function loadClass($class)
121
            {
122
                if (false === strpos($class, AbstractTest::TEST_PROJECT_ROOT_NAMESPACE)) {
123
                    return false;
124
                }
125
                $found = parent::loadClass($class);
126
                if (\in_array(gettype($found), ['boolean', 'NULL'], true)) {
127
                    //good spot to set a break point ;)
128
                    return false;
129
                }
130
131
                return true;
132
            }
133
        };
134
        $loader->addPsr4(
135
            static::TEST_PROJECT_ROOT_NAMESPACE.'\\',
136
            static::WORK_DIR.'/'.AbstractCommand::DEFAULT_SRC_SUBFOLDER
137
        );
138
        $loader->register();
139
    }
140
141
    protected function clearWorkDir()
142
    {
143
        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...
144
            throw new \RuntimeException(
145
                "You must set a `const WORK_DIR=AbstractTest::VAR_PATH.'/folderName/';` in your test class"
146
            );
147
        }
148
        $this->getFileSystem()->mkdir(static::WORK_DIR);
149
        $this->emptyDirectory(static::WORK_DIR);
150
        if (empty($this->entitiesPath)) {
151
            throw new \RuntimeException('$this->entitiesPath path is empty');
152
        }
153
        $this->getFileSystem()->mkdir($this->entitiesPath);
154
    }
155
156
    protected function getFileSystem(): Filesystem
157
    {
158
        if (null === $this->filesystem) {
159
            $this->filesystem = (null !== $this->container)
160
                ? $this->container->get(Filesystem::class)
161
                : new Filesystem();
162
        }
163
164
        return $this->filesystem;
165
    }
166
167
    protected function emptyDirectory(string $path)
168
    {
169
        $fileSystem = $this->getFileSystem();
170
        $fileSystem->remove($path);
171
        $fileSystem->mkdir($path);
172
    }
173
174
    protected function assertNoMissedReplacements(string $createdFile)
175
    {
176
        $createdFile = $this->container->get(CodeHelper::class)->resolvePath($createdFile);
177
        $this->assertFileExists($createdFile);
178
        $contents = file_get_contents($createdFile);
179
        $this->assertNotContains(
180
            'template',
181
            $contents,
182
            'Found the word "template" (case insensitive) in the created file '.$createdFile,
183
            true
184
        );
185
    }
186
187
    protected function assertFileContains(string $createdFile, string $needle)
188
    {
189
        $createdFile = $this->container->get(CodeHelper::class)->resolvePath($createdFile);
190
        $this->assertFileExists($createdFile);
191
        $contents = file_get_contents($createdFile);
192
        $this->assertContains(
193
            $needle,
194
            $contents,
195
            "Missing '$needle' in file '$createdFile'"
196
        );
197
    }
198
199
    protected function getEntityGenerator(): EntityGenerator
200
    {
201
        /**
202
         * @var EntityGenerator $entityGenerator
203
         */
204
        $entityGenerator = $this->container->get(EntityGenerator::class);
205
        $entityGenerator->setPathToProjectRoot(static::WORK_DIR)
206
                        ->setProjectRootNamespace(static::TEST_PROJECT_ROOT_NAMESPACE);
207
208
        return $entityGenerator;
209
    }
210
211
    protected function getRelationsGenerator(): RelationsGenerator
212
    {
213
        /**
214
         * @var RelationsGenerator $relationsGenerator
215
         */
216
        $relationsGenerator = $this->container->get(RelationsGenerator::class);
217
        $relationsGenerator->setPathToProjectRoot(static::WORK_DIR)
218
                           ->setProjectRootNamespace(static::TEST_PROJECT_ROOT_NAMESPACE);
219
220
        return $relationsGenerator;
221
    }
222
223
    protected function getFieldGenerator(): FieldGenerator
224
    {
225
        /**
226
         * @var FieldGenerator $fieldGenerator
227
         */
228
        $fieldGenerator = $this->container->get(FieldGenerator::class);
229
        $fieldGenerator->setPathToProjectRoot(static::WORK_DIR)
230
                       ->setProjectRootNamespace(static::TEST_PROJECT_ROOT_NAMESPACE);
231
232
        return $fieldGenerator;
233
    }
234
235
    protected function getSchema(): Schema
236
    {
237
        return $this->container->get(Schema::class);
238
    }
239
240
    /**
241
     * @SuppressWarnings(PHPMD.Superglobals)
242
     */
243
    public function qaGeneratedCode(): bool
244
    {
245
        if (isset($_SERVER[Constants::QA_QUICK_TESTS_KEY])
246
            && (int)$_SERVER[Constants::QA_QUICK_TESTS_KEY] === Constants::QA_QUICK_TESTS_ENABLED
247
        ) {
248
            return true;
249
        }
250
        //lint
251
        $path       = static::WORK_DIR;
252
        $exclude    = ['vendor'];
253
        $extensions = ['php'];
254
255
        $linter  = new Linter($path, $exclude, $extensions);
256
        $lint    = $linter->lint([], false);
257
        $message = str_replace($path, '', print_r($lint, true));
258
        $this->assertEmpty($lint, "\n\nPHP Syntax Errors in $path\n\n$message\n\n");
259
260
        $phpstanNamespace  = static::TEST_PROJECT_ROOT_NAMESPACE.'\\\\';
261
        $phpstanFolder     = static::WORK_DIR.'/'.AbstractCommand::DEFAULT_SRC_SUBFOLDER;
262
        $phpstanAutoLoader = '<?php declare(strict_types=1);
263
require __DIR__."/../../../vendor/autoload.php";
264
265
use Composer\Autoload\ClassLoader;
266
267
$loader = new class extends ClassLoader
268
        {
269
            public function loadClass($class)
270
            {
271
                if (false === strpos($class, "'.AbstractTest::TEST_PROJECT_ROOT_NAMESPACE.'")) {
272
                    return false;
273
                }
274
                $found = parent::loadClass($class);
275
                if (\in_array(gettype($found), [\'boolean\', \'NULL\'], true)) {
276
                    //good spot to set a break point ;)
277
                    return false;
278
                }
279
280
                return true;
281
            }
282
        };
283
        $loader->addPsr4(
284
            "'.$phpstanNamespace.'","'.$phpstanFolder.'"
285
        );
286
        $loader->register();
287
';
288
        file_put_contents(static::WORK_DIR.'/phpstan-autoloader.php', $phpstanAutoLoader);
289
        // A hunch that travis is not liking the no xdebug command
290
        $phpstanCommand = GeneratedCodeTest::BASH_PHPNOXDEBUG_FUNCTION
291
                          ."\n\nphpNoXdebug bin/phpstan.phar analyse $path/src -l7 -a "
292
                          .static::WORK_DIR.'/phpstan-autoloader.php 2>&1';
293
        if ($this->isTravis()) {
294
            $phpstanCommand = "bin/phpstan.phar analyse $path/src -l7 -a "
295
                              .static::WORK_DIR.'/phpstan-autoloader.php 2>&1';
296
        }
297
        exec(
298
            $phpstanCommand,
299
            $output,
300
            $exitCode
301
        );
302
        if (0 !== $exitCode) {
303
            $this->fail('PHPStan errors found in generated code at '.$path
304
                        .':'."\n\n".implode("\n", $output));
305
        }
306
307
        return true;
308
    }
309
}
310