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 (#185)
by joseph
33:43
created

FixturesHelperTest   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 526
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 289
dl 0
loc 526
c 0
b 0
f 0
rs 10
wmc 9

27 Methods

Rating   Name   Duplication   Size   Complexity  
A setup() 0 22 2
A itCanTakeAModifierToCustomiseTheFixtures() 0 22 2
A hp$0 ➔ getString() 0 3 1
A getFixture() 0 5 1
A hp$0 ➔ getId() 0 3 1
A hp$1 ➔ getEntityFqn() 0 3 1
A itLoadsAllTheFixturesWithRandomDataByDefault() 0 14 1
B overrideCode() 0 124 1
B hp$1 ➔ getFixtureModifier() 0 156 1
A hp$1 ➔ __construct() 0 5 1
fixturesUseTheCorrectFakerDataProviders() 0 16 ?
A hp$1 ➔ getAttributesEmails() 0 6 1
A hp$1 ➔ addAnotherEntity() 0 53 1
A getModifiedFixture() 0 5 1
A hp$1 ➔ getId() 0 3 1
getFixtureModifier() 0 156 ?
A hp$0 ➔ __construct() 0 4 1
A hp$2 ➔ modifyEntities() 0 5 1
A hp$1 ➔ getString() 0 3 1
A hp$1 ➔ fixturesUseTheCorrectFakerDataProviders() 0 16 2
A hp$2 ➔ __construct() 0 12 1
A hp$0 ➔ updateFirstEntity() 0 35 1
A getArrayKeyedByUuid() 0 8 2
A hp$0 ➔ getEntityFqn() 0 3 1
A itUsesTheCacheTheSecondTime() 0 33 2
A getUnmodifiedFixture() 0 3 1
A itCanBeConfiguredNotToLoadFromTheCache() 0 26 2
1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta\Tests\Large\G\Entity\Testing\Fixtures;
4
5
use Doctrine\Common\Cache\FilesystemCache;
6
use Doctrine\Common\Collections\ArrayCollection;
7
use EdmondsCommerce\DoctrineStaticMeta\Entity\DataTransferObjects\DtoFactory;
8
use EdmondsCommerce\DoctrineStaticMeta\Entity\Factory\EntityFactoryInterface;
9
use EdmondsCommerce\DoctrineStaticMeta\Entity\Fields\Factories\UuidFactory;
10
use EdmondsCommerce\DoctrineStaticMeta\Entity\Fields\Interfaces\String\EnumFieldInterface;
11
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\DataTransferObjectInterface;
12
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\EntityInterface;
13
use EdmondsCommerce\DoctrineStaticMeta\Entity\Savers\EntitySaverFactory;
14
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\Fixtures\AbstractEntityFixtureLoader;
15
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\Fixtures\FixtureEntitiesModifierInterface;
16
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\Fixtures\FixturesHelper;
17
use EdmondsCommerce\DoctrineStaticMeta\Schema\Database;
18
use EdmondsCommerce\DoctrineStaticMeta\Schema\Schema;
19
use EdmondsCommerce\DoctrineStaticMeta\Tests\Assets\AbstractLargeTest;
20
use EdmondsCommerce\DoctrineStaticMeta\Tests\Assets\AbstractTest;
21
use EdmondsCommerce\DoctrineStaticMeta\Tests\Assets\TestCodeGenerator;
22
use Ramsey\Uuid\UuidInterface;
23
24
/**
25
 * @covers \EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\Fixtures\AbstractEntityFixtureLoader
26
 * @covers \EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\Fixtures\FixturesHelper
27
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
28
 * @SuppressWarnings(PHPMD.StaticAccess)
29
 */
30
class FixturesHelperTest extends AbstractLargeTest
31
{
32
    public const WORK_DIR = AbstractTest::VAR_PATH .
33
                            self::TEST_TYPE_LARGE .
34
                            '/FixturesTest';
35
36
    private const ENTITY_WITHOUT_MODIFIER = self::TEST_ENTITIES_ROOT_NAMESPACE .
37
                                            TestCodeGenerator::TEST_ENTITY_PERSON;
38
39
    private const ENTITY_WITH_MODIFIER = self::TEST_ENTITIES_ROOT_NAMESPACE .
40
                                         TestCodeGenerator::TEST_ENTITY_PERSON;
41
42
    protected static $buildOnce = true;
43
    /**
44
     * @var FixturesHelper
45
     */
46
    private $helper;
47
48
    public function setup(): void
49
    {
50
        parent::setUp();
51
        if (false === self::$built) {
52
            $this->getTestCodeGenerator()
53
                 ->copyTo(self::WORK_DIR, self::TEST_PROJECT_ROOT_NAMESPACE);
54
            $this->overrideCode();
55
            self::$built = true;
56
        }
57
        $this->setupCopiedWorkDirAndCreateDatabase();
58
        $this->recreateDtos();
59
        $cacheDir = $this->copiedWorkDir . '/cache';
60
        mkdir($cacheDir, 0777, true);
61
        $this->helper = new FixturesHelper(
62
            $this->getEntityManager(),
63
            $this->container->get(Database::class),
64
            $this->container->get(Schema::class),
65
            new FilesystemCache($cacheDir),
66
            $this->container->get(EntitySaverFactory::class),
67
            $this->getNamespaceHelper(),
68
            $this->getTestEntityGeneratorFactory(),
69
            $this->container
70
        );
71
    }
72
73
    private function overrideCode(): void
74
    {
75
        $personClass = <<<'PHP'
76
<?php declare(strict_types=1);
77
78
namespace My\Test\Project\Entities;
79
// phpcs:disable Generic.Files.LineLength.TooLong
80
81
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
82
use EdmondsCommerce\DoctrineStaticMeta\MappingHelper;
83
use EdmondsCommerce\DoctrineStaticMeta\Entity as DSM;
84
use My\Test\Project\Entity\Fields\Traits\BooleanFieldTrait;
85
use My\Test\Project\Entity\Fields\Traits\DatetimeFieldTrait;
86
use My\Test\Project\Entity\Fields\Traits\DecimalFieldTrait;
87
use My\Test\Project\Entity\Fields\Traits\FloatFieldTrait;
88
use My\Test\Project\Entity\Fields\Traits\IntegerFieldTrait;
89
use My\Test\Project\Entity\Fields\Traits\JsonFieldTrait;
90
use My\Test\Project\Entity\Fields\Traits\StringFieldTrait;
91
use My\Test\Project\Entity\Fields\Traits\TextFieldTrait;
92
use My\Test\Project\Entity\Interfaces\PersonInterface;
93
use My\Test\Project\Entity\Relations\Attributes\Address\Traits\HasAttributesAddress\HasAttributesAddressUnidirectionalManyToOne;
94
use My\Test\Project\Entity\Relations\Attributes\Email\Traits\HasRequiredAttributesEmails\HasRequiredAttributesEmailsOneToMany;
95
use My\Test\Project\Entity\Relations\Company\Director\Traits\HasCompanyDirector\HasCompanyDirectorInverseOneToOne;
96
use My\Test\Project\Entity\Relations\Large\Relation\Traits\HasLargeRelation\HasLargeRelationInverseOneToOne;
97
98
// phpcs:enable
99
class Person implements 
100
    PersonInterface
101
{
102
    /**
103
     * DSM Traits 
104
     */
105
    use DSM\Traits\UsesPHPMetaDataTrait;
106
    use DSM\Traits\ValidatedEntityTrait;
107
    use DSM\Traits\ImplementNotifyChangeTrackingPolicy;
108
    use DSM\Traits\AlwaysValidTrait;
109
110
    /**
111
     * Required Relations 
112
     */
113
    use HasRequiredAttributesEmailsOneToMany;
114
115
    /**
116
     * Relations 
117
     */
118
    use HasAttributesAddressUnidirectionalManyToOne;
119
    use HasCompanyDirectorInverseOneToOne;
120
    use HasLargeRelationInverseOneToOne;
121
122
    /**
123
     * DSM Fields 
124
     */
125
    use DSM\Fields\Traits\PrimaryKey\NonOrderedUuidFieldTrait;
126
127
    /**
128
     * Fields 
129
     */
130
    use StringFieldTrait;
131
    use DatetimeFieldTrait;
132
    use FloatFieldTrait;
133
    use DecimalFieldTrait;
134
    use IntegerFieldTrait;
135
    use TextFieldTrait;
136
    use BooleanFieldTrait;
137
    use JsonFieldTrait;
138
    
139
    use DSM\Fields\Traits\String\EnumFieldTrait;
140
}
141
PHP;
142
        \ts\file_put_contents(self::WORK_DIR . '/src/Entities/Person.php', $personClass);
143
144
        $personFixture = <<<'PHP'
145
<?php declare(strict_types=1);
146
147
namespace My\Test\Project\Assets\Entity\Fixtures;
148
149
use Doctrine\Common\Collections\ArrayCollection;
150
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
151
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\Fixtures\AbstractEntityFixtureLoader;
152
use My\Test\Project\Assets\Entity\Fixtures\Attributes\EmailFixture;
153
154
class PersonFixture extends AbstractEntityFixtureLoader implements DependentFixtureInterface
155
{
156
    public const REFERENCE_PREFIX = 'Person_';
157
    
158
    public const BULK_AMOUNT_TO_GENERATE = 2;
159
160
    public function getDependencies(): array
161
    {
162
        return [EmailFixture::class];
163
    }
164
165
    protected function loadBulk(): array
166
    {
167
        $entities = parent::loadBulk();
168
        $num      = 0;
169
        foreach ($entities as $person) {
170
            $collection = new ArrayCollection();
171
            $collection->add($this->getReference(EmailFixture::REFERENCE_PREFIX . $num++));
172
            $person->setAttributesEmails($collection);
173
        }
174
175
        return $entities;
176
    }
177
}
178
PHP;
179
        \ts\file_put_contents(self::WORK_DIR . '/tests/Assets/Entity/Fixtures/PersonFixture.php', $personFixture);
180
181
        $emailFixture = <<<'PHP'
182
<?php declare(strict_types=1);
183
184
namespace My\Test\Project\Assets\Entity\Fixtures\Attributes;
185
186
use EdmondsCommerce\DoctrineStaticMeta\Entity\Testing\Fixtures\AbstractEntityFixtureLoader;
187
188
class EmailFixture extends AbstractEntityFixtureLoader
189
{
190
    public const REFERENCE_PREFIX = 'Email_';
191
    public const BULK_AMOUNT_TO_GENERATE = 2;
192
}
193
194
PHP;
195
        \ts\file_put_contents(self::WORK_DIR . '/tests/Assets/Entity/Fixtures/Attributes/EmailFixture.php',
196
                              $emailFixture);
197
    }
198
199
    /**
200
     * @test
201
     * @large
202
     */
203
    public function itLoadsAllTheFixturesWithRandomDataByDefault(): array
204
    {
205
        $this->helper->setCacheKey(__CLASS__ . '_unmodified');
206
        $fixture = $this->getUnmodifiedFixture();
207
        $this->helper->addFixture($fixture);
208
        $this->helper->createDb();
209
        $entityFqn   = $this->getCopiedFqn(self::ENTITY_WITHOUT_MODIFIER);
210
        $actual      = $this->getRepositoryFactory()
211
                            ->getRepository($entityFqn)
212
                            ->findAll();
213
        $actualCount = count($actual);
214
        self::assertSame($fixture::BULK_AMOUNT_TO_GENERATE, $actualCount);
215
216
        return $actual;
217
    }
218
219
    private function getUnmodifiedFixture(): AbstractEntityFixtureLoader
220
    {
221
        return $this->getFixture($this->getCopiedFqn(self::ENTITY_WITHOUT_MODIFIER));
222
    }
223
224
    private function getFixture(
225
        string $entityFqn,
226
        ?FixtureEntitiesModifierInterface $modifier = null
227
    ): AbstractEntityFixtureLoader {
228
        return $this->helper->createFixtureInstanceForEntityFqn($entityFqn, $modifier);
229
    }
230
231
    /**
232
     * @test
233
     * @large
234
     * @depends itLoadsAllTheFixturesWithRandomDataByDefault
235
     *
236
     * @param array $loadedFirstTime
237
     *
238
     * @return array
239
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
240
     * @throws \ReflectionException
241
     */
242
    public function itUsesTheCacheTheSecondTime(array $loadedFirstTime): array
243
    {
244
        $this->getFileSystem()
245
             ->mirror(
246
                 $this->copiedWorkDir .
247
                 '/../FixturesHelperTest_ItLoadsAllTheFixturesWithRandomDataByDefault_/cache',
248
                 $this->copiedWorkDir . '/cache'
249
             );
250
        $this->helper->setCacheKey(__CLASS__ . '_unmodified');
251
        $fixture = $this->getUnmodifiedFixture();
252
        $this->helper->addFixture($fixture);
253
        $this->helper->createDb();
254
        self::assertTrue($this->helper->isLoadedFromCache());
255
        /**
256
         * @var EntityInterface[] $loadedSecondTime
257
         */
258
        $loadedSecondTime = $this->getRepositoryFactory()
259
                                 ->getRepository($this->getCopiedFqn(self::ENTITY_WITHOUT_MODIFIER))
260
                                 ->findAll();
261
        $actualCount      = count($loadedSecondTime);
262
        $expectedCount    = count($loadedFirstTime);
263
        self::assertSame($expectedCount, $actualCount);
264
        $first  = $this->getArrayKeyedByUuid($loadedFirstTime);
265
        $second = $this->getArrayKeyedByUuid($loadedSecondTime);
266
        foreach ($second as $secondId => $actualEntity) {
267
            self::assertArrayHasKey($secondId, $first, 'Failed finding UUID ' . $secondId . ' in first Entities');
268
            $expectedEntity = $first[$secondId];
269
            $expectedText   = $expectedEntity->getString();
270
            $actualText     = $actualEntity->getString();
271
            self::assertEquals($expectedText, $actualText, 'Cached Faker data does not match');
272
        }
273
274
        return $loadedSecondTime;
275
    }
276
277
    /**
278
     * @param array $entities
279
     *
280
     * @return EntityInterface[]
281
     * @return EntityInterface[]
282
     */
283
    private function getArrayKeyedByUuid(array $entities): array
284
    {
285
        $return = [];
286
        foreach ($entities as $entity) {
287
            $return[$entity->getId()->toString()] = $entity;
288
        }
289
290
        return $return;
291
    }
292
293
    /**
294
     * @test
295
     * @large
296
     * @depends itUsesTheCacheTheSecondTime
297
     *
298
     * @param array $loadedSecondTime
299
     *
300
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
301
     * @throws \ReflectionException
302
     */
303
    public function itCanBeConfiguredNotToLoadFromTheCache(array $loadedSecondTime): void
304
    {
305
        $this->getFileSystem()
306
             ->mirror(
307
                 $this->copiedWorkDir .
308
                 '/../FixturesHelperTest_ItUsesTheCacheTheSecondTime_/cache',
309
                 $this->copiedWorkDir . '/cache'
310
             );
311
        $this->helper->setCacheKey(__CLASS__ . '_unmodified');
312
        $fixture = $this->getUnmodifiedFixture();
313
        $this->helper->setLoadFromCache(false);
314
        $this->helper->addFixture($fixture);
315
        $this->helper->createDb();
316
        self::assertFalse($this->helper->isLoadedFromCache());
317
        /**
318
         * @var EntityInterface[] $loadedThirdTime
319
         */
320
        $loadedThirdTime = $this->getRepositoryFactory()
321
                                ->getRepository($this->getCopiedFqn(self::ENTITY_WITHOUT_MODIFIER))
322
                                ->findAll();
323
        $actualCount     = count($loadedThirdTime);
324
        $expectedCount   = count($loadedSecondTime);
325
        self::assertSame($expectedCount, $actualCount);
326
        $second = $this->getArrayKeyedByUuid($loadedSecondTime);
327
        foreach ($loadedThirdTime as $actualEntity) {
328
            self::assertArrayNotHasKey($actualEntity->getId()->toString(), $second);
329
        }
330
    }
331
332
    /**
333
     * @test
334
     * @large
335
     */
336
    public function itCanTakeAModifierToCustomiseTheFixtures(): void
337
    {
338
        $this->helper->setCacheKey(__CLASS__ . '_modified');
339
        $fixture = $this->getModifiedFixture();
340
        $this->helper->addFixture($fixture);
341
        $this->helper->createDb();
342
        /**
343
         * @var EntityInterface[] $actual
344
         */
345
        $actual      = $this->getRepositoryFactory()
346
                            ->getRepository($this->getCopiedFqn(self::ENTITY_WITH_MODIFIER))
347
                            ->findAll();
348
        $actualCount = count($actual);
349
        self::assertSame($fixture::BULK_AMOUNT_TO_GENERATE + 1, $actualCount);
350
        $foundStrings = [];
351
        foreach ($actual as $entity) {
352
            $foundStrings[$entity->getString()] = true;
0 ignored issues
show
Bug introduced by
The method getString() does not exist on EdmondsCommerce\Doctrine...erfaces\EntityInterface. ( Ignorable by Annotation )

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

352
            $foundStrings[$entity->/** @scrutinizer ignore-call */ getString()] = true;

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
353
        }
354
        $overwrittenString = 'This has been overridden';
355
        $createdString     = 'This has been created';
356
        self::assertArrayHasKey($overwrittenString, $foundStrings);
357
        self::assertArrayHasKey($createdString, $foundStrings);
358
    }
359
360
    private function getModifiedFixture(): AbstractEntityFixtureLoader
361
    {
362
        return $this->getFixture(
363
            $this->getCopiedFqn(self::ENTITY_WITH_MODIFIER),
364
            $this->getFixtureModifier()
365
        );
366
    }
367
368
    /**
369
     * @return FixtureEntitiesModifierInterface
370
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
371
     * @throws \ReflectionException
372
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
373
     */
374
    private function getFixtureModifier(): FixtureEntitiesModifierInterface
375
    {
376
377
        return new class(
378
            $this->getCopiedFqn(self::ENTITY_WITH_MODIFIER),
379
            $this->getEntityFactory(),
380
            $this->getEntityDtoFactory(),
381
            $this->getUuidFactory(),
382
            $this->getCopiedFqn(self::TEST_ENTITIES_ROOT_NAMESPACE . TestCodeGenerator::TEST_ENTITY_EMAIL)
383
        )
384
            implements FixtureEntitiesModifierInterface
385
        {
386
            /**
387
             * @var string
388
             */
389
            protected $entityFqn;
390
            /**
391
             * @var EntityFactoryInterface
392
             */
393
            protected $factory;
394
            /**
395
             * @var array|EntityInterface[]
396
             */
397
            private $entities;
398
            /**
399
             * @var DtoFactory
400
             */
401
            private $dtoFactory;
402
            /**
403
             * @var UuidFactory
404
             */
405
            private $uuidFactory;
406
            /**
407
             * @var string
408
             */
409
            private $emailFqn;
410
411
            public function __construct(
412
                string $entityFqn,
413
                EntityFactoryInterface $factory,
414
                DtoFactory $dtoFactory,
415
                UuidFactory $uuidFactory,
416
                string $emailFqn
417
            ) {
418
                $this->entityFqn   = $entityFqn;
419
                $this->factory     = $factory;
420
                $this->dtoFactory  = $dtoFactory;
421
                $this->uuidFactory = $uuidFactory;
422
                $this->emailFqn    = $emailFqn;
423
            }
424
425
            /**
426
             * Update the entities array by reference
427
             *
428
             * @param array $entities
429
             */
430
            public function modifyEntities(array &$entities): void
431
            {
432
                $this->entities = &$entities;
433
                $this->updateFirstEntity();
434
                $this->addAnotherEntity();
435
            }
436
437
            private function updateFirstEntity(): void
438
            {
439
                $firstEntity = current($this->entities);
440
                $firstEntity->update(
441
                    new class($this->entityFqn, $firstEntity->getId())
442
                        implements DataTransferObjectInterface
443
                    {
444
                        /**
445
                         * @var string
446
                         */
447
                        private static $entityFqn;
448
                        /**
449
                         * @var UuidInterface
450
                         */
451
                        private $id;
452
453
                        public function __construct(string $entityFqn, UuidInterface $id)
454
                        {
455
                            self::$entityFqn = $entityFqn;
456
                            $this->id        = $id;
457
                        }
458
459
                        public function getString(): string
460
                        {
461
                            return 'This has been overridden';
462
                        }
463
464
                        public static function getEntityFqn(): string
465
                        {
466
                            return self::$entityFqn;
467
                        }
468
469
                        public function getId(): UuidInterface
470
                        {
471
                            return $this->id;
472
                        }
473
                    }
474
                );
475
            }
476
477
            private function addAnotherEntity(): void
478
            {
479
                $address = $this->factory->create($this->emailFqn);
480
                $entity  = $this->factory->create(
481
                    $this->entityFqn,
482
                    new class($this->entityFqn, $this->uuidFactory, $address) implements DataTransferObjectInterface
483
                    {
484
                        /**
485
                         * @var string
486
                         */
487
                        private static $entityFqn;
488
                        /**
489
                         * @var \Ramsey\Uuid\UuidInterface
490
                         */
491
                        private $id;
492
                        /**
493
                         * @var EntityInterface
494
                         */
495
                        private $email;
496
497
                        public function __construct(string $entityFqn, UuidFactory $factory, EntityInterface $email)
498
                        {
499
                            self::$entityFqn = $entityFqn;
500
                            $this->id        = $factory->getOrderedTimeUuid();
501
                            $this->email     = $email;
502
                        }
503
504
                        public function getString(): string
505
                        {
506
                            return 'This has been created';
507
                        }
508
509
                        public static function getEntityFqn(): string
510
                        {
511
                            return self::$entityFqn;
512
                        }
513
514
                        public function getId(): UuidInterface
515
                        {
516
                            return $this->id;
517
                        }
518
519
                        public function getAttributesEmails(): ArrayCollection
520
                        {
521
                            $collection = new ArrayCollection();
522
                            $collection->add($this->email);
523
524
                            return $collection;
525
                        }
526
                    }
527
                );
528
529
                $this->entities[] = $entity;
530
            }
531
        };
532
    }
533
534
    /**
535
     * @test
536
     * @large
537
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
538
     * @throws \ReflectionException
539
     */
540
    public function fixturesUseTheCorrectFakerDataProviders(): void
541
    {
542
        $entityFqn = $this->getCopiedFqn(self::ENTITY_WITHOUT_MODIFIER);
543
544
        $this->helper->setCacheKey(__CLASS__ . '_faker');
545
        $fixture = $this->getUnmodifiedFixture();
546
        $this->helper->addFixture($fixture);
547
        $this->helper->createDb();
548
        $actual = $this->getRepositoryFactory()
549
                       ->getRepository($entityFqn)
550
                       ->findAll();
551
        /**
552
         * @var EntityInterface $entity
553
         */
554
        foreach ($actual as $entity) {
555
            self::assertContains($entity->getEnum(), EnumFieldInterface::ENUM_OPTIONS);
556
        }
557
    }
558
}
559