Failed Conditions
Pull Request — master (#153)
by Gert de
17:07 queued 16:02
created

Assert::object()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

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