Passed
Push — master ( 8f13cb...dc4563 )
by AJ
02:21
created

ValidationTest::testInvaldType()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 0
dl 0
loc 12
rs 10
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 testInvaldType()
240
    {
241
        $rules = [
242
            'a' => ['type' => 'abcdef']
243
        ];
244
        $array = [
245
            'a' => 'This isn\'t real.'
246
        ];
247
        try {
248
            $this->assertFalse(Validation::validate($array, $rules));
249
        } catch (Exception $e) {
250
            $this->assertEquals('Invalid type "abcdef" for key: a.', $e->getMessage());
251
        }
252
    }
253
254
    public function testValidatePattern()
255
    {
256
        $rules = [
257
            'a' => ['type' => 'string', 'pattern' => '[A-Z]{2}'],
258
            'b' => ['type' => 'string', 'pattern' => 'ISO 8601']
259
        ];
260
        $array = [
261
            'a' => 'CA',
262
            'b' => '2014-01-22T14:30:51-06:00'
263
        ];
264
        $this->assertTrue(Validation::validate($array, $rules));
265
266
        $array = [
267
            'a' => 'CAT',
268
        ];
269
270
        try {
271
            $this->assertFalse(Validation::validate($array, $rules));
272
        } catch (Exception $e) {
273
            $this->assertEquals('Invalid value "CAT" does not match pattern "[A-Z]{2}" for key: a.', $e->getMessage());
274
        }
275
276
        $array = [
277
            'b' => '2014-01-22',
278
        ];
279
280
        try {
281
            $this->assertFalse(Validation::validate($array, $rules));
282
        } catch (Exception $e) {
283
            $this->assertEquals('Invalid value "2014-01-22" does not match ISO 8601 pattern for key: b.', $e->getMessage());
284
        }
285
    }
286
287
    public function testFieldNotInRules()
288
    {
289
        $rules = [
290
            'a' => ['type' => 'string']
291
        ];
292
        $array = [
293
            'a' => 'string',
294
            'b' => 'unexpected'
295
        ];
296
297
        try {
298
            $this->assertFalse(Validation::validate($array, $rules));
299
        } catch (Exception $e) {
300
            $this->assertEquals('Unexpected key "b" found in array.', $e->getMessage());
301
        }
302
    }
303
304
    public function testMultidimensionalValidation()
305
    {
306
        $rules = [
307
            'a' => ['type' => 'array',
308
                'fields' => [
309
                    'a' => ['type' => 'string'],
310
                    'b' => ['type' => 'string']
311
                ]
312
            ],
313
            'b' => ['type' => 'string']
314
        ];
315
        $array = [
316
            'a' => [
317
                'a' => 'string',
318
                'b' => 'test'
319
            ],
320
            'b' => 'b'
321
        ];
322
        $this->assertTrue(Validation::validate($array, $rules));
323
324
        $array = [
325
            'b' => [
326
                'a' => 'string',
327
                'b' => 'test'
328
            ]
329
        ];
330
331
        try {
332
            $this->assertFalse(Validation::validate($array, $rules));
333
        } catch (Exception $e) {
334
            $this->assertEquals("Unexpected array found for key: b.", $e->getMessage());
335
        }
336
    }
337
338
    public function testGroupValidation()
339
    {
340
        $rules2 = [
341
            'b' => ['type' => 'string']
342
        ];
343
        $rules = [
344
            'a' => [
345
                'type' => 'group',
346
                'fields' => $rules2
347
            ]
348
        ];
349
        $array = [
350
            'a' => [['b' => 'Hello']]
351
        ];
352
        $this->assertTrue(Validation::validate($array, $rules));
353
        $array = [
354
            'a' => [
355
                ['b' => 'Hello'],
356
                ['b' => 'World'],
357
            ]
358
        ];
359
        $this->assertTrue(Validation::validate($array, $rules));
360
    }
361
362
    public function testRequiredComplex()
363
    {
364
        $rules = [
365
            'a' => ['type' => 'string', 'required' => true],
366
            'b' => ['type' => 'string',
367
                'required' => [
368
                    'a' => 'banana'
369
                ]
370
            ],
371
            'c' => ['type' => 'string',
372
                'required' => [
373
                    [
374
                        'a' => 'banana',
375
                        'b' => 'orange'
376
                    ],
377
                    [
378
                        'a' => 'banana',
379
                        'b' => 'carrot'
380
                    ],
381
                    [
382
                        'a' => 'pickle'
383
                    ],
384
                    [
385
                        'b' => 'banana'
386
                    ]
387
                ]
388
            ],
389
        ];
390
        $array = [
391
            'a' => 'apple'
392
        ];
393
        $this->assertTrue(Validation::validate($array, $rules));
394
395
        $array = [
396
            'a' => 'banana',
397
            'b' => 'orange',
398
            'c' => 'other'
399
        ];
400
        $this->assertTrue(Validation::validate($array, $rules));
401
402
        $array = [
403
            'a' => 'banana',
404
            'c' => 'orange'
405
        ];
406
407
        try {
408
            $this->assertFalse(Validation::validate($array, $rules));
409
        } catch (Exception $e) {
410
            $this->assertEquals('Required value not found for key: b.', $e->getMessage());
411
        }
412
413
        $array = [
414
            'a' => 'banana',
415
            'b' => '',
416
            'c' => 'orange'
417
        ];
418
419
        try {
420
            $this->assertFalse(Validation::validate($array, $rules));
421
        } catch (Exception $e) {
422
            $this->assertEquals('Required value not found for key: b.', $e->getMessage());
423
        }
424
425
        $array = [
426
            'a' => 'banana',
427
            'b' => 'carrot'
428
        ];
429
430
        try {
431
            $this->assertFalse(Validation::validate($array, $rules));
432
        } catch (Exception $e) {
433
            $this->assertEquals('Required value not found for key: c.', $e->getMessage());
434
        }
435
436
437
        $array = [
438
            'a' => 'banana',
439
            'b' => 'carrot',
440
            'c' => ''
441
        ];
442
443
        try {
444
            $this->assertFalse(Validation::validate($array, $rules));
445
        } catch (Exception $e) {
446
            $this->assertEquals('Required value not found for key: c.', $e->getMessage());
447
        }
448
449
        $array = [
450
            'b' => 'banana'
451
        ];
452
453
        try {
454
            $this->assertFalse(Validation::validate($array, $rules));
455
        } catch (Exception $e) {
456
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
457
        }
458
459
        $array = [
460
            'a' => '',
461
            'b' => 'banana',
462
            'c' => ''
463
        ];
464
465
        try {
466
            $this->assertFalse(Validation::validate($array, $rules));
467
        } catch (Exception $e) {
468
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
469
        }
470
471
472
        $array = [
473
            'a' => 'carrot',
474
            'b' => 'banana'
475
        ];
476
477
        try {
478
            $this->assertFalse(Validation::validate($array, $rules));
479
        } catch (Exception $e) {
480
            $this->assertEquals('Required value not found for key: c.', $e->getMessage());
481
        }
482
    }
483
484
    public function testRequiredNull()
485
    {
486
        $rules = [
487
            'a' => ['type' => 'string',
488
                'required' => [
489
                    'b' => 'null'
490
                ]
491
            ],
492
            'b' => ['type' => 'string'],
493
            'c' => ['type' => 'string'],
494
        ];
495
        $array = [
496
            'b' => 'not a null value',
497
            'c' => 'no one cares about c'
498
        ];
499
        $this->assertTrue(Validation::validate($array, $rules));
500
501
        $array = [
502
            'c' => 'c is lonely'
503
        ];
504
505
        try {
506
            $this->assertFalse(Validation::validate($array, $rules));
507
        } catch (Exception $e) {
508
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
509
        }
510
511
        $array = [];
512
513
        try {
514
            $this->assertFalse(Validation::validate($array, $rules));
515
        } catch (Exception $e) {
516
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
517
        }
518
519
        $rules['a']['required']['b'] = null;
520
521
        try {
522
            $this->assertFalse(Validation::validate($array, $rules));
523
        } catch (Exception $e) {
524
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
525
        }
526
    }
527
528
    public function testNullValue()
529
    {
530
        $rules = [
531
            'a' => ['type' => 'string']
532
        ];
533
        $array = [
534
            'a' => null
535
        ];
536
        $this->assertTrue(Validation::validate($array, $rules));
537
538
        $array['a'] = 'null';
539
        $this->assertTrue(Validation::validate($array, $rules));
540
    }
541
542
    public function testInvalidRequiredValue()
543
    {
544
        $rules = [
545
            'a' => [
546
                'type' => 'string',
547
                'required' => 'banana'
548
            ]
549
        ];
550
        $array = [
551
            'a' => null
552
        ];
553
554
        try {
555
            $this->assertFalse(Validation::validate($array, $rules));
556
        } catch (Exception $e) {
557
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
558
        }
559
    }
560
561
    public function testRequiredWhenNull()
562
    {
563
        $rules = [
564
            'a' =>
565
                ['type' => 'string',
566
                    'required' => [
567
                        'b' => null
568
                    ]
569
                ],
570
            'b' => ['type' => 'string'],
571
            'c' => ['type' => 'string']
572
        ];
573
        $array = ['c' => 'Hi'];
574
575
        try {
576
            $this->assertFalse(Validation::validate($array, $rules));
577
        } catch (Exception $e) {
578
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
579
        }
580
    }
581
582
    public function testRequiredWhenEmpty()
583
    {
584
        $rules = [
585
            'a' =>
586
                ['type' => 'string',
587
                    'required' => [
588
                        'b' => ''
589
                    ]
590
                ],
591
            'b' => ['type' => 'string'],
592
            'c' => ['type' => 'string']
593
        ];
594
        $array = ['c' => 'Hi'];
595
596
        try {
597
            $this->assertFalse(Validation::validate($array, $rules));
598
        } catch (Exception $e) {
599
            $this->assertEquals('Required value not found for key: a.', $e->getMessage());
600
        }
601
    }
602
603
    public function testUnexpectedArray()
604
    {
605
        $rules = [
606
            'a' => [
607
                'type' => 'string'
608
            ]
609
        ];
610
        $array = [
611
            'a' => [
612
                'b' => 'c'
613
            ]
614
        ];
615
        try {
616
            $this->assertFalse(Validation::validate($array, $rules));
617
        } catch (Exception $e) {
618
            $this->assertEquals('Unexpected array found for key: a.', $e->getMessage());
619
        }
620
    }
621
622
    public function testMultiDimensionalArray()
623
    {
624
        $rules = [
625
            'RateV4Response' => [
626
                'type' => 'array',
627
                'fields' => [
628
                    'Package' => [
629
                        'type' => 'group',
630
                        'fields' => [
631
                            '@ID' => [
632
                                'type' => 'string',
633
                                'required' => true
634
                            ],
635
                            'ZipOrigination' => [
636
                                'type' => 'string',
637
                                'required' => true,
638
                                'pattern' => '\d{5}'
639
                            ],
640
                            'ZipDestination' => [
641
                                'type' => 'string',
642
                                'required' => true,
643
                                'pattern' => '\d{5}'
644
                            ],
645
                            'Pounds' => [
646
                                'type' => 'decimal',
647
                                'required' => true,
648
                            ],
649
                            'Ounces' => [
650
                                'type' => 'decimal',
651
                                'required' => true,
652
                            ],
653
                            'FirstClassMailType' => [
654
                                'type' => 'string'
655
                            ],
656
                            'Container' => [
657
                                'type' => 'string',
658
                            ],
659
                            'Size' => [
660
                                'type' => 'string',
661
                                'required' => true,
662
                                'values' => [
663
                                    'REGULAR',
664
                                    'LARGE'
665
                                ]
666
                            ],
667
                            'Width' => [
668
                                'type' => 'decimal'
669
                            ],
670
                            'Length' => [
671
                                'type' => 'decimal'
672
                            ],
673
                            'Height' => [
674
                                'type' => 'decimal'
675
                            ],
676
                            'Girth' => [
677
                                'type' => 'decimal'
678
                            ],
679
                            'Machinable' => [
680
                                'type' => 'boolean'
681
                            ],
682
                            'Zone' => [
683
                                'type' => 'string'
684
                            ],
685
                            'Postage' => [
686
                                'type' => 'group',
687
                                'required' => true,
688
                                'fields' => [
689
                                    '@CLASSID' => [
690
                                        'type' => 'integer'
691
                                    ],
692
                                    'MailService' => [
693
                                        'type' => 'string'
694
                                    ],
695
                                    'Rate' => [
696
                                        'type' => 'decimal'
697
                                    ]
698
                                ]
699
                            ]
700
                        ]
701
                    ]
702
                ]
703
            ]
704
        ];
705
        $array = [
706
            'RateV4Response' => [
707
                'Package' => [
708
                    '@ID' => '123',
709
                    'ZipOrigination' => '20500',
710
                    'ZipDestination' => '90210',
711
                    'Pounds' => 0.0,
712
                    'Ounces' => 32.0,
713
                    'Size' => 'REGULAR',
714
                    'Machinable' => true,
715
                    'Zone' => '8',
716
                    'Postage' => [
717
                        0 => [
718
                            '@CLASSID' => 1,
719
                            'MailService' => 'Priority Mail 2-Day<sup>™</sup>',
720
                            'Rate' => 12.75
721
                        ],
722
                        1 => [
723
                            '@CLASSID' => 22,
724
                            'MailService' => 'Priority Mail 2-Day<sup>™</sup> Large Flat Rate Box',
725
                            'Rate' => 18.85
726
                        ],
727
                        2 => [
728
                            '@CLASSID' => 17,
729
                            'MailService' => 'Priority Mail 2-Day<sup>™</sup> Medium Flat Rate Box',
730
                            'Rate' => 13.60
731
                        ],
732
                        3 => [
733
                            '@CLASSID' => 28,
734
                            'MailService' => 'Priority Mail 2-Day<sup>™</sup> Small Flat Rate Box',
735
                            'Rate' => 7.15
736
                        ]
737
                    ]
738
                ]
739
            ]
740
        ];
741
        $this->assertTrue(Validation::validate($array, $rules));
742
    }
743
744
    public function testMultiMultiMultidimensionalArray()
745
    {
746
        $rules = [
747
            'RateV4Response' => [
748
                'type' => 'array',
749
                'fields' => [
750
                    'Package' => [
751
                        'type' => 'group',
752
                        'fields' => [
753
                            '@ID' => [
754
                                'type' => 'string',
755
                                'required' => true
756
                            ],
757
                            'ZipOrigination' => [
758
                                'type' => 'string',
759
                                'required' => true,
760
                                'pattern' => '\d{5}'
761
                            ],
762
                            'ZipDestination' => [
763
                                'type' => 'string',
764
                                'required' => true,
765
                                'pattern' => '\d{5}'
766
                            ],
767
                            'Pounds' => [
768
                                'type' => 'decimal',
769
                                'required' => true,
770
                            ],
771
                            'Ounces' => [
772
                                'type' => 'decimal',
773
                                'required' => true,
774
                            ],
775
                            'FirstClassMailType' => [
776
                                'type' => 'string'
777
                            ],
778
                            'Container' => [
779
                                'type' => 'string',
780
                            ],
781
                            'Size' => [
782
                                'type' => 'string',
783
                                'required' => true,
784
                                'values' => [
785
                                    'REGULAR',
786
                                    'LARGE'
787
                                ]
788
                            ],
789
                            'Width' => [
790
                                'type' => 'decimal'
791
                            ],
792
                            'Length' => [
793
                                'type' => 'decimal'
794
                            ],
795
                            'Height' => [
796
                                'type' => 'decimal'
797
                            ],
798
                            'Girth' => [
799
                                'type' => 'decimal'
800
                            ],
801
                            'Machinable' => [
802
                                'type' => 'boolean'
803
                            ],
804
                            'Zone' => [
805
                                'type' => 'string'
806
                            ],
807
                            'Postage' => [
808
                                'type' => 'group',
809
                                'required' => true,
810
                                'fields' => [
811
                                    '@CLASSID' => [
812
                                        'type' => 'integer'
813
                                    ],
814
                                    'MailService' => [
815
                                        'type' => 'string'
816
                                    ],
817
                                    'Rate' => [
818
                                        'type' => 'decimal'
819
                                    ]
820
                                ]
821
                            ]
822
                        ]
823
                    ]
824
                ]
825
            ]
826
        ];
827
        $array = [
828
            'RateV4Response' => [
829
                'Package' => [
830
                    0 => [
831
                        '@ID' => '123',
832
                        'ZipOrigination' => '20500',
833
                        'ZipDestination' => '90210',
834
                        'Pounds' => 0.0,
835
                        'Ounces' => 32.0,
836
                        'Size' => 'REGULAR',
837
                        'Machinable' => true,
838
                        'Zone' => '8',
839
                        'Postage' => [
840
                            0 => [
841
                                '@CLASSID' => 1,
842
                                'MailService' => 'Priority Mail 2-Day<sup>™</sup>',
843
                                'Rate' => 12.75
844
                            ],
845
                            1 => [
846
                                '@CLASSID' => 22,
847
                                'MailService' => 'Priority Mail 2-Day<sup>™</sup> Large Flat Rate Box',
848
                                'Rate' => 18.85
849
                            ],
850
                            2 => [
851
                                '@CLASSID' => 17,
852
                                'MailService' => 'Priority Mail 2-Day<sup>™</sup> Medium Flat Rate Box',
853
                                'Rate' => 13.60
854
                            ],
855
                            3 => [
856
                                '@CLASSID' => 28,
857
                                'MailService' => 'Priority Mail 2-Day<sup>™</sup> Small Flat Rate Box',
858
                                'Rate' => 7.15
859
                            ]
860
                        ]
861
                    ]
862
                ]
863
            ]
864
        ];
865
        $this->assertTrue(Validation::validate($array, $rules));
866
    }
867
}
868