Completed
Push — master ( 3febd0...37877d )
by AJ
11:49
created

ValidationTest::testUnexpectedArray()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 10
nc 2
nop 0
dl 0
loc 16
rs 9.9332
c 0
b 0
f 0
1
<?php
2
/**
3
 *       __  ___      ____  _     ___                           _                    __
4
 *      /  |/  /_  __/ / /_(_)___/ (_)___ ___  ___  ____  _____(_)___  ____   ____ _/ /
5
 *     / /|_/ / / / / / __/ / __  / / __ `__ \/ _ \/ __ \/ ___/ / __ \/ __ \ / __ `/ /
6
 *    / /  / / /_/ / / /_/ / /_/ / / / / / / /  __/ / / (__  ) / /_/ / / / // /_/ / /
7
 *   /_/  /_/\__,_/_/\__/_/\__,_/_/_/ /_/ /_/\___/_/ /_/____/_/\____/_/ /_(_)__,_/_/
8
 *
9
 *  Array Validation Library
10
 *  Copyright (c) Multidimension.al (http://multidimension.al)
11
 *  Github : https://github.com/multidimension-al/array-validation
12
 *
13
 *  Licensed under The MIT License
14
 *  For full copyright and license information, please see the LICENSE file
15
 *  Redistributions of files must retain the above copyright notice.
16
 *
17
 *  @copyright  Copyright © 2017-2019 Multidimension.al (http://multidimension.al)
18
 *  @link       https://github.com/multidimension-al/array-validation Github
19
 *  @license    http://www.opensource.org/licenses/mit-license.php MIT License
20
 */
21
22
namespace Multidimensional\ArrayValidation\Test;
23
24
use Exception;
25
use Multidimensional\ArrayValidation\Validation;
26
use PHPUnit\Framework\TestCase;
27
28
class ValidationTest extends TestCase
29
{
30
31
    public function testEmptyValidation()
32
    {
33
        $this->assertTrue(Validation::validate([], []));
34
    }
35
36
    public function testFailedValidation()
37
    {
38
        try {
39
            $this->assertFalse(Validation::validate('', ''));
0 ignored issues
show
Bug introduced by
'' of type string is incompatible with the type array expected by parameter $array of Multidimensional\ArrayVa...\Validation::validate(). ( Ignorable by Annotation )

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

39
            $this->assertFalse(Validation::validate(/** @scrutinizer ignore-type */ '', ''));
Loading history...
Bug introduced by
'' of type string is incompatible with the type array expected by parameter $rules of Multidimensional\ArrayVa...\Validation::validate(). ( Ignorable by Annotation )

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

39
            $this->assertFalse(Validation::validate('', /** @scrutinizer ignore-type */ ''));
Loading history...
40
        } catch (Exception $e) {
41
            $this->assertEquals('Validation array not found.', $e->getMessage());
42
        }
43
44
        try {
45
            $this->assertFalse(Validation::validate([], ''));
46
        } catch (Exception $e) {
47
            $this->assertEquals('Validation rules array not found.', $e->getMessage());
48
        }
49
50
        try {
51
            $this->assertFalse(Validation::validate('', []));
52
        } catch (Exception $e) {
53
            $this->assertEquals('Validation array not found.', $e->getMessage());
54
        }
55
    }
56
57
    public function testRequiredTrue()
58
    {
59
        $rules = [
60
            'a' => ['type' => 'string', 'required' => true],
61
            'b' => ['type' => 'string']
62
        ];
63
        $array = [
64
            'a' => 'Hello',
65
            'b' => 'World'
66
        ];
67
        $this->assertTrue(Validation::validate($array, $rules));
68
69
        $array = [
70
            'b' => 'Goodbye'
71
        ];
72
73
        try {
74
            $this->assertFalse(Validation::validate($array, $rules));
75
        } catch (Exception $e) {
76
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
77
        }
78
79
        $rules['a']['required'] = 'true';
80
81
        try {
82
            $this->assertFalse(Validation::validate($array, $rules));
83
        } catch (Exception $e) {
84
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
85
        }
86
    }
87
88
    public function testValidateValues()
89
    {
90
        $rules = [
91
            'a' => ['type' => 'string', 'values' => ['a', 'b', 'c']]
92
        ];
93
        $array = [
94
            'a' => 'b'
95
        ];
96
        $this->assertTrue(Validation::validate($array, $rules));
97
    }
98
99
    public function testValidateValuesFailure()
100
    {
101
        $rules = [
102
            'a' => ['type' => 'string', 'values' => ['cat', 'dog']]
103
        ];
104
        $array = [
105
            'a' => 'kat'
106
        ];
107
        try {
108
            $this->assertFalse(Validation::validate($array, $rules));
109
        } catch (Exception $e) {
110
            $this->assertEquals('Invalid value "kat" for key: a. Did you mean "cat"?', $e->getMessage());
111
        }
112
    }
113
114
    public function testValidateValuesOnlyOption()
115
    {
116
        $rules = [
117
            'a' => ['type' => 'string', 'values' => 'b']
118
        ];
119
        $array = [
120
            'a' => 'b'
121
        ];
122
        $this->assertTrue(Validation::validate($array, $rules));
123
    }
124
125
    public function testInteger()
126
    {
127
        $rules = [
128
            'a' => ['type' => 'integer'],
129
            'b' => ['type' => 'integer']
130
        ];
131
        $array = [
132
            'a' => 1,
133
            'b' => 2
134
        ];
135
        $this->assertTrue(Validation::validate($array, $rules));
136
        $array = [
137
            'a' => 1,
138
            'b' => 'one'
139
        ];
140
141
        try {
142
            $this->assertFalse(Validation::validate($array, $rules));
143
        } catch (Exception $e) {
144
            $this->assertEquals('Invalid integer "one" for key: b.', $e->getMessage());
145
        }
146
    }
147
148
    public function testDecimal()
149
    {
150
        $rules = [
151
            'a' => ['type' => 'decimal'],
152
            'b' => ['type' => 'decimal']
153
        ];
154
        $array = [
155
            'a' => 1.0,
156
            'b' => 2.1
157
        ];
158
        $this->assertTrue(Validation::validate($array, $rules));
159
        $array = [
160
            'a' => 1.0,
161
            'b' => 'one point 2'
162
        ];
163
164
        try {
165
            $this->assertFalse(Validation::validate($array, $rules));
166
        } catch (Exception $e) {
167
            $this->assertEquals('Invalid decimal "one point 2" for key: b.', $e->getMessage());
168
        }
169
    }
170
171
    public function testRequiredDecimal()
172
    {
173
        $rules = [
174
            'a' => ['type' => 'decimal', 'required' => true]
175
        ];
176
        $array = [
177
            'a' => 0
178
        ];
179
        $this->assertTrue(Validation::validate($array, $rules));
180
    }
181
182
    public function testString()
183
    {
184
        $rules = [
185
            'a' => ['type' => 'string'],
186
            'b' => ['type' => 'string']
187
        ];
188
        $array = [
189
            'a' => 'Yes this is obviously',
190
            'b' => "a string"
191
        ];
192
        $this->assertTrue(Validation::validate($array, $rules));
193
        $array = [
194
            'a' => 1,
195
            'b' => 'one point 2'
196
        ];
197
198
        try {
199
            $this->assertFalse(Validation::validate($array, $rules));
200
        } catch (Exception $e) {
201
            $this->assertEquals('Invalid string "1" for key: a.', $e->getMessage());
202
        }
203
    }
204
205
    public function testBoolean()
206
    {
207
        $rules = [
208
            'a' => ['type' => 'boolean'],
209
            'b' => ['type' => 'boolean']
210
        ];
211
        $array = [
212
            'a' => true,
213
            'b' => false
214
        ];
215
        $this->assertTrue(Validation::validate($array, $rules));
216
217
        $array = [
218
            'a' => 'true',
219
            'b' => 'false'
220
        ];
221
        try {
222
            $this->assertFalse(Validation::validate($array, $rules));
223
        } catch (Exception $e) {
224
            $this->assertEquals('Invalid boolean "true" for key: a.', $e->getMessage());
225
        }
226
227
        $array = [
228
            'a' => 1,
229
            'b' => 'false'
230
        ];
231
232
        try {
233
            $this->assertFalse(Validation::validate($array, $rules));
234
        } catch (Exception $e) {
235
            $this->assertEquals('Invalid boolean "1" for key: a.', $e->getMessage());
236
        }
237
    }
238
239
    public function testValidatePattern()
240
    {
241
        $rules = [
242
            'a' => ['type' => 'string', 'pattern' => '[A-Z]{2}'],
243
            'b' => ['type' => 'datetime', 'pattern' => 'ISO 8601']
244
        ];
245
        $array = [
246
            'a' => 'CA',
247
            'b' => '2014-01-22T14:30:51-06:00'
248
        ];
249
        $this->assertTrue(Validation::validate($array, $rules));
250
251
        $array = [
252
            'a' => 'CAT',
253
        ];
254
255
        try {
256
            $this->assertFalse(Validation::validate($array, $rules));
257
        } catch (Exception $e) {
258
            $this->assertEquals('Invalid value "CAT" does not match pattern "[A-Z]{2}" for key: a.', $e->getMessage());
259
        }
260
261
        $array = [
262
            'b' => '2014-01-22',
263
        ];
264
265
        try {
266
            $this->assertFalse(Validation::validate($array, $rules));
267
        } catch (Exception $e) {
268
            $this->assertEquals('Invalid value "2014-01-22" does not match ISO 8601 pattern for key: b.', $e->getMessage());
269
        }
270
    }
271
272
    public function testFieldNotInRules()
273
    {
274
        $rules = [
275
            'a' => ['type' => 'string']
276
        ];
277
        $array = [
278
            'a' => 'string',
279
            'b' => 'unexpected'
280
        ];
281
282
        try {
283
            $this->assertFalse(Validation::validate($array, $rules));
284
        } catch (Exception $e) {
285
            $this->assertEquals('Unexpected key "b" found in array.', $e->getMessage());
286
        }
287
    }
288
289
    public function testMultidimensionalValidation()
290
    {
291
        $rules = [
292
            'a' => ['type' => 'array',
293
                'fields' => [
294
                    'a' => ['type' => 'string'],
295
                    'b' => ['type' => 'string']
296
                ]
297
            ],
298
            'b' => ['type' => 'string']
299
        ];
300
        $array = [
301
            'a' => [
302
                'a' => 'string',
303
                'b' => 'test'
304
            ],
305
            'b' => 'b'
306
        ];
307
        $this->assertTrue(Validation::validate($array, $rules));
308
309
        $array = [
310
            'b' => [
311
                'a' => 'string',
312
                'b' => 'test'
313
            ]
314
        ];
315
316
        try {
317
            $this->assertFalse(Validation::validate($array, $rules));
318
        } catch (Exception $e) {
319
            $this->assertEquals("Unexpected array found for key: b.", $e->getMessage());
320
        }
321
    }
322
323
    public function testGroupValidation()
324
    {
325
        $rules2 = [
326
            'b' => ['type' => 'string']
327
        ];
328
        $rules = [
329
            'a' => [
330
                'type' => 'group',
331
                'fields' => $rules2
332
            ]
333
        ];
334
        $array = [
335
            'a' => [['b' => 'Hello']]
336
        ];
337
        $this->assertTrue(Validation::validate($array, $rules));
338
        $array = [
339
            'a' => [
340
                ['b' => 'Hello'],
341
                ['b' => 'World'],
342
            ]
343
        ];
344
        $this->assertTrue(Validation::validate($array, $rules));
345
    }
346
347
    public function testRequiredComplex()
348
    {
349
        $rules = [
350
            'a' => ['type' => 'string', 'required' => true],
351
            'b' => ['type' => 'string',
352
                'required' => [
353
                    'a' => 'banana'
354
                ]
355
            ],
356
            'c' => ['type' => 'string',
357
                'required' => [
358
                    [
359
                        'a' => 'banana',
360
                        'b' => 'orange'
361
                    ],
362
                    [
363
                        'a' => 'banana',
364
                        'b' => 'carrot'
365
                    ],
366
                    [
367
                        'a' => 'pickle'
368
                    ],
369
                    [
370
                        'b' => 'banana'
371
                    ]
372
                ]
373
            ],
374
        ];
375
        $array = [
376
            'a' => 'apple'
377
        ];
378
        $this->assertTrue(Validation::validate($array, $rules));
379
380
        $array = [
381
            'a' => 'banana',
382
            'b' => 'orange',
383
            'c' => 'other'
384
        ];
385
        $this->assertTrue(Validation::validate($array, $rules));
386
387
        $array = [
388
            'a' => 'banana',
389
            'c' => 'orange'
390
        ];
391
392
        try {
393
            $this->assertFalse(Validation::validate($array, $rules));
394
        } catch (Exception $e) {
395
            $this->assertEquals('Required value not found for key: b.', $e->getMessage());
396
        }
397
398
        $array = [
399
            'a' => 'banana',
400
            'b' => 'carrot'
401
        ];
402
403
        try {
404
            $this->assertFalse(Validation::validate($array, $rules));
405
        } catch (Exception $e) {
406
            $this->assertEquals('Required value not found for key: c.', $e->getMessage());
407
        }
408
409
        $array = [
410
            'b' => 'banana'
411
        ];
412
413
        try {
414
            $this->assertFalse(Validation::validate($array, $rules));
415
        } catch (Exception $e) {
416
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
417
        }
418
419
        $array = [
420
            'a' => 'carrot',
421
            'b' => 'banana'
422
        ];
423
424
        try {
425
            $this->assertFalse(Validation::validate($array, $rules));
426
        } catch (Exception $e) {
427
            $this->assertEquals('Required value not found for key: c.', $e->getMessage());
428
        }
429
    }
430
431
    public function testRequiredNull()
432
    {
433
        $rules = [
434
            'a' => ['type' => 'string',
435
                'required' => [
436
                    'b' => 'null'
437
                ]
438
            ],
439
            'b' => ['type' => 'string'],
440
            'c' => ['type' => 'string'],
441
        ];
442
        $array = [
443
            'b' => 'not a null value',
444
            'c' => 'no one cares about c'
445
        ];
446
        $this->assertTrue(Validation::validate($array, $rules));
447
448
        $array = [
449
            'c' => 'c is lonely'
450
        ];
451
452
        try {
453
            $this->assertFalse(Validation::validate($array, $rules));
454
        } catch (Exception $e) {
455
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
456
        }
457
458
        $array = [];
459
460
        try {
461
            $this->assertFalse(Validation::validate($array, $rules));
462
        } catch (Exception $e) {
463
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
464
        }
465
466
        $rules['a']['required']['b'] = null;
467
468
        try {
469
            $this->assertFalse(Validation::validate($array, $rules));
470
        } catch (Exception $e) {
471
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
472
        }
473
    }
474
475
    public function testNullValue()
476
    {
477
        $rules = [
478
            'a' => ['type' => 'string']
479
        ];
480
        $array = [
481
            'a' => null
482
        ];
483
        $this->assertTrue(Validation::validate($array, $rules));
484
485
        $array['a'] = 'null';
486
        $this->assertTrue(Validation::validate($array, $rules));
487
    }
488
489
    public function testInvalidRequiredValue()
490
    {
491
        $rules = [
492
            'a' => [
493
                'type' => 'string',
494
                'required' => 'banana'
495
            ]
496
        ];
497
        $array = [
498
            'a' => null
499
        ];
500
501
        try {
502
            $this->assertFalse(Validation::validate($array, $rules));
503
        } catch (Exception $e) {
504
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
505
        }
506
    }
507
508
    public function testRequiredWhenNull()
509
    {
510
        $rules = [
511
            'a' =>
512
                ['type' => 'string',
513
                    'required' => [
514
                        'b' => null
515
                    ]
516
                ],
517
            'b' => ['type' => 'string'],
518
            'c' => ['type' => 'string']
519
        ];
520
        $array = ['c' => 'Hi'];
521
522
        try {
523
            $this->assertFalse(Validation::validate($array, $rules));
524
        } catch (Exception $e) {
525
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
526
        }
527
    }
528
529
    public function testUnexpectedArray()
530
    {
531
        $rules = [
532
            'a' => [
533
                'type' => 'string'
534
            ]
535
        ];
536
        $array = [
537
            'a' => [
538
                'b' => 'c'
539
            ]
540
        ];
541
        try {
542
            $this->assertFalse(Validation::validate($array, $rules));
543
        } catch (Exception $e) {
544
            $this->assertEquals('Unexpected array found for key: a.', $e->getMessage());
545
        }
546
    }
547
548
    public function testMultiDimensionalArray()
549
    {
550
        $rules = [
551
            'RateV4Response' => [
552
                'type' => 'array',
553
                'fields' => [
554
                    'Package' => [
555
                        'type' => 'group',
556
                        'fields' => [
557
                            '@ID' => [
558
                                'type' => 'string',
559
                                'required' => true
560
                            ],
561
                            'ZipOrigination' => [
562
                                'type' => 'string',
563
                                'required' => true,
564
                                'pattern' => '\d{5}'
565
                            ],
566
                            'ZipDestination' => [
567
                                'type' => 'string',
568
                                'required' => true,
569
                                'pattern' => '\d{5}'
570
                            ],
571
                            'Pounds' => [
572
                                'type' => 'decimal',
573
                                'required' => true,
574
                            ],
575
                            'Ounces' => [
576
                                'type' => 'decimal',
577
                                'required' => true,
578
                            ],
579
                            'FirstClassMailType' => [
580
                                'type' => 'string'
581
                            ],
582
                            'Container' => [
583
                                'type' => 'string',
584
                            ],
585
                            'Size' => [
586
                                'type' => 'string',
587
                                'required' => true,
588
                                'values' => [
589
                                    'REGULAR',
590
                                    'LARGE'
591
                                ]
592
                            ],
593
                            'Width' => [
594
                                'type' => 'decimal'
595
                            ],
596
                            'Length' => [
597
                                'type' => 'decimal'
598
                            ],
599
                            'Height' => [
600
                                'type' => 'decimal'
601
                            ],
602
                            'Girth' => [
603
                                'type' => 'decimal'
604
                            ],
605
                            'Machinable' => [
606
                                'type' => 'boolean'
607
                            ],
608
                            'Zone' => [
609
                                'type' => 'string'
610
                            ],
611
                            'Postage' => [
612
                                'type' => 'group',
613
                                'required' => true,
614
                                'fields' => [
615
                                    '@CLASSID' => [
616
                                        'type' => 'integer'
617
                                    ],
618
                                    'MailService' => [
619
                                        'type' => 'string'
620
                                    ],
621
                                    'Rate' => [
622
                                        'type' => 'decimal'
623
                                    ]
624
                                ]
625
                            ]
626
                        ]
627
                    ]
628
                ]
629
            ]
630
        ];
631
        $array = [
632
            'RateV4Response' => [
633
                'Package' => [
634
                    '@ID' => '123',
635
                    'ZipOrigination' => '20500',
636
                    'ZipDestination' => '90210',
637
                    'Pounds' => 0.0,
638
                    'Ounces' => 32.0,
639
                    'Size' => 'REGULAR',
640
                    'Machinable' => true,
641
                    'Zone' => '8',
642
                    'Postage' => [
643
                        0 => [
644
                            '@CLASSID' => 1,
645
                            'MailService' => 'Priority Mail 2-Day<sup>™</sup>',
646
                            'Rate' => 12.75
647
                        ],
648
                        1 => [
649
                            '@CLASSID' => 22,
650
                            'MailService' => 'Priority Mail 2-Day<sup>™</sup> Large Flat Rate Box',
651
                            'Rate' => 18.85
652
                        ],
653
                        2 => [
654
                            '@CLASSID' => 17,
655
                            'MailService' => 'Priority Mail 2-Day<sup>™</sup> Medium Flat Rate Box',
656
                            'Rate' => 13.60
657
                        ],
658
                        3 => [
659
                            '@CLASSID' => 28,
660
                            'MailService' => 'Priority Mail 2-Day<sup>™</sup> Small Flat Rate Box',
661
                            'Rate' => 7.15
662
                        ]
663
                    ]
664
                ]
665
            ]
666
        ];
667
        $this->assertTrue(Validation::validate($array, $rules));
668
    }
669
670
    public function testMultiMultiMultidimensionalArray()
671
    {
672
        $rules = [
673
            'RateV4Response' => [
674
                'type' => 'array',
675
                'fields' => [
676
                    'Package' => [
677
                        'type' => 'group',
678
                        'fields' => [
679
                            '@ID' => [
680
                                'type' => 'string',
681
                                'required' => true
682
                            ],
683
                            'ZipOrigination' => [
684
                                'type' => 'string',
685
                                'required' => true,
686
                                'pattern' => '\d{5}'
687
                            ],
688
                            'ZipDestination' => [
689
                                'type' => 'string',
690
                                'required' => true,
691
                                'pattern' => '\d{5}'
692
                            ],
693
                            'Pounds' => [
694
                                'type' => 'decimal',
695
                                'required' => true,
696
                            ],
697
                            'Ounces' => [
698
                                'type' => 'decimal',
699
                                'required' => true,
700
                            ],
701
                            'FirstClassMailType' => [
702
                                'type' => 'string'
703
                            ],
704
                            'Container' => [
705
                                'type' => 'string',
706
                            ],
707
                            'Size' => [
708
                                'type' => 'string',
709
                                'required' => true,
710
                                'values' => [
711
                                    'REGULAR',
712
                                    'LARGE'
713
                                ]
714
                            ],
715
                            'Width' => [
716
                                'type' => 'decimal'
717
                            ],
718
                            'Length' => [
719
                                'type' => 'decimal'
720
                            ],
721
                            'Height' => [
722
                                'type' => 'decimal'
723
                            ],
724
                            'Girth' => [
725
                                'type' => 'decimal'
726
                            ],
727
                            'Machinable' => [
728
                                'type' => 'boolean'
729
                            ],
730
                            'Zone' => [
731
                                'type' => 'string'
732
                            ],
733
                            'Postage' => [
734
                                'type' => 'group',
735
                                'required' => true,
736
                                'fields' => [
737
                                    '@CLASSID' => [
738
                                        'type' => 'integer'
739
                                    ],
740
                                    'MailService' => [
741
                                        'type' => 'string'
742
                                    ],
743
                                    'Rate' => [
744
                                        'type' => 'decimal'
745
                                    ]
746
                                ]
747
                            ]
748
                        ]
749
                    ]
750
                ]
751
            ]
752
        ];
753
        $array = [
754
            'RateV4Response' => [
755
                'Package' => [
756
                    0 => [
757
                        '@ID' => '123',
758
                        'ZipOrigination' => '20500',
759
                        'ZipDestination' => '90210',
760
                        'Pounds' => 0.0,
761
                        'Ounces' => 32.0,
762
                        'Size' => 'REGULAR',
763
                        'Machinable' => true,
764
                        'Zone' => '8',
765
                        'Postage' => [
766
                            0 => [
767
                                '@CLASSID' => 1,
768
                                'MailService' => 'Priority Mail 2-Day<sup>™</sup>',
769
                                'Rate' => 12.75
770
                            ],
771
                            1 => [
772
                                '@CLASSID' => 22,
773
                                'MailService' => 'Priority Mail 2-Day<sup>™</sup> Large Flat Rate Box',
774
                                'Rate' => 18.85
775
                            ],
776
                            2 => [
777
                                '@CLASSID' => 17,
778
                                'MailService' => 'Priority Mail 2-Day<sup>™</sup> Medium Flat Rate Box',
779
                                'Rate' => 13.60
780
                            ],
781
                            3 => [
782
                                '@CLASSID' => 28,
783
                                'MailService' => 'Priority Mail 2-Day<sup>™</sup> Small Flat Rate Box',
784
                                'Rate' => 7.15
785
                            ]
786
                        ]
787
                    ]
788
                ]
789
            ]
790
        ];
791
        $this->assertTrue(Validation::validate($array, $rules));
792
    }
793
}
794