GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( 971fda...722cc4 )
by Markus
01:03 queued 12s
created

ArrayAccessTest::it_works_with_arrays()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 0
dl 0
loc 15
rs 9.9666
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: Error: [minLength], Data pointer: [key1], Error: [type], Data pointer: [key2], Error: [additionalProperties], Data pointer: []');
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_at_path_on_empty_access(): void
202
    {
203
        $access = ArrayAccess::create([]);
204
        $newAccess = $access->writeAtPath('new-value', 'Foo', 'Bar', 'New');
205
206
        static::assertSame(
207
            [
208
                'Foo' => [
209
                    'Bar' => [
210
                        'New' => 'new-value',
211
                    ],
212
                ],
213
            ],
214
            $newAccess->data()
215
        );
216
    }
217
218
    /**
219
     * @test
220
     */
221
    public function it_writes_on_zero_index_if_empty_path_provided(): void
222
    {
223
        $access = ArrayAccess::create([]);
224
        $access = $access->writeAtPath('foo');
225
226
        static::assertSame(['foo'], $access->data());
227
    }
228
229
    /**
230
     * @test
231
     */
232
    public function it_writes_null_value_on_zero_index(): void
233
    {
234
        $access = ArrayAccess::create([]);
235
        $access = $access->writeAtPath(null);
236
237
        static::assertSame([0 => null], $access->data());
238
    }
239
240
    /**
241
     * @test
242
     */
243
    public function it_can_write_at_path_with_complex_data(): void
244
    {
245
        $testArray = [
246
            'Foo' => [
247
                'Bar' => [
248
                    'Baz' => 'Buz',
249
                    'next-key' => 'next-value',
250
                    'next-array' => [
251
                        'some' => 'some-value',
252
                        'other' => 'other-value'
253
                    ],
254
                ],
255
            ],
256
        ];
257
258
        $access = ArrayAccess::create($testArray);
259
        $newAccess = $access->writeAtPath(
260
            [
261
                'some' => 'some-value-2',
262
                'other' => 'new-other',
263
                'new' => 'new',
264
            ],
265
            'Foo', 'Bar', 'next-array'
266
        );
267
268
        static::assertSame(
269
            [
270
                'Foo' => [
271
                    'Bar' => [
272
                        'Baz' => 'Buz',
273
                        'next-key' => 'next-value',
274
                        'next-array' => [
275
                            'some' => 'some-value-2',
276
                            'other' => 'new-other',
277
                            'new' => 'new',
278
                        ],
279
                    ],
280
                ],
281
            ],
282
            $newAccess->data()
283
        );
284
    }
285
286
    /**
287
     * @test
288
     */
289
    public function it_can_overwrite_at_path(): void
290
    {
291
        $testArray = [
292
            'Foo' => [
293
                'Bar' => [
294
                    'Baz' => 'Buz',
295
                ],
296
            ],
297
        ];
298
299
        $access = ArrayAccess::create($testArray);
300
        $newAccess = $access->writeAtPath('new-value', 'Foo', 'Bar', 'Baz');
301
302
        static::assertSame(
303
            [
304
                'Foo' => [
305
                    'Bar' => [
306
                        'Baz' => 'new-value',
307
                    ],
308
                ],
309
            ],
310
            $newAccess->data()
311
        );
312
    }
313
314
    /**
315
     * @test
316
     */
317
    public function it_can_return_if_a_path_exists(): void
318
    {
319
        $testArray = [
320
                'Foo' => [
321
                    'Bar' => [
322
                        'Baz' => 'Buz',
323
                    ],
324
                ],
325
            ];
326
327
        $access = ArrayAccess::create($testArray);
328
329
        static::assertTrue($access->hasPath('Foo'));
330
        static::assertTrue($access->hasPath('Foo', 'Bar'));
331
        static::assertTrue($access->hasPath('Foo', 'Bar', 'Baz'));
332
        static::assertFalse($access->hasPath('Foo', 'Bar', 'Baz', 'Buz'));
333
        static::assertFalse($access->hasPath('BuzBuz'));
334
    }
335
336
    /**
337
     * @test
338
     */
339
    public function it_raises_an_exception_on_not_existing_path(): void
340
    {
341
        $this->expectException(ArrayAccessFailed::class);
342
        $this->expectExceptionMessage('Path not found');
343
344
        $access = ArrayAccess::create(['foo' => ['bar' => null]]);
345
        $access->int('foo', 'bar', 'baz');
346
    }
347
348
    /**
349
     * @test
350
     */
351
    public function it_raises_an_exception_on_unknown_method_call(): void
352
    {
353
        $this->expectException(BadMethodCallException::class);
354
        $this->expectExceptionMessage('Method "unknownMethod" not found');
355
356
        ArrayAccess::create([])->unknownMethod();
357
    }
358
359
    /**
360
     * @test
361
     */
362
    public function it_works_with_strings(): void
363
    {
364
        $testArray = [
365
            'Foo' => [
366
                'Bar' => [
367
                    'Baz' => 'Buz',
368
                ],
369
            ],
370
        ];
371
        $access = ArrayAccess::create($testArray);
372
        $result = $access->string('Foo', 'Bar', 'Baz');
373
374
        static::assertSame('Buz', $result);
375
    }
376
377
    /**
378
     * @test
379
     */
380
    public function it_works_with_nullable_strings(): void
381
    {
382
        $testArray = [
383
            'Foo' => [
384
                'Bar' => [
385
                    'Baz' => null,
386
                ],
387
            ],
388
        ];
389
        $access = ArrayAccess::create($testArray);
390
        $result = $access->stringOrNull('Foo', 'Bar', 'Baz');
391
392
        static::assertNull($result);
393
    }
394
395
    /**
396
     * @test
397
     */
398
    public function it_raises_an_exception_on_value_other_than_null_when_requesting_nullable(): void
399
    {
400
        $this->expectException(ArrayAccessFailed::class);
401
        $this->expectExceptionMessage('[Array path: Foo.Bar.Baz] Could not get value for "Baz". Invalid type "integer". Expected type: "stringOrNull"');
402
403
        $testArray = [
404
            'Foo' => [
405
                'Bar' => [
406
                    'Baz' => 1,
407
                ],
408
            ],
409
        ];
410
        $access = ArrayAccess::create($testArray);
411
        $access->stringOrNull('Foo', 'Bar', 'Baz');
412
    }
413
414
    /**
415
     * @test
416
     */
417
    public function it_works_with_integers(): void
418
    {
419
        $testArray = [
420
            'Foo' => [
421
                'Bar' => [
422
                    'Baz' => -999,
423
                ],
424
            ],
425
        ];
426
        $access = ArrayAccess::create($testArray);
427
        $result = $access->int('Foo', 'Bar', 'Baz');
428
429
        static::assertSame(-999, $result);
430
    }
431
432
    /**
433
     * @test
434
     */
435
    public function it_works_with_floats(): void
436
    {
437
        $testArray = [
438
            'Foo' => [
439
                'Bar' => [
440
                    'Baz' => -98.112,
441
                ],
442
            ],
443
        ];
444
        $access = ArrayAccess::create($testArray);
445
        $result = $access->float('Foo', 'Bar', 'Baz');
446
447
        static::assertSame(-98.112, $result);
448
    }
449
450
    /**
451
     * @test
452
     */
453
    public function it_works_with_booleans(): void
454
    {
455
        $testArray = [
456
            'Foo' => [
457
                'Bar' => [
458
                    'is_true' => true,
459
                    'is_false' => false,
460
                ],
461
            ],
462
        ];
463
        $access = ArrayAccess::create($testArray);
464
        $result1 = $access->bool('Foo', 'Bar', 'is_true');
465
        $result2 = $access->bool('Foo', 'Bar', 'is_false');
466
467
        static::assertTrue($result1);
468
        static::assertFalse($result2);
469
    }
470
471
    /**
472
     * @test
473
     */
474
    public function it_works_with_arrays(): void
475
    {
476
        $testArray = [
477
            'Foo' => [
478
                'Bar' => [
479
                    'Baz' => -999,
480
                ],
481
            ],
482
        ];
483
        $access = ArrayAccess::create($testArray);
484
        $result1 = $access->array('Foo');
485
        $result2 = $access->array('Foo', 'Bar');
486
487
        static::assertSame(['Bar' => ['Baz' => -999]], $result1);
488
        static::assertSame(['Baz' => -999], $result2);
489
    }
490
491
    /**
492
     * @test
493
     */
494
    public function it_works_with_arrays_returning_new_array_access(): void
495
    {
496
        $testArray = [
497
            'Foo' => [
498
                'Bar' => [
499
                    'Baz' => -999,
500
                ],
501
            ],
502
        ];
503
        $access = ArrayAccess::create($testArray);
504
        $result1 = $access->arrayAccess('Foo');
505
        $result2 = $access->arrayAccess('Foo', 'Bar');
506
507
        static::assertSame(['Bar' => ['Baz' => -999]], $result1->data());
508
        static::assertSame(['Baz' => -999], $result2->data());
509
    }
510
511
    /**
512
     * @test
513
     */
514
    public function it_works_with_objects_of_type(): void
515
    {
516
        $date = new \DateTimeImmutable();
517
        $testArray = [
518
            'Foo' => [
519
                'Bar' => [
520
                    'Baz' => $date,
521
                ],
522
            ],
523
        ];
524
        $access = ArrayAccess::create($testArray);
525
        $result = $access->objectOfType(\DateTimeImmutable::class, 'Foo', 'Bar', 'Baz');
526
527
        static::assertSame($date, $result);
528
    }
529
530
    /**
531
     * @test
532
     */
533
    public function it_works_with_custom_callback(): void
534
    {
535
        $testArray1 = [
536
            'Foo' => [
537
                'Bar' => [
538
                    'Baz' => 'Buz',
539
                ],
540
            ],
541
        ];
542
        $testArray2 = [
543
            'Foo' => [
544
                'Bar' => [
545
                    'Baz' => 99,
546
                ],
547
            ],
548
        ];
549
        $customCallback = function($value) {
550
            return is_string($value) || is_int($value);
551
        };
552
553
        $access1 = ArrayAccess::create($testArray1);
554
        $result1 = $access1->callback($customCallback, 'Foo', 'Bar', 'Baz');
555
556
        $access2 = ArrayAccess::create($testArray2);
557
        $result2 = $access2->callback($customCallback, 'Foo', 'Bar', 'Baz');
558
559
        static::assertSame('Buz', $result1);
560
        static::assertSame(99, $result2);
561
    }
562
563
    /**
564
     * @test
565
     */
566
    public function it_raises_an_exception_on_callback_restriction(): void
567
    {
568
        $this->expectException(ArrayAccessFailed::class);
569
        $this->expectExceptionMessage('[Array path: Foo.Bar.Baz] Could not get value for "Baz". Reason: Callback restriction');
570
571
        $testArray = [
572
            'Foo' => [
573
                    'Bar' => [
574
                    'Baz' => 'Buz',
575
                ],
576
            ],
577
        ];
578
        $customCallback = function($value) {
579
            return is_string($value) && in_array($value, ['Allowed value 1', 'Allowed value 2']);
580
        };
581
        $access = ArrayAccess::create($testArray);
582
        $access->callback($customCallback, 'Foo', 'Bar', 'Baz');
583
    }
584
585
    /**
586
     * @test
587
     */
588
    public function it_raises_an_exception_on_object_type_missmatch(): void
589
    {
590
        $this->expectException(ArrayAccessFailed::class);
591
        $this->expectExceptionMessage('[Array path: Foo.Bar.Baz] Could not get value for "Baz". Invalid type "DateTimeImmutable". Expected type: "DateTime"');
592
593
        $date = new \DateTimeImmutable();
594
        $testArray = [
595
            'Foo' => [
596
                'Bar' => [
597
                    'Baz' => $date,
598
                ],
599
            ],
600
        ];
601
        $access = ArrayAccess::create($testArray);
602
        $access->objectOfType(\DateTime::class, 'Foo', 'Bar', 'Baz');
603
    }
604
605
    /**
606
     * @test
607
     */
608
    public function it_works_with_datetime_immutable_parsing(): void
609
    {
610
        $testArray = [
611
            'Foo' => [
612
                'Bar' => [
613
                    'Baz' => '2020-01-02 14:30:55',
614
                ],
615
            ],
616
        ];
617
        $access = ArrayAccess::create($testArray);
618
        $result = $access->dateTimeImmutable('Y-m-d H:i:s', 'Foo', 'Bar', 'Baz');
619
620
        static::assertInstanceOf(\DateTimeImmutable::class, $result);
621
        static::assertSame('2020-01-02 14:30:55', $result->format('Y-m-d H:i:s'));
622
    }
623
624
    /**
625
     * @test
626
     */
627
    public function it_raises_an_exception_on_datetime_immutable_format_missmatch(): void
628
    {
629
        $this->expectException(ArrayAccessFailed::class);
630
        $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"');
631
632
        $testArray = [
633
            'Foo' => [
634
                'Bar' => [
635
                    'Baz' => '2020-01-02T14:30:55',
636
                ],
637
            ],
638
        ];
639
        $access = ArrayAccess::create($testArray);
640
        $access->dateTimeImmutable('Y-m-d H:i:s', 'Foo', 'Bar', 'Baz');
641
    }
642
643
    /**
644
     * @test
645
     */
646
    public function it_works_with_datetime_parsing(): void
647
    {
648
        $testArray = [
649
            'Foo' => [
650
                'Bar' => [
651
                    'Baz' => '2020-01-02 14:30:55',
652
                ],
653
            ],
654
        ];
655
        $access = ArrayAccess::create($testArray);
656
        $result = $access->dateTime('Y-m-d H:i:s', 'Foo', 'Bar', 'Baz');
657
658
        static::assertInstanceOf(\DateTime::class, $result);
659
        static::assertSame('2020-01-02 14:30:55', $result->format('Y-m-d H:i:s'));
660
    }
661
662
    /**
663
     * @test
664
     */
665
    public function it_raises_an_exception_on_datetime_format_missmatch(): void
666
    {
667
        $this->expectException(ArrayAccessFailed::class);
668
        $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"');
669
670
        $testArray = [
671
            'Foo' => [
672
                'Bar' => [
673
                    'Baz' => '2020-01-02T14:30:55',
674
                ],
675
            ],
676
        ];
677
        $access = ArrayAccess::create($testArray);
678
        $access->dateTime('Y-m-d H:i:s', 'Foo', 'Bar', 'Baz');
679
    }
680
681
    /**
682
     * @test
683
     */
684
    public function it_works_with_array_pos(): void
685
    {
686
        $testArray = [
687
            'Foo' => [
688
                'Bar' => [
689
                    [
690
                        'Baz1' => 'Buz1',
691
                    ],
692
                    [
693
                        'Baz2' => 'Buz2',
694
                    ],
695
                    [
696
                        'Baz3' => 'Buz3',
697
                    ],
698
                ],
699
            ],
700
        ];
701
702
        $access = ArrayAccess::create($testArray);
703
        $result1 = $access->string('Foo', 'Bar', '0', 'Baz1');
704
        $result2 = $access->string('Foo', 'Bar', '1', 'Baz2');
705
        $result3 = $access->string('Foo', 'Bar', '2', 'Baz3');
706
707
        static::assertSame('Buz1', $result1);
708
        static::assertSame('Buz2', $result2);
709
        static::assertSame('Buz3', $result3);
710
    }
711
712
    /**
713
     * @test
714
     * @dataProvider invalidInputProvider
715
     */
716
    public function it_raises_an_exception_on_invalid_input_type($value, $message): void
717
    {
718
        $this->expectException(ArrayAccessFailed::class);
719
        $this->expectExceptionMessage($message);
720
721
        ArrayAccess::create($value);
722
    }
723
724
    public function invalidInputProvider(): \Generator
725
    {
726
        yield [new \stdClass(), 'Given parameter "object" is not an array'];
727
        yield [1, 'Given parameter "integer" is not an array'];
728
        yield ['some', 'Given parameter "string" is not an array'];
729
    }
730
731
    /**
732
     * @test
733
     */
734
    public function it_raises_an_exception_on_invalid_method_call(): void
735
    {
736
        $this->expectException(BadMethodCallException::class);
737
        $this->expectExceptionMessage('Method "double" not found');
738
739
        $access = ArrayAccess::create([]);
740
        $access->double();
741
    }
742
}
743