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.
Passed
Pull Request — master (#58)
by joseph
17:08
created

FieldGeneratorIntegrationTest::buildAndCheck()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 59
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 59
rs 8.7117
c 0
b 0
f 0
cc 5
eloc 38
nc 7
nop 4

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\CodeGeneration\Generator\Field;
4
5
use EdmondsCommerce\DoctrineStaticMeta\AbstractIntegrationTest;
6
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\AbstractGenerator;
7
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\NamespaceHelper;
8
use EdmondsCommerce\DoctrineStaticMeta\MappingHelper;
9
10
/**
11
 * Class FieldGeneratorIntegrationTest
12
 *
13
 * @package EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator
14
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
15
 */
16
class FieldGeneratorIntegrationTest extends AbstractIntegrationTest
17
{
18
    public const WORK_DIR = AbstractIntegrationTest::VAR_PATH.'/'.self::TEST_TYPE.'/FieldGeneratorIntegrationTest/';
19
20
    private const TEST_ENTITY_CAR = self::TEST_PROJECT_ROOT_NAMESPACE.'\\'
21
                                    .AbstractGenerator::ENTITIES_FOLDER_NAME.'\\Car';
22
23
    private const TEST_FIELD_NAMESPACE = self::TEST_PROJECT_ROOT_NAMESPACE.'\\'
24
                                         .AbstractGenerator::ENTITY_FIELD_TRAIT_NAMESPACE;
25
26
    private const CAR_FIELDS_TO_TYPES = [
27
        [self::TEST_FIELD_NAMESPACE.'\\Brand', MappingHelper::TYPE_STRING],
28
        [self::TEST_FIELD_NAMESPACE.'\\EngineCC', MappingHelper::TYPE_INTEGER],
29
        [self::TEST_FIELD_NAMESPACE.'\\Manufactured', MappingHelper::TYPE_DATETIME],
30
        [self::TEST_FIELD_NAMESPACE.'\\Mpg', MappingHelper::TYPE_FLOAT],
31
        [self::TEST_FIELD_NAMESPACE.'\\Description', MappingHelper::TYPE_TEXT],
32
        [self::TEST_FIELD_NAMESPACE.'\\IsCar', MappingHelper::TYPE_BOOLEAN],
33
    ];
34
35
    private const UNIQUE_FIELDS_TO_TYPES = [
36
        [self::TEST_FIELD_NAMESPACE.'\\UniqueString', MappingHelper::TYPE_STRING],
37
        [self::TEST_FIELD_NAMESPACE.'\\UniqueInt', MappingHelper::TYPE_INTEGER],
38
    ];
39
40
    /**
41
     * @var FieldGenerator
42
     */
43
    private $fieldGenerator;
44
    /**
45
     * @var EntityFieldSetter
46
     */
47
    private $entityFieldSetter;
48
    /**
49
     * @var NamespaceHelper
50
     */
51
    private $namespaceHelper;
52
53
    public function setup()
54
    {
55
        parent::setup();
56
        $this->getEntityGenerator()->generateEntity(self::TEST_ENTITY_CAR);
57
        $this->fieldGenerator    = $this->getFieldGenerator();
58
        $this->entityFieldSetter = $this->container->get(EntityFieldSetter::class);
59
        $this->namespaceHelper   = $this->container->get(NamespaceHelper::class);
60
    }
61
62
    public function testArchetypeFieldCanBeStandardLibraryField(): void
63
    {
64
        foreach (FieldGenerator::STANDARD_FIELDS as $standardField) {
65
            $fieldFqn = \str_replace(
66
                [
67
                    'EdmondsCommerce\\DoctrineStaticMeta',
68
                    $this->namespaceHelper->getClassShortName($standardField),
69
                ],
70
                [
71
                    self::TEST_PROJECT_ROOT_NAMESPACE,
72
                    'Copied'.$this->namespaceHelper->getClassShortName($standardField),
73
                ],
74
                $standardField
75
            );
76
            $this->buildAndCheck(
77
                $fieldFqn,
78
                $standardField
79
            );
80
        }
81
    }
82
83
    public function testArchetypeFieldCanBeNonStandardLibraryField(): void
84
    {
85
        $args         = current(self::CAR_FIELDS_TO_TYPES);
86
        $archetypeFqn = $this->fieldGenerator->generateField($args[0], $args[1]);
87
        $this->buildAndCheck(self::TEST_FIELD_NAMESPACE.'\\BrandCopied', $archetypeFqn);
88
    }
89
90
91
    public function testFieldMustContainEntityNamespace()
92
    {
93
        $this->expectException(\InvalidArgumentException::class);
94
        $this->fieldGenerator->generateField(
95
            '\\Blah\\Foop',
96
            MappingHelper::TYPE_STRING,
97
            null,
98
            null,
99
            true
100
        );
101
    }
102
103
    public function testFieldTypeMustBeValid()
104
    {
105
        $this->expectException(\InvalidArgumentException::class);
106
        $this->fieldGenerator->generateField(
107
            self::CAR_FIELDS_TO_TYPES[0][0],
108
            'invalid',
109
            null,
110
            null,
111
            true
112
        );
113
    }
114
115
    public function testPHPTypeMustBeValid()
116
    {
117
        $this->expectException(\InvalidArgumentException::class);
118
        $this->fieldGenerator->generateField(
119
            self::CAR_FIELDS_TO_TYPES[0][0],
120
            MappingHelper::PHP_TYPE_FLOAT,
121
            'invalid',
122
            null,
123
            true
124
        );
125
    }
126
127
    public function testDefaultTypeMustBeValid()
128
    {
129
        $this->expectException(\InvalidArgumentException::class);
130
        $this->fieldGenerator->generateField(
131
            self::CAR_FIELDS_TO_TYPES[0][0],
132
            MappingHelper::PHP_TYPE_FLOAT,
133
            'invalid',
134
            'clearly not a float',
135
            true
136
        );
137
    }
138
139
    /**
140
     * Default values passed in by CLI could come through quite dirty and need to be normalised     *
141
     */
142
    public function testDefaultValueIsNormalised()
143
    {
144
        $defaultValuesToTypes = [
145
            MappingHelper::TYPE_INTEGER => [
146
                1,
147
                '1',
148
                ' 1',
149
                ' 1 ',
150
            ],
151
            MappingHelper::TYPE_FLOAT   => [
152
                1,
153
                1.0,
154
                '1',
155
                '1.1',
156
                ' 1.1 ',
157
                ' 1.1 ',
158
            ],
159
            MappingHelper::TYPE_BOOLEAN => [
160
                'true',
161
                'false',
162
                'TRUE',
163
                'FALSE',
164
                ' TRue ',
165
                ' FaLse ',
166
            ],
167
        ];
168
        $errors               = [];
169
        foreach ($defaultValuesToTypes as $type => $defaultValues) {
170
            foreach ($defaultValues as $key => $defaultValue) {
171
                try {
172
                    $this->buildAndCheck(
173
                        self::TEST_FIELD_NAMESPACE.'\\normalisedDefault'.$type.$key,
174
                        $type,
175
                        $defaultValue
176
                    );
177
                } catch (\Throwable $e) {
178
                    $errors[] = [
179
                        'type'    => $type,
180
                        'default' => $defaultValue,
181
                        'error'   => $e->getMessage(),
182
                    ];
183
                }
184
            }
185
        }
186
        $this->assertSame([], $errors, print_r($errors, true));
187
    }
188
189
    /**
190
     * Build and then test a field
191
     *
192
     * @param string $name
193
     * @param string $type
194
     *
195
     * @param mixed  $default
196
     * @param bool   $isUnique
197
     *
198
     * @return string
199
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
200
     * @throws \ReflectionException
201
     * @SuppressWarnings(PHPMD.StaticAccess)
202
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
203
     */
204
    protected function buildAndCheck(
205
        string $name,
206
        string $type,
207
        $default = null,
208
        bool $isUnique = false
209
    ): string {
210
        $fieldTraitFqn = $this->fieldGenerator->generateField(
211
            $name,
212
            $type,
213
            null,
214
            $default,
215
            $isUnique
216
        );
217
218
        $this->qaGeneratedCode();
219
        $interfacePath = $this->getPathFromFqn(
220
            \str_replace(
221
                '\\Fields\\Traits\\',
222
                '\\Fields\\Interfaces\\',
223
                $this->namespaceHelper->cropSuffix($fieldTraitFqn, 'Trait').'Interface'
224
            )
225
        );
226
        $this->assertNoMissedReplacements($interfacePath);
227
228
        $traitPath = $this->getPathFromFqn($fieldTraitFqn);
229
        $this->assertNoMissedReplacements($traitPath);
230
231
        $interfaceContents = file_get_contents($interfacePath);
232
        $traitContents     = file_get_contents($traitPath);
233
234
        $isArchetype = !\in_array($type, MappingHelper::ALL_DBAL_TYPES, true);
235
        if (true === $isArchetype) {
236
            //TODO - some more validation for archetype fields
237
            return $fieldTraitFqn;
238
        }
239
240
        if (!\in_array($type, [MappingHelper::TYPE_TEXT, MappingHelper::TYPE_STRING], true)) {
241
            $this->assertNotContains(': string', $interfaceContents);
242
            $this->assertNotContains('(string', $interfaceContents);
243
            $this->assertNotContains(': string', $traitContents);
244
            $this->assertNotContains('(string', $traitContents);
245
            $phpType = MappingHelper::COMMON_TYPES_TO_PHP_TYPES[$type];
246
            if (null === $default) {
247
                $phpType = "?$phpType";
248
            }
249
            $this->assertContains(': '.$phpType, $interfaceContents);
250
            $this->assertContains('('.$phpType, $interfaceContents);
251
            $this->assertContains(': '.$phpType, $traitContents);
252
            $this->assertContains('('.$phpType, $traitContents);
253
        }
254
255
        if ($type === MappingHelper::TYPE_BOOLEAN) {
256
            $this->assertNotContains('public function get', $interfaceContents);
257
            $this->assertNotContains('public function isIs', $interfaceContents, '', true);
258
            $this->assertNotContains('public function get', $traitContents);
259
            $this->assertNotContains('public function isIs', $traitContents, '', true);
260
        }
261
262
        return $fieldTraitFqn;
263
    }
264
265
    protected function getPathFromFqn(string $fqn): string
266
    {
267
        $path = self::WORK_DIR.'src/Entity/Fields';
268
        $exp  = explode(
269
            '\\',
270
            \substr(
271
                $fqn,
272
                strpos(
273
                    $fqn,
274
                    '\\Entity\\Fields\\'
275
                ) + \strlen('\\Entity\\Fields\\')
276
            )
277
        );
278
        foreach ($exp as $item) {
279
            $path .= '/'.$item;
280
        }
281
        $path .= '.php';
282
283
        return $path;
284
    }
285
286
    public function testBuildFieldsAndSetToEntity()
287
    {
288
        foreach (self::CAR_FIELDS_TO_TYPES as $args) {
289
            $fieldFqn = $this->buildAndCheck($args[0], $args[1], null);
290
            $this->entityFieldSetter->setEntityHasField(self::TEST_ENTITY_CAR, $fieldFqn);
291
        }
292
        $this->qaGeneratedCode();
293
    }
294
295
    public function testBuildFieldsWithSuffixAndSetToEntity()
296
    {
297
        foreach (self::CAR_FIELDS_TO_TYPES as $args) {
298
            $fieldFqn = $this->buildAndCheck($args[0].FieldGenerator::FIELD_TRAIT_SUFFIX, $args[1], null);
299
            $this->entityFieldSetter->setEntityHasField(self::TEST_ENTITY_CAR, $fieldFqn);
300
        }
301
        $this->qaGeneratedCode();
302
    }
303
304
    public function testBuildNullableFieldsAndSetToEntity()
305
    {
306
        foreach (self::CAR_FIELDS_TO_TYPES as $args) {
307
            $fieldFqn = $this->buildAndCheck($args[0], $args[1], null);
308
            $this->entityFieldSetter->setEntityHasField(self::TEST_ENTITY_CAR, $fieldFqn);
309
        }
310
        $this->qaGeneratedCode();
311
    }
312
313
    public function testBuildUniqueFieldsAndSetToEntity()
314
    {
315
        foreach (self::UNIQUE_FIELDS_TO_TYPES as $args) {
316
            $fieldFqn = $this->buildAndCheck($args[0], $args[1], null, true);
317
            $this->entityFieldSetter->setEntityHasField(self::TEST_ENTITY_CAR, $fieldFqn);
318
        }
319
        $this->qaGeneratedCode();
320
    }
321
}
322