Passed
Push — main ( 6c9276...76dcd0 )
by Anatoly
06:53 queued 02:07
created

HydratorTest.php$46 ➔ runTest()   B

Complexity

Conditions 9

Size

Total Lines 63

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 63
rs 7.2517
cc 9

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
2
3
declare(strict_types=1);
4
5
namespace Sunrise\Hydrator\Tests;
6
7
use DateTimeImmutable;
8
use LogicException;
9
use PHPUnit\Framework\TestCase;
10
use stdClass;
11
use Sunrise\Hydrator\Annotation\Format;
12
use Sunrise\Hydrator\Annotation\Subtype;
13
use Sunrise\Hydrator\Dictionary\ContextKey;
14
use Sunrise\Hydrator\Dictionary\ErrorCode;
15
use Sunrise\Hydrator\Exception\InvalidDataException;
16
use Sunrise\Hydrator\Exception\InvalidObjectException;
17
use Sunrise\Hydrator\Hydrator;
18
use Sunrise\Hydrator\HydratorInterface;
19
use Sunrise\Hydrator\Tests\Fixtures\IntegerEnum;
20
use Sunrise\Hydrator\Tests\Fixtures\Issue25;
21
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithAliasedProperty;
22
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithIgnoredProperty;
23
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithIntegerEnum;
24
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithRelationshipWithString;
25
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithUnsupportedInternalClass;
26
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithNullableIntegerEnum;
27
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithNullableRelationship;
28
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithNullableRelationships;
29
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithNullableStringEnum;
30
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithNullableTimezone;
31
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithNullableUid;
32
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithNullableUnixTimeStamp;
33
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithOptionalIntegerEnum;
34
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithOptionalRelationship;
35
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithOptionalRelationships;
36
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithOptionalStringEnum;
37
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithOptionalTimezone;
38
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithOptionalUid;
39
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithOptionalUnixTimeStamp;
40
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithRelationship;
41
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithRelationshipWithNullableString;
42
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithRelationshipWithOptionalString;
43
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithRelationships;
44
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithRelationshipsWithLimit;
45
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithRelationshipsWithUnstantiableObject;
46
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithStaticalProperty;
47
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithString;
48
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithStringEnum;
49
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithTimestamp;
50
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithTimezone;
51
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithUid;
52
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithUnformattedTimestampProperty;
53
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithUnixTimeStamp;
54
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithUnstantiableRelationship;
55
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithUnsupportedPropertyType;
56
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithUnsupportedPropertyNotation;
57
use Sunrise\Hydrator\Tests\Fixtures\ObjectWithUntypedProperty;
58
use Sunrise\Hydrator\Tests\Fixtures\Store\Product;
59
use Sunrise\Hydrator\Tests\Fixtures\Store\Status;
60
use Sunrise\Hydrator\Tests\Fixtures\StringEnum;
61
use Sunrise\Hydrator\Tests\Fixtures\UnstantiableObject;
62
use Sunrise\Hydrator\Tests\Stub\Collection;
63
use Sunrise\Hydrator\Tests\Stub\OverflowedCollection;
64
use Sunrise\Hydrator\Tests\Stub\UnstantiableCollection;
65
use Sunrise\Hydrator\TypeConverter\TimestampTypeConverter;
66
67
use function sprintf;
68
use function version_compare;
69
70
use const PHP_VERSION;
71
use const PHP_VERSION_ID;
72
73
class HydratorTest extends TestCase
74
{
75
    private ?int $invalidValueExceptionCount = null;
76
    private array $invalidValueExceptionMessage = [];
77
    private array $invalidValueExceptionPropertyPath = [];
78
    private array $invalidValueExceptionErrorCode = [];
79
80
    /**
81
     * @group boolean
82
     * @dataProvider strictBooleanDataProvider
83
     * @dataProvider nonStrictBooleanDataProvider
84
     */
85
    public function testHydrateBooleanProperty(array $data, bool $expected): void
86
    {
87
        $object = new class {
88
            public bool $value;
89
        };
90
91
        $this->assertInvalidValueExceptionCount(0);
92
        $this->createHydrator()->hydrate($object, $data);
93
        $this->assertSame($expected, $object->value);
94
    }
95
96
    /**
97
     * @group boolean
98
     * @dataProvider strictBooleanDataProvider
99
     * @dataProvider nonStrictBooleanDataProvider
100
     * @dataProvider strictNullDataProvider
101
     * @dataProvider nonStrictNullDataProvider
102
     */
103
    public function testHydrateNullableBooleanProperty(array $data, ?bool $expected): void
104
    {
105
        $object = new class {
106
            public ?bool $value;
107
        };
108
109
        $this->assertInvalidValueExceptionCount(0);
110
        $this->createHydrator()->hydrate($object, $data);
111
        $this->assertSame($expected, $object->value);
112
    }
113
114
    /**
115
     * @group boolean
116
     * @dataProvider strictBooleanDataProvider
117
     * @dataProvider nonStrictBooleanDataProvider
118
     * @dataProvider emptyDataProvider
119
     */
120
    public function testHydrateOptionalBooleanProperty(array $data, bool $expected = true): void
121
    {
122
        $object = new class {
123
            public bool $value = true;
124
        };
125
126
        $this->assertInvalidValueExceptionCount(0);
127
        $this->createHydrator()->hydrate($object, $data);
128
        $this->assertSame($expected, $object->value);
129
    }
130
131
    /**
132
     * @group boolean
133
     * @dataProvider strictNullDataProvider
134
     * @dataProvider nonStrictNullDataProvider
135
     */
136
    public function testHydrateBooleanPropertyWithEmptyValue(array $data): void
137
    {
138
        $object = new class {
139
            public bool $value;
140
        };
141
142
        $this->assertInvalidValueExceptionCount(1);
143
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
144
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
145
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
146
        $this->createHydrator()->hydrate($object, $data);
147
    }
148
149
    /**
150
     * @group boolean
151
     * @dataProvider notBooleanDataProvider
152
     */
153
    public function testHydrateBooleanPropertyWithInvalidValue(array $data): void
154
    {
155
        $object = new class {
156
            public bool $value;
157
        };
158
159
        $this->assertInvalidValueExceptionCount(1);
160
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type boolean.');
161
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_BOOLEAN);
162
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
163
        $this->createHydrator()->hydrate($object, $data);
164
    }
165
166
    /**
167
     * @group boolean
168
     */
169
    public function testHydrateBooleanPropertyWithoutValue(): void
170
    {
171
        $object = new class {
172
            public bool $value;
173
        };
174
175
        $this->assertInvalidValueExceptionCount(1);
176
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
177
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
178
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
179
        $this->createHydrator()->hydrate($object, []);
180
    }
181
182
    /**
183
     * @group integer
184
     * @dataProvider strictIntegerDataProvider
185
     * @dataProvider nonStrictIntegerDataProvider
186
     */
187
    public function testHydrateIntegerProperty(array $data, int $expected): void
188
    {
189
        $object = new class {
190
            public int $value;
191
        };
192
193
        $this->assertInvalidValueExceptionCount(0);
194
        $this->createHydrator()->hydrate($object, $data);
195
        $this->assertSame($expected, $object->value);
196
    }
197
198
    /**
199
     * @group integer
200
     * @dataProvider strictIntegerDataProvider
201
     * @dataProvider nonStrictIntegerDataProvider
202
     * @dataProvider strictNullDataProvider
203
     * @dataProvider nonStrictNullDataProvider
204
     */
205
    public function testHydrateNullableIntegerProperty(array $data, ?int $expected): void
206
    {
207
        $object = new class {
208
            public ?int $value;
209
        };
210
211
        $this->assertInvalidValueExceptionCount(0);
212
        $this->createHydrator()->hydrate($object, $data);
213
        $this->assertSame($expected, $object->value);
214
    }
215
216
    /**
217
     * @group integer
218
     * @dataProvider strictIntegerDataProvider
219
     * @dataProvider nonStrictIntegerDataProvider
220
     * @dataProvider emptyDataProvider
221
     */
222
    public function testHydrateOptionalIntegerProperty(array $data, int $expected = 42): void
223
    {
224
        $object = new class {
225
            public int $value = 42;
226
        };
227
228
        $this->assertInvalidValueExceptionCount(0);
229
        $this->createHydrator()->hydrate($object, $data);
230
        $this->assertSame($expected, $object->value);
231
    }
232
233
    /**
234
     * @group integer
235
     * @dataProvider strictNullDataProvider
236
     * @dataProvider nonStrictNullDataProvider
237
     */
238
    public function testHydrateIntegerPropertyWithEmptyValue(array $data): void
239
    {
240
        $object = new class {
241
            public int $value;
242
        };
243
244
        $this->assertInvalidValueExceptionCount(1);
245
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
246
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
247
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
248
        $this->createHydrator()->hydrate($object, $data);
249
    }
250
251
    /**
252
     * @group integer
253
     * @dataProvider notIntegerDataProvider
254
     */
255
    public function testHydrateIntegerPropertyWithInvalidValue(array $data): void
256
    {
257
        $object = new class {
258
            public int $value;
259
        };
260
261
        $this->assertInvalidValueExceptionCount(1);
262
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type integer.');
263
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_INTEGER);
264
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
265
        $this->createHydrator()->hydrate($object, $data);
266
    }
267
268
    /**
269
     * @group integer
270
     */
271
    public function testHydrateIntegerPropertyWithoutValue(): void
272
    {
273
        $object = new class {
274
            public int $value;
275
        };
276
277
        $this->assertInvalidValueExceptionCount(1);
278
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
279
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
280
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
281
        $this->createHydrator()->hydrate($object, []);
282
    }
283
284
    /**
285
     * @group number
286
     * @dataProvider strictNumberDataProvider
287
     * @dataProvider nonStrictNumberDataProvider
288
     */
289
    public function testHydrateNumericProperty(array $data, float $expected): void
290
    {
291
        $object = new class {
292
            public float $value;
293
        };
294
295
        $this->assertInvalidValueExceptionCount(0);
296
        $this->createHydrator()->hydrate($object, $data);
297
        $this->assertSame($expected, $object->value);
298
    }
299
300
    /**
301
     * @group number
302
     * @dataProvider strictNumberDataProvider
303
     * @dataProvider nonStrictNumberDataProvider
304
     * @dataProvider strictNullDataProvider
305
     * @dataProvider nonStrictNullDataProvider
306
     */
307
    public function testHydrateNullableNumericProperty(array $data, ?float $expected): void
308
    {
309
        $object = new class {
310
            public ?float $value;
311
        };
312
313
        $this->assertInvalidValueExceptionCount(0);
314
        $this->createHydrator()->hydrate($object, $data);
315
        $this->assertSame($expected, $object->value);
316
    }
317
318
    /**
319
     * @group number
320
     * @dataProvider strictNumberDataProvider
321
     * @dataProvider nonStrictNumberDataProvider
322
     * @dataProvider emptyDataProvider
323
     */
324
    public function testHydrateOptionalNumericProperty(array $data, float $expected = 3.14159): void
325
    {
326
        $object = new class {
327
            public float $value = 3.14159;
328
        };
329
330
        $this->assertInvalidValueExceptionCount(0);
331
        $this->createHydrator()->hydrate($object, $data);
332
        $this->assertSame($expected, $object->value);
333
    }
334
335
    /**
336
     * @group number
337
     * @dataProvider strictNullDataProvider
338
     * @dataProvider nonStrictNullDataProvider
339
     */
340
    public function testHydrateNumericPropertyWithEmptyValue(array $data): void
341
    {
342
        $object = new class {
343
            public float $value;
344
        };
345
346
        $this->assertInvalidValueExceptionCount(1);
347
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
348
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
349
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
350
        $this->createHydrator()->hydrate($object, $data);
351
    }
352
353
    /**
354
     * @group number
355
     * @dataProvider notNumberDataProvider
356
     */
357
    public function testHydrateNumericPropertyWithInvalidValue(array $data): void
358
    {
359
        $object = new class {
360
            public float $value;
361
        };
362
363
        $this->assertInvalidValueExceptionCount(1);
364
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type number.');
365
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_NUMBER);
366
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
367
        $this->createHydrator()->hydrate($object, $data);
368
    }
369
370
    /**
371
     * @group number
372
     */
373
    public function testHydrateNumericPropertyWithoutValue(): void
374
    {
375
        $object = new class {
376
            public float $value;
377
        };
378
379
        $this->assertInvalidValueExceptionCount(1);
380
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
381
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
382
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
383
        $this->createHydrator()->hydrate($object, []);
384
    }
385
386
    /**
387
     * @group string
388
     * @dataProvider nonStrictStringDataProvider
389
     */
390
    public function testHydrateStringProperty(array $data, string $expected): void
391
    {
392
        $object = new class {
393
            public string $value;
394
        };
395
396
        $this->assertInvalidValueExceptionCount(0);
397
        $this->createHydrator()->hydrate($object, $data);
398
        $this->assertSame($expected, $object->value);
399
    }
400
401
    /**
402
     * @group string
403
     * @dataProvider nonStrictStringDataProvider
404
     * @dataProvider strictNullDataProvider
405
     */
406
    public function testHydrateNullableStringProperty(array $data, ?string $expected): void
407
    {
408
        $object = new class {
409
            public ?string $value;
410
        };
411
412
        $this->assertInvalidValueExceptionCount(0);
413
        $this->createHydrator()->hydrate($object, $data);
414
        $this->assertSame($expected, $object->value);
415
    }
416
417
    /**
418
     * @group string
419
     * @dataProvider nonStrictStringDataProvider
420
     * @dataProvider emptyDataProvider
421
     */
422
    public function testHydrateOptionalStringProperty(array $data, string $expected = 'default'): void
423
    {
424
        $object = new class {
425
            public string $value = 'default';
426
        };
427
428
        $this->assertInvalidValueExceptionCount(0);
429
        $this->createHydrator()->hydrate($object, $data);
430
        $this->assertSame($expected, $object->value);
431
    }
432
433
    /**
434
     * @group string
435
     * @dataProvider strictNullDataProvider
436
     */
437
    public function testHydrateStringPropertyWithNull(array $data): void
438
    {
439
        $object = new class {
440
            public string $value;
441
        };
442
443
        $this->assertInvalidValueExceptionCount(1);
444
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
445
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
446
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
447
        $this->createHydrator()->hydrate($object, $data);
448
    }
449
450
    /**
451
     * @group string
452
     * @dataProvider nonStrictNotStringDataProvider
453
     */
454
    public function testHydrateStringPropertyWithInvalidValue(array $data): void
455
    {
456
        $object = new class {
457
            public string $value;
458
        };
459
460
        $this->assertInvalidValueExceptionCount(1);
461
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type string.');
462
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_STRING);
463
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
464
        $this->createHydrator()->hydrate($object, $data);
465
    }
466
467
    /**
468
     * @group string
469
     */
470
    public function testHydrateStringPropertyWithoutValue(): void
471
    {
472
        $object = new class {
473
            public string $value;
474
        };
475
476
        $this->assertInvalidValueExceptionCount(1);
477
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
478
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
479
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
480
        $this->createHydrator()->hydrate($object, []);
481
    }
482
483
    /**
484
     * @group array
485
     * @dataProvider arrayDataProvider
486
     */
487
    public function testHydrateArrayProperty(array $data, array $expected): void
488
    {
489
        $object = new class {
490
            public array $value;
491
        };
492
493
        $this->assertInvalidValueExceptionCount(0);
494
        $this->createHydrator()->hydrate($object, $data);
495
        $this->assertSame($expected, $object->value);
496
    }
497
498
    /**
499
     * @group array
500
     * @dataProvider arrayDataProvider
501
     * @dataProvider strictNullDataProvider
502
     */
503
    public function testHydrateNullableArrayProperty(array $data, ?array $expected): void
504
    {
505
        $object = new class {
506
            public ?array $value;
507
        };
508
509
        $this->assertInvalidValueExceptionCount(0);
510
        $this->createHydrator()->hydrate($object, $data);
511
        $this->assertSame($expected, $object->value);
512
    }
513
514
    /**
515
     * @group array
516
     * @dataProvider arrayDataProvider
517
     * @dataProvider emptyDataProvider
518
     */
519
    public function testHydrateOptionalArrayProperty(array $data, array $expected = []): void
520
    {
521
        $object = new class {
522
            public array $value = [];
523
        };
524
525
        $this->assertInvalidValueExceptionCount(0);
526
        $this->createHydrator()->hydrate($object, $data);
527
        $this->assertSame($expected, $object->value);
528
    }
529
530
    /**
531
     * @group array
532
     * @dataProvider strictNullDataProvider
533
     */
534
    public function testHydrateArrayPropertyWithNull(array $data): void
535
    {
536
        $object = new class {
537
            public array $value;
538
        };
539
540
        $this->assertInvalidValueExceptionCount(1);
541
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
542
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
543
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
544
        $this->createHydrator()->hydrate($object, $data);
545
    }
546
547
    /**
548
     * @group array
549
     * @dataProvider notArrayDataProvider
550
     */
551
    public function testHydrateArrayPropertyWithInvalidValue(array $data): void
552
    {
553
        $object = new class {
554
            public array $value;
555
        };
556
557
        $this->assertInvalidValueExceptionCount(1);
558
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type array.');
559
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_ARRAY);
560
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
561
        $this->createHydrator()->hydrate($object, $data);
562
    }
563
564
    /**
565
     * @group array
566
     */
567
    public function testHydrateArrayPropertyWithoutValue(): void
568
    {
569
        $object = new class {
570
            public array $value;
571
        };
572
573
        $this->assertInvalidValueExceptionCount(1);
574
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
575
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
576
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
577
        $this->createHydrator()->hydrate($object, []);
578
    }
579
580
    /**
581
     * @group array
582
     */
583
    public function testHydrateTypedArrayProperty(): void
584
    {
585
        $object = new class {
586
            /** @Subtype("string") */
587
            #[Subtype('string')]
588
            public array $value;
589
        };
590
591
        $this->assertInvalidValueExceptionCount(1);
592
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type string.');
593
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_STRING);
594
        $this->assertInvalidValueExceptionPropertyPath(0, 'value.0');
595
        $this->createHydrator()->hydrate($object, ['value' => [[]]]);
596
    }
597
598
    /**
599
     * @group array
600
     */
601
    public function testHydrateLimitedArrayProperty(): void
602
    {
603
        $object = new class {
604
            /** @Subtype("string", 1) */
605
            #[Subtype('string', 1)]
606
            public array $value;
607
        };
608
609
        $this->assertInvalidValueExceptionCount(1);
610
        $this->assertInvalidValueExceptionMessage(0, 'This value is limited to 1 elements.');
611
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::ARRAY_OVERFLOW);
612
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
613
        $this->createHydrator()->hydrate($object, ['value' => ['foo', 'bar']]);
614
    }
615
616
    /**
617
     * @group array-access
618
     * @dataProvider arrayDataProvider
619
     */
620
    public function testHydrateArrayAccessProperty(array $data, array $expected): void
621
    {
622
        $object = new class {
623
            public Stub\Collection $value;
624
        };
625
626
        $this->assertInvalidValueExceptionCount(0);
627
        $this->createHydrator()->hydrate($object, $data);
628
        $this->assertSame($expected, $object->value->elements);
629
    }
630
631
    /**
632
     * @group array-access
633
     * @dataProvider arrayDataProvider
634
     * @dataProvider strictNullDataProvider
635
     */
636
    public function testHydrateNullableArrayAccessProperty(array $data, ?array $expected): void
637
    {
638
        $object = new class {
639
            public ?Stub\Collection $value;
640
        };
641
642
        $this->assertInvalidValueExceptionCount(0);
643
        $this->createHydrator()->hydrate($object, $data);
644
        $this->assertSame($expected, $object->value->elements ?? null);
645
    }
646
647
    /**
648
     * @group array-access
649
     * @dataProvider arrayDataProvider
650
     * @dataProvider emptyDataProvider
651
     */
652
    public function testHydrateOptionalArrayAccessProperty(array $data, array $expected = []): void
653
    {
654
        $object = new class {
655
            public ?Stub\Collection $value = null;
656
        };
657
658
        $this->assertInvalidValueExceptionCount(0);
659
        $this->createHydrator()->hydrate($object, $data);
660
        $this->assertSame($expected, $object->value->elements ?? []);
661
    }
662
663
    /**
664
     * @group array-access
665
     * @dataProvider strictNullDataProvider
666
     */
667
    public function testHydrateArrayAccessPropertyWithNull(array $data): void
668
    {
669
        $object = new class {
670
            public Stub\Collection $value;
671
        };
672
673
        $this->assertInvalidValueExceptionCount(1);
674
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
675
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
676
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
677
        $this->createHydrator()->hydrate($object, $data);
678
    }
679
680
    /**
681
     * @group array-access
682
     * @dataProvider notArrayDataProvider
683
     */
684
    public function testHydrateArrayAccessPropertyWithInvalidValue(array $data): void
685
    {
686
        $object = new class {
687
            public Stub\Collection $value;
688
        };
689
690
        $this->assertInvalidValueExceptionCount(1);
691
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type array.');
692
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_ARRAY);
693
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
694
        $this->createHydrator()->hydrate($object, $data);
695
    }
696
697
    /**
698
     * @group array-access
699
     */
700
    public function testHydrateArrayAccessPropertyWithoutValue(): void
701
    {
702
        $object = new class {
703
            public Stub\Collection $value;
704
        };
705
706
        $this->assertInvalidValueExceptionCount(1);
707
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
708
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
709
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
710
        $this->createHydrator()->hydrate($object, []);
711
    }
712
713
    /**
714
     * @group array-access
715
     */
716
    public function testHydrateTypedArrayAccessProperty(): void
717
    {
718
        $object = new class {
719
            /** @Subtype("string") */
720
            #[Subtype('string')]
721
            public Collection $value;
722
        };
723
724
        $this->assertInvalidValueExceptionCount(1);
725
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type string.');
726
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_STRING);
727
        $this->assertInvalidValueExceptionPropertyPath(0, 'value.0');
728
        $this->createHydrator()->hydrate($object, ['value' => [[]]]);
729
    }
730
731
    /**
732
     * @group array-access
733
     */
734
    public function testHydrateLimitedArrayAccessProperty(): void
735
    {
736
        $object = new class {
737
            /** @Subtype("string", 1) */
738
            #[Subtype('string', 1)]
739
            public Collection $value;
740
        };
741
742
        $this->assertInvalidValueExceptionCount(1);
743
        $this->assertInvalidValueExceptionMessage(0, 'This value is limited to 1 elements.');
744
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::ARRAY_OVERFLOW);
745
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
746
        $this->createHydrator()->hydrate($object, ['value' => ['foo', 'bar']]);
747
    }
748
749
    /**
750
     * @group array-access
751
     */
752
    public function testHydrateOverflowedArrayAccessProperty(): void
753
    {
754
        $object = new class {
755
            public OverflowedCollection $value;
756
        };
757
758
        $this->assertInvalidValueExceptionCount(1);
759
        $this->assertInvalidValueExceptionMessage(0, 'This value is limited to 0 elements.');
760
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::ARRAY_OVERFLOW);
761
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
762
        $this->createHydrator()->hydrate($object, ['value' => ['foo']]);
763
    }
764
765
    /**
766
     * @group array-access
767
     */
768
    public function testHydrateUnstantiableArrayAccessProperty(): void
769
    {
770
        $object = new class {
771
            public UnstantiableCollection $value;
772
        };
773
774
        $this->expectException(InvalidObjectException::class);
775
        $this->createHydrator()->hydrate($object, ['value' => []]);
776
    }
777
778
    /**
779
     * @group timestamp
780
     * @dataProvider timestampDataProvider
781
     */
782
    public function testHydrateTimestampProperty(array $data, string $expected, ?string $format): void
783
    {
784
        $object = new class {
785
            public DateTimeImmutable $value;
786
        };
787
788
        $this->assertInvalidValueExceptionCount(0);
789
        $this->createHydrator([ContextKey::TIMESTAMP_FORMAT => $format])->hydrate($object, $data);
790
        $this->assertSame($expected, $object->value->format($format ?? TimestampTypeConverter::DEFAULT_FORMAT));
791
    }
792
793
    /**
794
     * @group timestamp
795
     * @dataProvider timestampDataProvider
796
     * @dataProvider strictNullDataProvider
797
     * @dataProvider nonStrictNullDataProvider
798
     */
799
    // phpcs:ignore Generic.Files.LineLength
800
    public function testHydrateNullableTimestampProperty(array $data, ?string $expected = null, ?string $format = null): void
801
    {
802
        $object = new class {
803
            public ?DateTimeImmutable $value;
804
        };
805
806
        $this->assertInvalidValueExceptionCount(0);
807
        $this->createHydrator([ContextKey::TIMESTAMP_FORMAT => $format])->hydrate($object, $data);
808
        // phpcs:ignore Generic.Files.LineLength
809
        $this->assertSame($expected, isset($object->value) ? $object->value->format($format ?? TimestampTypeConverter::DEFAULT_FORMAT) : null);
0 ignored issues
show
Bug introduced by
The method format() does not exist on null. ( Ignorable by Annotation )

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

809
        $this->assertSame($expected, isset($object->value) ? $object->value->/** @scrutinizer ignore-call */ format($format ?? TimestampTypeConverter::DEFAULT_FORMAT) : null);

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...
810
    }
811
812
    /**
813
     * @group timestamp
814
     * @dataProvider timestampDataProvider
815
     * @dataProvider emptyDataProvider
816
     */
817
    // phpcs:ignore Generic.Files.LineLength
818
    public function testHydrateOptionalTimestampProperty(array $data, ?string $expected = null, ?string $format = null): void
819
    {
820
        $object = new class {
821
            public ?DateTimeImmutable $value = null;
822
        };
823
824
        $this->assertInvalidValueExceptionCount(0);
825
        $this->createHydrator([ContextKey::TIMESTAMP_FORMAT => $format])->hydrate($object, $data);
826
        // phpcs:ignore Generic.Files.LineLength
827
        $this->assertSame($expected, isset($object->value) ? $object->value->format($format ?? TimestampTypeConverter::DEFAULT_FORMAT) : null);
828
    }
829
830
    /**
831
     * @group timestamp
832
     * @dataProvider strictNullDataProvider
833
     * @dataProvider nonStrictNullDataProvider
834
     */
835
    public function testHydrateTimestampPropertyWithEmptyValue(array $data): void
836
    {
837
        $object = new class {
838
            public DateTimeImmutable $value;
839
        };
840
841
        $this->assertInvalidValueExceptionCount(1);
842
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
843
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
844
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
845
        $this->createHydrator()->hydrate($object, $data);
846
    }
847
848
    // @todo should be improved...
849
850
    /**
851
     * @group datetimeTimestamp
852
     * @dataProvider nonStrictNotStringDataProvider
853
     */
854
    public function testHydrateTimestampPropertyWithNotString(array $data): void
855
    {
856
        $this->assertInvalidValueExceptionCount(1);
857
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type string.');
858
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_STRING);
859
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
860
        $this->createHydrator()->hydrate(ObjectWithTimestamp::class, $data);
861
    }
862
863
    /**
864
     * @group datetimeTimestamp
865
     * @dataProvider invalidTimestampDataProvider
866
     */
867
    public function testHydrateTimestampPropertyWithInvalidTimestamp(array $data): void
868
    {
869
        $this->assertInvalidValueExceptionCount(1);
870
        $this->assertInvalidValueExceptionMessage(0, 'This value is not a valid timestamp.');
871
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::INVALID_TIMESTAMP);
872
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
873
        $this->createHydrator()->hydrate(ObjectWithTimestamp::class, $data);
874
    }
875
876
    /**
877
     * @group datetimeTimestamp
878
     */
879
    public function testHydrateRequiredTimestampPropertyWithoutValue(): void
880
    {
881
        $this->assertInvalidValueExceptionCount(1);
882
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
883
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
884
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
885
        $this->createHydrator()->hydrate(ObjectWithTimestamp::class, []);
886
    }
887
888
    /**
889
     * @group unixTimestamp
890
     * @dataProvider strictUnixTimeStampDataProvider
891
     * @dataProvider nonStrictUnixTimeStampDataProvider
892
     */
893
    public function testHydrateUnixTimeStampProperty(array $data, string $expected, string $format): void
894
    {
895
        $this->assertInvalidValueExceptionCount(0);
896
        $object = $this->createHydrator()->hydrate(ObjectWithUnixTimeStamp::class, $data);
897
        $this->assertSame($expected, $object->value->format($format));
898
    }
899
900
    /**
901
     * @group unixTimestamp
902
     * @dataProvider strictUnixTimeStampDataProvider
903
     * @dataProvider nonStrictUnixTimeStampDataProvider
904
     * @dataProvider strictNullDataProvider
905
     * @dataProvider nonStrictNullDataProvider
906
     */
907
    // phpcs:ignore Generic.Files.LineLength
908
    public function testHydrateNullableUnixTimeStampProperty(array $data, ?string $expected = null, ?string $format = null): void
909
    {
910
        $this->assertInvalidValueExceptionCount(0);
911
        $object = $this->createHydrator()->hydrate(ObjectWithNullableUnixTimeStamp::class, $data);
912
        $this->assertSame($expected, isset($object->value, $format) ? $object->value->format($format) : null);
913
    }
914
915
    /**
916
     * @group unixTimestamp
917
     * @dataProvider strictUnixTimeStampDataProvider
918
     * @dataProvider nonStrictUnixTimeStampDataProvider
919
     * @dataProvider emptyDataProvider
920
     */
921
    // phpcs:ignore Generic.Files.LineLength
922
    public function testHydrateOptionalUnixTimeStampProperty(array $data, ?string $expected = null, ?string $format = null): void
923
    {
924
        $this->assertInvalidValueExceptionCount(0);
925
        $object = $this->createHydrator()->hydrate(ObjectWithOptionalUnixTimeStamp::class, $data);
926
        $this->assertSame($expected, isset($object->value, $format) ? $object->value->format($format) : null);
927
    }
928
929
    /**
930
     * @group unixTimestamp
931
     * @dataProvider strictNullDataProvider
932
     * @dataProvider nonStrictNullDataProvider
933
     */
934
    public function testHydrateNonNullableUnixTimeStampPropertyWithNull(array $data): void
935
    {
936
        $this->assertInvalidValueExceptionCount(1);
937
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
938
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
939
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
940
        $this->createHydrator()->hydrate(ObjectWithUnixTimeStamp::class, $data);
941
    }
942
943
    /**
944
     * @group unixTimestamp
945
     * @dataProvider notIntegerDataProvider
946
     */
947
    public function testHydrateUnixTimeStampPropertyWithNotInteger(array $data): void
948
    {
949
        $this->assertInvalidValueExceptionCount(1);
950
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type integer.');
951
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_INTEGER);
952
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
953
        $this->createHydrator()->hydrate(ObjectWithUnixTimeStamp::class, $data);
954
    }
955
956
    /**
957
     * @group unixTimestamp
958
     */
959
    public function testHydrateRequiredUnixTimeStampPropertyWithoutValue(): void
960
    {
961
        $this->assertInvalidValueExceptionCount(1);
962
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
963
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
964
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
965
        $this->createHydrator()->hydrate(ObjectWithUnixTimeStamp::class, []);
966
    }
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
    /**
1018
     * @group timezone
1019
     * @dataProvider timezoneDataProvider
1020
     */
1021
    public function testHydrateTimezoneProperty(array $data, string $expected): void
1022
    {
1023
        $this->assertInvalidValueExceptionCount(0);
1024
        $object = $this->createHydrator()->hydrate(ObjectWithTimezone::class, $data);
1025
        $this->assertSame($expected, $object->value->getName());
1026
    }
1027
1028
    /**
1029
     * @group timezone
1030
     * @dataProvider timezoneDataProvider
1031
     * @dataProvider strictNullDataProvider
1032
     * @dataProvider nonStrictNullDataProvider
1033
     */
1034
    public function testHydrateNullableTimezoneProperty(array $data, ?string $expected = null): void
1035
    {
1036
        $this->assertInvalidValueExceptionCount(0);
1037
        $object = $this->createHydrator()->hydrate(ObjectWithNullableTimezone::class, $data);
1038
        $this->assertSame($expected, isset($object->value) ? $object->value->getName() : null);
1039
    }
1040
1041
    /**
1042
     * @group timezone
1043
     * @dataProvider timezoneDataProvider
1044
     * @dataProvider emptyDataProvider
1045
     */
1046
    public function testHydrateOptionalTimezoneProperty(array $data, ?string $expected = null): void
1047
    {
1048
        $this->assertInvalidValueExceptionCount(0);
1049
        $object = $this->createHydrator()->hydrate(ObjectWithOptionalTimezone::class, $data);
1050
        $this->assertSame($expected, isset($object->value) ? $object->value->getName() : null);
1051
    }
1052
1053
    /**
1054
     * @group timezone
1055
     * @dataProvider strictNullDataProvider
1056
     * @dataProvider nonStrictNullDataProvider
1057
     */
1058
    public function testHydrateNonNullableTimezonePropertyWithNull(array $data): void
1059
    {
1060
        $this->assertInvalidValueExceptionCount(1);
1061
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
1062
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
1063
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1064
        $this->createHydrator()->hydrate(ObjectWithTimezone::class, $data);
1065
    }
1066
1067
    /**
1068
     * @group timezone
1069
     * @dataProvider nonStrictNotStringDataProvider
1070
     */
1071
    public function testHydrateTimezonePropertyWithNotString(array $data): void
1072
    {
1073
        $this->assertInvalidValueExceptionCount(1);
1074
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type string.');
1075
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_STRING);
1076
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1077
        $this->createHydrator()->hydrate(ObjectWithTimezone::class, $data);
1078
    }
1079
1080
    /**
1081
     * @group timezone
1082
     * @dataProvider invalidTimezoneDataProvider
1083
     */
1084
    public function testHydrateTimezonePropertyWithInvalidTimezone(array $data): void
1085
    {
1086
        $this->assertInvalidValueExceptionCount(1);
1087
        $this->assertInvalidValueExceptionMessage(0, 'This value is not a valid timezone.');
1088
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::INVALID_TIMEZONE);
1089
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1090
        $this->createHydrator()->hydrate(ObjectWithTimezone::class, $data);
1091
    }
1092
1093
    /**
1094
     * @group timezone
1095
     */
1096
    public function testHydrateRequiredTimezonePropertyWithoutValue(): void
1097
    {
1098
        $this->assertInvalidValueExceptionCount(1);
1099
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
1100
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
1101
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1102
        $this->createHydrator()->hydrate(ObjectWithTimezone::class, []);
1103
    }
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
    /**
1133
     * @group uid
1134
     * @dataProvider uidDataProvider
1135
     */
1136
    public function testHydrateUidProperty(array $data, string $expected): void
1137
    {
1138
        $this->assertInvalidValueExceptionCount(0);
1139
        $object = $this->createHydrator()->hydrate(ObjectWithUid::class, $data);
1140
        $this->assertSame($expected, $object->value->toRfc4122());
1141
    }
1142
1143
    /**
1144
     * @group uid
1145
     * @dataProvider uidDataProvider
1146
     * @dataProvider strictNullDataProvider
1147
     * @dataProvider nonStrictNullDataProvider
1148
     */
1149
    public function testHydrateNullableUidProperty(array $data, ?string $expected = null): void
1150
    {
1151
        $this->assertInvalidValueExceptionCount(0);
1152
        $object = $this->createHydrator()->hydrate(ObjectWithNullableUid::class, $data);
1153
        $this->assertSame($expected, isset($object->value) ? $object->value->toRfc4122() : null);
1154
    }
1155
1156
    /**
1157
     * @group uid
1158
     * @dataProvider uidDataProvider
1159
     * @dataProvider emptyDataProvider
1160
     */
1161
    public function testHydrateOptionalUidProperty(array $data, ?string $expected = null): void
1162
    {
1163
        $this->assertInvalidValueExceptionCount(0);
1164
        $object = $this->createHydrator()->hydrate(ObjectWithOptionalUid::class, $data);
1165
        $this->assertSame($expected, isset($object->value) ? $object->value->toRfc4122() : null);
1166
    }
1167
1168
    /**
1169
     * @group uid
1170
     * @dataProvider strictNullDataProvider
1171
     * @dataProvider nonStrictNullDataProvider
1172
     */
1173
    public function testHydrateNonNullableUidPropertyWithNull(array $data): void
1174
    {
1175
        $this->assertInvalidValueExceptionCount(1);
1176
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
1177
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
1178
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1179
        $this->createHydrator()->hydrate(ObjectWithUid::class, $data);
1180
    }
1181
1182
    /**
1183
     * @group uid
1184
     * @dataProvider nonStrictNotStringDataProvider
1185
     */
1186
    public function testHydrateUidPropertyWithNotString(array $data): void
1187
    {
1188
        $this->assertInvalidValueExceptionCount(1);
1189
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type string.');
1190
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_STRING);
1191
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1192
        $this->createHydrator()->hydrate(ObjectWithUid::class, $data);
1193
    }
1194
1195
    /**
1196
     * @group uid
1197
     * @dataProvider invalidUidDataProvider
1198
     */
1199
    public function testHydrateUidPropertyWithInvalidUid(array $data): void
1200
    {
1201
        $this->assertInvalidValueExceptionCount(1);
1202
        $this->assertInvalidValueExceptionMessage(0, 'This value is not a valid UID.');
1203
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::INVALID_UID);
1204
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1205
        $this->createHydrator()->hydrate(ObjectWithUid::class, $data);
1206
    }
1207
1208
    /**
1209
     * @group uid
1210
     */
1211
    public function testHydrateRequiredUidPropertyWithoutValue(): void
1212
    {
1213
        $this->assertInvalidValueExceptionCount(1);
1214
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
1215
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
1216
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1217
        $this->createHydrator()->hydrate(ObjectWithUid::class, []);
1218
    }
1219
1220
    /**
1221
     * @group integerEnumeration
1222
     * @dataProvider strictIntegerEnumerationDataProvider
1223
     * @dataProvider nonStrictIntegerEnumerationDataProvider
1224
     * @param IntegerEnum $expected
1225
     */
1226
    public function testHydrateIntegerEnumerationProperty(array $data, $expected): void
1227
    {
1228
        $this->phpRequired('8.1');
1229
        $this->assertInvalidValueExceptionCount(0);
1230
        $object = $this->createHydrator()->hydrate(ObjectWithIntegerEnum::class, $data);
1231
        $this->assertSame($expected, $object->value);
1232
    }
1233
1234
    /**
1235
     * @group integerEnumeration
1236
     * @dataProvider strictIntegerEnumerationDataProvider
1237
     * @dataProvider nonStrictIntegerEnumerationDataProvider
1238
     * @dataProvider strictNullDataProvider
1239
     * @dataProvider nonStrictNullDataProvider
1240
     * @param IntegerEnum|null $expected
1241
     */
1242
    public function testHydrateNullableIntegerEnumerationProperty(array $data, $expected): void
1243
    {
1244
        $this->phpRequired('8.1');
1245
        $this->assertInvalidValueExceptionCount(0);
1246
        $object = $this->createHydrator()->hydrate(ObjectWithNullableIntegerEnum::class, $data);
1247
        $this->assertSame($expected, $object->value);
1248
    }
1249
1250
    /**
1251
     * @group integerEnumeration
1252
     * @dataProvider strictIntegerEnumerationDataProvider
1253
     * @dataProvider nonStrictIntegerEnumerationDataProvider
1254
     * @dataProvider emptyDataProvider
1255
     * @param IntegerEnum|null $expected
1256
     */
1257
    // phpcs:ignore Generic.Files.LineLength
1258
    public function testHydrateOptionalIntegerEnumerationProperty(array $data, $expected = null): void
1259
    {
1260
        $this->phpRequired('8.1');
1261
        $this->assertInvalidValueExceptionCount(0);
1262
        $object = $this->createHydrator()->hydrate(ObjectWithOptionalIntegerEnum::class, $data);
1263
        $this->assertSame($expected ?? IntegerEnum::FOO, $object->value);
1264
    }
1265
1266
    /**
1267
     * @group integerEnumeration
1268
     * @dataProvider strictNullDataProvider
1269
     * @dataProvider nonStrictNullDataProvider
1270
     */
1271
    public function testHydrateNonNullableIntegerEnumerationPropertyWithNull(array $data): void
1272
    {
1273
        $this->phpRequired('8.1');
1274
        $this->assertInvalidValueExceptionCount(1);
1275
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
1276
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
1277
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1278
        $this->createHydrator()->hydrate(ObjectWithIntegerEnum::class, $data);
1279
    }
1280
1281
    /**
1282
     * @group integerEnumeration
1283
     * @dataProvider notIntegerDataProvider
1284
     */
1285
    public function testHydrateIntegerEnumerationPropertyWithNotInteger(array $data): void
1286
    {
1287
        $this->phpRequired('8.1');
1288
        $this->assertInvalidValueExceptionCount(1);
1289
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type integer.');
1290
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_INTEGER);
1291
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1292
        $this->createHydrator()->hydrate(ObjectWithIntegerEnum::class, $data);
1293
    }
1294
1295
    /**
1296
     * @group integerEnumeration
1297
     */
1298
    public function testHydrateRequiredIntegerEnumerationPropertyWithoutValue(): void
1299
    {
1300
        $this->assertInvalidValueExceptionCount(1);
1301
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
1302
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
1303
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1304
        $this->createHydrator()->hydrate(ObjectWithIntegerEnum::class, []);
1305
    }
1306
1307
    /**
1308
     * @group stringEnumeration
1309
     */
1310
    public function testHydrateIntegerEnumerationPropertyWithInvalidChoice(): void
1311
    {
1312
        $this->phpRequired('8.1');
1313
        $this->assertInvalidValueExceptionCount(1);
1314
        // phpcs:ignore Generic.Files.LineLength
1315
        $this->assertInvalidValueExceptionMessage(0, 'This value is not a valid choice.');
1316
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::INVALID_CHOICE);
1317
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1318
        $this->createHydrator()->hydrate(ObjectWithIntegerEnum::class, ['value' => 42]);
1319
    }
1320
1321
    /**
1322
     * @group stringEnumeration
1323
     * @dataProvider stringEnumerationDataProvider
1324
     * @param StringEnum $expected
1325
     */
1326
    public function testHydrateStringEnumerationProperty(array $data, $expected): void
1327
    {
1328
        $this->phpRequired('8.1');
1329
        $this->assertInvalidValueExceptionCount(0);
1330
        $object = $this->createHydrator()->hydrate(ObjectWithStringEnum::class, $data);
1331
        $this->assertSame($expected, $object->value);
1332
    }
1333
1334
    /**
1335
     * @group stringEnumeration
1336
     * @dataProvider stringEnumerationDataProvider
1337
     * @dataProvider strictNullDataProvider
1338
     * @dataProvider nonStrictNullDataProvider
1339
     * @param StringEnum|null $expected
1340
     */
1341
    public function testHydrateNullableStringEnumerationProperty(array $data, $expected): void
1342
    {
1343
        $this->phpRequired('8.1');
1344
        $this->assertInvalidValueExceptionCount(0);
1345
        $object = $this->createHydrator()->hydrate(ObjectWithNullableStringEnum::class, $data);
1346
        $this->assertSame($expected, $object->value);
1347
    }
1348
1349
    /**
1350
     * @group stringEnumeration
1351
     * @dataProvider stringEnumerationDataProvider
1352
     * @dataProvider emptyDataProvider
1353
     * @param StringEnum|null $expected
1354
     */
1355
    // phpcs:ignore Generic.Files.LineLength
1356
    public function testHydrateOptionalStringEnumerationProperty(array $data, $expected = null): void
1357
    {
1358
        $this->phpRequired('8.1');
1359
        $this->assertInvalidValueExceptionCount(0);
1360
        $object = $this->createHydrator()->hydrate(ObjectWithOptionalStringEnum::class, $data);
1361
        $this->assertSame($expected ?? StringEnum::FOO, $object->value);
1362
    }
1363
1364
    /**
1365
     * @group stringEnumeration
1366
     * @dataProvider strictNullDataProvider
1367
     * @dataProvider nonStrictNullDataProvider
1368
     */
1369
    public function testHydrateNonNullableStringEnumerationPropertyWithNull(array $data): void
1370
    {
1371
        $this->phpRequired('8.1');
1372
        $this->assertInvalidValueExceptionCount(1);
1373
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
1374
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
1375
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1376
        $this->createHydrator()->hydrate(ObjectWithStringEnum::class, $data);
1377
    }
1378
1379
    /**
1380
     * @group stringEnumeration
1381
     * @dataProvider nonStrictNotStringDataProvider
1382
     */
1383
    public function testHydrateStringEnumerationPropertyWithNotInteger(array $data): void
1384
    {
1385
        $this->phpRequired('8.1');
1386
        $this->assertInvalidValueExceptionCount(1);
1387
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type string.');
1388
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_STRING);
1389
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1390
        $this->createHydrator()->hydrate(ObjectWithStringEnum::class, $data);
1391
    }
1392
1393
    /**
1394
     * @group stringEnumeration
1395
     */
1396
    public function testHydrateStringEnumerationPropertyWithInvalidChoice(): void
1397
    {
1398
        $this->phpRequired('8.1');
1399
        $this->assertInvalidValueExceptionCount(1);
1400
        // phpcs:ignore Generic.Files.LineLength
1401
        $this->assertInvalidValueExceptionMessage(0, 'This value is not a valid choice.');
1402
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::INVALID_CHOICE);
1403
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1404
        $this->createHydrator()->hydrate(ObjectWithStringEnum::class, ['value' => 'unknown']);
1405
    }
1406
1407
    /**
1408
     * @group stringEnumeration
1409
     */
1410
    public function testHydrateRequiredStringEnumerationPropertyWithoutValue(): void
1411
    {
1412
        $this->assertInvalidValueExceptionCount(1);
1413
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
1414
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
1415
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1416
        $this->createHydrator()->hydrate(ObjectWithStringEnum::class, []);
1417
    }
1418
1419
    /**
1420
     * @group relationship
1421
     * @dataProvider nonStrictStringDataProvider
1422
     */
1423
    public function testHydrateRelationshipProperty(array $data, string $expected): void
1424
    {
1425
        $this->assertInvalidValueExceptionCount(0);
1426
        $object = $this->createHydrator()->hydrate(ObjectWithRelationship::class, ['value' => $data]);
1427
        $this->assertSame($expected, $object->value->value);
1428
    }
1429
1430
    /**
1431
     * @group relationship
1432
     * @dataProvider strictNullDataProvider
1433
     */
1434
    public function testHydrateNullableRelationshipProperty(array $data): void
1435
    {
1436
        $this->assertInvalidValueExceptionCount(0);
1437
        $object = $this->createHydrator()->hydrate(ObjectWithNullableRelationship::class, $data);
1438
        $this->assertNull($object->value);
1439
    }
1440
1441
    /**
1442
     * @group relationship
1443
     * @dataProvider emptyDataProvider
1444
     */
1445
    public function testHydrateOptionalRelationshipProperty(array $data): void
1446
    {
1447
        $this->assertInvalidValueExceptionCount(0);
1448
        $object = $this->createHydrator()->hydrate(ObjectWithOptionalRelationship::class, $data);
1449
        $this->assertNull($object->value);
1450
    }
1451
1452
    /**
1453
     * @group relationship
1454
     * @dataProvider strictNullDataProvider
1455
     */
1456
    public function testHydrateNonNullableRelationshipPropertyWithNull(array $data): void
1457
    {
1458
        $this->assertInvalidValueExceptionCount(1);
1459
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
1460
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
1461
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1462
        $this->createHydrator()->hydrate(ObjectWithRelationship::class, $data);
1463
    }
1464
1465
    /**
1466
     * @group relationship
1467
     * @dataProvider notArrayDataProvider
1468
     */
1469
    public function testHydrateRelationshipPropertyWithNotArray(array $data): void
1470
    {
1471
        $this->assertInvalidValueExceptionCount(1);
1472
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type array.');
1473
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_ARRAY);
1474
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1475
        $this->createHydrator()->hydrate(ObjectWithRelationship::class, $data);
1476
    }
1477
1478
    /**
1479
     * @group relationship
1480
     */
1481
    public function testHydrateRequiredRelationshipPropertyWithoutValue(): void
1482
    {
1483
        $this->assertInvalidValueExceptionCount(1);
1484
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
1485
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
1486
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1487
        $this->createHydrator()->hydrate(ObjectWithRelationship::class, []);
1488
    }
1489
1490
    /**
1491
     * @group relationship
1492
     * @dataProvider nonStrictStringDataProvider
1493
     */
1494
    public function testHydrateRelationshipWithStringProperty(array $data, string $expected): void
1495
    {
1496
        $this->assertInvalidValueExceptionCount(0);
1497
        $object = $this->createHydrator()->hydrate(ObjectWithRelationshipWithString::class, ['value' => $data]);
1498
        $this->assertSame($expected, $object->value->value);
1499
    }
1500
1501
    /**
1502
     * @group relationship
1503
     * @dataProvider nonStrictStringDataProvider
1504
     * @dataProvider strictNullDataProvider
1505
     */
1506
    public function testHydrateRelationshipWithNullableStringProperty(array $data, ?string $expected): void
1507
    {
1508
        $this->assertInvalidValueExceptionCount(0);
1509
        $object = $this->createHydrator()->hydrate(ObjectWithRelationshipWithNullableString::class, ['value' => $data]);
1510
        $this->assertSame($expected, $object->value->value);
1511
    }
1512
1513
    /**
1514
     * @group relationship
1515
     * @dataProvider nonStrictStringDataProvider
1516
     * @dataProvider emptyDataProvider
1517
     */
1518
    public function testHydrateRelationshipWithOptionalStringProperty(array $data, string $expected = 'default'): void
1519
    {
1520
        $this->assertInvalidValueExceptionCount(0);
1521
        $object = $this->createHydrator()->hydrate(ObjectWithRelationshipWithOptionalString::class, ['value' => $data]);
1522
        $this->assertSame($expected, $object->value->value);
1523
    }
1524
1525
    /**
1526
     * @group relationship
1527
     * @dataProvider strictNullDataProvider
1528
     */
1529
    public function testHydrateRelationshipWithNonNullablePropertyWithNull(array $data): void
1530
    {
1531
        $this->assertInvalidValueExceptionCount(1);
1532
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
1533
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
1534
        $this->assertInvalidValueExceptionPropertyPath(0, 'value.value');
1535
        $this->createHydrator()->hydrate(ObjectWithRelationshipWithString::class, ['value' => $data]);
1536
    }
1537
1538
    /**
1539
     * @group relationship
1540
     * @dataProvider nonStrictNotStringDataProvider
1541
     */
1542
    public function testHydrateRelationshipWithStringPropertyWithNotString(array $data): void
1543
    {
1544
        $this->assertInvalidValueExceptionCount(1);
1545
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type string.');
1546
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_STRING);
1547
        $this->assertInvalidValueExceptionPropertyPath(0, 'value.value');
1548
        $this->createHydrator()->hydrate(ObjectWithRelationshipWithString::class, ['value' => $data]);
1549
    }
1550
1551
    /**
1552
     * @group relationship
1553
     */
1554
    public function testHydrateRelationshipWithRequiredStringPropertyWithoutValue(): void
1555
    {
1556
        $this->assertInvalidValueExceptionCount(1);
1557
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
1558
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
1559
        $this->assertInvalidValueExceptionPropertyPath(0, 'value.value');
1560
        $this->createHydrator()->hydrate(ObjectWithRelationshipWithString::class, ['value' => []]);
1561
    }
1562
1563
    /**
1564
     * @group relationship
1565
     */
1566
    public function testHydrateUnstantiableRelationshipProperty(): void
1567
    {
1568
        $this->expectException(InvalidObjectException::class);
1569
        $this->createHydrator()->hydrate(ObjectWithUnstantiableRelationship::class, ['value' => []]);
1570
    }
1571
1572
    /**
1573
     * @group relationships
1574
     */
1575
    public function testHydrateRelationshipsProperty(): void
1576
    {
1577
        $data = ['value' => [['value' => ['value' => 'foo']], ['value' => ['value' => 'bar']]]];
1578
1579
        $this->assertInvalidValueExceptionCount(0);
1580
        $object = $this->createHydrator()->hydrate(ObjectWithRelationships::class, $data);
1581
        $this->assertCount(2, $object->value);
1582
        $this->assertArrayHasKey(0, $object->value);
1583
        $this->assertSame($data['value'][0]['value']['value'], $object->value[0]->value->value);
1584
        $this->assertArrayHasKey(1, $object->value);
1585
        $this->assertSame($data['value'][1]['value']['value'], $object->value[1]->value->value);
1586
    }
1587
1588
    /**
1589
     * @group relationships
1590
     * @dataProvider strictNullDataProvider
1591
     */
1592
    public function testHydrateNullableRelationshipsProperty(array $data): void
1593
    {
1594
        $this->assertInvalidValueExceptionCount(0);
1595
        $object = $this->createHydrator()->hydrate(ObjectWithNullableRelationships::class, $data);
1596
        $this->assertNull($object->value);
1597
    }
1598
1599
    /**
1600
     * @group relationships
1601
     * @dataProvider emptyDataProvider
1602
     */
1603
    public function testHydrateOptionalRelationshipsProperty(array $data): void
1604
    {
1605
        $this->assertInvalidValueExceptionCount(0);
1606
        $object = $this->createHydrator()->hydrate(ObjectWithOptionalRelationships::class, $data);
1607
        $this->assertSame([], $object->value);
1608
    }
1609
1610
    /**
1611
     * @group relationships
1612
     * @dataProvider strictNullDataProvider
1613
     */
1614
    public function testHydrateNonNullableRelationshipsPropertyWithNull(array $data): void
1615
    {
1616
        $this->assertInvalidValueExceptionCount(1);
1617
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
1618
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
1619
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1620
        $this->createHydrator()->hydrate(ObjectWithRelationships::class, $data);
1621
    }
1622
1623
    /**
1624
     * @group relationships
1625
     * @dataProvider notArrayDataProvider
1626
     */
1627
    public function testHydrateRelationshipsPropertyWithNotArray(array $data): void
1628
    {
1629
        $this->assertInvalidValueExceptionCount(1);
1630
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type array.');
1631
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_ARRAY);
1632
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1633
        $this->createHydrator()->hydrate(ObjectWithRelationships::class, $data);
1634
    }
1635
1636
    /**
1637
     * @group relationships
1638
     */
1639
    public function testHydrateRequiredRelationshipsPropertyWithoutValue(): void
1640
    {
1641
        $this->assertInvalidValueExceptionCount(1);
1642
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
1643
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
1644
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1645
        $this->createHydrator()->hydrate(ObjectWithRelationships::class, []);
1646
    }
1647
1648
    /**
1649
     * @group relationships
1650
     * @dataProvider strictNullDataProvider
1651
     */
1652
    public function testHydrateRelationshipsPropertyWithNullsForNonNullableValues(array $data): void
1653
    {
1654
        $this->assertInvalidValueExceptionCount(1);
1655
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
1656
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
1657
        $this->assertInvalidValueExceptionPropertyPath(0, 'value.0.value.value');
1658
        $this->createHydrator()->hydrate(ObjectWithRelationships::class, ['value' => [['value' => $data]]]);
1659
    }
1660
1661
    /**
1662
     * @group relationships
1663
     * @dataProvider nonStrictNotStringDataProvider
1664
     */
1665
    public function testHydrateRelationshipsPropertyWithNotStringForStringValue(array $data): void
1666
    {
1667
        $this->assertInvalidValueExceptionCount(1);
1668
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type string.');
1669
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_STRING);
1670
        $this->assertInvalidValueExceptionPropertyPath(0, 'value.0.value.value');
1671
        $this->createHydrator()->hydrate(ObjectWithRelationships::class, ['value' => [['value' => $data]]]);
1672
    }
1673
1674
    /**
1675
     * @group relationships
1676
     */
1677
    public function testHydrateRelationshipsPropertyWithoutValueForRequiredValue(): void
1678
    {
1679
        $this->assertInvalidValueExceptionCount(1);
1680
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
1681
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
1682
        $this->assertInvalidValueExceptionPropertyPath(0, 'value.0.value.value');
1683
        $this->createHydrator()->hydrate(ObjectWithRelationships::class, ['value' => [['value' => []]]]);
1684
    }
1685
1686
    /**
1687
     * @group relationships
1688
     */
1689
    public function testHydrateRelationshipsPropertyWithNotArrayForRelation(): void
1690
    {
1691
        $this->assertInvalidValueExceptionCount(1);
1692
        $this->assertInvalidValueExceptionMessage(0, 'This value must be of type array.');
1693
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_ARRAY);
1694
        $this->assertInvalidValueExceptionPropertyPath(0, 'value.0');
1695
        $this->createHydrator()->hydrate(ObjectWithRelationships::class, ['value' => [42]]);
1696
    }
1697
1698
    /**
1699
     * @group relationships
1700
     */
1701
    public function testSeveralErrorsWhenHydratingRelationshipsProperty(): void
1702
    {
1703
        $this->assertInvalidValueExceptionCount(3);
1704
        $this->assertInvalidValueExceptionMessage(0, 'This value must not be empty.');
1705
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_NOT_BE_EMPTY);
1706
        $this->assertInvalidValueExceptionPropertyPath(0, 'value.0.value.value');
1707
        $this->assertInvalidValueExceptionMessage(1, 'This value must be of type string.');
1708
        $this->assertInvalidValueExceptionErrorCode(1, ErrorCode::MUST_BE_STRING);
1709
        $this->assertInvalidValueExceptionPropertyPath(1, 'value.1.value.value');
1710
        $this->assertInvalidValueExceptionMessage(2, 'This value must be provided.');
1711
        $this->assertInvalidValueExceptionErrorCode(2, ErrorCode::MUST_BE_PROVIDED);
1712
        $this->assertInvalidValueExceptionPropertyPath(2, 'value.2.value.value');
1713
        $this->createHydrator()->hydrate(ObjectWithRelationships::class, ['value' => [
1714
            ['value' => ['value' => null]],
1715
            ['value' => ['value' => []]],
1716
            ['value' => []]
1717
        ]]);
1718
    }
1719
1720
    /**
1721
     * @group relationships
1722
     */
1723
    public function testHydrateLimitedRelationshipsProperty(): void
1724
    {
1725
        $this->assertInvalidValueExceptionCount(1);
1726
        $this->assertInvalidValueExceptionMessage(0, 'This value is limited to 1 elements.');
1727
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::ARRAY_OVERFLOW);
1728
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1729
        $this->createHydrator()->hydrate(ObjectWithRelationshipsWithLimit::class, ['value' => [
1730
            ['value' => 'foo'],
1731
            ['value' => 'bar'],
1732
        ]]);
1733
    }
1734
1735
    /**
1736
     * @group relationships
1737
     */
1738
    public function testHydrateRelationshipsPropertyWithUnstantiableObject(): void
1739
    {
1740
        $this->expectException(InvalidObjectException::class);
1741
        $this->createHydrator()->hydrate(
1742
            ObjectWithRelationshipsWithUnstantiableObject::class,
1743
            ['value' => [['value' => []]]],
1744
        );
1745
    }
1746
1747
    /**
1748
     * @group json
1749
     */
1750
    public function testHydrateObjectWithJson(): void
1751
    {
1752
        $this->assertInvalidValueExceptionCount(0);
1753
        $object = $this->createHydrator()->hydrateWithJson(ObjectWithString::class, '{"value": "foo"}');
1754
        $this->assertSame('foo', $object->value);
1755
    }
1756
1757
    /**
1758
     * @group json
1759
     */
1760
    public function testHydrateObjectWithInvalidJson(): void
1761
    {
1762
        $this->expectException(InvalidDataException::class);
1763
        $this->expectExceptionMessageMatches('/^The JSON is invalid and couldn‘t be decoded due to: .+$/');
1764
        $this->createHydrator()->hydrateWithJson(ObjectWithString::class, '[[]]', 0, 1);
1765
    }
1766
1767
    /**
1768
     * @group json
1769
     */
1770
    public function testHydrateObjectWithNonObjectableJson(): void
1771
    {
1772
        $this->expectException(InvalidDataException::class);
1773
        $this->expectExceptionMessage('The JSON must be in the form of an array or an object.');
1774
        $this->createHydrator()->hydrateWithJson(ObjectWithString::class, 'null');
1775
    }
1776
1777
    public function testInstantedObject(): void
1778
    {
1779
        $object = new class {
1780
            public string $value;
1781
        };
1782
1783
        $this->assertInvalidValueExceptionCount(0);
1784
        $this->createHydrator()->hydrate($object, ['value' => 'foo']);
1785
        $this->assertSame('foo', $object->value);
1786
    }
1787
1788
    public function testUnstantiableObject(): void
1789
    {
1790
        $this->expectException(InvalidObjectException::class);
1791
        $this->createHydrator()->hydrate(UnstantiableObject::class, []);
1792
    }
1793
1794
    public function testStaticalProperty(): void
1795
    {
1796
        $this->assertInvalidValueExceptionCount(0);
1797
        $this->createHydrator()->hydrate(ObjectWithStaticalProperty::class, ['value' => 'foo']);
1798
        $this->assertNotSame('foo', ObjectWithStaticalProperty::$value);
1799
    }
1800
1801
    public function testIgnoredProperty(): void
1802
    {
1803
        $this->assertInvalidValueExceptionCount(0);
1804
        $object = $this->createHydrator()->hydrate(ObjectWithIgnoredProperty::class, ['value' => 'foo']);
1805
        $this->assertNotSame('foo', $object->value);
1806
    }
1807
1808
    public function testUnsupportedPropertyType(): void
1809
    {
1810
        $this->expectException(InvalidObjectException::class);
1811
        $this->createHydrator()->hydrate(ObjectWithUnsupportedPropertyType::class, ['value' => []]);
1812
    }
1813
1814
    public function testUnsupportedPropertyTypeNotation(): void
1815
    {
1816
        $this->phpRequired('8.0');
1817
        $this->expectException(InvalidObjectException::class);
1818
        $this->createHydrator()->hydrate(ObjectWithUnsupportedPropertyNotation::class, ['value' => []]);
1819
    }
1820
1821
    public function testUnsupportedInternalClass(): void
1822
    {
1823
        $this->expectException(InvalidObjectException::class);
1824
        $this->createHydrator()->hydrate(ObjectWithUnsupportedInternalClass::class, ['value' => []]);
1825
    }
1826
1827
    public function testUntypedProperty(): void
1828
    {
1829
        $object = $this->createHydrator()->hydrate(ObjectWithUntypedProperty::class, ['value' => []]);
1830
1831
        $this->assertSame([], $object->value);
1832
    }
1833
1834
    public function testAnnotatedAlias(): void
1835
    {
1836
        $hydrator = $this->createHydrator();
1837
1838
        $this->assertInvalidValueExceptionCount(0);
1839
        $object = $hydrator->hydrate(ObjectWithAliasedProperty::class, ['non-normalized-value' => 'foo']);
1840
        $this->assertSame('foo', $object->value);
1841
1842
        $this->assertInvalidValueExceptionCount(1);
1843
        $hydrator->hydrate(ObjectWithAliasedProperty::class, ['value' => 'foo']);
1844
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
1845
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
1846
        $this->assertInvalidValueExceptionPropertyPath(0, 'value');
1847
    }
1848
1849
    public function testHydrateStore(): void
1850
    {
1851
        $this->phpRequired('8.1');
1852
1853
        $sold = Status::SOLD;
1854
1855
        $data = [];
1856
        $data['name'] = 'Some product';
1857
        $data['category']['name'] = 'Some category';
1858
        $data['tags'][]['name'] = 'foo';
1859
        $data['tags'][]['name'] = 'bar';
1860
        $data['status'] = $sold->value;
1861
        $data['createdAt'] = '2000-01-01 00:00:00';
1862
1863
        $this->assertInvalidValueExceptionCount(0);
1864
        $product = $this->createHydrator()->hydrate(Product::class, $data);
1865
        $this->assertSame('Some product', $product->name);
1866
        $this->assertSame('Some category', $product->category->name);
1867
        $this->assertCount(2, $product->tags);
1868
        $this->assertArrayHasKey(0, $product->tags);
1869
        $this->assertSame('foo', $product->tags[0]->name);
1870
        $this->assertArrayHasKey(1, $product->tags);
1871
        $this->assertSame('bar', $product->tags[1]->name);
1872
        $this->assertSame(Status::SOLD, $product->status);
1873
        $this->assertSame('2000-01-01 00:00:00', $product->createdAt->format('Y-m-d H:i:s'));
1874
1875
        unset($data['createdAt']);
1876
        $this->assertInvalidValueExceptionCount(0);
1877
        $product = $this->createHydrator()->hydrate(Product::class, $data);
1878
        $this->assertSame('2020-01-01 12:00:00', $product->createdAt->format('Y-m-d H:i:s'));
1879
    }
1880
1881
    public function testSymfonyViolations(): void
1882
    {
1883
        $violations = null;
1884
        try {
1885
            $this->createHydrator()->hydrate(ObjectWithString::class, []);
1886
        } catch (InvalidDataException $e) {
1887
            $violations = $e->getViolations();
1888
        }
1889
1890
        $this->assertNotNull($violations);
1891
        $this->assertCount(1, $violations);
1892
        $this->assertTrue($violations->has(0));
1893
        $this->assertSame(ErrorCode::MUST_BE_PROVIDED, $violations->get(0)->getCode());
1894
        $this->assertSame('This value must be provided.', $violations->get(0)->getMessage());
1895
        $this->assertSame('value', $violations->get(0)->getPropertyPath());
1896
    }
1897
1898
    public function emptyDataProvider(): array
1899
    {
1900
        return [
1901
            [[]],
1902
        ];
1903
    }
1904
1905
    public function strictNullDataProvider(): array
1906
    {
1907
        return [
1908
            [['value' => null], null],
1909
        ];
1910
    }
1911
1912
    public function nonStrictNullDataProvider(): array
1913
    {
1914
        return [
1915
            [['value' => ''], null],
1916
            [['value' => ' '], null],
1917
        ];
1918
    }
1919
1920
    public function strictBooleanDataProvider(): array
1921
    {
1922
        return [
1923
            [['value' => true], true],
1924
            [['value' => false], false],
1925
        ];
1926
    }
1927
1928
    public function nonStrictBooleanDataProvider(): array
1929
    {
1930
        return [
1931
            [['value' => '1'], true],
1932
            [['value' => '0'], false],
1933
            [['value' => 'true'], true],
1934
            [['value' => 'false'], false],
1935
            [['value' => 'yes'], true],
1936
            [['value' => 'no'], false],
1937
            [['value' => 'on'], true],
1938
            [['value' => 'off'], false],
1939
        ];
1940
    }
1941
1942
    public function notBooleanDataProvider(): array
1943
    {
1944
        return [
1945
            [['value' => 0]],
1946
            [['value' => 1]],
1947
            [['value' => 42]],
1948
            [['value' => 3.14159]],
1949
            [['value' => 'foo']],
1950
            [['value' => []]],
1951
        ];
1952
    }
1953
1954
    public function strictIntegerDataProvider(): array
1955
    {
1956
        return [
1957
            [['value' => -1], -1],
1958
            [['value' => 0], 0],
1959
            [['value' => 1], 1],
1960
        ];
1961
    }
1962
1963
    public function nonStrictIntegerDataProvider(): array
1964
    {
1965
        return [
1966
            [['value' => '-1'], -1],
1967
            [['value' => '0'], 0],
1968
            [['value' => '+1'], 1],
1969
        ];
1970
    }
1971
1972
    public function notIntegerDataProvider(): array
1973
    {
1974
        return [
1975
            [['value' => true]],
1976
            [['value' => false]],
1977
            [['value' => 3.14159]],
1978
            [['value' => 'foo']],
1979
            [['value' => []]],
1980
        ];
1981
    }
1982
1983
    public function strictNumberDataProvider(): array
1984
    {
1985
        return [
1986
            [['value' => -1], -1.],
1987
            [['value' => 0], 0.],
1988
            [['value' => 1], 1.],
1989
            [['value' => -1.], -1.],
1990
            [['value' => 0.], 0.],
1991
            [['value' => 1.], 1.],
1992
            [['value' => -.1], -.1],
1993
            [['value' => .0], .0],
1994
            [['value' => .1], .1],
1995
        ];
1996
    }
1997
1998
    public function nonStrictNumberDataProvider(): array
1999
    {
2000
        return [
2001
            [['value' => '-1'], -1.],
2002
            [['value' => '0'], 0.],
2003
            [['value' => '+1'], 1.],
2004
            [['value' => '-1.'], -1.],
2005
            [['value' => '0.'], 0.],
2006
            [['value' => '+1.'], 1.],
2007
            [['value' => '-.1'], -.1],
2008
            [['value' => '.0'], .0],
2009
            [['value' => '+.1'], .1],
2010
            [['value' => '-1.0'], -1.],
2011
            [['value' => '0.0'], 0.],
2012
            [['value' => '+1.0'], 1.],
2013
            [['value' => '1e-1'], .1],
2014
            [['value' => '1e1'], 10.],
2015
            [['value' => '1e+1'], 10.],
2016
            [['value' => '1.e-1'], .1],
2017
            [['value' => '1.e1'], 10.],
2018
            [['value' => '1.e+1'], 10.],
2019
            [['value' => '.1e-1'], .01],
2020
            [['value' => '.1e1'], 1.],
2021
            [['value' => '.1e+1'], 1.],
2022
            [['value' => '1.0e-1'], .1],
2023
            [['value' => '1.0e1'], 10.],
2024
            [['value' => '1.0e+1'], 10.],
2025
        ];
2026
    }
2027
2028
    public function notNumberDataProvider(): array
2029
    {
2030
        return [
2031
            [['value' => true]],
2032
            [['value' => false]],
2033
            [['value' => 'foo']],
2034
            [['value' => []]],
2035
        ];
2036
    }
2037
2038
    public function nonStrictStringDataProvider(): array
2039
    {
2040
        return [
2041
            [['value' => 'foo'], 'foo'],
2042
2043
            // Must not be cast to a null
2044
            [['value' => ''], ''],
2045
            [['value' => ' '], ' '],
2046
2047
            // Must not be cast to a boolean
2048
            [['value' => '1'], '1'],
2049
            [['value' => '0'], '0'],
2050
            [['value' => 'true'], 'true'],
2051
            [['value' => 'false'], 'false'],
2052
            [['value' => 'yes'], 'yes'],
2053
            [['value' => 'no'], 'no'],
2054
            [['value' => 'on'], 'on'],
2055
            [['value' => 'off'], 'off'],
2056
2057
            // Must not be cast to a number
2058
            [['value' => '42'], '42'],
2059
            [['value' => '3.14159'], '3.14159'],
2060
2061
            // Must be cast to a string
2062
            [['value' => -1], '-1'],
2063
            [['value' => 0], '0'],
2064
            [['value' => 1], '1'],
2065
        ];
2066
    }
2067
2068
    public function nonStrictNotStringDataProvider(): array
2069
    {
2070
        return [
2071
            [['value' => true]],
2072
            [['value' => false]],
2073
            [['value' => 3.14159]],
2074
            [['value' => []]],
2075
        ];
2076
    }
2077
2078
    public function strictNotStringDataProvider(): array
2079
    {
2080
        return [
2081
            [['value' => true]],
2082
            [['value' => false]],
2083
            [['value' => 42]],
2084
            [['value' => 3.14159]],
2085
            [['value' => []]],
2086
        ];
2087
    }
2088
2089
    public function arrayDataProvider(): array
2090
    {
2091
        return [
2092
            [['value' => ['foo']], ['foo']]
2093
        ];
2094
    }
2095
2096
    public function notArrayDataProvider(): array
2097
    {
2098
        return [
2099
            [['value' => true]],
2100
            [['value' => false]],
2101
            [['value' => 42]],
2102
            [['value' => 3.14159]],
2103
            [['value' => 'foo']],
2104
        ];
2105
    }
2106
2107
    public function timestampDataProvider(): array
2108
    {
2109
        return [
2110
            [['value' => '1970-01-01T00:00:00.000+00:00'], '1970-01-01T00:00:00.000+00:00', null],
2111
            [['value' => '1970-01-01 00:00:00'], '1970-01-01 00:00:00', 'Y-m-d H:i:s'],
2112
            [['value' => '-1'], '-1', 'U'],
2113
            [['value' => '0'], '0', 'U'],
2114
            [['value' => '1'], '1', 'U'],
2115
            [['value' => -1], '-1', 'U'],
2116
            [['value' => 0], '0', 'U'],
2117
            [['value' => 1], '1', 'U'],
2118
        ];
2119
    }
2120
2121
    public function invalidTimestampDataProvider(): array
2122
    {
2123
        return [
2124
            [['value' => 'Tue, 06 Jun 23 16:50:23']],
2125
        ];
2126
    }
2127
2128
    public function notTimestampDataProvider(): array
2129
    {
2130
        return [
2131
            [['value' => true]],
2132
            [['value' => false]],
2133
            [['value' => 42]],
2134
            [['value' => 3.14159]],
2135
            [['value' => []]],
2136
        ];
2137
    }
2138
2139
    public function strictUnixTimeStampDataProvider(): array
2140
    {
2141
        return [
2142
            [['value' => -1], '1969-12-31 23:59:59', 'Y-m-d H:i:s'],
2143
            [['value' => 0], '1970-01-01 00:00:00', 'Y-m-d H:i:s'],
2144
            [['value' => 1], '1970-01-01 00:00:01', 'Y-m-d H:i:s'],
2145
        ];
2146
    }
2147
2148
    public function nonStrictUnixTimeStampDataProvider(): array
2149
    {
2150
        return [
2151
            [['value' => '-1'], '1969-12-31 23:59:59', 'Y-m-d H:i:s'],
2152
            [['value' => '0'], '1970-01-01 00:00:00', 'Y-m-d H:i:s'],
2153
            [['value' => '1'], '1970-01-01 00:00:01', 'Y-m-d H:i:s'],
2154
        ];
2155
    }
2156
2157
    public function notUnixTimeStampDataProvider(): array
2158
    {
2159
        return [
2160
            [['value' => true]],
2161
            [['value' => false]],
2162
            [['value' => 'foo']],
2163
            [['value' => []]],
2164
        ];
2165
    }
2166
2167
    public function timezoneDataProvider(): array
2168
    {
2169
        return [
2170
            [['value' => 'Europe/Belgrade'], 'Europe/Belgrade'],
2171
        ];
2172
    }
2173
2174
    public function invalidTimezoneDataProvider(): array
2175
    {
2176
        return [
2177
            [['value' => 'Haafingar/Solitude']],
2178
        ];
2179
    }
2180
2181
    public function uidDataProvider(): array
2182
    {
2183
        return [
2184
            [['value' => '207ddb61-c300-4368-9f26-33d0a99eac00'], '207ddb61-c300-4368-9f26-33d0a99eac00'],
2185
        ];
2186
    }
2187
2188
    public function invalidUidDataProvider(): array
2189
    {
2190
        return [
2191
            [['value' => '207ddb61-c300-4368-9f26-33d0a99eac0']],
2192
            [['value' => '207ddb61-c300-4368-9f26-33d0a99eac0x']],
2193
            [['value' => '207ddb61-c300-4368-9f26-33d0a99eac000']],
2194
        ];
2195
    }
2196
2197
    public function strictIntegerEnumerationDataProvider(): array
2198
    {
2199
        if (PHP_VERSION_ID < 80100) {
2200
            return [[[], null]];
2201
        }
2202
2203
        $foo = IntegerEnum::FOO;
2204
        $bar = IntegerEnum::BAR;
2205
        $baz = IntegerEnum::BAZ;
2206
2207
        return [
2208
            [['value' => $foo->value], $foo],
2209
            [['value' => $bar->value], $bar],
2210
            [['value' => $baz->value], $baz],
2211
        ];
2212
    }
2213
2214
    public function nonStrictIntegerEnumerationDataProvider(): array
2215
    {
2216
        if (PHP_VERSION_ID < 80100) {
2217
            return [[[], null]];
2218
        }
2219
2220
        $foo = IntegerEnum::FOO;
2221
        $bar = IntegerEnum::BAR;
2222
        $baz = IntegerEnum::BAZ;
2223
2224
        return [
2225
            [['value' => (string) $foo->value], $foo],
2226
            [['value' => (string) $bar->value], $bar],
2227
            [['value' => (string) $baz->value], $baz],
2228
        ];
2229
    }
2230
2231
    public function stringEnumerationDataProvider(): array
2232
    {
2233
        if (PHP_VERSION_ID < 80100) {
2234
            return [[[], null]];
2235
        }
2236
2237
        $foo = StringEnum::FOO;
2238
        $bar = StringEnum::BAR;
2239
        $baz = StringEnum::BAZ;
2240
2241
        return [
2242
            [['value' => $foo->value], $foo],
2243
            [['value' => $bar->value], $bar],
2244
            [['value' => $baz->value], $baz],
2245
        ];
2246
    }
2247
2248
    public function testIssue25(): void
2249
    {
2250
        $this->assertInvalidValueExceptionCount(1);
2251
        $this->assertInvalidValueExceptionMessage(0, 'This value must be provided.');
2252
        $this->assertInvalidValueExceptionErrorCode(0, ErrorCode::MUST_BE_PROVIDED);
2253
        $this->assertInvalidValueExceptionPropertyPath(0, 'foo');
2254
        $this->createHydrator()->hydrate(Issue25::class, []);
2255
    }
2256
2257
    private function createHydrator(array $context = []): HydratorInterface
2258
    {
2259
        $hydrator = new Hydrator($context);
2260
        if (PHP_VERSION_ID < 80000) {
2261
            $hydrator->useDefaultAnnotationReader();
0 ignored issues
show
Deprecated Code introduced by
The function Sunrise\Hydrator\Hydrato...faultAnnotationReader() has been deprecated: 3.2.0 Use the {@see setAnnotationReader()} method with the {@see DoctrineAnnotationReader::default()} attribute. ( Ignorable by Annotation )

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

2261
            /** @scrutinizer ignore-deprecated */ $hydrator->useDefaultAnnotationReader();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
2262
        }
2263
2264
        return $hydrator;
2265
    }
2266
2267
    private function phpRequired(string $version): void
2268
    {
2269
        if (version_compare(PHP_VERSION, $version, '<')) {
2270
            $this->markTestSkipped(sprintf('PHP %s is required.', $version));
2271
        }
2272
    }
2273
2274
    private function assertInvalidValueExceptionCount(int $expectedCount): void
2275
    {
2276
        $this->invalidValueExceptionCount = $expectedCount;
2277
    }
2278
2279
    private function assertInvalidValueExceptionMessage(int $exceptionIndex, string $expectedMessage): void
2280
    {
2281
        $this->invalidValueExceptionMessage[] = [$exceptionIndex, $expectedMessage];
2282
    }
2283
2284
    private function assertInvalidValueExceptionPropertyPath(int $exceptionIndex, string $expectedPropertyPath): void
2285
    {
2286
        $this->invalidValueExceptionPropertyPath[] = [$exceptionIndex, $expectedPropertyPath];
2287
    }
2288
2289
    private function assertInvalidValueExceptionErrorCode(int $exceptionIndex, string $expectedErrorCode): void
2290
    {
2291
        $this->invalidValueExceptionErrorCode[] = [$exceptionIndex, $expectedErrorCode];
2292
    }
2293
2294
    protected function runTest(): void
2295
    {
2296
        $invalidDataExceptionHandled = false;
2297
2298
        try {
2299
            parent::runTest();
2300
        } catch (InvalidDataException $invalidDataException) {
2301
            $invalidDataExceptionMessages = [];
2302
            foreach ($invalidDataException->getExceptions() as $invalidValueException) {
2303
                $invalidDataExceptionMessages[] = sprintf(
2304
                    '[%s] %s',
2305
                    $invalidValueException->getPropertyPath(),
2306
                    $invalidValueException->getMessage(),
2307
                );
2308
            }
2309
2310
            if (isset($this->invalidValueExceptionCount)) {
2311
                $invalidDataExceptionHandled = true;
2312
                $this->assertCount(
2313
                    $this->invalidValueExceptionCount,
0 ignored issues
show
Bug introduced by
It seems like $this->invalidValueExceptionCount can also be of type null; however, parameter $expectedCount of PHPUnit\Framework\Assert::assertCount() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

2313
                    /** @scrutinizer ignore-type */ $this->invalidValueExceptionCount,
Loading history...
2314
                    $invalidDataException->getExceptions(),
2315
                    \join(\PHP_EOL, $invalidDataExceptionMessages),
2316
                );
2317
            }
2318
2319
            foreach ($this->invalidValueExceptionMessage as [$index, $invalidValueExceptionMessage]) {
2320
                $invalidDataExceptionHandled = true;
2321
                $this->assertArrayHasKey($index, $invalidDataException->getExceptions());
2322
                $this->assertSame(
2323
                    $invalidValueExceptionMessage,
2324
                    $invalidDataException->getExceptions()[$index]->getMessage(),
2325
                );
2326
            }
2327
2328
            foreach ($this->invalidValueExceptionPropertyPath as [$index, $invalidValueExceptionPropertyPath]) {
2329
                $invalidDataExceptionHandled = true;
2330
                $this->assertArrayHasKey($index, $invalidDataException->getExceptions());
2331
                $this->assertSame(
2332
                    $invalidValueExceptionPropertyPath,
2333
                    $invalidDataException->getExceptions()[$index]->getPropertyPath(),
2334
                );
2335
            }
2336
2337
            foreach ($this->invalidValueExceptionErrorCode as [$index, $invalidValueExceptionErrorCode]) {
2338
                $invalidDataExceptionHandled = true;
2339
                $this->assertArrayHasKey($index, $invalidDataException->getExceptions());
2340
                $this->assertSame(
2341
                    $invalidValueExceptionErrorCode,
2342
                    $invalidDataException->getExceptions()[$index]->getErrorCode(),
2343
                );
2344
            }
2345
2346
            if (!$invalidDataExceptionHandled) {
2347
                throw $invalidDataException;
2348
            }
2349
        } finally {
2350
            $this->invalidValueExceptionCount = null;
2351
            $this->invalidValueExceptionMessage = [];
2352
            $this->invalidValueExceptionPropertyPath = [];
2353
            $this->invalidValueExceptionErrorCode = [];
2354
2355
            if ($invalidDataExceptionHandled) {
2356
                $this->assertTrue(true);
2357
            }
2358
        }
2359
    }
2360
}
2361