Failed Conditions
Pull Request — master (#153)
by Gert de
02:52
created

Assert::count()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 1
nop 3
crap 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 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 nullOrIsEmpty($value, $message = '')
49
 * @method static void nullOrNotEmpty($value, $message = '')
50
 * @method static void nullOrTrue($value, $message = '')
51
 * @method static void nullOrFalse($value, $message = '')
52
 * @method static void nullOrIp($value, $message = '')
53
 * @method static void nullOrIpv4($value, $message = '')
54
 * @method static void nullOrIpv6($value, $message = '')
55
 * @method static void nullOrEmail($value, $message = '')
56
 * @method static void nullOrUniqueValues($values, $message = '')
57
 * @method static void nullOrEq($value, $expect, $message = '')
58
 * @method static void nullOrNotEq($value, $expect, $message = '')
59
 * @method static void nullOrSame($value, $expect, $message = '')
60
 * @method static void nullOrNotSame($value, $expect, $message = '')
61
 * @method static void nullOrGreaterThan($value, $limit, $message = '')
62
 * @method static void nullOrGreaterThanEq($value, $limit, $message = '')
63
 * @method static void nullOrLessThan($value, $limit, $message = '')
64
 * @method static void nullOrLessThanEq($value, $limit, $message = '')
65
 * @method static void nullOrRange($value, $min, $max, $message = '')
66
 * @method static void nullOrOneOf($value, $values, $message = '')
67
 * @method static void nullOrContains($value, $subString, $message = '')
68
 * @method static void nullOrNotContains($value, $subString, $message = '')
69
 * @method static void nullOrNotWhitespaceOnly($value, $message = '')
70
 * @method static void nullOrStartsWith($value, $prefix, $message = '')
71
 * @method static void nullOrStartsWithLetter($value, $message = '')
72
 * @method static void nullOrEndsWith($value, $suffix, $message = '')
73
 * @method static void nullOrRegex($value, $pattern, $message = '')
74
 * @method static void nullOrNotRegex($value, $pattern, $message = '')
75
 * @method static void nullOrUnicodeLetters($value, $message = '')
76
 * @method static void nullOrAlpha($value, $message = '')
77
 * @method static void nullOrDigits($value, $message = '')
78
 * @method static void nullOrAlnum($value, $message = '')
79
 * @method static void nullOrLower($value, $message = '')
80
 * @method static void nullOrUpper($value, $message = '')
81
 * @method static void nullOrLength($value, $length, $message = '')
82
 * @method static void nullOrMinLength($value, $min, $message = '')
83
 * @method static void nullOrMaxLength($value, $max, $message = '')
84
 * @method static void nullOrLengthBetween($value, $min, $max, $message = '')
85
 * @method static void nullOrFileExists($value, $message = '')
86
 * @method static void nullOrFile($value, $message = '')
87
 * @method static void nullOrDirectory($value, $message = '')
88
 * @method static void nullOrReadable($value, $message = '')
89
 * @method static void nullOrWritable($value, $message = '')
90
 * @method static void nullOrClassExists($value, $message = '')
91
 * @method static void nullOrSubclassOf($value, $class, $message = '')
92
 * @method static void nullOrInterfaceExists($value, $message = '')
93
 * @method static void nullOrImplementsInterface($value, $interface, $message = '')
94
 * @method static void nullOrPropertyExists($value, $property, $message = '')
95
 * @method static void nullOrPropertyNotExists($value, $property, $message = '')
96
 * @method static void nullOrMethodExists($value, $method, $message = '')
97
 * @method static void nullOrMethodNotExists($value, $method, $message = '')
98
 * @method static void nullOrKeyExists($value, $key, $message = '')
99
 * @method static void nullOrKeyNotExists($value, $key, $message = '')
100
 * @method static void nullOrValidArrayKey($value, $message = '')
101
 * @method static void nullOrCount($value, $key, $message = '')
102
 * @method static void nullOrMinCount($value, $min, $message = '')
103
 * @method static void nullOrMaxCount($value, $max, $message = '')
104
 * @method static void nullOrIsList($value, $message = '')
105
 * @method static void nullOrIsNonEmptyList($value, $message = '')
106
 * @method static void nullOrIsMap($value, $message = '')
107
 * @method static void nullOrIsNonEmptyMap($value, $message = '')
108
 * @method static void nullOrCountBetween($value, $min, $max, $message = '')
109
 * @method static void nullOrUuid($values, $message = '')
110
 * @method static void nullOrThrows($expression, $class = 'Exception', $message = '')
111
 * @method static void allString($values, $message = '')
112
 * @method static void allStringNotEmpty($values, $message = '')
113
 * @method static void allInteger($values, $message = '')
114
 * @method static void allIntegerish($values, $message = '')
115
 * @method static void allFloat($values, $message = '')
116
 * @method static void allNumeric($values, $message = '')
117
 * @method static void allNatural($values, $message = '')
118
 * @method static void allBoolean($values, $message = '')
119
 * @method static void allScalar($values, $message = '')
120
 * @method static void allObject($values, $message = '')
121
 * @method static void allResource($values, $type = null, $message = '')
122
 * @method static void allIsCallable($values, $message = '')
123
 * @method static void allIsArray($values, $message = '')
124
 * @method static void allIsTraversable($values, $message = '')
125
 * @method static void allIsArrayAccessible($values, $message = '')
126
 * @method static void allIsCountable($values, $message = '')
127
 * @method static void allIsIterable($values, $message = '')
128
 * @method static void allIsInstanceOf($values, $class, $message = '')
129
 * @method static void allNotInstanceOf($values, $class, $message = '')
130
 * @method static void allIsInstanceOfAny($values, $classes, $message = '')
131
 * @method static void allNull($values, $message = '')
132
 * @method static void allNotNull($values, $message = '')
133
 * @method static void allIsEmpty($values, $message = '')
134
 * @method static void allNotEmpty($values, $message = '')
135
 * @method static void allTrue($values, $message = '')
136
 * @method static void allFalse($values, $message = '')
137
 * @method static void allIp($values, $message = '')
138
 * @method static void allIpv4($values, $message = '')
139
 * @method static void allIpv6($values, $message = '')
140
 * @method static void allEmail($values, $message = '')
141
 * @method static void allUniqueValues($values, $message = '')
142
 * @method static void allEq($values, $expect, $message = '')
143
 * @method static void allNotEq($values, $expect, $message = '')
144
 * @method static void allSame($values, $expect, $message = '')
145
 * @method static void allNotSame($values, $expect, $message = '')
146
 * @method static void allGreaterThan($values, $limit, $message = '')
147
 * @method static void allGreaterThanEq($values, $limit, $message = '')
148
 * @method static void allLessThan($values, $limit, $message = '')
149
 * @method static void allLessThanEq($values, $limit, $message = '')
150
 * @method static void allRange($values, $min, $max, $message = '')
151
 * @method static void allOneOf($values, $values, $message = '')
152
 * @method static void allContains($values, $subString, $message = '')
153
 * @method static void allNotContains($values, $subString, $message = '')
154
 * @method static void allNotWhitespaceOnly($values, $message = '')
155
 * @method static void allStartsWith($values, $prefix, $message = '')
156
 * @method static void allStartsWithLetter($values, $message = '')
157
 * @method static void allEndsWith($values, $suffix, $message = '')
158
 * @method static void allRegex($values, $pattern, $message = '')
159
 * @method static void allNotRegex($values, $pattern, $message = '')
160
 * @method static void allUnicodeLetters($values, $message = '')
161
 * @method static void allAlpha($values, $message = '')
162
 * @method static void allDigits($values, $message = '')
163
 * @method static void allAlnum($values, $message = '')
164
 * @method static void allLower($values, $message = '')
165
 * @method static void allUpper($values, $message = '')
166
 * @method static void allLength($values, $length, $message = '')
167
 * @method static void allMinLength($values, $min, $message = '')
168
 * @method static void allMaxLength($values, $max, $message = '')
169
 * @method static void allLengthBetween($values, $min, $max, $message = '')
170
 * @method static void allFileExists($values, $message = '')
171
 * @method static void allFile($values, $message = '')
172
 * @method static void allDirectory($values, $message = '')
173
 * @method static void allReadable($values, $message = '')
174
 * @method static void allWritable($values, $message = '')
175
 * @method static void allClassExists($values, $message = '')
176
 * @method static void allSubclassOf($values, $class, $message = '')
177
 * @method static void allInterfaceExists($values, $message = '')
178
 * @method static void allImplementsInterface($values, $interface, $message = '')
179
 * @method static void allPropertyExists($values, $property, $message = '')
180
 * @method static void allPropertyNotExists($values, $property, $message = '')
181
 * @method static void allMethodExists($values, $method, $message = '')
182
 * @method static void allMethodNotExists($values, $method, $message = '')
183
 * @method static void allKeyExists($values, $key, $message = '')
184
 * @method static void allKeyNotExists($values, $key, $message = '')
185
 * @method static void allValidArrayKey($values, $message = '')
186
 * @method static void allCount($values, $key, $message = '')
187
 * @method static void allMinCount($values, $min, $message = '')
188
 * @method static void allMaxCount($values, $max, $message = '')
189
 * @method static void allCountBetween($values, $min, $max, $message = '')
190
 * @method static void allIsList($values, $message = '')
191
 * @method static void allIsNonEmptyList($values, $message = '')
192
 * @method static void allIsMap($values, $message = '')
193
 * @method static void allIsNonEmptyMap($values, $message = '')
194
 * @method static void allUuid($values, $message = '')
195
 * @method static void allThrows($expressions, $class = 'Exception', $message = '')
196
 *
197
 * @since  1.0
198
 *
199
 * @author Bernhard Schussek <[email protected]>
200
 */
201
class Assert
0 ignored issues
show
Coding Style introduced by
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
202
{
203
    /**
204
     * @psalm-assert string $value
205
     *
206
     * @param mixed  $value
207
     * @param string $message
208
     *
209
     * @throws InvalidArgumentException
210
     */
211 350
    public static function string($value, $message = '')
212
    {
213 350
        if (!\is_string($value)) {
214 98
            static::reportInvalidArgument(\sprintf(
215 98
                $message ?: 'Expected a string. Got: %s',
216 98
                static::typeToString($value)
217
            ));
218
        }
219 252
    }
220
221
    /**
222
     * @param mixed  $value
223
     * @param string $message
224
     *
225
     * @throws InvalidArgumentException
226
     */
227 16
    public static function stringNotEmpty($value, $message = '')
228
    {
229 16
        static::string($value, $message);
230 12
        static::notEq($value, '', $message);
231 8
    }
232
233
    /**
234
     * @psalm-assert int $value
235
     *
236
     * @param mixed  $value
237
     * @param string $message
238
     *
239
     * @throws InvalidArgumentException
240
     */
241 17
    public static function integer($value, $message = '')
242
    {
243 17
        if (!\is_int($value)) {
244 13
            static::reportInvalidArgument(\sprintf(
245 13
                $message ?: 'Expected an integer. Got: %s',
246 13
                static::typeToString($value)
247
            ));
248
        }
249 4
    }
250
251
    /**
252
     * @psalm-assert numeric $value
253
     *
254
     * @param mixed  $value
255
     * @param string $message
256
     *
257
     * @throws InvalidArgumentException
258
     */
259 16
    public static function integerish($value, $message = '')
260
    {
261 16
        if (!\is_numeric($value) || $value != (int) $value) {
262 4
            static::reportInvalidArgument(\sprintf(
263 4
                $message ?: 'Expected an integerish value. Got: %s',
264 4
                static::typeToString($value)
265
            ));
266
        }
267 12
    }
268
269
    /**
270
     * @psalm-assert float $value
271
     *
272
     * @param mixed  $value
273
     * @param string $message
274
     *
275
     * @throws InvalidArgumentException
276
     */
277 16
    public static function float($value, $message = '')
278
    {
279 16
        if (!\is_float($value)) {
280 8
            static::reportInvalidArgument(\sprintf(
281 8
                $message ?: 'Expected a float. Got: %s',
282 8
                static::typeToString($value)
283
            ));
284
        }
285 8
    }
286
287
    /**
288
     * @psalm-assert numeric $value
289
     *
290
     * @param mixed  $value
291
     * @param string $message
292
     *
293
     * @throws InvalidArgumentException
294
     */
295 20
    public static function numeric($value, $message = '')
296
    {
297 20
        if (!\is_numeric($value)) {
298 4
            static::reportInvalidArgument(\sprintf(
299 4
                $message ?: 'Expected a numeric. Got: %s',
300 4
                static::typeToString($value)
301
            ));
302
        }
303 16
    }
304
305
    /**
306
     * @psalm-assert int $value
307
     *
308
     * @param mixed  $value
309
     * @param string $message
310
     *
311
     * @throws InvalidArgumentException
312
     */
313 24
    public static function natural($value, $message = '')
314
    {
315 24
        if (!\is_int($value) || $value < 0) {
316 16
            static::reportInvalidArgument(\sprintf(
317 16
                $message ?: 'Expected a non-negative integer. Got %s',
318 16
                static::valueToString($value)
319
            ));
320
        }
321 8
    }
322
323
    /**
324
     * @psalm-assert bool $value
325
     *
326
     * @param mixed  $value
327
     * @param string $message
328
     *
329
     * @throws InvalidArgumentException
330
     */
331 16
    public static function boolean($value, $message = '')
332
    {
333 16
        if (!\is_bool($value)) {
334 8
            static::reportInvalidArgument(\sprintf(
335 8
                $message ?: 'Expected a boolean. Got: %s',
336 8
                static::typeToString($value)
337
            ));
338
        }
339 8
    }
340
341
    /**
342
     * @psalm-assert scalar $value
343
     *
344
     * @param mixed  $value
345
     * @param string $message
346
     *
347
     * @throws InvalidArgumentException
348
     */
349 23
    public static function scalar($value, $message = '')
350
    {
351 23
        if (!\is_scalar($value)) {
352 11
            static::reportInvalidArgument(\sprintf(
353 11
                $message ?: 'Expected a scalar. Got: %s',
354 11
                static::typeToString($value)
355
            ));
356
        }
357 12
    }
358
359
    /**
360
     * @psalm-assert object $value
361
     *
362
     * @param mixed  $value
363
     * @param string $message
364
     *
365
     * @throws InvalidArgumentException
366
     */
367 23
    public static function object($value, $message = '')
368
    {
369 23
        if (!\is_object($value)) {
370 15
            static::reportInvalidArgument(\sprintf(
371 15
                $message ?: 'Expected an object. Got: %s',
372 15
                static::typeToString($value)
373
            ));
374
        }
375 8
    }
376
377
    /**
378
     * @psalm-assert resource $value
379
     *
380
     * @param mixed       $value
381
     * @param string|null $type    type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php
382
     * @param string      $message
383
     *
384
     * @throws InvalidArgumentException
385
     */
386 16
    public static function resource($value, $type = null, $message = '')
387
    {
388 16
        if (!\is_resource($value)) {
389 4
            static::reportInvalidArgument(\sprintf(
390 4
                $message ?: 'Expected a resource. Got: %s',
391 4
                static::typeToString($value)
392
            ));
393
        }
394
395 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...
396 4
            static::reportInvalidArgument(\sprintf(
397 4
                $message ?: 'Expected a resource of type %2$s. Got: %s',
398 4
                static::typeToString($value),
399 4
                $type
400
            ));
401
        }
402 8
    }
403
404
    /**
405
     * @psalm-assert callable $value
406
     *
407
     * @param mixed  $value
408
     * @param string $message
409
     *
410
     * @throws InvalidArgumentException
411
     */
412 20
    public static function isCallable($value, $message = '')
413
    {
414 20
        if (!\is_callable($value)) {
415 8
            static::reportInvalidArgument(\sprintf(
416 8
                $message ?: 'Expected a callable. Got: %s',
417 8
                static::typeToString($value)
418
            ));
419
        }
420 12
    }
421
422
    /**
423
     * @psalm-assert array $value
424
     *
425
     * @param mixed  $value
426
     * @param string $message
427
     *
428
     * @throws InvalidArgumentException
429
     */
430 20
    public static function isArray($value, $message = '')
431
    {
432 20
        if (!\is_array($value)) {
433 12
            static::reportInvalidArgument(\sprintf(
434 12
                $message ?: 'Expected an array. Got: %s',
435 12
                static::typeToString($value)
436
            ));
437
        }
438 8
    }
439
440
    /**
441
     * @psalm-assert iterable $value
442
     *
443
     * @deprecated use "isIterable" or "isInstanceOf" instead
444
     *
445
     * @param mixed  $value
446
     * @param string $message
447
     *
448
     * @throws InvalidArgumentException
449
     */
450 20
    public static function isTraversable($value, $message = '')
451
    {
452 20
        @\trigger_error(
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

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