Passed
Push — master ( b5dddf...91d417 )
by Richard
09:12
created

Assert::object()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 3
nc 2
nop 2
1
<?php
2
3
/*
4
 * This file is part of the webmozart/assert package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Webmozart\Assert;
13
14
use ArrayAccess;
15
use BadMethodCallException;
16
use Closure;
17
use Countable;
18
use Exception;
19
use InvalidArgumentException;
20
use Throwable;
21
use Traversable;
22
23
/**
24
 * Efficient assertions to validate the input/output of your methods.
25
 *
26
 * @method static void nullOrString($value, $message = '')
27
 * @method static void nullOrStringNotEmpty($value, $message = '')
28
 * @method static void nullOrInteger($value, $message = '')
29
 * @method static void nullOrIntegerish($value, $message = '')
30
 * @method static void nullOrFloat($value, $message = '')
31
 * @method static void nullOrNumeric($value, $message = '')
32
 * @method static void nullOrBoolean($value, $message = '')
33
 * @method static void nullOrScalar($value, $message = '')
34
 * @method static void nullOrObject($value, $message = '')
35
 * @method static void nullOrResource($value, $type = null, $message = '')
36
 * @method static void nullOrIsCallable($value, $message = '')
37
 * @method static void nullOrIsArray($value, $message = '')
38
 * @method static void nullOrIsTraversable($value, $message = '')
39
 * @method static void nullOrIsArrayAccessible($value, $message = '')
40
 * @method static void nullOrIsCountable($value, $message = '')
41
 * @method static void nullOrIsInstanceOf($value, $class, $message = '')
42
 * @method static void nullOrNotInstanceOf($value, $class, $message = '')
43
 * @method static void nullOrIsInstanceOfAny($value, $classes, $message = '')
44
 * @method static void nullOrIsEmpty($value, $message = '')
45
 * @method static void nullOrNotEmpty($value, $message = '')
46
 * @method static void nullOrTrue($value, $message = '')
47
 * @method static void nullOrFalse($value, $message = '')
48
 * @method static void nullOrEq($value, $value2, $message = '')
49
 * @method static void nullOrNotEq($value,$value2,  $message = '')
50
 * @method static void nullOrSame($value, $value2, $message = '')
51
 * @method static void nullOrNotSame($value, $value2, $message = '')
52
 * @method static void nullOrGreaterThan($value, $value2, $message = '')
53
 * @method static void nullOrGreaterThanEq($value, $value2, $message = '')
54
 * @method static void nullOrLessThan($value, $value2, $message = '')
55
 * @method static void nullOrLessThanEq($value, $value2, $message = '')
56
 * @method static void nullOrRange($value, $min, $max, $message = '')
57
 * @method static void nullOrOneOf($value, $values, $message = '')
58
 * @method static void nullOrContains($value, $subString, $message = '')
59
 * @method static void nullOrNotContains($value, $subString, $message = '')
60
 * @method static void nullOrNotWhitespaceOnly($value, $message = '')
61
 * @method static void nullOrStartsWith($value, $prefix, $message = '')
62
 * @method static void nullOrStartsWithLetter($value, $message = '')
63
 * @method static void nullOrEndsWith($value, $suffix, $message = '')
64
 * @method static void nullOrRegex($value, $pattern, $message = '')
65
 * @method static void nullOrAlpha($value, $message = '')
66
 * @method static void nullOrDigits($value, $message = '')
67
 * @method static void nullOrAlnum($value, $message = '')
68
 * @method static void nullOrLower($value, $message = '')
69
 * @method static void nullOrUpper($value, $message = '')
70
 * @method static void nullOrLength($value, $length, $message = '')
71
 * @method static void nullOrMinLength($value, $min, $message = '')
72
 * @method static void nullOrMaxLength($value, $max, $message = '')
73
 * @method static void nullOrLengthBetween($value, $min, $max, $message = '')
74
 * @method static void nullOrFileExists($value, $message = '')
75
 * @method static void nullOrFile($value, $message = '')
76
 * @method static void nullOrDirectory($value, $message = '')
77
 * @method static void nullOrReadable($value, $message = '')
78
 * @method static void nullOrWritable($value, $message = '')
79
 * @method static void nullOrClassExists($value, $message = '')
80
 * @method static void nullOrSubclassOf($value, $class, $message = '')
81
 * @method static void nullOrImplementsInterface($value, $interface, $message = '')
82
 * @method static void nullOrPropertyExists($value, $property, $message = '')
83
 * @method static void nullOrPropertyNotExists($value, $property, $message = '')
84
 * @method static void nullOrMethodExists($value, $method, $message = '')
85
 * @method static void nullOrMethodNotExists($value, $method, $message = '')
86
 * @method static void nullOrKeyExists($value, $key, $message = '')
87
 * @method static void nullOrKeyNotExists($value, $key, $message = '')
88
 * @method static void nullOrCount($value, $key, $message = '')
89
 * @method static void nullOrMinCount($value, $min, $message = '')
90
 * @method static void nullOrMaxCount($value, $max, $message = '')
91
 * @method static void nullCountBetween($value, $min, $max, $message = '')
92
 * @method static void nullOrUuid($values, $message = '')
93
 * @method static void allString($values, $message = '')
94
 * @method static void allStringNotEmpty($values, $message = '')
95
 * @method static void allInteger($values, $message = '')
96
 * @method static void allIntegerish($values, $message = '')
97
 * @method static void allFloat($values, $message = '')
98
 * @method static void allNumeric($values, $message = '')
99
 * @method static void allBoolean($values, $message = '')
100
 * @method static void allScalar($values, $message = '')
101
 * @method static void allObject($values, $message = '')
102
 * @method static void allResource($values, $type = null, $message = '')
103
 * @method static void allIsCallable($values, $message = '')
104
 * @method static void allIsArray($values, $message = '')
105
 * @method static void allIsTraversable($values, $message = '')
106
 * @method static void allIsArrayAccessible($values, $message = '')
107
 * @method static void allIsCountable($values, $message = '')
108
 * @method static void allIsInstanceOf($values, $class, $message = '')
109
 * @method static void allNotInstanceOf($values, $class, $message = '')
110
 * @method static void allIsInstanceOfAny($values, $classes, $message = '')
111
 * @method static void allNull($values, $message = '')
112
 * @method static void allNotNull($values, $message = '')
113
 * @method static void allIsEmpty($values, $message = '')
114
 * @method static void allNotEmpty($values, $message = '')
115
 * @method static void allTrue($values, $message = '')
116
 * @method static void allFalse($values, $message = '')
117
 * @method static void allEq($values, $value2, $message = '')
118
 * @method static void allNotEq($values,$value2,  $message = '')
119
 * @method static void allSame($values, $value2, $message = '')
120
 * @method static void allNotSame($values, $value2, $message = '')
121
 * @method static void allGreaterThan($values, $value2, $message = '')
122
 * @method static void allGreaterThanEq($values, $value2, $message = '')
123
 * @method static void allLessThan($values, $value2, $message = '')
124
 * @method static void allLessThanEq($values, $value2, $message = '')
125
 * @method static void allRange($values, $min, $max, $message = '')
126
 * @method static void allOneOf($values, $values, $message = '')
127
 * @method static void allContains($values, $subString, $message = '')
128
 * @method static void allNotContains($values, $subString, $message = '')
129
 * @method static void allNotWhitespaceOnly($values, $message = '')
130
 * @method static void allStartsWith($values, $prefix, $message = '')
131
 * @method static void allStartsWithLetter($values, $message = '')
132
 * @method static void allEndsWith($values, $suffix, $message = '')
133
 * @method static void allRegex($values, $pattern, $message = '')
134
 * @method static void allAlpha($values, $message = '')
135
 * @method static void allDigits($values, $message = '')
136
 * @method static void allAlnum($values, $message = '')
137
 * @method static void allLower($values, $message = '')
138
 * @method static void allUpper($values, $message = '')
139
 * @method static void allLength($values, $length, $message = '')
140
 * @method static void allMinLength($values, $min, $message = '')
141
 * @method static void allMaxLength($values, $max, $message = '')
142
 * @method static void allLengthBetween($values, $min, $max, $message = '')
143
 * @method static void allFileExists($values, $message = '')
144
 * @method static void allFile($values, $message = '')
145
 * @method static void allDirectory($values, $message = '')
146
 * @method static void allReadable($values, $message = '')
147
 * @method static void allWritable($values, $message = '')
148
 * @method static void allClassExists($values, $message = '')
149
 * @method static void allSubclassOf($values, $class, $message = '')
150
 * @method static void allImplementsInterface($values, $interface, $message = '')
151
 * @method static void allPropertyExists($values, $property, $message = '')
152
 * @method static void allPropertyNotExists($values, $property, $message = '')
153
 * @method static void allMethodExists($values, $method, $message = '')
154
 * @method static void allMethodNotExists($values, $method, $message = '')
155
 * @method static void allKeyExists($values, $key, $message = '')
156
 * @method static void allKeyNotExists($values, $key, $message = '')
157
 * @method static void allCount($values, $key, $message = '')
158
 * @method static void allMinCount($values, $min, $message = '')
159
 * @method static void allMaxCount($values, $max, $message = '')
160
 * @method static void allCountBetween($values, $min, $max, $message = '')
161
 * @method static void allUuid($values, $message = '')
162
 *
163
 * @since  1.0
164
 *
165
 * @author Bernhard Schussek <[email protected]>
166
 */
167
class Assert
168
{
169
    public static function string($value, $message = '')
170
    {
171
        if (!is_string($value)) {
172
            static::reportInvalidArgument(sprintf(
173
                $message ?: 'Expected a string. Got: %s',
174
                static::typeToString($value)
175
            ));
176
        }
177
    }
178
179
    public static function stringNotEmpty($value, $message = '')
180
    {
181
        static::string($value, $message);
182
        static::notEq($value, '', $message);
183
    }
184
185
    public static function integer($value, $message = '')
186
    {
187
        if (!is_int($value)) {
188
            static::reportInvalidArgument(sprintf(
189
                $message ?: 'Expected an integer. Got: %s',
190
                static::typeToString($value)
191
            ));
192
        }
193
    }
194
195
    public static function integerish($value, $message = '')
196
    {
197
        if (!is_numeric($value) || $value != (int) $value) {
198
            static::reportInvalidArgument(sprintf(
199
                $message ?: 'Expected an integerish value. Got: %s',
200
                static::typeToString($value)
201
            ));
202
        }
203
    }
204
205
    public static function float($value, $message = '')
206
    {
207
        if (!is_float($value)) {
208
            static::reportInvalidArgument(sprintf(
209
                $message ?: 'Expected a float. Got: %s',
210
                static::typeToString($value)
211
            ));
212
        }
213
    }
214
215
    public static function numeric($value, $message = '')
216
    {
217
        if (!is_numeric($value)) {
218
            static::reportInvalidArgument(sprintf(
219
                $message ?: 'Expected a numeric. Got: %s',
220
                static::typeToString($value)
221
            ));
222
        }
223
    }
224
225
    public static function natural($value, $message = '')
226
    {
227
        if (!is_int($value) || $value < 0) {
228
            static::reportInvalidArgument(sprintf(
229
                $message ?: 'Expected a non-negative integer. Got %s',
230
                static::valueToString($value)
231
            ));
232
        }
233
    }
234
235
    public static function boolean($value, $message = '')
236
    {
237
        if (!is_bool($value)) {
238
            static::reportInvalidArgument(sprintf(
239
                $message ?: 'Expected a boolean. Got: %s',
240
                static::typeToString($value)
241
            ));
242
        }
243
    }
244
245
    public static function scalar($value, $message = '')
246
    {
247
        if (!is_scalar($value)) {
248
            static::reportInvalidArgument(sprintf(
249
                $message ?: 'Expected a scalar. Got: %s',
250
                static::typeToString($value)
251
            ));
252
        }
253
    }
254
255
    public static function object($value, $message = '')
256
    {
257
        if (!is_object($value)) {
258
            static::reportInvalidArgument(sprintf(
259
                $message ?: 'Expected an object. Got: %s',
260
                static::typeToString($value)
261
            ));
262
        }
263
    }
264
265
    public static function resource($value, $type = null, $message = '')
266
    {
267
        if (!is_resource($value)) {
268
            static::reportInvalidArgument(sprintf(
269
                $message ?: 'Expected a resource. Got: %s',
270
                static::typeToString($value)
271
            ));
272
        }
273
274
        if ($type && $type !== get_resource_type($value)) {
275
            static::reportInvalidArgument(sprintf(
276
                $message ?: 'Expected a resource of type %2$s. Got: %s',
277
                static::typeToString($value),
278
                $type
279
            ));
280
        }
281
    }
282
283
    public static function isCallable($value, $message = '')
284
    {
285
        if (!is_callable($value)) {
286
            static::reportInvalidArgument(sprintf(
287
                $message ?: 'Expected a callable. Got: %s',
288
                static::typeToString($value)
289
            ));
290
        }
291
    }
292
293
    public static function isArray($value, $message = '')
294
    {
295
        if (!is_array($value)) {
296
            static::reportInvalidArgument(sprintf(
297
                $message ?: 'Expected an array. Got: %s',
298
                static::typeToString($value)
299
            ));
300
        }
301
    }
302
303
    public static function isTraversable($value, $message = '')
304
    {
305
        @trigger_error(
306
            sprintf(
307
                'The "%s" assertion is deprecated. You should stop using it, as it will soon be removed in 2.0 version. Use "isIterable" or "isInstanceOf" instead.',
308
                __METHOD__
309
            ),
310
            E_USER_DEPRECATED
311
        );
312
313
        if (!is_array($value) && !($value instanceof Traversable)) {
314
            static::reportInvalidArgument(sprintf(
315
                $message ?: 'Expected a traversable. Got: %s',
316
                static::typeToString($value)
317
            ));
318
        }
319
    }
320
321
    public static function isArrayAccessible($value, $message = '')
322
    {
323
        if (!is_array($value) && !($value instanceof ArrayAccess)) {
324
            static::reportInvalidArgument(sprintf(
325
                $message ?: 'Expected an array accessible. Got: %s',
326
                static::typeToString($value)
327
            ));
328
        }
329
    }
330
331
    public static function isCountable($value, $message = '')
332
    {
333
        if (!is_array($value) && !($value instanceof Countable)) {
334
            static::reportInvalidArgument(sprintf(
335
                $message ?: 'Expected a countable. Got: %s',
336
                static::typeToString($value)
337
            ));
338
        }
339
    }
340
341
    public static function isIterable($value, $message = '')
342
    {
343
        if (!is_array($value) && !($value instanceof Traversable)) {
344
            static::reportInvalidArgument(sprintf(
345
                $message ?: 'Expected an iterable. Got: %s',
346
                static::typeToString($value)
347
            ));
348
        }
349
    }
350
351
    public static function isInstanceOf($value, $class, $message = '')
352
    {
353
        if (!($value instanceof $class)) {
354
            static::reportInvalidArgument(sprintf(
355
                $message ?: 'Expected an instance of %2$s. Got: %s',
356
                static::typeToString($value),
357
                $class
358
            ));
359
        }
360
    }
361
362
    public static function notInstanceOf($value, $class, $message = '')
363
    {
364
        if ($value instanceof $class) {
365
            static::reportInvalidArgument(sprintf(
366
                $message ?: 'Expected an instance other than %2$s. Got: %s',
367
                static::typeToString($value),
368
                $class
369
            ));
370
        }
371
    }
372
373
    public static function isInstanceOfAny($value, array $classes, $message = '')
374
    {
375
        foreach ($classes as $class) {
376
            if ($value instanceof $class) {
377
                return;
378
            }
379
        }
380
381
        static::reportInvalidArgument(sprintf(
382
            $message ?: 'Expected an instance of any of %2$s. Got: %s',
383
            static::typeToString($value),
384
            implode(', ', array_map(array('static', 'valueToString'), $classes))
385
        ));
386
    }
387
388
    public static function isEmpty($value, $message = '')
389
    {
390
        if (!empty($value)) {
391
            static::reportInvalidArgument(sprintf(
392
                $message ?: 'Expected an empty value. Got: %s',
393
                static::valueToString($value)
394
            ));
395
        }
396
    }
397
398
    public static function notEmpty($value, $message = '')
399
    {
400
        if (empty($value)) {
401
            static::reportInvalidArgument(sprintf(
402
                $message ?: 'Expected a non-empty value. Got: %s',
403
                static::valueToString($value)
404
            ));
405
        }
406
    }
407
408
    public static function null($value, $message = '')
409
    {
410
        if (null !== $value) {
411
            static::reportInvalidArgument(sprintf(
412
                $message ?: 'Expected null. Got: %s',
413
                static::valueToString($value)
414
            ));
415
        }
416
    }
417
418
    public static function notNull($value, $message = '')
419
    {
420
        if (null === $value) {
421
            static::reportInvalidArgument(
422
                $message ?: 'Expected a value other than null.'
423
            );
424
        }
425
    }
426
427
    public static function true($value, $message = '')
428
    {
429
        if (true !== $value) {
430
            static::reportInvalidArgument(sprintf(
431
                $message ?: 'Expected a value to be true. Got: %s',
432
                static::valueToString($value)
433
            ));
434
        }
435
    }
436
437
    public static function false($value, $message = '')
438
    {
439
        if (false !== $value) {
440
            static::reportInvalidArgument(sprintf(
441
                $message ?: 'Expected a value to be false. Got: %s',
442
                static::valueToString($value)
443
            ));
444
        }
445
    }
446
447
    public static function eq($value, $value2, $message = '')
448
    {
449
        if ($value2 != $value) {
450
            static::reportInvalidArgument(sprintf(
451
                $message ?: 'Expected a value equal to %2$s. Got: %s',
452
                static::valueToString($value),
453
                static::valueToString($value2)
454
            ));
455
        }
456
    }
457
458
    public static function notEq($value, $value2, $message = '')
459
    {
460
        if ($value2 == $value) {
461
            static::reportInvalidArgument(sprintf(
462
                $message ?: 'Expected a different value than %s.',
463
                static::valueToString($value2)
464
            ));
465
        }
466
    }
467
468
    public static function same($value, $value2, $message = '')
469
    {
470
        if ($value2 !== $value) {
471
            static::reportInvalidArgument(sprintf(
472
                $message ?: 'Expected a value identical to %2$s. Got: %s',
473
                static::valueToString($value),
474
                static::valueToString($value2)
475
            ));
476
        }
477
    }
478
479
    public static function notSame($value, $value2, $message = '')
480
    {
481
        if ($value2 === $value) {
482
            static::reportInvalidArgument(sprintf(
483
                $message ?: 'Expected a value not identical to %s.',
484
                static::valueToString($value2)
485
            ));
486
        }
487
    }
488
489
    public static function greaterThan($value, $limit, $message = '')
490
    {
491
        if ($value <= $limit) {
492
            static::reportInvalidArgument(sprintf(
493
                $message ?: 'Expected a value greater than %2$s. Got: %s',
494
                static::valueToString($value),
495
                static::valueToString($limit)
496
            ));
497
        }
498
    }
499
500
    public static function greaterThanEq($value, $limit, $message = '')
501
    {
502
        if ($value < $limit) {
503
            static::reportInvalidArgument(sprintf(
504
                $message ?: 'Expected a value greater than or equal to %2$s. Got: %s',
505
                static::valueToString($value),
506
                static::valueToString($limit)
507
            ));
508
        }
509
    }
510
511
    public static function lessThan($value, $limit, $message = '')
512
    {
513
        if ($value >= $limit) {
514
            static::reportInvalidArgument(sprintf(
515
                $message ?: 'Expected a value less than %2$s. Got: %s',
516
                static::valueToString($value),
517
                static::valueToString($limit)
518
            ));
519
        }
520
    }
521
522
    public static function lessThanEq($value, $limit, $message = '')
523
    {
524
        if ($value > $limit) {
525
            static::reportInvalidArgument(sprintf(
526
                $message ?: 'Expected a value less than or equal to %2$s. Got: %s',
527
                static::valueToString($value),
528
                static::valueToString($limit)
529
            ));
530
        }
531
    }
532
533
    public static function range($value, $min, $max, $message = '')
534
    {
535
        if ($value < $min || $value > $max) {
536
            static::reportInvalidArgument(sprintf(
537
                $message ?: 'Expected a value between %2$s and %3$s. Got: %s',
538
                static::valueToString($value),
539
                static::valueToString($min),
540
                static::valueToString($max)
541
            ));
542
        }
543
    }
544
545
    public static function oneOf($value, array $values, $message = '')
546
    {
547
        if (!in_array($value, $values, true)) {
548
            static::reportInvalidArgument(sprintf(
549
                $message ?: 'Expected one of: %2$s. Got: %s',
550
                static::valueToString($value),
551
                implode(', ', array_map(array('static', 'valueToString'), $values))
552
            ));
553
        }
554
    }
555
556
    public static function contains($value, $subString, $message = '')
557
    {
558
        if (false === strpos($value, $subString)) {
559
            static::reportInvalidArgument(sprintf(
560
                $message ?: 'Expected a value to contain %2$s. Got: %s',
561
                static::valueToString($value),
562
                static::valueToString($subString)
563
            ));
564
        }
565
    }
566
567
    public static function notContains($value, $subString, $message = '')
568
    {
569
        if (false !== strpos($value, $subString)) {
570
            static::reportInvalidArgument(sprintf(
571
                $message ?: '%2$s was not expected to be contained in a value. Got: %s',
572
                static::valueToString($value),
573
                static::valueToString($subString)
574
            ));
575
        }
576
    }
577
578
    public static function notWhitespaceOnly($value, $message = '')
579
    {
580
        if (preg_match('/^\s*$/', $value)) {
581
            static::reportInvalidArgument(sprintf(
582
                $message ?: 'Expected a non-whitespace string. Got: %s',
583
                static::valueToString($value)
584
            ));
585
        }
586
    }
587
588
    public static function startsWith($value, $prefix, $message = '')
589
    {
590
        if (0 !== strpos($value, $prefix)) {
591
            static::reportInvalidArgument(sprintf(
592
                $message ?: 'Expected a value to start with %2$s. Got: %s',
593
                static::valueToString($value),
594
                static::valueToString($prefix)
595
            ));
596
        }
597
    }
598
599
    public static function startsWithLetter($value, $message = '')
600
    {
601
        $valid = isset($value[0]);
602
603
        if ($valid) {
604
            $locale = setlocale(LC_CTYPE, 0);
605
            setlocale(LC_CTYPE, 'C');
606
            $valid = ctype_alpha($value[0]);
607
            setlocale(LC_CTYPE, $locale);
608
        }
609
610
        if (!$valid) {
611
            static::reportInvalidArgument(sprintf(
612
                $message ?: 'Expected a value to start with a letter. Got: %s',
613
                static::valueToString($value)
614
            ));
615
        }
616
    }
617
618
    public static function endsWith($value, $suffix, $message = '')
619
    {
620
        if ($suffix !== substr($value, -static::strlen($suffix))) {
621
            static::reportInvalidArgument(sprintf(
622
                $message ?: 'Expected a value to end with %2$s. Got: %s',
623
                static::valueToString($value),
624
                static::valueToString($suffix)
625
            ));
626
        }
627
    }
628
629
    public static function regex($value, $pattern, $message = '')
630
    {
631
        if (!preg_match($pattern, $value)) {
632
            static::reportInvalidArgument(sprintf(
633
                $message ?: 'The value %s does not match the expected pattern.',
634
                static::valueToString($value)
635
            ));
636
        }
637
    }
638
639
    public static function alpha($value, $message = '')
640
    {
641
        $locale = setlocale(LC_CTYPE, 0);
642
        setlocale(LC_CTYPE, 'C');
643
        $valid = !ctype_alpha($value);
644
        setlocale(LC_CTYPE, $locale);
645
646
        if ($valid) {
647
            static::reportInvalidArgument(sprintf(
648
                $message ?: 'Expected a value to contain only letters. Got: %s',
649
                static::valueToString($value)
650
            ));
651
        }
652
    }
653
654
    public static function digits($value, $message = '')
655
    {
656
        $locale = setlocale(LC_CTYPE, 0);
657
        setlocale(LC_CTYPE, 'C');
658
        $valid = !ctype_digit($value);
659
        setlocale(LC_CTYPE, $locale);
660
661
        if ($valid) {
662
            static::reportInvalidArgument(sprintf(
663
                $message ?: 'Expected a value to contain digits only. Got: %s',
664
                static::valueToString($value)
665
            ));
666
        }
667
    }
668
669
    public static function alnum($value, $message = '')
670
    {
671
        $locale = setlocale(LC_CTYPE, 0);
672
        setlocale(LC_CTYPE, 'C');
673
        $valid = !ctype_alnum($value);
674
        setlocale(LC_CTYPE, $locale);
675
676
        if ($valid) {
677
            static::reportInvalidArgument(sprintf(
678
                $message ?: 'Expected a value to contain letters and digits only. Got: %s',
679
                static::valueToString($value)
680
            ));
681
        }
682
    }
683
684
    public static function lower($value, $message = '')
685
    {
686
        $locale = setlocale(LC_CTYPE, 0);
687
        setlocale(LC_CTYPE, 'C');
688
        $valid = !ctype_lower($value);
689
        setlocale(LC_CTYPE, $locale);
690
691
        if ($valid) {
692
            static::reportInvalidArgument(sprintf(
693
                $message ?: 'Expected a value to contain lowercase characters only. Got: %s',
694
                static::valueToString($value)
695
            ));
696
        }
697
    }
698
699
    public static function upper($value, $message = '')
700
    {
701
        $locale = setlocale(LC_CTYPE, 0);
702
        setlocale(LC_CTYPE, 'C');
703
        $valid = !ctype_upper($value);
704
        setlocale(LC_CTYPE, $locale);
705
706
        if ($valid) {
707
            static::reportInvalidArgument(sprintf(
708
                $message ?: 'Expected a value to contain uppercase characters only. Got: %s',
709
                static::valueToString($value)
710
            ));
711
        }
712
    }
713
714
    public static function length($value, $length, $message = '')
715
    {
716
        if ($length !== static::strlen($value)) {
717
            static::reportInvalidArgument(sprintf(
718
                $message ?: 'Expected a value to contain %2$s characters. Got: %s',
719
                static::valueToString($value),
720
                $length
721
            ));
722
        }
723
    }
724
725
    public static function minLength($value, $min, $message = '')
726
    {
727
        if (static::strlen($value) < $min) {
728
            static::reportInvalidArgument(sprintf(
729
                $message ?: 'Expected a value to contain at least %2$s characters. Got: %s',
730
                static::valueToString($value),
731
                $min
732
            ));
733
        }
734
    }
735
736
    public static function maxLength($value, $max, $message = '')
737
    {
738
        if (static::strlen($value) > $max) {
739
            static::reportInvalidArgument(sprintf(
740
                $message ?: 'Expected a value to contain at most %2$s characters. Got: %s',
741
                static::valueToString($value),
742
                $max
743
            ));
744
        }
745
    }
746
747
    public static function lengthBetween($value, $min, $max, $message = '')
748
    {
749
        $length = static::strlen($value);
750
751
        if ($length < $min || $length > $max) {
752
            static::reportInvalidArgument(sprintf(
753
                $message ?: 'Expected a value to contain between %2$s and %3$s characters. Got: %s',
754
                static::valueToString($value),
755
                $min,
756
                $max
757
            ));
758
        }
759
    }
760
761
    public static function fileExists($value, $message = '')
762
    {
763
        static::string($value);
764
765
        if (!file_exists($value)) {
766
            static::reportInvalidArgument(sprintf(
767
                $message ?: 'The file %s does not exist.',
768
                static::valueToString($value)
769
            ));
770
        }
771
    }
772
773
    public static function file($value, $message = '')
774
    {
775
        static::fileExists($value, $message);
776
777
        if (!is_file($value)) {
778
            static::reportInvalidArgument(sprintf(
779
                $message ?: 'The path %s is not a file.',
780
                static::valueToString($value)
781
            ));
782
        }
783
    }
784
785
    public static function directory($value, $message = '')
786
    {
787
        static::fileExists($value, $message);
788
789
        if (!is_dir($value)) {
790
            static::reportInvalidArgument(sprintf(
791
                $message ?: 'The path %s is no directory.',
792
                static::valueToString($value)
793
            ));
794
        }
795
    }
796
797
    public static function readable($value, $message = '')
798
    {
799
        if (!is_readable($value)) {
800
            static::reportInvalidArgument(sprintf(
801
                $message ?: 'The path %s is not readable.',
802
                static::valueToString($value)
803
            ));
804
        }
805
    }
806
807
    public static function writable($value, $message = '')
808
    {
809
        if (!is_writable($value)) {
810
            static::reportInvalidArgument(sprintf(
811
                $message ?: 'The path %s is not writable.',
812
                static::valueToString($value)
813
            ));
814
        }
815
    }
816
817
    public static function classExists($value, $message = '')
818
    {
819
        if (!class_exists($value)) {
820
            static::reportInvalidArgument(sprintf(
821
                $message ?: 'Expected an existing class name. Got: %s',
822
                static::valueToString($value)
823
            ));
824
        }
825
    }
826
827
    public static function subclassOf($value, $class, $message = '')
828
    {
829
        if (!is_subclass_of($value, $class)) {
830
            static::reportInvalidArgument(sprintf(
831
                $message ?: 'Expected a sub-class of %2$s. Got: %s',
832
                static::valueToString($value),
833
                static::valueToString($class)
834
            ));
835
        }
836
    }
837
838
    public static function implementsInterface($value, $interface, $message = '')
839
    {
840
        if (!in_array($interface, class_implements($value))) {
841
            static::reportInvalidArgument(sprintf(
842
                $message ?: 'Expected an implementation of %2$s. Got: %s',
843
                static::valueToString($value),
844
                static::valueToString($interface)
845
            ));
846
        }
847
    }
848
849
    public static function propertyExists($classOrObject, $property, $message = '')
850
    {
851
        if (!property_exists($classOrObject, $property)) {
852
            static::reportInvalidArgument(sprintf(
853
                $message ?: 'Expected the property %s to exist.',
854
                static::valueToString($property)
855
            ));
856
        }
857
    }
858
859
    public static function propertyNotExists($classOrObject, $property, $message = '')
860
    {
861
        if (property_exists($classOrObject, $property)) {
862
            static::reportInvalidArgument(sprintf(
863
                $message ?: 'Expected the property %s to not exist.',
864
                static::valueToString($property)
865
            ));
866
        }
867
    }
868
869
    public static function methodExists($classOrObject, $method, $message = '')
870
    {
871
        if (!method_exists($classOrObject, $method)) {
872
            static::reportInvalidArgument(sprintf(
873
                $message ?: 'Expected the method %s to exist.',
874
                static::valueToString($method)
875
            ));
876
        }
877
    }
878
879
    public static function methodNotExists($classOrObject, $method, $message = '')
880
    {
881
        if (method_exists($classOrObject, $method)) {
882
            static::reportInvalidArgument(sprintf(
883
                $message ?: 'Expected the method %s to not exist.',
884
                static::valueToString($method)
885
            ));
886
        }
887
    }
888
889
    public static function keyExists($array, $key, $message = '')
890
    {
891
        if (!array_key_exists($key, $array)) {
892
            static::reportInvalidArgument(sprintf(
893
                $message ?: 'Expected the key %s to exist.',
894
                static::valueToString($key)
895
            ));
896
        }
897
    }
898
899
    public static function keyNotExists($array, $key, $message = '')
900
    {
901
        if (array_key_exists($key, $array)) {
902
            static::reportInvalidArgument(sprintf(
903
                $message ?: 'Expected the key %s to not exist.',
904
                static::valueToString($key)
905
            ));
906
        }
907
    }
908
909
    public static function count($array, $number, $message = '')
910
    {
911
        static::eq(
912
            count($array),
913
            $number,
914
            $message ?: sprintf('Expected an array to contain %d elements. Got: %d.', $number, count($array))
915
        );
916
    }
917
918
    public static function minCount($array, $min, $message = '')
919
    {
920
        if (count($array) < $min) {
921
            static::reportInvalidArgument(sprintf(
922
                $message ?: 'Expected an array to contain at least %2$d elements. Got: %d',
923
                count($array),
924
                $min
925
            ));
926
        }
927
    }
928
929
    public static function maxCount($array, $max, $message = '')
930
    {
931
        if (count($array) > $max) {
932
            static::reportInvalidArgument(sprintf(
933
                $message ?: 'Expected an array to contain at most %2$d elements. Got: %d',
934
                count($array),
935
                $max
936
            ));
937
        }
938
    }
939
940
    public static function countBetween($array, $min, $max, $message = '')
941
    {
942
        $count = count($array);
943
944
        if ($count < $min || $count > $max) {
945
            static::reportInvalidArgument(sprintf(
946
                $message ?: 'Expected an array to contain between %2$d and %3$d elements. Got: %d',
947
                $count,
948
                $min,
949
                $max
950
            ));
951
        }
952
    }
953
954
    public static function uuid($value, $message = '')
955
    {
956
        $value = str_replace(array('urn:', 'uuid:', '{', '}'), '', $value);
957
958
        // The nil UUID is special form of UUID that is specified to have all
959
        // 128 bits set to zero.
960
        if ('00000000-0000-0000-0000-000000000000' === $value) {
961
            return;
962
        }
963
964
        if (!preg_match('/^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/', $value)) {
965
            static::reportInvalidArgument(sprintf(
966
                $message ?: 'Value %s is not a valid UUID.',
967
                static::valueToString($value)
968
            ));
969
        }
970
    }
971
972
    public static function throws(Closure $expression, $class = 'Exception', $message = '')
973
    {
974
        static::string($class);
975
976
        $actual = 'none';
977
978
        try {
979
            $expression();
980
        } catch (Exception $e) {
981
            $actual = get_class($e);
982
            if ($e instanceof $class) {
983
                return;
984
            }
985
        } catch (Throwable $e) {
986
            $actual = get_class($e);
987
            if ($e instanceof $class) {
988
                return;
989
            }
990
        }
991
992
        static::reportInvalidArgument($message ?: sprintf(
993
            'Expected to throw "%s", got "%s"',
994
            $class,
995
            $actual
996
        ));
997
    }
998
999
    public static function __callStatic($name, $arguments)
1000
    {
1001
        if ('nullOr' === substr($name, 0, 6)) {
1002
            if (null !== $arguments[0]) {
1003
                $method = lcfirst(substr($name, 6));
1004
                call_user_func_array(array('static', $method), $arguments);
1005
            }
1006
1007
            return;
1008
        }
1009
1010
        if ('all' === substr($name, 0, 3)) {
1011
            static::isIterable($arguments[0]);
1012
1013
            $method = lcfirst(substr($name, 3));
1014
            $args = $arguments;
1015
1016
            foreach ($arguments[0] as $entry) {
1017
                $args[0] = $entry;
1018
1019
                call_user_func_array(array('static', $method), $args);
1020
            }
1021
1022
            return;
1023
        }
1024
1025
        throw new BadMethodCallException('No such method: '.$name);
1026
    }
1027
1028
    protected static function valueToString($value)
1029
    {
1030
        if (null === $value) {
1031
            return 'null';
1032
        }
1033
1034
        if (true === $value) {
1035
            return 'true';
1036
        }
1037
1038
        if (false === $value) {
1039
            return 'false';
1040
        }
1041
1042
        if (is_array($value)) {
1043
            return 'array';
1044
        }
1045
1046
        if (is_object($value)) {
1047
            return get_class($value);
1048
        }
1049
1050
        if (is_resource($value)) {
1051
            return 'resource';
1052
        }
1053
1054
        if (is_string($value)) {
1055
            return '"'.$value.'"';
1056
        }
1057
1058
        return (string) $value;
1059
    }
1060
1061
    protected static function typeToString($value)
1062
    {
1063
        return is_object($value) ? get_class($value) : gettype($value);
1064
    }
1065
1066
    protected static function strlen($value)
1067
    {
1068
        if (!function_exists('mb_detect_encoding')) {
1069
            return strlen($value);
1070
        }
1071
1072
        if (false === $encoding = mb_detect_encoding($value)) {
1073
            return strlen($value);
1074
        }
1075
1076
        return mb_strwidth($value, $encoding);
1077
    }
1078
1079
    protected static function reportInvalidArgument($message)
1080
    {
1081
        throw new InvalidArgumentException($message);
1082
    }
1083
1084
    private function __construct()
1085
    {
1086
    }
1087
}
1088