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 ( 6a4e57...36c412 )
by joseph
26:54
created

AbstractFieldTraitTest::getGetter()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta\Tests\Large\Entity\Fields\Traits;
4
5
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\AbstractGenerator;
6
use EdmondsCommerce\DoctrineStaticMeta\Entity\Fields\FakerData\FakerDataProviderInterface;
7
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\EntityInterface;
8
use EdmondsCommerce\DoctrineStaticMeta\Entity\Savers\EntitySaver;
9
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\EntityTestInterface;
10
use EdmondsCommerce\DoctrineStaticMeta\Exception\ValidationException;
11
use EdmondsCommerce\DoctrineStaticMeta\Tests\Assets\AbstractLargeTest;
12
use Faker\Generator;
13
14
/**
15
 * Extend this test with your Field Trait test to get basic test coverage.
16
 *
17
 * You should extend your field trait test to test your validation
18
 *
19
 * Class AbstractFieldTraitTest
20
 *
21
 * @package EdmondsCommerce\DoctrineStaticMeta\Entity\Fields\Traits
22
 * @SuppressWarnings(PHPMD.NumberOfChildren)
23
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
24
 * @large
25
 */
26
abstract class AbstractFieldTraitTest extends AbstractLargeTest
27
{
28
    protected const TEST_ENTITY_FQN_BASE = self::TEST_PROJECT_ROOT_NAMESPACE
29
                                           . '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME
30
                                           . '\\';
31
32
    protected const TEST_FIELD_FQN = 'Override Me';
33
34
    /**
35
     * The expected default value for the field. Most fields are marked as nullable so the default is null.
36
     * Should be overriden in the actual field test for any fields that are not nullable
37
     */
38
    protected const TEST_FIELD_DEFAULT = null;
39
40
    protected const TEST_FIELD_PROP = 'Override Me';
41
42
    /**
43
     * set to false for read only fields (with no setter)
44
     */
45
    protected const HAS_SETTER = true;
46
47
    /**
48
     * set to false for fields that do not have a validator configuration
49
     */
50
    protected const VALIDATES = true;
51
52
    /**
53
     * Override this with an array of valid values to set
54
     */
55
    protected const VALID_VALUES = [];
56
57
    /**
58
     * Override this with an array of invalid values to set.
59
     */
60
    protected const INVALID_VALUES = [];
61
62
    /**
63
     * @var Generator
64
     */
65
    protected static $fakerGenerator;
66
    protected static $buildOnce = true;
67
    protected $entitySuffix;
68
69
    public function setup()
70
    {
71
        parent::setUp();
72
        $this->entitySuffix = substr(static::class, strrpos(static::class, '\\') + 1);
73
        if (false === static::$built) {
74
            $this->generateCode();
75
            static::$built = true;
76
        }
77
        $this->setupCopiedWorkDir();
78
    }
79
80
    protected function generateCode()
81
    {
82
        $this->getEntityGenerator()
83
             ->generateEntity(static::TEST_ENTITY_FQN_BASE . $this->entitySuffix);
84
        $this->getFieldSetter()
85
             ->setEntityHasField(
86
                 static::TEST_ENTITY_FQN_BASE . $this->entitySuffix,
87
                 static::TEST_FIELD_FQN
88
             );
89
    }
90
91
    /**
92
     * @SuppressWarnings(PHPMD.StaticAccess)
93
     */
94
    public static function setUpBeforeClass()
95
    {
96
        parent::setUpBeforeClass();
97
        self::$fakerGenerator = \Faker\Factory::create();
98
    }
99
100
    /**
101
     * @throws \ReflectionException
102
     * @large
103
     * @test
104
     */
105
    public function createEntityWithField(): void
106
    {
107
        $entity = $this->getEntity();
108
        $getter = $this->getGetter($entity);
109
        self::assertTrue(\method_exists($entity, $getter));
110
        $value = $entity->$getter();
111
        self::assertSame(
112
            static::TEST_FIELD_DEFAULT,
113
            $value,
114
            'The getter on a newly created entity returns ' . var_export($value, true)
115
            . ' whereas the configured default value is ' . var_export(static::TEST_FIELD_DEFAULT, true)
116
        );
117
        if (false === static::HAS_SETTER) {
0 ignored issues
show
introduced by
The condition false === static::HAS_SETTER is always false.
Loading history...
118
            return;
119
        }
120
        $setValue = $this->setFakerValueForProperty($entity);
121
        self::assertSame($setValue, $entity->$getter());
122
    }
123
124
    protected function getEntity()
125
    {
126
        return $this->createEntity($this->getEntityFqn());
127
    }
128
129
    protected function getEntityFqn(): string
130
    {
131
        return $this->getCopiedFqn(self::TEST_ENTITY_FQN_BASE . $this->entitySuffix);
132
    }
133
134
    /**
135
     * @param EntityInterface $entity
136
     *
137
     * @return string
138
     * @throws \Exception
139
     */
140
    protected function getGetter(EntityInterface $entity): string
141
    {
142
        foreach (['get', 'is', 'has'] as $prefix) {
143
            $method = $prefix . static::TEST_FIELD_PROP;
144
            if (\method_exists($entity, $method)) {
145
                return $method;
146
            }
147
        }
148
        throw new \RuntimeException('Failed finding a getter in ' . __METHOD__);
149
    }
150
151
    /**
152
     * @param EntityInterface $entity
153
     *
154
     * @return mixed
155
     * @throws \ReflectionException
156
     * @throws \Exception
157
     */
158
    protected function setFakerValueForProperty(EntityInterface $entity)
159
    {
160
        $setter        = 'set' . static::TEST_FIELD_PROP;
161
        $fakerProvider = $this->getFakerDataProvider();
162
        if ($fakerProvider instanceof FakerDataProviderInterface) {
163
            $setValue = $fakerProvider();
164
            $entity->$setter($setValue);
165
166
            return $setValue;
167
        }
168
        $reflection       = new  \ts\Reflection\ReflectionClass(\get_class($entity));
169
        $setterReflection = $reflection->getMethod($setter);
170
        $setParamType     = current($setterReflection->getParameters())->getType()->getName();
171
        switch ($setParamType) {
172
            case 'string':
173
                $setValue = self::$fakerGenerator->text();
174
                break;
175
            case 'int':
176
                $setValue = self::$fakerGenerator->numberBetween(0, PHP_INT_MAX);
177
                break;
178
            case 'float':
179
                $setValue = self::$fakerGenerator->randomFloat(12, 0, 10000);
180
                break;
181
            case 'bool':
182
                $setValue = self::$fakerGenerator->boolean;
183
                break;
184
            case 'DateTime':
185
                $setValue = self::$fakerGenerator->dateTime;
186
                break;
187
            case 'DateTimeImmutable':
188
                $setValue = new \DateTimeImmutable(
189
                    self::$fakerGenerator->dateTime->format('Y-m-d')
190
                );
191
                break;
192
            default:
193
                throw new \RuntimeException('Failed getting a data provider for the property type ' . $setParamType);
194
        }
195
        $entity->$setter($setValue);
196
197
        return $setValue;
198
    }
199
200
    protected function getFakerDataProvider(): ?FakerDataProviderInterface
201
    {
202
        if (isset(EntityTestInterface::FAKER_DATA_PROVIDERS[static::TEST_FIELD_PROP])) {
203
            $provider = EntityTestInterface::FAKER_DATA_PROVIDERS[static::TEST_FIELD_PROP];
204
205
            return new $provider(self::$fakerGenerator);
206
        }
207
208
        return null;
209
    }
210
211
    /**
212
     * @test
213
     * @large
214
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
215
     * @throws \ReflectionException
216
     */
217
    public function createDatabaseSchema()
218
    {
219
        $this->createDatabase();
220
        $entity   = $this->getEntity();
221
        $setValue = null;
222
        if (false !== static::HAS_SETTER) {
0 ignored issues
show
introduced by
The condition false !== static::HAS_SETTER is always true.
Loading history...
223
            $setValue = $this->setFakerValueForProperty($entity);
224
        }
225
        $saver = $this->container->get(EntitySaver::class);
226
        $saver->save($entity);
227
        $repository  = $this->getEntityManager()->getRepository($this->getEntityFqn());
228
        $entities    = $repository->findAll();
229
        $savedEntity = current($entities);
230
        $getter      = $this->getGetter($entity);
231
        $gotValue    = $savedEntity->$getter();
232
        if (false !== static::HAS_SETTER) {
0 ignored issues
show
introduced by
The condition false !== static::HAS_SETTER is always true.
Loading history...
233
            self::assertEquals($setValue, $gotValue);
234
235
            return;
236
        }
237
        self::assertNotNull($gotValue);
238
    }
239
240
    /**
241
     * @test
242
     * @large
243
     */
244
    public function validValuesAreAccepted(): void
245
    {
246
        if (false === static::VALIDATES) {
0 ignored issues
show
introduced by
The condition false === static::VALIDATES is always false.
Loading history...
247
            self::markTestSkipped('This field does has no validation');
248
        }
249
        if (false === static::HAS_SETTER) {
0 ignored issues
show
introduced by
The condition false === static::HAS_SETTER is always false.
Loading history...
250
            self::markTestSkipped('No setter for this field');
251
        }
252
        if ([] === static::VALID_VALUES) {
253
            self::fail('You need to assign some valid values to ' . static::class . '::VALID_VALUES');
254
        }
255
        $entity = $this->getEntity();
256
        $setter = 'set' . static::TEST_FIELD_PROP;
257
        $getter = $this->getGetter($entity);
258
        foreach (static::VALID_VALUES as $value) {
259
            $entity->$setter($value);
260
            self::assertSame($value, $entity->$getter());
261
        }
262
    }
263
264
    /**
265
     * @test
266
     * @large
267
     * @dataProvider invalidValuesProvider
268
     */
269
    public function invalidValuesAreNotAccepted($invalidValue): void
270
    {
271
        if (false === static::VALIDATES) {
0 ignored issues
show
introduced by
The condition false === static::VALIDATES is always false.
Loading history...
272
            self::markTestSkipped('This field does has no validation');
273
        }
274
        if (false === static::HAS_SETTER) {
0 ignored issues
show
introduced by
The condition false === static::HAS_SETTER is always false.
Loading history...
275
            self::markTestSkipped('No setter for this field');
276
        }
277
        $entity = $this->getEntity();
278
        $setter = 'set' . static::TEST_FIELD_PROP;
279
        $this->expectException(ValidationException::class);
280
        try {
281
            $entity->$setter($invalidValue);
282
        } catch (\TypeError $e) {
283
            self::markTestSkipped(
284
                'You have set an INVALID_VALUE item of ' .
285
                $invalidValue .
286
                ' which has caused a TypeError as the setter does not accept this type of value.'
287
            );
288
        }
289
    }
290
291
    /**
292
     * Yield the invalid data, keyed by a namespace safe version of the value
293
     *
294
     * @return \Generator
295
     */
296
    public function invalidValuesProvider(): \Generator
297
    {
298
        if (false === static::VALIDATES) {
0 ignored issues
show
introduced by
The condition false === static::VALIDATES is always false.
Loading history...
299
            self::markTestSkipped('This field does not validate');
300
        }
301
        if ([] === static::INVALID_VALUES) {
302
            self::fail('You need to assign some invalid values to ' . static::class . '::INVALID_VALUES');
303
        }
304
        foreach (static::INVALID_VALUES as $invalidValue) {
305
            yield $invalidValue => [$invalidValue];
306
        }
307
    }
308
}
309