GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

it_raises_an_exception_on_not_existing_path()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Tests\mschindler83\ArrayAccess;
5
6
use BadMethodCallException;
7
use Mschindler83\ArrayAccess\ArrayAccess;
8
use Mschindler83\ArrayAccess\ArrayAccessFailed;
9
use Mschindler83\ArrayAccess\ArrayAccessValidationFailed;
10
use Mschindler83\ArrayAccess\DotAnnotation\SimpleDotAnnotation;
11
use PHPUnit\Framework\TestCase;
12
13
class ArrayAccessTest extends TestCase
14
{
15
    /**
16
     * @test
17
     */
18
    public function it_returns_array_data(): void
19
    {
20
        $testArray = [
21
                'Foo' => [
22
                    'Bar' => [
23
                        'Baz' => 'Buz',
24
                    ],
25
                ],
26
            ];
27
        $access = ArrayAccess::create($testArray);
28
29
        static::assertSame($testArray, $access->data());
30
    }
31
32
    /**
33
     * @test
34
     */
35
    public function it_validates_with_json_schema_validator(): void
36
    {
37
        $data = [
38
            'key1' => 'value1',
39
            'key2' => true,
40
        ];
41
42
        $access = ArrayAccess::createWithJsonSchemaValidation($data, \file_get_contents(__DIR__ . '/../Fixture/json-schema.json'));
43
        static::assertSame('value1', $access->string('key1'));
44
        static::assertTrue($access->bool('key2'));
45
    }
46
47
    /**
48
     * @test
49
     */
50
    public function it_raises_an_exception_on_failed_json_schema_validation(): void
51
    {
52
        $this->expectException(ArrayAccessValidationFailed::class);
53
        $this->expectExceptionMessage('Json schema validation failed');
54
55
        $data = [
56
            'key1' => 'v',
57
            'key2' => '1',
58
            'key3' => 'some-other-value',
59
        ];
60
61
        ArrayAccess::createWithJsonSchemaValidation($data, \file_get_contents(__DIR__ . '/../Fixture/json-schema.json'));
62
    }
63
64
    /**
65
     * @test
66
     */
67
    public function it_can_be_created_from_dot_annotation(): void
68
    {
69
        $access = ArrayAccess::newFromDotAnnotation(SimpleDotAnnotation::create('key1.key2.2.key3', 'the-value'));
70
71
        static::assertSame(
72
            [
73
                'key1' => [
74
                    'key2' => [
75
                        2 => [
76
                            'key3' => 'the-value',
77
                        ],
78
                    ],
79
                ],
80
            ],
81
            $access->data()
82
        );
83
    }
84
85
    /**
86
     * @test
87
     */
88
    public function it_can_be_created_from_dot_annotation_with_empty_keys(): void
89
    {
90
        $access = ArrayAccess::newFromDotAnnotation(SimpleDotAnnotation::create('key1...key2', 'the-value'));
91
92
        static::assertSame(
93
            [
94
                'key1' => [
95
                    0 => [
96
                        0 => [
97
                            'key2' => 'the-value'
98
                        ],
99
                    ],
100
                ],
101
            ],
102
            $access->data()
103
        );
104
    }
105
106
    /**
107
     * @test
108
     */
109
    public function it_can_be_created_from_multiple_dot_annotation(): void
110
    {
111
        $access = ArrayAccess::newFromDotAnnotation(
112
            SimpleDotAnnotation::create('key1.some', 'some-value'),
113
            SimpleDotAnnotation::create('key1.key2.0.key3', 'the-value-1'),
114
            SimpleDotAnnotation::create('key1.key2.1.key3', 'the-value-2'),
115
            SimpleDotAnnotation::create('key1.key2.2.key3', 'the-value-3'),
116
            SimpleDotAnnotation::create('key1.key2.3.key3', 'the-value-4'),
117
            SimpleDotAnnotation::create('key1.key2.3.key4', 'the-value-5')
118
        );
119
120
        static::assertSame(
121
            [
122
                'key1' => [
123
                    'some' => 'some-value',
124
                    'key2' => [
125
                        0 => [
126
                            'key3' => 'the-value-1',
127
                        ],
128
                        1 => [
129
                            'key3' => 'the-value-2',
130
                        ],
131
                        2 => [
132
                            'key3' => 'the-value-3',
133
                        ],
134
                        3 => [
135
                            'key3' => 'the-value-4',
136
                            'key4' => 'the-value-5',
137
                        ],
138
                    ],
139
                ],
140
            ],
141
            $access->data()
142
        );
143
    }
144
145
    /**
146
     * @test
147
     */
148
    public function it_can_write_at_path(): void
149
    {
150
        $testArray = [
151
            'Foo' => [
152
                'Bar' => [
153
                    'Baz' => 'Buz',
154
                ],
155
            ],
156
        ];
157
158
        $access = ArrayAccess::create($testArray);
159
        $access = $access->writeAtPath('new-value', 'Foo', 'Bar', 'New');
160
        $access = $access->writeAtPath('new-value-2', 'Foo', 'Bar', 'New-2');
161
162
        static::assertSame(
163
            [
164
                'Foo' => [
165
                    'Bar' => [
166
                        'Baz' => 'Buz',
167
                        'New' => 'new-value',
168
                        'New-2' => 'new-value-2',
169
                    ],
170
                ],
171
            ],
172
            $access->data()
173
        );
174
    }
175
176
    /**
177
     * @test
178
     */
179
    public function it_can_write_value_at_single_path(): void
180
    {
181
        $access = ArrayAccess::create([]);
182
        $newAccess = $access->writeAtPath('new-value', 'Foo');
183
184
        static::assertSame('new-value', $newAccess->string('Foo'));
185
    }
186
187
    /**
188
     * @test
189
     */
190
    public function it_can_write_empty_array(): void
191
    {
192
        $access = ArrayAccess::create([]);
193
        $access = $access->writeAtPath([], '0');
194
195
        static::assertSame([], $access->array(0));
196
    }
197
198
    /**
199
     * @test
200
     */
201
    public function it_can_write_array_at_path(): void
202
    {
203
        $access = ArrayAccess::create([]);
204
        $arrayToWrite = ['foo' => ['bar' => 'baz']];
205
        $access = $access->writeAtPath($arrayToWrite);
206
207
        static::assertSame(
208
            [
209
                [
210
                    'foo' => [
211
                        'bar' => 'baz'
212
                    ],
213
                ]
214
            ],
215
            $access->data()
216
        );
217
    }
218
219
    /**
220
     * @test
221
     */
222
    public function it_can_write_empty_array_path(): void
223
    {
224
        $access = ArrayAccess::create([]);
225
        $access = $access->writeAtPath('foo', ...[]);
226
227
        static::assertSame(['foo'], $access->data());
228
    }
229
230
    /**
231
     * @test
232
     */
233
    public function it_can_write_at_path_on_empty_access(): void
234
    {
235
        $access = ArrayAccess::create([]);
236
        $newAccess = $access->writeAtPath('new-value', 'Foo', 'Bar', 'New');
237
238
        static::assertSame(
239
            [
240
                'Foo' => [
241
                    'Bar' => [
242
                        'New' => 'new-value',
243
                    ],
244
                ],
245
            ],
246
            $newAccess->data()
247
        );
248
    }
249
250
    /**
251
     * @test
252
     */
253
    public function it_writes_on_zero_index_if_empty_path_provided(): void
254
    {
255
        $access = ArrayAccess::create([]);
256
        $access = $access->writeAtPath('foo');
257
258
        static::assertSame(['foo'], $access->data());
259
    }
260
261
    /**
262
     * @test
263
     */
264
    public function it_writes_null_value_on_zero_index(): void
265
    {
266
        $access = ArrayAccess::create([]);
267
        $access = $access->writeAtPath(null);
268
269
        static::assertSame([0 => null], $access->data());
270
    }
271
272
    /**
273
     * @test
274
     */
275
    public function it_can_write_at_path_with_complex_data(): void
276
    {
277
        $testArray = [
278
            'Foo' => [
279
                'Bar' => [
280
                    'Baz' => 'Buz',
281
                    'next-key' => 'next-value',
282
                    'next-array' => [
283
                        'some' => 'some-value',
284
                        'other' => 'other-value'
285
                    ],
286
                ],
287
            ],
288
        ];
289
290
        $access = ArrayAccess::create($testArray);
291
        $newAccess = $access->writeAtPath(
292
            [
293
                'some' => 'some-value-2',
294
                'other' => 'new-other',
295
                'new' => 'new',
296
            ],
297
            'Foo', 'Bar', 'next-array'
298
        );
299
300
        static::assertSame(
301
            [
302
                'Foo' => [
303
                    'Bar' => [
304
                        'Baz' => 'Buz',
305
                        'next-key' => 'next-value',
306
                        'next-array' => [
307
                            'some' => 'some-value-2',
308
                            'other' => 'new-other',
309
                            'new' => 'new',
310
                        ],
311
                    ],
312
                ],
313
            ],
314
            $newAccess->data()
315
        );
316
    }
317
318
    /**
319
     * @test
320
     */
321
    public function it_can_overwrite_at_path(): void
322
    {
323
        $testArray = [
324
            'Foo' => [
325
                'Bar' => [
326
                    'Baz' => 'Buz',
327
                ],
328
            ],
329
        ];
330
331
        $access = ArrayAccess::create($testArray);
332
        $newAccess = $access->writeAtPath('new-value', 'Foo', 'Bar', 'Baz');
333
334
        static::assertSame(
335
            [
336
                'Foo' => [
337
                    'Bar' => [
338
                        'Baz' => 'new-value',
339
                    ],
340
                ],
341
            ],
342
            $newAccess->data()
343
        );
344
    }
345
346
    /**
347
     * @test
348
     */
349
    public function it_can_return_if_a_path_exists(): void
350
    {
351
        $testArray = [
352
                'Foo' => [
353
                    'Bar' => [
354
                        'Baz' => 'Buz',
355
                    ],
356
                ],
357
            ];
358
359
        $access = ArrayAccess::create($testArray);
360
361
        static::assertTrue($access->hasPath('Foo'));
362
        static::assertTrue($access->hasPath('Foo', 'Bar'));
363
        static::assertTrue($access->hasPath('Foo', 'Bar', 'Baz'));
364
        static::assertFalse($access->hasPath('Foo', 'Bar', 'Baz', 'Buz'));
365
        static::assertFalse($access->hasPath('BuzBuz'));
366
    }
367
368
    /**
369
     * @test
370
     */
371
    public function it_raises_an_exception_on_not_existing_path(): void
372
    {
373
        $this->expectException(ArrayAccessFailed::class);
374
        $this->expectExceptionMessage('Path not found');
375
376
        $access = ArrayAccess::create(['foo' => ['bar' => null]]);
377
        $access->int('foo', 'bar', 'baz');
378
    }
379
380
    /**
381
     * @test
382
     */
383
    public function it_raises_an_exception_on_unknown_method_call(): void
384
    {
385
        $this->expectException(BadMethodCallException::class);
386
        $this->expectExceptionMessage('Method "unknownMethod" not found');
387
388
        ArrayAccess::create([])->unknownMethod();
389
    }
390
391
    /**
392
     * @test
393
     */
394
    public function it_works_with_strings(): void
395
    {
396
        $testArray = [
397
            'Foo' => [
398
                'Bar' => [
399
                    'Baz' => 'Buz',
400
                ],
401
            ],
402
        ];
403
        $access = ArrayAccess::create($testArray);
404
        $result = $access->string('Foo', 'Bar', 'Baz');
405
406
        static::assertSame('Buz', $result);
407
    }
408
409
    /**
410
     * @test
411
     */
412
    public function it_works_with_nullable_strings(): void
413
    {
414
        $testArray = [
415
            'Foo' => [
416
                'Bar' => [
417
                    'Baz' => null,
418
                ],
419
            ],
420
        ];
421
        $access = ArrayAccess::create($testArray);
422
        $result = $access->stringOrNull('Foo', 'Bar', 'Baz');
423
424
        static::assertNull($result);
425
    }
426
427
    /**
428
     * @test
429
     */
430
    public function it_raises_an_exception_on_value_other_than_null_when_requesting_nullable(): void
431
    {
432
        $this->expectException(ArrayAccessFailed::class);
433
        $this->expectExceptionMessage('[Array path: Foo.Bar.Baz] Could not get value for "Baz". Invalid type "integer". Expected type: "stringOrNull"');
434
435
        $testArray = [
436
            'Foo' => [
437
                'Bar' => [
438
                    'Baz' => 1,
439
                ],
440
            ],
441
        ];
442
        $access = ArrayAccess::create($testArray);
443
        $access->stringOrNull('Foo', 'Bar', 'Baz');
444
    }
445
446
    /**
447
     * @test
448
     */
449
    public function it_works_with_integers(): void
450
    {
451
        $testArray = [
452
            'Foo' => [
453
                'Bar' => [
454
                    'Baz' => -999,
455
                ],
456
            ],
457
        ];
458
        $access = ArrayAccess::create($testArray);
459
        $result = $access->int('Foo', 'Bar', 'Baz');
460
461
        static::assertSame(-999, $result);
462
    }
463
464
    /**
465
     * @test
466
     */
467
    public function it_works_with_floats(): void
468
    {
469
        $testArray = [
470
            'Foo' => [
471
                'Bar' => [
472
                    'Baz' => -98.112,
473
                ],
474
            ],
475
        ];
476
        $access = ArrayAccess::create($testArray);
477
        $result = $access->float('Foo', 'Bar', 'Baz');
478
479
        static::assertSame(-98.112, $result);
480
    }
481
482
    /**
483
     * @test
484
     */
485
    public function it_works_with_booleans(): void
486
    {
487
        $testArray = [
488
            'Foo' => [
489
                'Bar' => [
490
                    'is_true' => true,
491
                    'is_false' => false,
492
                ],
493
            ],
494
        ];
495
        $access = ArrayAccess::create($testArray);
496
        $result1 = $access->bool('Foo', 'Bar', 'is_true');
497
        $result2 = $access->bool('Foo', 'Bar', 'is_false');
498
499
        static::assertTrue($result1);
500
        static::assertFalse($result2);
501
    }
502
503
    /**
504
     * @test
505
     */
506
    public function it_works_with_arrays(): void
507
    {
508
        $testArray = [
509
            'Foo' => [
510
                'Bar' => [
511
                    'Baz' => -999,
512
                ],
513
            ],
514
        ];
515
        $access = ArrayAccess::create($testArray);
516
        $result1 = $access->array('Foo');
517
        $result2 = $access->array('Foo', 'Bar');
518
519
        static::assertSame(['Bar' => ['Baz' => -999]], $result1);
520
        static::assertSame(['Baz' => -999], $result2);
521
    }
522
523
    /**
524
     * @test
525
     */
526
    public function it_works_with_arrays_returning_new_array_access(): void
527
    {
528
        $testArray = [
529
            'Foo' => [
530
                'Bar' => [
531
                    'Baz' => -999,
532
                ],
533
            ],
534
        ];
535
        $access = ArrayAccess::create($testArray);
536
        $result1 = $access->arrayAccess('Foo');
537
        $result2 = $access->arrayAccess('Foo', 'Bar');
538
539
        static::assertSame(['Bar' => ['Baz' => -999]], $result1->data());
540
        static::assertSame(['Baz' => -999], $result2->data());
541
    }
542
543
    /**
544
     * @test
545
     */
546
    public function it_works_with_objects_of_type(): void
547
    {
548
        $date = new \DateTimeImmutable();
549
        $testArray = [
550
            'Foo' => [
551
                'Bar' => [
552
                    'Baz' => $date,
553
                ],
554
            ],
555
        ];
556
        $access = ArrayAccess::create($testArray);
557
        $result = $access->objectOfType(\DateTimeImmutable::class, 'Foo', 'Bar', 'Baz');
558
559
        static::assertSame($date, $result);
560
    }
561
562
    /**
563
     * @test
564
     */
565
    public function it_works_with_custom_callback(): void
566
    {
567
        $testArray1 = [
568
            'Foo' => [
569
                'Bar' => [
570
                    'Baz' => 'Buz',
571
                ],
572
            ],
573
        ];
574
        $testArray2 = [
575
            'Foo' => [
576
                'Bar' => [
577
                    'Baz' => 99,
578
                ],
579
            ],
580
        ];
581
        $customCallback = function($value) {
582
            return is_string($value) || is_int($value);
583
        };
584
585
        $access1 = ArrayAccess::create($testArray1);
586
        $result1 = $access1->callback($customCallback, 'Foo', 'Bar', 'Baz');
587
588
        $access2 = ArrayAccess::create($testArray2);
589
        $result2 = $access2->callback($customCallback, 'Foo', 'Bar', 'Baz');
590
591
        static::assertSame('Buz', $result1);
592
        static::assertSame(99, $result2);
593
    }
594
595
    /**
596
     * @test
597
     */
598
    public function it_raises_an_exception_on_callback_restriction(): void
599
    {
600
        $this->expectException(ArrayAccessFailed::class);
601
        $this->expectExceptionMessage('[Array path: Foo.Bar.Baz] Could not get value for "Baz". Reason: Callback restriction');
602
603
        $testArray = [
604
            'Foo' => [
605
                    'Bar' => [
606
                    'Baz' => 'Buz',
607
                ],
608
            ],
609
        ];
610
        $customCallback = function($value) {
611
            return is_string($value) && in_array($value, ['Allowed value 1', 'Allowed value 2']);
612
        };
613
        $access = ArrayAccess::create($testArray);
614
        $access->callback($customCallback, 'Foo', 'Bar', 'Baz');
615
    }
616
617
    /**
618
     * @test
619
     */
620
    public function it_raises_an_exception_on_object_type_missmatch(): void
621
    {
622
        $this->expectException(ArrayAccessFailed::class);
623
        $this->expectExceptionMessage('[Array path: Foo.Bar.Baz] Could not get value for "Baz". Invalid type "DateTimeImmutable". Expected type: "DateTime"');
624
625
        $date = new \DateTimeImmutable();
626
        $testArray = [
627
            'Foo' => [
628
                'Bar' => [
629
                    'Baz' => $date,
630
                ],
631
            ],
632
        ];
633
        $access = ArrayAccess::create($testArray);
634
        $access->objectOfType(\DateTime::class, 'Foo', 'Bar', 'Baz');
635
    }
636
637
    /**
638
     * @test
639
     */
640
    public function it_works_with_datetime_immutable_parsing(): void
641
    {
642
        $testArray = [
643
            'Foo' => [
644
                'Bar' => [
645
                    'Baz' => '2020-01-02 14:30:55',
646
                ],
647
            ],
648
        ];
649
        $access = ArrayAccess::create($testArray);
650
        $result = $access->dateTimeImmutable('Y-m-d H:i:s', 'Foo', 'Bar', 'Baz');
651
652
        static::assertInstanceOf(\DateTimeImmutable::class, $result);
653
        static::assertSame('2020-01-02 14:30:55', $result->format('Y-m-d H:i:s'));
654
    }
655
656
    /**
657
     * @test
658
     */
659
    public function it_raises_an_exception_on_datetime_immutable_format_missmatch(): void
660
    {
661
        $this->expectException(ArrayAccessFailed::class);
662
        $this->expectExceptionMessage('[Array path: Foo.Bar.Baz] Could not get datetime object at "Baz" with format "Y-m-d H:i:s" from value "2020-01-02T14:30:55"');
663
664
        $testArray = [
665
            'Foo' => [
666
                'Bar' => [
667
                    'Baz' => '2020-01-02T14:30:55',
668
                ],
669
            ],
670
        ];
671
        $access = ArrayAccess::create($testArray);
672
        $access->dateTimeImmutable('Y-m-d H:i:s', 'Foo', 'Bar', 'Baz');
673
    }
674
675
    /**
676
     * @test
677
     */
678
    public function it_works_with_datetime_parsing(): void
679
    {
680
        $testArray = [
681
            'Foo' => [
682
                'Bar' => [
683
                    'Baz' => '2020-01-02 14:30:55',
684
                ],
685
            ],
686
        ];
687
        $access = ArrayAccess::create($testArray);
688
        $result = $access->dateTime('Y-m-d H:i:s', 'Foo', 'Bar', 'Baz');
689
690
        static::assertInstanceOf(\DateTime::class, $result);
691
        static::assertSame('2020-01-02 14:30:55', $result->format('Y-m-d H:i:s'));
692
    }
693
694
    /**
695
     * @test
696
     */
697
    public function it_raises_an_exception_on_datetime_format_missmatch(): void
698
    {
699
        $this->expectException(ArrayAccessFailed::class);
700
        $this->expectExceptionMessage('[Array path: Foo.Bar.Baz] Could not get datetime object at "Baz" with format "Y-m-d H:i:s" from value "2020-01-02T14:30:55"');
701
702
        $testArray = [
703
            'Foo' => [
704
                'Bar' => [
705
                    'Baz' => '2020-01-02T14:30:55',
706
                ],
707
            ],
708
        ];
709
        $access = ArrayAccess::create($testArray);
710
        $access->dateTime('Y-m-d H:i:s', 'Foo', 'Bar', 'Baz');
711
    }
712
713
    /**
714
     * @test
715
     */
716
    public function it_works_with_array_pos(): void
717
    {
718
        $testArray = [
719
            'Foo' => [
720
                'Bar' => [
721
                    [
722
                        'Baz1' => 'Buz1',
723
                    ],
724
                    [
725
                        'Baz2' => 'Buz2',
726
                    ],
727
                    [
728
                        'Baz3' => 'Buz3',
729
                    ],
730
                ],
731
            ],
732
        ];
733
734
        $access = ArrayAccess::create($testArray);
735
        $result1 = $access->string('Foo', 'Bar', '0', 'Baz1');
736
        $result2 = $access->string('Foo', 'Bar', '1', 'Baz2');
737
        $result3 = $access->string('Foo', 'Bar', '2', 'Baz3');
738
739
        static::assertSame('Buz1', $result1);
740
        static::assertSame('Buz2', $result2);
741
        static::assertSame('Buz3', $result3);
742
    }
743
744
    /**
745
     * @test
746
     * @dataProvider invalidInputProvider
747
     */
748
    public function it_raises_an_exception_on_invalid_input_type($value, $message): void
749
    {
750
        $this->expectException(ArrayAccessFailed::class);
751
        $this->expectExceptionMessage($message);
752
753
        ArrayAccess::create($value);
754
    }
755
756
    public function invalidInputProvider(): \Generator
757
    {
758
        yield [new \stdClass(), 'Given parameter "object" is not an array'];
759
        yield [1, 'Given parameter "integer" is not an array'];
760
        yield ['some', 'Given parameter "string" is not an array'];
761
    }
762
763
    /**
764
     * @test
765
     */
766
    public function it_raises_an_exception_on_invalid_method_call(): void
767
    {
768
        $this->expectException(BadMethodCallException::class);
769
        $this->expectExceptionMessage('Method "double" not found');
770
771
        $access = ArrayAccess::create([]);
772
        $access->double();
773
    }
774
}
775