Failed Conditions
Push — master ( 88356a...26903c )
by Gert de
02:41
created

src/Assert.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 ResourceBundle;
21
use SimpleXMLElement;
22
use Throwable;
23
use Traversable;
24
25
/**
26
 * Efficient assertions to validate the input/output of your methods.
27
 *
28
 * @method static void nullOrString($value, $message = '')
29
 * @method static void nullOrStringNotEmpty($value, $message = '')
30
 * @method static void nullOrInteger($value, $message = '')
31
 * @method static void nullOrIntegerish($value, $message = '')
32
 * @method static void nullOrFloat($value, $message = '')
33
 * @method static void nullOrNumeric($value, $message = '')
34
 * @method static void nullOrNatural($value, $message = '')
35
 * @method static void nullOrBoolean($value, $message = '')
36
 * @method static void nullOrScalar($value, $message = '')
37
 * @method static void nullOrObject($value, $message = '')
38
 * @method static void nullOrResource($value, $type = null, $message = '')
39
 * @method static void nullOrIsCallable($value, $message = '')
40
 * @method static void nullOrIsArray($value, $message = '')
41
 * @method static void nullOrIsTraversable($value, $message = '')
42
 * @method static void nullOrIsArrayAccessible($value, $message = '')
43
 * @method static void nullOrIsCountable($value, $message = '')
44
 * @method static void nullOrIsIterable($value, $message = '')
45
 * @method static void nullOrIsInstanceOf($value, $class, $message = '')
46
 * @method static void nullOrNotInstanceOf($value, $class, $message = '')
47
 * @method static void nullOrIsInstanceOfAny($value, $classes, $message = '')
48
 * @method static void nullOrIsAOf($value, $classes, $message = '')
49
 * @method static void nullOrIsAnyOf($value, $classes, $message = '')
50
 * @method static void nullOrIsNotA($value, $classes, $message = '')
51
 * @method static void nullOrIsEmpty($value, $message = '')
52
 * @method static void nullOrNotEmpty($value, $message = '')
53
 * @method static void nullOrTrue($value, $message = '')
54
 * @method static void nullOrFalse($value, $message = '')
55
 * @method static void nullOrNotFalse($value, $message = '')
56
 * @method static void nullOrIp($value, $message = '')
57
 * @method static void nullOrIpv4($value, $message = '')
58
 * @method static void nullOrIpv6($value, $message = '')
59
 * @method static void nullOrEmail($value, $message = '')
60
 * @method static void nullOrUniqueValues($values, $message = '')
61
 * @method static void nullOrEq($value, $expect, $message = '')
62
 * @method static void nullOrNotEq($value, $expect, $message = '')
63
 * @method static void nullOrSame($value, $expect, $message = '')
64
 * @method static void nullOrNotSame($value, $expect, $message = '')
65
 * @method static void nullOrGreaterThan($value, $limit, $message = '')
66
 * @method static void nullOrGreaterThanEq($value, $limit, $message = '')
67
 * @method static void nullOrLessThan($value, $limit, $message = '')
68
 * @method static void nullOrLessThanEq($value, $limit, $message = '')
69
 * @method static void nullOrRange($value, $min, $max, $message = '')
70
 * @method static void nullOrOneOf($value, $values, $message = '')
71
 * @method static void nullOrContains($value, $subString, $message = '')
72
 * @method static void nullOrNotContains($value, $subString, $message = '')
73
 * @method static void nullOrNotWhitespaceOnly($value, $message = '')
74
 * @method static void nullOrStartsWith($value, $prefix, $message = '')
75
 * @method static void nullOrStartsWithLetter($value, $message = '')
76
 * @method static void nullOrEndsWith($value, $suffix, $message = '')
77
 * @method static void nullOrRegex($value, $pattern, $message = '')
78
 * @method static void nullOrNotRegex($value, $pattern, $message = '')
79
 * @method static void nullOrUnicodeLetters($value, $message = '')
80
 * @method static void nullOrAlpha($value, $message = '')
81
 * @method static void nullOrDigits($value, $message = '')
82
 * @method static void nullOrAlnum($value, $message = '')
83
 * @method static void nullOrLower($value, $message = '')
84
 * @method static void nullOrUpper($value, $message = '')
85
 * @method static void nullOrLength($value, $length, $message = '')
86
 * @method static void nullOrMinLength($value, $min, $message = '')
87
 * @method static void nullOrMaxLength($value, $max, $message = '')
88
 * @method static void nullOrLengthBetween($value, $min, $max, $message = '')
89
 * @method static void nullOrFileExists($value, $message = '')
90
 * @method static void nullOrFile($value, $message = '')
91
 * @method static void nullOrDirectory($value, $message = '')
92
 * @method static void nullOrReadable($value, $message = '')
93
 * @method static void nullOrWritable($value, $message = '')
94
 * @method static void nullOrClassExists($value, $message = '')
95
 * @method static void nullOrSubclassOf($value, $class, $message = '')
96
 * @method static void nullOrInterfaceExists($value, $message = '')
97
 * @method static void nullOrImplementsInterface($value, $interface, $message = '')
98
 * @method static void nullOrPropertyExists($value, $property, $message = '')
99
 * @method static void nullOrPropertyNotExists($value, $property, $message = '')
100
 * @method static void nullOrMethodExists($value, $method, $message = '')
101
 * @method static void nullOrMethodNotExists($value, $method, $message = '')
102
 * @method static void nullOrKeyExists($value, $key, $message = '')
103
 * @method static void nullOrKeyNotExists($value, $key, $message = '')
104
 * @method static void nullOrValidArrayKey($value, $message = '')
105
 * @method static void nullOrCount($value, $key, $message = '')
106
 * @method static void nullOrMinCount($value, $min, $message = '')
107
 * @method static void nullOrMaxCount($value, $max, $message = '')
108
 * @method static void nullOrIsList($value, $message = '')
109
 * @method static void nullOrIsNonEmptyList($value, $message = '')
110
 * @method static void nullOrIsMap($value, $message = '')
111
 * @method static void nullOrIsNonEmptyMap($value, $message = '')
112
 * @method static void nullOrCountBetween($value, $min, $max, $message = '')
113
 * @method static void nullOrUuid($values, $message = '')
114
 * @method static void nullOrThrows($expression, $class = 'Exception', $message = '')
115
 * @method static void allString($values, $message = '')
116
 * @method static void allStringNotEmpty($values, $message = '')
117
 * @method static void allInteger($values, $message = '')
118
 * @method static void allIntegerish($values, $message = '')
119
 * @method static void allFloat($values, $message = '')
120
 * @method static void allNumeric($values, $message = '')
121
 * @method static void allNatural($values, $message = '')
122
 * @method static void allBoolean($values, $message = '')
123
 * @method static void allScalar($values, $message = '')
124
 * @method static void allObject($values, $message = '')
125
 * @method static void allResource($values, $type = null, $message = '')
126
 * @method static void allIsCallable($values, $message = '')
127
 * @method static void allIsArray($values, $message = '')
128
 * @method static void allIsTraversable($values, $message = '')
129
 * @method static void allIsArrayAccessible($values, $message = '')
130
 * @method static void allIsCountable($values, $message = '')
131
 * @method static void allIsIterable($values, $message = '')
132
 * @method static void allIsInstanceOf($values, $class, $message = '')
133
 * @method static void allNotInstanceOf($values, $class, $message = '')
134
 * @method static void allIsInstanceOfAny($values, $classes, $message = '')
135
 * @method static void allIsAOf($values, $class, $message = '')
136
 * @method static void allIsAnyOf($values, $class, $message = '')
137
 * @method static void allIsNotA($values, $class, $message = '')
138
 * @method static void allNull($values, $message = '')
139
 * @method static void allNotNull($values, $message = '')
140
 * @method static void allIsEmpty($values, $message = '')
141
 * @method static void allNotEmpty($values, $message = '')
142
 * @method static void allTrue($values, $message = '')
143
 * @method static void allFalse($values, $message = '')
144
 * @method static void allNotFalse($values, $message = '')
145
 * @method static void allIp($values, $message = '')
146
 * @method static void allIpv4($values, $message = '')
147
 * @method static void allIpv6($values, $message = '')
148
 * @method static void allEmail($values, $message = '')
149
 * @method static void allUniqueValues($values, $message = '')
150
 * @method static void allEq($values, $expect, $message = '')
151
 * @method static void allNotEq($values, $expect, $message = '')
152
 * @method static void allSame($values, $expect, $message = '')
153
 * @method static void allNotSame($values, $expect, $message = '')
154
 * @method static void allGreaterThan($values, $limit, $message = '')
155
 * @method static void allGreaterThanEq($values, $limit, $message = '')
156
 * @method static void allLessThan($values, $limit, $message = '')
157
 * @method static void allLessThanEq($values, $limit, $message = '')
158
 * @method static void allRange($values, $min, $max, $message = '')
159
 * @method static void allOneOf($values, $values, $message = '')
160
 * @method static void allContains($values, $subString, $message = '')
161
 * @method static void allNotContains($values, $subString, $message = '')
162
 * @method static void allNotWhitespaceOnly($values, $message = '')
163
 * @method static void allStartsWith($values, $prefix, $message = '')
164
 * @method static void allStartsWithLetter($values, $message = '')
165
 * @method static void allEndsWith($values, $suffix, $message = '')
166
 * @method static void allRegex($values, $pattern, $message = '')
167
 * @method static void allNotRegex($values, $pattern, $message = '')
168
 * @method static void allUnicodeLetters($values, $message = '')
169
 * @method static void allAlpha($values, $message = '')
170
 * @method static void allDigits($values, $message = '')
171
 * @method static void allAlnum($values, $message = '')
172
 * @method static void allLower($values, $message = '')
173
 * @method static void allUpper($values, $message = '')
174
 * @method static void allLength($values, $length, $message = '')
175
 * @method static void allMinLength($values, $min, $message = '')
176
 * @method static void allMaxLength($values, $max, $message = '')
177
 * @method static void allLengthBetween($values, $min, $max, $message = '')
178
 * @method static void allFileExists($values, $message = '')
179
 * @method static void allFile($values, $message = '')
180
 * @method static void allDirectory($values, $message = '')
181
 * @method static void allReadable($values, $message = '')
182
 * @method static void allWritable($values, $message = '')
183
 * @method static void allClassExists($values, $message = '')
184
 * @method static void allSubclassOf($values, $class, $message = '')
185
 * @method static void allInterfaceExists($values, $message = '')
186
 * @method static void allImplementsInterface($values, $interface, $message = '')
187
 * @method static void allPropertyExists($values, $property, $message = '')
188
 * @method static void allPropertyNotExists($values, $property, $message = '')
189
 * @method static void allMethodExists($values, $method, $message = '')
190
 * @method static void allMethodNotExists($values, $method, $message = '')
191
 * @method static void allKeyExists($values, $key, $message = '')
192
 * @method static void allKeyNotExists($values, $key, $message = '')
193
 * @method static void allValidArrayKey($values, $message = '')
194
 * @method static void allCount($values, $key, $message = '')
195
 * @method static void allMinCount($values, $min, $message = '')
196
 * @method static void allMaxCount($values, $max, $message = '')
197
 * @method static void allCountBetween($values, $min, $max, $message = '')
198
 * @method static void allIsList($values, $message = '')
199
 * @method static void allIsNonEmptyList($values, $message = '')
200
 * @method static void allIsMap($values, $message = '')
201
 * @method static void allIsNonEmptyMap($values, $message = '')
202
 * @method static void allUuid($values, $message = '')
203
 * @method static void allThrows($expressions, $class = 'Exception', $message = '')
204
 *
205
 * @since  1.0
206
 *
207
 * @author Bernhard Schussek <[email protected]>
208
 */
209
class Assert
210
{
211
    /**
212
     * @psalm-assert string $value
213
     *
214
     * @param mixed  $value
215
     * @param string $message
216
     *
217
     * @throws InvalidArgumentException
218
     */
219 241
    public static function string($value, $message = '')
220
    {
221 241
        if (!\is_string($value)) {
222 45
            static::reportInvalidArgument(\sprintf(
223 45
                $message ?: 'Expected a string. Got: %s',
224 45
                static::typeToString($value)
225
            ));
226
        }
227 196
    }
228
229
    /**
230
     * @param mixed  $value
231
     * @param string $message
232
     *
233
     * @throws InvalidArgumentException
234
     */
235 16
    public static function stringNotEmpty($value, $message = '')
236
    {
237 16
        static::string($value, $message);
238 12
        static::notEq($value, '', $message);
239 8
    }
240
241
    /**
242
     * @psalm-assert int $value
243
     *
244
     * @param mixed  $value
245
     * @param string $message
246
     *
247
     * @throws InvalidArgumentException
248
     */
249 17
    public static function integer($value, $message = '')
250
    {
251 17
        if (!\is_int($value)) {
252 13
            static::reportInvalidArgument(\sprintf(
253 13
                $message ?: 'Expected an integer. Got: %s',
254 13
                static::typeToString($value)
255
            ));
256
        }
257 4
    }
258
259
    /**
260
     * @psalm-assert numeric $value
261
     *
262
     * @param mixed  $value
263
     * @param string $message
264
     *
265
     * @throws InvalidArgumentException
266
     */
267 16
    public static function integerish($value, $message = '')
268
    {
269 16
        if (!\is_numeric($value) || $value != (int) $value) {
270 4
            static::reportInvalidArgument(\sprintf(
271 4
                $message ?: 'Expected an integerish value. Got: %s',
272 4
                static::typeToString($value)
273
            ));
274
        }
275 12
    }
276
277
    /**
278
     * @psalm-assert float $value
279
     *
280
     * @param mixed  $value
281
     * @param string $message
282
     *
283
     * @throws InvalidArgumentException
284
     */
285 16
    public static function float($value, $message = '')
286
    {
287 16
        if (!\is_float($value)) {
288 8
            static::reportInvalidArgument(\sprintf(
289 8
                $message ?: 'Expected a float. Got: %s',
290 8
                static::typeToString($value)
291
            ));
292
        }
293 8
    }
294
295
    /**
296
     * @psalm-assert numeric $value
297
     *
298
     * @param mixed  $value
299
     * @param string $message
300
     *
301
     * @throws InvalidArgumentException
302
     */
303 20
    public static function numeric($value, $message = '')
304
    {
305 20
        if (!\is_numeric($value)) {
306 4
            static::reportInvalidArgument(\sprintf(
307 4
                $message ?: 'Expected a numeric. Got: %s',
308 4
                static::typeToString($value)
309
            ));
310
        }
311 16
    }
312
313
    /**
314
     * @psalm-assert int $value
315
     *
316
     * @param mixed  $value
317
     * @param string $message
318
     *
319
     * @throws InvalidArgumentException
320
     */
321 24
    public static function natural($value, $message = '')
322
    {
323 24
        if (!\is_int($value) || $value < 0) {
324 16
            static::reportInvalidArgument(\sprintf(
325 16
                $message ?: 'Expected a non-negative integer. Got %s',
326 16
                static::valueToString($value)
327
            ));
328
        }
329 8
    }
330
331
    /**
332
     * @psalm-assert bool $value
333
     *
334
     * @param mixed  $value
335
     * @param string $message
336
     *
337
     * @throws InvalidArgumentException
338
     */
339 16
    public static function boolean($value, $message = '')
340
    {
341 16
        if (!\is_bool($value)) {
342 8
            static::reportInvalidArgument(\sprintf(
343 8
                $message ?: 'Expected a boolean. Got: %s',
344 8
                static::typeToString($value)
345
            ));
346
        }
347 8
    }
348
349
    /**
350
     * @psalm-assert scalar $value
351
     *
352
     * @param mixed  $value
353
     * @param string $message
354
     *
355
     * @throws InvalidArgumentException
356
     */
357 23
    public static function scalar($value, $message = '')
358
    {
359 23
        if (!\is_scalar($value)) {
360 11
            static::reportInvalidArgument(\sprintf(
361 11
                $message ?: 'Expected a scalar. Got: %s',
362 11
                static::typeToString($value)
363
            ));
364
        }
365 12
    }
366
367
    /**
368
     * @psalm-assert object $value
369
     *
370
     * @param mixed  $value
371
     * @param string $message
372
     *
373
     * @throws InvalidArgumentException
374
     */
375 23
    public static function object($value, $message = '')
376
    {
377 23
        if (!\is_object($value)) {
378 15
            static::reportInvalidArgument(\sprintf(
379 15
                $message ?: 'Expected an object. Got: %s',
380 15
                static::typeToString($value)
381
            ));
382
        }
383 8
    }
384
385
    /**
386
     * @psalm-assert resource $value
387
     *
388
     * @param mixed       $value
389
     * @param string|null $type    type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php
390
     * @param string      $message
391
     *
392
     * @throws InvalidArgumentException
393
     */
394 16
    public static function resource($value, $type = null, $message = '')
395
    {
396 16
        if (!\is_resource($value)) {
397 4
            static::reportInvalidArgument(\sprintf(
398 4
                $message ?: 'Expected a resource. Got: %s',
399 4
                static::typeToString($value)
400
            ));
401
        }
402
403 12
        if ($type && $type !== \get_resource_type($value)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $type of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
404 4
            static::reportInvalidArgument(\sprintf(
405 4
                $message ?: 'Expected a resource of type %2$s. Got: %s',
406 4
                static::typeToString($value),
407 4
                $type
408
            ));
409
        }
410 8
    }
411
412
    /**
413
     * @psalm-assert callable $value
414
     *
415
     * @param mixed  $value
416
     * @param string $message
417
     *
418
     * @throws InvalidArgumentException
419
     */
420 20
    public static function isCallable($value, $message = '')
421
    {
422 20
        if (!\is_callable($value)) {
423 8
            static::reportInvalidArgument(\sprintf(
424 8
                $message ?: 'Expected a callable. Got: %s',
425 8
                static::typeToString($value)
426
            ));
427
        }
428 12
    }
429
430
    /**
431
     * @psalm-assert array $value
432
     *
433
     * @param mixed  $value
434
     * @param string $message
435
     *
436
     * @throws InvalidArgumentException
437
     */
438 20
    public static function isArray($value, $message = '')
439
    {
440 20
        if (!\is_array($value)) {
441 12
            static::reportInvalidArgument(\sprintf(
442 12
                $message ?: 'Expected an array. Got: %s',
443 12
                static::typeToString($value)
444
            ));
445
        }
446 8
    }
447
448
    /**
449
     * @psalm-assert iterable $value
450
     *
451
     * @deprecated use "isIterable" or "isInstanceOf" instead
452
     *
453
     * @param mixed  $value
454
     * @param string $message
455
     *
456
     * @throws InvalidArgumentException
457
     */
458 20
    public static function isTraversable($value, $message = '')
459
    {
460 20
        @\trigger_error(
461 20
            \sprintf(
462 20
                '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.',
463 20
                __METHOD__
464
            ),
465 20
            \E_USER_DEPRECATED
466
        );
467
468 20
        if (!\is_array($value) && !($value instanceof Traversable)) {
469 8
            static::reportInvalidArgument(\sprintf(
470 8
                $message ?: 'Expected a traversable. Got: %s',
471 8
                static::typeToString($value)
472
            ));
473
        }
474 12
    }
475
476
    /**
477
     * @param mixed  $value
478
     * @param string $message
479
     *
480
     * @throws InvalidArgumentException
481
     */
482 20 View Code Duplication
    public static function isArrayAccessible($value, $message = '')
483
    {
484 20
        if (!\is_array($value) && !($value instanceof ArrayAccess)) {
485 8
            static::reportInvalidArgument(\sprintf(
486 8
                $message ?: 'Expected an array accessible. Got: %s',
487 8
                static::typeToString($value)
488
            ));
489
        }
490 12
    }
491
492
    /**
493
     * @psalm-assert countable $value
494
     *
495
     * @param mixed  $value
496
     * @param string $message
497
     *
498
     * @throws InvalidArgumentException
499
     */
500 28
    public static function isCountable($value, $message = '')
501
    {
502
        if (
503 28
            !\is_array($value)
504 28
            && !($value instanceof Countable)
505 28
            && !($value instanceof ResourceBundle)
0 ignored issues
show
The class ResourceBundle does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
506 28
            && !($value instanceof SimpleXMLElement)
507
        ) {
508 12
            static::reportInvalidArgument(\sprintf(
509 12
                $message ?: 'Expected a countable. Got: %s',
510 12
                static::typeToString($value)
511
            ));
512
        }
513 16
    }
514
515
    /**
516
     * @psalm-assert iterable $value
517
     *
518
     * @param mixed  $value
519
     * @param string $message
520
     *
521
     * @throws InvalidArgumentException
522
     */
523 992 View Code Duplication
    public static function isIterable($value, $message = '')
524
    {
525 992
        if (!\is_array($value) && !($value instanceof Traversable)) {
526 8
            static::reportInvalidArgument(\sprintf(
527 8
                $message ?: 'Expected an iterable. Got: %s',
528 8
                static::typeToString($value)
529
            ));
530
        }
531 988
    }
532
533
    /**
534
     * @psalm-template ExpectedType of object
535
     * @psalm-param class-string<ExpectedType> $class
536
     * @psalm-assert ExpectedType $value
537
     *
538
     * @param mixed         $value
539
     * @param string|object $class
540
     * @param string        $message
541
     *
542
     * @throws InvalidArgumentException
543
     */
544 19
    public static function isInstanceOf($value, $class, $message = '')
545
    {
546 19
        if (!($value instanceof $class)) {
547 15
            static::reportInvalidArgument(\sprintf(
548 15
                $message ?: 'Expected an instance of %2$s. Got: %s',
549 15
                static::typeToString($value),
550 15
                $class
551
            ));
552
        }
553 4
    }
554
555
    /**
556
     * @psalm-template ExpectedType of object
557
     * @psalm-param class-string<ExpectedType> $class
558
     * @psalm-assert !ExpectedType $value
559
     *
560
     * @param mixed         $value
561
     * @param string|object $class
562
     * @param string        $message
563
     *
564
     * @throws InvalidArgumentException
565
     */
566 16
    public static function notInstanceOf($value, $class, $message = '')
567
    {
568 16
        if ($value instanceof $class) {
569 4
            static::reportInvalidArgument(\sprintf(
570 4
                $message ?: 'Expected an instance other than %2$s. Got: %s',
571 4
                static::typeToString($value),
572 4
                $class
573
            ));
574
        }
575 12
    }
576
577
    /**
578
     * @param mixed                $value
579
     * @param array<object|string> $classes
580
     * @param string               $message
581
     *
582
     * @throws InvalidArgumentException
583
     */
584 20
    public static function isInstanceOfAny($value, array $classes, $message = '')
585
    {
586 20
        foreach ($classes as $class) {
587 20
            if ($value instanceof $class) {
588 8
                return;
589
            }
590
        }
591
592 12
        static::reportInvalidArgument(\sprintf(
593 12
            $message ?: 'Expected an instance of any of %2$s. Got: %s',
594 12
            static::typeToString($value),
595 12
            \implode(', ', \array_map(array('static', 'valueToString'), $classes))
596
        ));
597
    }
598
599
    /**
600
     * @param object|string $value
601
     * @param string        $class
602
     * @param string        $message
603
     *
604
     * @throws InvalidArgumentException
605
     */
606 20 View Code Duplication
    public static function isAOf($value, $class, $message = '')
607
    {
608 20
        static::string($class, 'Expected class as a string. Got: %s');
609
610 16
        if (!\is_a($value, $class, \is_string($value))) {
611 12
            static::reportInvalidArgument(sprintf(
612 12
                $message ?: 'Expected an instance of this class or to this class among his parents %2$s. Got: %s',
613 12
                static::typeToString($value),
614
                $class
615
            ));
616
        }
617 4
    }
618
619
    /**
620
     * @param object|string $value
621
     * @param string        $class
622
     * @param string        $message
623
     *
624
     * @throws InvalidArgumentException
625
     */
626 20 View Code Duplication
    public static function isNotA($value, $class, $message = '')
627
    {
628 20
        static::string($class, 'Expected class as a string. Got: %s');
629
630 16
        if (\is_a($value, $class, \is_string($value))) {
631 4
            static::reportInvalidArgument(sprintf(
632 4
                $message ?: 'Expected an instance of this class or to this class among his parents other than %2$s. Got: %s',
633 4
                static::typeToString($value),
634
                $class
635
            ));
636
        }
637 12
    }
638
639
    /**
640
     * @param object|string $value
641
     * @param string[]      $classes
642
     * @param string        $message
643
     *
644
     * @throws InvalidArgumentException
645
     */
646 24
    public static function isAnyOf($value, array $classes, $message = '')
647
    {
648 24
        foreach ($classes as $class) {
649 24
            static::string($class, 'Expected class as a string. Got: %s');
650
651 20
            if (\is_a($value, $class, \is_string($value))) {
652 8
                return;
653
            }
654
        }
655
656 12
        static::reportInvalidArgument(sprintf(
657 12
            $message ?: 'Expected an any of instance of this class or to this class among his parents other than %2$s. Got: %s',
658 12
            static::typeToString($value),
659 12
            \implode(', ', \array_map(array('static', 'valueToString'), $classes))
660
        ));
661
    }
662
663
    /**
664
     * @psalm-assert empty $value
665
     *
666
     * @param mixed  $value
667
     * @param string $message
668
     *
669
     * @throws InvalidArgumentException
670
     */
671 23
    public static function isEmpty($value, $message = '')
672
    {
673 23
        if (!empty($value)) {
674 8
            static::reportInvalidArgument(\sprintf(
675 8
                $message ?: 'Expected an empty value. Got: %s',
676 8
                static::valueToString($value)
677
            ));
678
        }
679 15
    }
680
681
    /**
682
     * @psalm-assert !empty $value
683
     *
684
     * @param mixed  $value
685
     * @param string $message
686
     *
687
     * @throws InvalidArgumentException
688
     */
689 55
    public static function notEmpty($value, $message = '')
690
    {
691 55
        if (empty($value)) {
692 23
            static::reportInvalidArgument(\sprintf(
693 23
                $message ?: 'Expected a non-empty value. Got: %s',
694 23
                static::valueToString($value)
695
            ));
696
        }
697 32
    }
698
699
    /**
700
     * @psalm-assert null $value
701
     *
702
     * @param mixed  $value
703
     * @param string $message
704
     *
705
     * @throws InvalidArgumentException
706
     */
707 11
    public static function null($value, $message = '')
708
    {
709 11
        if (null !== $value) {
710 8
            static::reportInvalidArgument(\sprintf(
711 8
                $message ?: 'Expected null. Got: %s',
712 8
                static::valueToString($value)
713
            ));
714
        }
715 3
    }
716
717
    /**
718
     * @psalm-assert !null $value
719
     *
720
     * @param mixed  $value
721
     * @param string $message
722
     *
723
     * @throws InvalidArgumentException
724
     */
725 11
    public static function notNull($value, $message = '')
726
    {
727 11
        if (null === $value) {
728 3
            static::reportInvalidArgument(
729 3
                $message ?: 'Expected a value other than null.'
730
            );
731
        }
732 8
    }
733
734
    /**
735
     * @psalm-assert true $value
736
     *
737
     * @param mixed  $value
738
     * @param string $message
739
     *
740
     * @throws InvalidArgumentException
741
     */
742 15
    public static function true($value, $message = '')
743
    {
744 15
        if (true !== $value) {
745 11
            static::reportInvalidArgument(\sprintf(
746 11
                $message ?: 'Expected a value to be true. Got: %s',
747 11
                static::valueToString($value)
748
            ));
749
        }
750 4
    }
751
752
    /**
753
     * @psalm-assert false $value
754
     *
755
     * @param mixed  $value
756
     * @param string $message
757
     *
758
     * @throws InvalidArgumentException
759
     */
760 19
    public static function false($value, $message = '')
761
    {
762 19
        if (false !== $value) {
763 15
            static::reportInvalidArgument(\sprintf(
764 15
                $message ?: 'Expected a value to be false. Got: %s',
765 15
                static::valueToString($value)
766
            ));
767
        }
768 4
    }
769
770
    /**
771
     * @psalm-assert !false $value
772
     *
773
     * @param mixed  $value
774
     * @param string $message
775
     *
776
     * @throws InvalidArgumentException
777
     */
778 19
    public static function notFalse($value, $message = '')
779
    {
780 19
        if (false === $value) {
781 4
            static::reportInvalidArgument(
782 4
                $message ?: 'Expected a value other than false.'
783
            );
784
        }
785 15
    }
786
787
    /**
788
     * @param mixed  $value
789
     * @param string $message
790
     *
791
     * @throws InvalidArgumentException
792
     */
793 51 View Code Duplication
    public static function ip($value, $message = '')
794
    {
795 51
        if (false === \filter_var($value, \FILTER_VALIDATE_IP)) {
796 19
            static::reportInvalidArgument(\sprintf(
797 19
                $message ?: 'Expected a value to be an IP. Got: %s',
798 19
                static::valueToString($value)
799
            ));
800
        }
801 32
    }
802
803
    /**
804
     * @param mixed  $value
805
     * @param string $message
806
     *
807
     * @throws InvalidArgumentException
808
     */
809 51 View Code Duplication
    public static function ipv4($value, $message = '')
810
    {
811 51
        if (false === \filter_var($value, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) {
812 35
            static::reportInvalidArgument(\sprintf(
813 35
                $message ?: 'Expected a value to be an IPv4. Got: %s',
814 35
                static::valueToString($value)
815
            ));
816
        }
817 16
    }
818
819
    /**
820
     * @param mixed  $value
821
     * @param string $message
822
     *
823
     * @throws InvalidArgumentException
824
     */
825 51 View Code Duplication
    public static function ipv6($value, $message = '')
826
    {
827 51
        if (false === \filter_var($value, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) {
828 31
            static::reportInvalidArgument(\sprintf(
829 31
                $message ?: 'Expected a value to be an IPv6. Got %s',
830 31
                static::valueToString($value)
831
            ));
832
        }
833 20
    }
834
835
    /**
836
     * @param mixed  $value
837
     * @param string $message
838
     *
839
     * @throws InvalidArgumentException
840
     */
841 20 View Code Duplication
    public static function email($value, $message = '')
842
    {
843 20
        if (false === \filter_var($value, FILTER_VALIDATE_EMAIL)) {
844 12
            static::reportInvalidArgument(\sprintf(
845 12
                $message ?: 'Expected a value to be a valid e-mail address. Got %s',
846 12
                static::valueToString($value)
847
            ));
848
        }
849 8
    }
850
851
    /**
852
     * Does non strict comparisons on the items, so ['3', 3] will not pass the assertion.
853
     *
854
     * @param array  $values
855
     * @param string $message
856
     *
857
     * @throws InvalidArgumentException
858
     */
859 12
    public static function uniqueValues(array $values, $message = '')
860
    {
861 12
        $allValues = \count($values);
862 12
        $uniqueValues = \count(\array_unique($values));
863
864 12
        if ($allValues !== $uniqueValues) {
865 8
            $difference = $allValues - $uniqueValues;
866
867 8
            static::reportInvalidArgument(\sprintf(
868 8
                $message ?: 'Expected an array of unique values, but %s of them %s duplicated',
869 8
                $difference,
870 8
                (1 === $difference ? 'is' : 'are')
871
            ));
872
        }
873 4
    }
874
875
    /**
876
     * @param mixed  $value
877
     * @param mixed  $expect
878
     * @param string $message
879
     *
880
     * @throws InvalidArgumentException
881
     */
882 33
    public static function eq($value, $expect, $message = '')
883
    {
884 33
        if ($expect != $value) {
885 17
            static::reportInvalidArgument(\sprintf(
886 17
                $message ?: 'Expected a value equal to %2$s. Got: %s',
887 17
                static::valueToString($value),
888 17
                static::valueToString($expect)
889
            ));
890
        }
891 16
    }
892
893
    /**
894
     * @param mixed  $value
895
     * @param mixed  $expect
896
     * @param string $message
897
     *
898
     * @throws InvalidArgumentException
899
     */
900 28
    public static function notEq($value, $expect, $message = '')
901
    {
902 28
        if ($expect == $value) {
903 16
            static::reportInvalidArgument(\sprintf(
904 16
                $message ?: 'Expected a different value than %s.',
905 16
                static::valueToString($expect)
906
            ));
907
        }
908 12
    }
909
910
    /**
911
     * @param mixed  $value
912
     * @param mixed  $expect
913
     * @param string $message
914
     *
915
     * @throws InvalidArgumentException
916
     */
917 16
    public static function same($value, $expect, $message = '')
918
    {
919 16
        if ($expect !== $value) {
920 12
            static::reportInvalidArgument(\sprintf(
921 12
                $message ?: 'Expected a value identical to %2$s. Got: %s',
922 12
                static::valueToString($value),
923 12
                static::valueToString($expect)
924
            ));
925
        }
926 4
    }
927
928
    /**
929
     * @param mixed  $value
930
     * @param mixed  $expect
931
     * @param string $message
932
     *
933
     * @throws InvalidArgumentException
934
     */
935 16
    public static function notSame($value, $expect, $message = '')
936
    {
937 16
        if ($expect === $value) {
938 4
            static::reportInvalidArgument(\sprintf(
939 4
                $message ?: 'Expected a value not identical to %s.',
940 4
                static::valueToString($expect)
941
            ));
942
        }
943 12
    }
944
945
    /**
946
     * @param mixed  $value
947
     * @param mixed  $limit
948
     * @param string $message
949
     *
950
     * @throws InvalidArgumentException
951
     */
952 8
    public static function greaterThan($value, $limit, $message = '')
953
    {
954 8
        if ($value <= $limit) {
955 4
            static::reportInvalidArgument(\sprintf(
956 4
                $message ?: 'Expected a value greater than %2$s. Got: %s',
957 4
                static::valueToString($value),
958 4
                static::valueToString($limit)
959
            ));
960
        }
961 4
    }
962
963
    /**
964
     * @param mixed  $value
965
     * @param mixed  $limit
966
     * @param string $message
967
     *
968
     * @throws InvalidArgumentException
969
     */
970 12
    public static function greaterThanEq($value, $limit, $message = '')
971
    {
972 12
        if ($value < $limit) {
973 4
            static::reportInvalidArgument(\sprintf(
974 4
                $message ?: 'Expected a value greater than or equal to %2$s. Got: %s',
975 4
                static::valueToString($value),
976 4
                static::valueToString($limit)
977
            ));
978
        }
979 8
    }
980
981
    /**
982
     * @param mixed  $value
983
     * @param mixed  $limit
984
     * @param string $message
985
     *
986
     * @throws InvalidArgumentException
987
     */
988 8
    public static function lessThan($value, $limit, $message = '')
989
    {
990 8
        if ($value >= $limit) {
991 4
            static::reportInvalidArgument(\sprintf(
992 4
                $message ?: 'Expected a value less than %2$s. Got: %s',
993 4
                static::valueToString($value),
994 4
                static::valueToString($limit)
995
            ));
996
        }
997 4
    }
998
999
    /**
1000
     * @param mixed  $value
1001
     * @param mixed  $limit
1002
     * @param string $message
1003
     *
1004
     * @throws InvalidArgumentException
1005
     */
1006 12
    public static function lessThanEq($value, $limit, $message = '')
1007
    {
1008 12
        if ($value > $limit) {
1009 4
            static::reportInvalidArgument(\sprintf(
1010 4
                $message ?: 'Expected a value less than or equal to %2$s. Got: %s',
1011 4
                static::valueToString($value),
1012 4
                static::valueToString($limit)
1013
            ));
1014
        }
1015 8
    }
1016
1017
    /**
1018
     * Inclusive range, so Assert::(3, 3, 5) passes.
1019
     *
1020
     * @param mixed  $value
1021
     * @param mixed  $min
1022
     * @param mixed  $max
1023
     * @param string $message
1024
     *
1025
     * @throws InvalidArgumentException
1026
     */
1027 16 View Code Duplication
    public static function range($value, $min, $max, $message = '')
1028
    {
1029 16
        if ($value < $min || $value > $max) {
1030 8
            static::reportInvalidArgument(\sprintf(
1031 8
                $message ?: 'Expected a value between %2$s and %3$s. Got: %s',
1032 8
                static::valueToString($value),
1033 8
                static::valueToString($min),
1034 8
                static::valueToString($max)
1035
            ));
1036
        }
1037 8
    }
1038
1039
    /**
1040
     * Does strict comparison, so Assert::oneOf(3, ['3']) does not pass the assertion.
1041
     *
1042
     * @param mixed  $value
1043
     * @param array  $values
1044
     * @param string $message
1045
     *
1046
     * @throws InvalidArgumentException
1047
     */
1048 8
    public static function oneOf($value, array $values, $message = '')
1049
    {
1050 8
        if (!\in_array($value, $values, true)) {
1051 4
            static::reportInvalidArgument(\sprintf(
1052 4
                $message ?: 'Expected one of: %2$s. Got: %s',
1053 4
                static::valueToString($value),
1054 4
                \implode(', ', \array_map(array('static', 'valueToString'), $values))
1055
            ));
1056
        }
1057 4
    }
1058
1059
    /**
1060
     * @param mixed  $value
1061
     * @param string $subString
1062
     * @param string $message
1063
     *
1064
     * @throws InvalidArgumentException
1065
     */
1066 80 View Code Duplication
    public static function contains($value, $subString, $message = '')
1067
    {
1068 80
        if (false === \strpos($value, $subString)) {
1069 32
            static::reportInvalidArgument(\sprintf(
1070 32
                $message ?: 'Expected a value to contain %2$s. Got: %s',
1071 32
                static::valueToString($value),
1072 32
                static::valueToString($subString)
1073
            ));
1074
        }
1075 48
    }
1076
1077
    /**
1078
     * @param mixed  $value
1079
     * @param string $subString
1080
     * @param string $message
1081
     *
1082
     * @throws InvalidArgumentException
1083
     */
1084 80 View Code Duplication
    public static function notContains($value, $subString, $message = '')
1085
    {
1086 80
        if (false !== \strpos($value, $subString)) {
1087 48
            static::reportInvalidArgument(\sprintf(
1088 48
                $message ?: '%2$s was not expected to be contained in a value. Got: %s',
1089 48
                static::valueToString($value),
1090 48
                static::valueToString($subString)
1091
            ));
1092
        }
1093 32
    }
1094
1095
    /**
1096
     * @param mixed  $value
1097
     * @param string $message
1098
     *
1099
     * @throws InvalidArgumentException
1100
     */
1101 40
    public static function notWhitespaceOnly($value, $message = '')
1102
    {
1103 40
        if (\preg_match('/^\s*$/', $value)) {
1104 24
            static::reportInvalidArgument(\sprintf(
1105 24
                $message ?: 'Expected a non-whitespace string. Got: %s',
1106 24
                static::valueToString($value)
1107
            ));
1108
        }
1109 16
    }
1110
1111
    /**
1112
     * @param mixed  $value
1113
     * @param string $prefix
1114
     * @param string $message
1115
     *
1116
     * @throws InvalidArgumentException
1117
     */
1118 48 View Code Duplication
    public static function startsWith($value, $prefix, $message = '')
1119
    {
1120 48
        if (0 !== \strpos($value, $prefix)) {
1121 32
            static::reportInvalidArgument(\sprintf(
1122 32
                $message ?: 'Expected a value to start with %2$s. Got: %s',
1123 32
                static::valueToString($value),
1124 32
                static::valueToString($prefix)
1125
            ));
1126
        }
1127 16
    }
1128
1129
    /**
1130
     * @param mixed  $value
1131
     * @param string $message
1132
     *
1133
     * @throws InvalidArgumentException
1134
     */
1135 35
    public static function startsWithLetter($value, $message = '')
1136
    {
1137 35
        static::string($value);
1138
1139 24
        $valid = isset($value[0]);
1140
1141 24
        if ($valid) {
1142 20
            $locale = \setlocale(LC_CTYPE, 0);
1143 20
            \setlocale(LC_CTYPE, 'C');
1144 20
            $valid = \ctype_alpha($value[0]);
1145 20
            \setlocale(LC_CTYPE, $locale);
1146
        }
1147
1148 24
        if (!$valid) {
1149 12
            static::reportInvalidArgument(\sprintf(
1150 12
                $message ?: 'Expected a value to start with a letter. Got: %s',
1151 12
                static::valueToString($value)
1152
            ));
1153
        }
1154 12
    }
1155
1156
    /**
1157
     * @param mixed  $value
1158
     * @param string $suffix
1159
     * @param string $message
1160
     *
1161
     * @throws InvalidArgumentException
1162
     */
1163 48 View Code Duplication
    public static function endsWith($value, $suffix, $message = '')
1164
    {
1165 48
        if ($suffix !== \substr($value, -\strlen($suffix))) {
1166 32
            static::reportInvalidArgument(\sprintf(
1167 32
                $message ?: 'Expected a value to end with %2$s. Got: %s',
1168 32
                static::valueToString($value),
1169 32
                static::valueToString($suffix)
1170
            ));
1171
        }
1172 16
    }
1173
1174
    /**
1175
     * @param mixed  $value
1176
     * @param mixed  $pattern
1177
     * @param string $message
1178
     *
1179
     * @throws InvalidArgumentException
1180
     */
1181 12
    public static function regex($value, $pattern, $message = '')
1182
    {
1183 12
        if (!\preg_match($pattern, $value)) {
1184 8
            static::reportInvalidArgument(\sprintf(
1185 8
                $message ?: 'The value %s does not match the expected pattern.',
1186 8
                static::valueToString($value)
1187
            ));
1188
        }
1189 4
    }
1190
1191
    /**
1192
     * @param mixed  $value
1193
     * @param mixed  $pattern
1194
     * @param string $message
1195
     *
1196
     * @throws InvalidArgumentException
1197
     */
1198 12
    public static function notRegex($value, $pattern, $message = '')
1199
    {
1200 12
        if (\preg_match($pattern, $value, $matches, PREG_OFFSET_CAPTURE)) {
1201 4
            static::reportInvalidArgument(\sprintf(
1202 4
                $message ?: 'The value %s matches the pattern %s (at offset %d).',
1203 4
                static::valueToString($value),
1204 4
                static::valueToString($pattern),
1205 4
                $matches[0][1]
1206
            ));
1207
        }
1208 8
    }
1209
1210
    /**
1211
     * @param mixed  $value
1212
     * @param string $message
1213
     *
1214
     * @throws InvalidArgumentException
1215
     */
1216 28 View Code Duplication
    public static function unicodeLetters($value, $message = '')
1217
    {
1218 28
        static::string($value);
1219
1220 28
        if (!\preg_match('/^\p{L}+$/u', $value)) {
1221 16
            static::reportInvalidArgument(\sprintf(
1222 16
                $message ?: 'Expected a value to contain only Unicode letters. Got: %s',
1223 16
                static::valueToString($value)
1224
            ));
1225
        }
1226 12
    }
1227
1228
    /**
1229
     * @param mixed  $value
1230
     * @param string $message
1231
     *
1232
     * @throws InvalidArgumentException
1233
     */
1234 20 View Code Duplication
    public static function alpha($value, $message = '')
1235
    {
1236 20
        static::string($value);
1237
1238 12
        $locale = \setlocale(LC_CTYPE, 0);
1239 12
        \setlocale(LC_CTYPE, 'C');
1240 12
        $valid = !\ctype_alpha($value);
1241 12
        \setlocale(LC_CTYPE, $locale);
1242
1243 12
        if ($valid) {
1244 8
            static::reportInvalidArgument(\sprintf(
1245 8
                $message ?: 'Expected a value to contain only letters. Got: %s',
1246 8
                static::valueToString($value)
1247
            ));
1248
        }
1249 4
    }
1250
1251
    /**
1252
     * @param mixed  $value
1253
     * @param string $message
1254
     *
1255
     * @throws InvalidArgumentException
1256
     */
1257 12 View Code Duplication
    public static function digits($value, $message = '')
1258
    {
1259 12
        $locale = \setlocale(LC_CTYPE, 0);
1260 12
        \setlocale(LC_CTYPE, 'C');
1261 12
        $valid = !\ctype_digit($value);
1262 12
        \setlocale(LC_CTYPE, $locale);
1263
1264 12
        if ($valid) {
1265 8
            static::reportInvalidArgument(\sprintf(
1266 8
                $message ?: 'Expected a value to contain digits only. Got: %s',
1267 8
                static::valueToString($value)
1268
            ));
1269
        }
1270 4
    }
1271
1272
    /**
1273
     * @param mixed  $value
1274
     * @param string $message
1275
     *
1276
     * @throws InvalidArgumentException
1277
     */
1278 12 View Code Duplication
    public static function alnum($value, $message = '')
1279
    {
1280 12
        $locale = \setlocale(LC_CTYPE, 0);
1281 12
        \setlocale(LC_CTYPE, 'C');
1282 12
        $valid = !\ctype_alnum($value);
1283 12
        \setlocale(LC_CTYPE, $locale);
1284
1285 12
        if ($valid) {
1286 8
            static::reportInvalidArgument(\sprintf(
1287 8
                $message ?: 'Expected a value to contain letters and digits only. Got: %s',
1288 8
                static::valueToString($value)
1289
            ));
1290
        }
1291 4
    }
1292
1293
    /**
1294
     * @param mixed  $value
1295
     * @param string $message
1296
     *
1297
     * @throws InvalidArgumentException
1298
     */
1299 16 View Code Duplication
    public static function lower($value, $message = '')
1300
    {
1301 16
        $locale = \setlocale(LC_CTYPE, 0);
1302 16
        \setlocale(LC_CTYPE, 'C');
1303 16
        $valid = !\ctype_lower($value);
1304 16
        \setlocale(LC_CTYPE, $locale);
1305
1306 16
        if ($valid) {
1307 12
            static::reportInvalidArgument(\sprintf(
1308 12
                $message ?: 'Expected a value to contain lowercase characters only. Got: %s',
1309 12
                static::valueToString($value)
1310
            ));
1311
        }
1312 4
    }
1313
1314
    /**
1315
     * @param mixed  $value
1316
     * @param string $message
1317
     *
1318
     * @throws InvalidArgumentException
1319
     */
1320 16 View Code Duplication
    public static function upper($value, $message = '')
1321
    {
1322 16
        $locale = \setlocale(LC_CTYPE, 0);
1323 16
        \setlocale(LC_CTYPE, 'C');
1324 16
        $valid = !\ctype_upper($value);
1325 16
        \setlocale(LC_CTYPE, $locale);
1326
1327 16
        if ($valid) {
1328 12
            static::reportInvalidArgument(\sprintf(
1329 12
                $message ?: 'Expected a value to contain uppercase characters only. Got: %s',
1330 12
                static::valueToString($value)
1331
            ));
1332
        }
1333 4
    }
1334
1335
    /**
1336
     * @param mixed  $value
1337
     * @param mixed  $length
1338
     * @param string $message
1339
     *
1340
     * @throws InvalidArgumentException
1341
     */
1342 36
    public static function length($value, $length, $message = '')
1343
    {
1344 36
        if ($length !== static::strlen($value)) {
1345 24
            static::reportInvalidArgument(\sprintf(
1346 24
                $message ?: 'Expected a value to contain %2$s characters. Got: %s',
1347 24
                static::valueToString($value),
1348 24
                $length
1349
            ));
1350
        }
1351 12
    }
1352
1353
    /**
1354
     * Inclusive min.
1355
     *
1356
     * @param mixed  $value
1357
     * @param mixed  $min
1358
     * @param string $message
1359
     *
1360
     * @throws InvalidArgumentException
1361
     */
1362 36
    public static function minLength($value, $min, $message = '')
1363
    {
1364 36
        if (static::strlen($value) < $min) {
1365 12
            static::reportInvalidArgument(\sprintf(
1366 12
                $message ?: 'Expected a value to contain at least %2$s characters. Got: %s',
1367 12
                static::valueToString($value),
1368 12
                $min
1369
            ));
1370
        }
1371 24
    }
1372
1373
    /**
1374
     * Inclusive max.
1375
     *
1376
     * @param mixed  $value
1377
     * @param mixed  $max
1378
     * @param string $message
1379
     *
1380
     * @throws InvalidArgumentException
1381
     */
1382 36
    public static function maxLength($value, $max, $message = '')
1383
    {
1384 36
        if (static::strlen($value) > $max) {
1385 12
            static::reportInvalidArgument(\sprintf(
1386 12
                $message ?: 'Expected a value to contain at most %2$s characters. Got: %s',
1387 12
                static::valueToString($value),
1388 12
                $max
1389
            ));
1390
        }
1391 24
    }
1392
1393
    /**
1394
     * Inclusive , so Assert::lengthBetween('asd', 3, 5); passes the assertion.
1395
     *
1396
     * @param mixed  $value
1397
     * @param mixed  $min
1398
     * @param mixed  $max
1399
     * @param string $message
1400
     *
1401
     * @throws InvalidArgumentException
1402
     */
1403 60 View Code Duplication
    public static function lengthBetween($value, $min, $max, $message = '')
1404
    {
1405 60
        $length = static::strlen($value);
1406
1407 60
        if ($length < $min || $length > $max) {
1408 24
            static::reportInvalidArgument(\sprintf(
1409 24
                $message ?: 'Expected a value to contain between %2$s and %3$s characters. Got: %s',
1410 24
                static::valueToString($value),
1411 24
                $min,
1412 24
                $max
1413
            ));
1414
        }
1415 36
    }
1416
1417
    /**
1418
     * Will also pass if $value is a directory, use Assert::file() instead if you need to be sure it is a file.
1419
     *
1420
     * @param mixed  $value
1421
     * @param string $message
1422
     *
1423
     * @throws InvalidArgumentException
1424
     */
1425 36 View Code Duplication
    public static function fileExists($value, $message = '')
1426
    {
1427 36
        static::string($value);
1428
1429 36
        if (!\file_exists($value)) {
1430 12
            static::reportInvalidArgument(\sprintf(
1431 12
                $message ?: 'The file %s does not exist.',
1432 12
                static::valueToString($value)
1433
            ));
1434
        }
1435 24
    }
1436
1437
    /**
1438
     * @param mixed  $value
1439
     * @param string $message
1440
     *
1441
     * @throws InvalidArgumentException
1442
     */
1443 12 View Code Duplication
    public static function file($value, $message = '')
1444
    {
1445 12
        static::fileExists($value, $message);
1446
1447 8
        if (!\is_file($value)) {
1448 4
            static::reportInvalidArgument(\sprintf(
1449 4
                $message ?: 'The path %s is not a file.',
1450 4
                static::valueToString($value)
1451
            ));
1452
        }
1453 4
    }
1454
1455
    /**
1456
     * @param mixed  $value
1457
     * @param string $message
1458
     *
1459
     * @throws InvalidArgumentException
1460
     */
1461 12 View Code Duplication
    public static function directory($value, $message = '')
1462
    {
1463 12
        static::fileExists($value, $message);
1464
1465 8
        if (!\is_dir($value)) {
1466 4
            static::reportInvalidArgument(\sprintf(
1467 4
                $message ?: 'The path %s is no directory.',
1468 4
                static::valueToString($value)
1469
            ));
1470
        }
1471 4
    }
1472
1473
    /**
1474
     * @param mixed  $value
1475
     * @param string $message
1476
     *
1477
     * @throws InvalidArgumentException
1478
     */
1479
    public static function readable($value, $message = '')
1480
    {
1481
        if (!\is_readable($value)) {
1482
            static::reportInvalidArgument(\sprintf(
1483
                $message ?: 'The path %s is not readable.',
1484
                static::valueToString($value)
1485
            ));
1486
        }
1487
    }
1488
1489
    /**
1490
     * @param mixed  $value
1491
     * @param string $message
1492
     *
1493
     * @throws InvalidArgumentException
1494
     */
1495
    public static function writable($value, $message = '')
1496
    {
1497
        if (!\is_writable($value)) {
1498
            static::reportInvalidArgument(\sprintf(
1499
                $message ?: 'The path %s is not writable.',
1500
                static::valueToString($value)
1501
            ));
1502
        }
1503
    }
1504
1505
    /**
1506
     * @psalm-assert class-string $value
1507
     *
1508
     * @param mixed  $value
1509
     * @param string $message
1510
     *
1511
     * @throws InvalidArgumentException
1512
     */
1513 8
    public static function classExists($value, $message = '')
1514
    {
1515 8
        if (!\class_exists($value)) {
1516 4
            static::reportInvalidArgument(\sprintf(
1517 4
                $message ?: 'Expected an existing class name. Got: %s',
1518 4
                static::valueToString($value)
1519
            ));
1520
        }
1521 4
    }
1522
1523
    /**
1524
     * @param mixed         $value
1525
     * @param string|object $class
1526
     * @param string        $message
1527
     *
1528
     * @throws InvalidArgumentException
1529
     */
1530 8
    public static function subclassOf($value, $class, $message = '')
1531
    {
1532 8
        if (!\is_subclass_of($value, $class)) {
1533 4
            static::reportInvalidArgument(\sprintf(
1534 4
                $message ?: 'Expected a sub-class of %2$s. Got: %s',
1535 4
                static::valueToString($value),
1536 4
                static::valueToString($class)
1537
            ));
1538
        }
1539 4
    }
1540
1541
    /**
1542
     * @psalm-assert class-string $value
1543
     *
1544
     * @param mixed  $value
1545
     * @param string $message
1546
     *
1547
     * @throws InvalidArgumentException
1548
     */
1549 8
    public static function interfaceExists($value, $message = '')
1550
    {
1551 8
        if (!\interface_exists($value)) {
1552 4
            static::reportInvalidArgument(\sprintf(
1553 4
                $message ?: 'Expected an existing interface name. got %s',
1554 4
                static::valueToString($value)
1555
            ));
1556
        }
1557 4
    }
1558
1559
    /**
1560
     * @param mixed  $value
1561
     * @param mixed  $interface
1562
     * @param string $message
1563
     *
1564
     * @throws InvalidArgumentException
1565
     */
1566 8 View Code Duplication
    public static function implementsInterface($value, $interface, $message = '')
1567
    {
1568 8
        if (!\in_array($interface, \class_implements($value))) {
1569 4
            static::reportInvalidArgument(\sprintf(
1570 4
                $message ?: 'Expected an implementation of %2$s. Got: %s',
1571 4
                static::valueToString($value),
1572 4
                static::valueToString($interface)
1573
            ));
1574
        }
1575 4
    }
1576
1577
    /**
1578
     * @param string|object $classOrObject
1579
     * @param mixed         $property
1580
     * @param string        $message
1581
     *
1582
     * @throws InvalidArgumentException
1583
     */
1584 12 View Code Duplication
    public static function propertyExists($classOrObject, $property, $message = '')
1585
    {
1586 12
        if (!\property_exists($classOrObject, $property)) {
1587 4
            static::reportInvalidArgument(\sprintf(
1588 4
                $message ?: 'Expected the property %s to exist.',
1589 4
                static::valueToString($property)
1590
            ));
1591
        }
1592 8
    }
1593
1594
    /**
1595
     * @param string|object $classOrObject
1596
     * @param mixed         $property
1597
     * @param string        $message
1598
     *
1599
     * @throws InvalidArgumentException
1600
     */
1601 12 View Code Duplication
    public static function propertyNotExists($classOrObject, $property, $message = '')
1602
    {
1603 12
        if (\property_exists($classOrObject, $property)) {
1604 8
            static::reportInvalidArgument(\sprintf(
1605 8
                $message ?: 'Expected the property %s to not exist.',
1606 8
                static::valueToString($property)
1607
            ));
1608
        }
1609 4
    }
1610
1611
    /**
1612
     * @param string|object $classOrObject
1613
     * @param mixed         $method
1614
     * @param string        $message
1615
     *
1616
     * @throws InvalidArgumentException
1617
     */
1618 27 View Code Duplication
    public static function methodExists($classOrObject, $method, $message = '')
1619
    {
1620 27
        if (!\method_exists($classOrObject, $method)) {
1621 19
            static::reportInvalidArgument(\sprintf(
1622 19
                $message ?: 'Expected the method %s to exist.',
1623 19
                static::valueToString($method)
1624
            ));
1625
        }
1626 8
    }
1627
1628
    /**
1629
     * @param string|object $classOrObject
1630
     * @param mixed         $method
1631
     * @param string        $message
1632
     *
1633
     * @throws InvalidArgumentException
1634
     */
1635 27 View Code Duplication
    public static function methodNotExists($classOrObject, $method, $message = '')
1636
    {
1637 27
        if (\method_exists($classOrObject, $method)) {
1638 8
            static::reportInvalidArgument(\sprintf(
1639 8
                $message ?: 'Expected the method %s to not exist.',
1640 8
                static::valueToString($method)
1641
            ));
1642
        }
1643 19
    }
1644
1645
    /**
1646
     * @param array      $array
1647
     * @param string|int $key
1648
     * @param string     $message
1649
     *
1650
     * @throws InvalidArgumentException
1651
     */
1652 12 View Code Duplication
    public static function keyExists($array, $key, $message = '')
1653
    {
1654 12
        if (!(isset($array[$key]) || \array_key_exists($key, $array))) {
1655 4
            static::reportInvalidArgument(\sprintf(
1656 4
                $message ?: 'Expected the key %s to exist.',
1657 4
                static::valueToString($key)
1658
            ));
1659
        }
1660 8
    }
1661
1662
    /**
1663
     * @param array      $array
1664
     * @param string|int $key
1665
     * @param string     $message
1666
     *
1667
     * @throws InvalidArgumentException
1668
     */
1669 12 View Code Duplication
    public static function keyNotExists($array, $key, $message = '')
1670
    {
1671 12
        if (isset($array[$key]) || \array_key_exists($key, $array)) {
1672 8
            static::reportInvalidArgument(\sprintf(
1673 8
                $message ?: 'Expected the key %s to not exist.',
1674 8
                static::valueToString($key)
1675
            ));
1676
        }
1677 4
    }
1678
1679
    /**
1680
     * Checks if a value is a valid array key (int or string).
1681
     *
1682
     * @psalm-assert array-key $value
1683
     *
1684
     * @param mixed  $value
1685
     * @param string $message
1686
     *
1687
     * @throws InvalidArgumentException
1688
     */
1689 28
    public static function validArrayKey($value, $message = '')
1690
    {
1691 28
        if (!(\is_int($value) || \is_string($value))) {
1692 20
            static::reportInvalidArgument(\sprintf(
1693 20
                $message ?: 'Expected string or integer. Got: %s',
1694 20
                static::typeToString($value)
1695
            ));
1696
        }
1697 8
    }
1698
1699
    /**
1700
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
1701
     *
1702
     * @param mixed  $array
1703
     * @param mixed  $number
1704
     * @param string $message
1705
     *
1706
     * @throws InvalidArgumentException
1707
     */
1708 8
    public static function count($array, $number, $message = '')
1709
    {
1710 8
        static::eq(
1711 8
            \count($array),
1712
            $number,
1713 8
            $message ?: \sprintf('Expected an array to contain %d elements. Got: %d.', $number, \count($array))
1714
        );
1715 4
    }
1716
1717
    /**
1718
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
1719
     *
1720
     * @param mixed  $array
1721
     * @param mixed  $min
1722
     * @param string $message
1723
     *
1724
     * @throws InvalidArgumentException
1725
     */
1726 12 View Code Duplication
    public static function minCount($array, $min, $message = '')
1727
    {
1728 12
        if (\count($array) < $min) {
1729 4
            static::reportInvalidArgument(\sprintf(
1730 4
                $message ?: 'Expected an array to contain at least %2$d elements. Got: %d',
1731 4
                \count($array),
1732 4
                $min
1733
            ));
1734
        }
1735 8
    }
1736
1737
    /**
1738
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
1739
     *
1740
     * @param mixed  $array
1741
     * @param mixed  $max
1742
     * @param string $message
1743
     *
1744
     * @throws InvalidArgumentException
1745
     */
1746 12 View Code Duplication
    public static function maxCount($array, $max, $message = '')
1747
    {
1748 12
        if (\count($array) > $max) {
1749 4
            static::reportInvalidArgument(\sprintf(
1750 4
                $message ?: 'Expected an array to contain at most %2$d elements. Got: %d',
1751 4
                \count($array),
1752 4
                $max
1753
            ));
1754
        }
1755 8
    }
1756
1757
    /**
1758
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
1759
     *
1760
     * @param mixed  $array
1761
     * @param mixed  $min
1762
     * @param mixed  $max
1763
     * @param string $message
1764
     *
1765
     * @throws InvalidArgumentException
1766
     */
1767 20
    public static function countBetween($array, $min, $max, $message = '')
1768
    {
1769 20
        $count = \count($array);
1770
1771 20
        if ($count < $min || $count > $max) {
1772 8
            static::reportInvalidArgument(\sprintf(
1773 8
                $message ?: 'Expected an array to contain between %2$d and %3$d elements. Got: %d',
1774 8
                $count,
1775 8
                $min,
1776 8
                $max
1777
            ));
1778
        }
1779 12
    }
1780
1781
    /**
1782
     * @psalm-assert list $array
1783
     *
1784
     * @param mixed  $array
1785
     * @param string $message
1786
     *
1787
     * @throws InvalidArgumentException
1788
     */
1789 80 View Code Duplication
    public static function isList($array, $message = '')
1790
    {
1791 80
        if (!\is_array($array) || $array !== \array_values($array)) {
1792 32
            static::reportInvalidArgument(
1793 32
                $message ?: 'Expected list - non-associative array.'
1794
            );
1795
        }
1796 48
    }
1797
1798
    /**
1799
     * @psalm-assert non-empty-list $array
1800
     *
1801
     * @param mixed  $array
1802
     * @param string $message
1803
     *
1804
     * @throws InvalidArgumentException
1805
     */
1806 40
    public static function isNonEmptyList($array, $message = '')
1807
    {
1808 40
        static::isList($array, $message);
1809 24
        static::notEmpty($array, $message);
1810 20
    }
1811
1812
    /**
1813
     * @param mixed  $array
1814
     * @param string $message
1815
     *
1816
     * @throws InvalidArgumentException
1817
     */
1818 32
    public static function isMap($array, $message = '')
1819
    {
1820
        if (
1821 32
            !\is_array($array) ||
1822 32
            \array_keys($array) !== \array_filter(\array_keys($array), '\is_string')
1823
        ) {
1824 16
            static::reportInvalidArgument(
1825 16
                $message ?: 'Expected map - associative array with string keys.'
1826
            );
1827
        }
1828 16
    }
1829
1830
    /**
1831
     * @param mixed  $array
1832
     * @param string $message
1833
     *
1834
     * @throws InvalidArgumentException
1835
     */
1836 16
    public static function isNonEmptyMap($array, $message = '')
1837
    {
1838 16
        static::isMap($array, $message);
1839 8
        static::notEmpty($array, $message);
1840 4
    }
1841
1842
    /**
1843
     * @param mixed  $value
1844
     * @param string $message
1845
     *
1846
     * @throws InvalidArgumentException
1847
     */
1848 56
    public static function uuid($value, $message = '')
1849
    {
1850 56
        $value = \str_replace(array('urn:', 'uuid:', '{', '}'), '', $value);
1851
1852
        // The nil UUID is special form of UUID that is specified to have all
1853
        // 128 bits set to zero.
1854 56
        if ('00000000-0000-0000-0000-000000000000' === $value) {
1855 4
            return;
1856
        }
1857
1858 52
        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)) {
1859 20
            static::reportInvalidArgument(\sprintf(
1860 20
                $message ?: 'Value %s is not a valid UUID.',
1861 20
                static::valueToString($value)
1862
            ));
1863
        }
1864 32
    }
1865
1866
    /**
1867
     * @param Closure       $expression
1868
     * @param string|object $class
1869
     * @param string        $message
1870
     *
1871
     * @throws InvalidArgumentException
1872
     */
1873 24
    public static function throws(Closure $expression, $class = 'Exception', $message = '')
1874
    {
1875 24
        static::string($class);
1876
1877 24
        $actual = 'none';
1878
1879
        try {
1880 24
            $expression();
1881 24
        } catch (Exception $e) {
1882 20
            $actual = \get_class($e);
1883 20
            if ($e instanceof $class) {
1884 20
                return;
1885
            }
1886 4
        } catch (Throwable $e) {
0 ignored issues
show
The class Throwable does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
1887 4
            $actual = \get_class($e);
1888 4
            if ($e instanceof $class) {
1889 4
                return;
1890
            }
1891
        }
1892
1893 8
        static::reportInvalidArgument($message ?: \sprintf(
1894 8
            'Expected to throw "%s", got "%s"',
1895 8
            $class,
1896 8
            $actual
1897
        ));
1898
    }
1899
1900
    /**
1901
     * @throws BadMethodCallException
1902
     */
1903 1561
    public static function __callStatic($name, $arguments)
1904
    {
1905 1561
        if ('nullOr' === \substr($name, 0, 6)) {
1906 578
            if (null !== $arguments[0]) {
1907 475
                $method = \lcfirst(\substr($name, 6));
1908 475
                \call_user_func_array(array('static', $method), $arguments);
1909
            }
1910
1911 334
            return;
1912
        }
1913
1914 983
        if ('all' === \substr($name, 0, 3)) {
1915 982
            static::isIterable($arguments[0]);
1916
1917 982
            $method = \lcfirst(\substr($name, 3));
1918 982
            $args = $arguments;
1919
1920 982
            foreach ($arguments[0] as $entry) {
1921 982
                $args[0] = $entry;
1922
1923 982
                \call_user_func_array(array('static', $method), $args);
1924
            }
1925
1926 470
            return;
1927
        }
1928
1929 1
        throw new BadMethodCallException('No such method: '.$name);
1930
    }
1931
1932
    /**
1933
     * @param mixed $value
1934
     *
1935
     * @return string
1936
     */
1937 714
    protected static function valueToString($value)
1938
    {
1939 714
        if (null === $value) {
1940 20
            return 'null';
1941
        }
1942
1943 696
        if (true === $value) {
1944 15
            return 'true';
1945
        }
1946
1947 686
        if (false === $value) {
1948 25
            return 'false';
1949
        }
1950
1951 661
        if (\is_array($value)) {
1952 21
            return 'array';
1953
        }
1954
1955 640
        if (\is_object($value)) {
1956 2
            if (\method_exists($value, '__toString')) {
1957 1
                return \get_class($value).': '.self::valueToString($value->__toString());
1958
            }
1959
1960 1
            return \get_class($value);
1961
        }
1962
1963 639
        if (\is_resource($value)) {
1964 1
            return 'resource';
1965
        }
1966
1967 639
        if (\is_string($value)) {
1968 537
            return '"'.$value.'"';
1969
        }
1970
1971 110
        return (string) $value;
1972
    }
1973
1974
    /**
1975
     * @param mixed $value
1976
     *
1977
     * @return string
1978
     */
1979 251
    protected static function typeToString($value)
1980
    {
1981 251
        return \is_object($value) ? \get_class($value) : \gettype($value);
1982
    }
1983
1984 168
    protected static function strlen($value)
1985
    {
1986 168
        if (!\function_exists('mb_detect_encoding')) {
1987
            return \strlen($value);
1988
        }
1989
1990 168
        if (false === $encoding = \mb_detect_encoding($value)) {
1991
            return \strlen($value);
1992
        }
1993
1994 168
        return \mb_strlen($value, $encoding);
1995
    }
1996
1997
    /**
1998
     * @param string $message
1999
     *
2000
     * @throws InvalidArgumentException
2001
     */
2002 1028
    protected static function reportInvalidArgument($message)
2003
    {
2004 1028
        throw new InvalidArgumentException($message);
2005
    }
2006
2007
    private function __construct()
2008
    {
2009
    }
2010
}
2011