Failed Conditions
Pull Request — master (#174)
by
unknown
02:40
created

Assert::keyExists()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 9

Duplication

Lines 9
Ratio 100 %

Code Coverage

Tests 6
CRAP Score 4

Importance

Changes 0
Metric Value
dl 9
loc 9
ccs 6
cts 6
cp 1
rs 9.9666
c 0
b 0
f 0
cc 4
nc 2
nop 3
crap 4
1
<?php
2
3
/*
4
 * This file is part of the webmozart/assert package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Webmozart\Assert;
13
14
use ArrayAccess;
15
use BadMethodCallException;
16
use Closure;
17
use Countable;
18
use Exception;
19
use InvalidArgumentException;
20
use ResourceBundle;
21
use SimpleXMLElement;
22
use Throwable;
23
use Traversable;
24
25
/**
26
 * Efficient assertions to validate the input/output of your methods.
27
 *
28
 * @method static void nullOrString($value, $message = '')
29
 * @method static void nullOrStringNotEmpty($value, $message = '')
30
 * @method static void nullOrInteger($value, $message = '')
31
 * @method static void nullOrIntegerish($value, $message = '')
32
 * @method static void nullOrFloat($value, $message = '')
33
 * @method static void nullOrNumeric($value, $message = '')
34
 * @method static void nullOrNatural($value, $message = '')
35
 * @method static void nullOrBoolean($value, $message = '')
36
 * @method static void nullOrScalar($value, $message = '')
37
 * @method static void nullOrObject($value, $message = '')
38
 * @method static void nullOrResource($value, $type = null, $message = '')
39
 * @method static void nullOrIsCallable($value, $message = '')
40
 * @method static void nullOrIsArray($value, $message = '')
41
 * @method static void nullOrIsTraversable($value, $message = '')
42
 * @method static void nullOrIsArrayAccessible($value, $message = '')
43
 * @method static void nullOrIsCountable($value, $message = '')
44
 * @method static void nullOrIsIterable($value, $message = '')
45
 * @method static void nullOrIsInstanceOf($value, $class, $message = '')
46
 * @method static void nullOrNotInstanceOf($value, $class, $message = '')
47
 * @method static void nullOrIsInstanceOfAny($value, $classes, $message = '')
48
 * @method static void nullOrIsAOf($value, $classes, $message = '')
49
 * @method static void nullOrIsAnyOf($value, $classes, $message = '')
50
 * @method static void nullOrIsNotA($value, $classes, $message = '')
51
 * @method static void nullOrIsEmpty($value, $message = '')
52
 * @method static void nullOrNotEmpty($value, $message = '')
53
 * @method static void nullOrTrue($value, $message = '')
54
 * @method static void nullOrFalse($value, $message = '')
55
 * @method static void nullOrNotFalse($value, $message = '')
56
 * @method static void nullOrIp($value, $message = '')
57
 * @method static void nullOrIpv4($value, $message = '')
58
 * @method static void nullOrIpv6($value, $message = '')
59
 * @method static void nullOrEmail($value, $message = '')
60
 * @method static void nullOrUniqueValues($values, $message = '')
61
 * @method static void nullOrEq($value, $expect, $message = '')
62
 * @method static void nullOrNotEq($value, $expect, $message = '')
63
 * @method static void nullOrSame($value, $expect, $message = '')
64
 * @method static void nullOrNotSame($value, $expect, $message = '')
65
 * @method static void nullOrGreaterThan($value, $limit, $message = '')
66
 * @method static void nullOrGreaterThanEq($value, $limit, $message = '')
67
 * @method static void nullOrLessThan($value, $limit, $message = '')
68
 * @method static void nullOrLessThanEq($value, $limit, $message = '')
69
 * @method static void nullOrRange($value, $min, $max, $message = '')
70
 * @method static void nullOrOneOf($value, $values, $message = '')
71
 * @method static void nullOrContains($value, $subString, $message = '')
72
 * @method static void nullOrNotContains($value, $subString, $message = '')
73
 * @method static void nullOrNotWhitespaceOnly($value, $message = '')
74
 * @method static void nullOrStartsWith($value, $prefix, $message = '')
75
 * @method static void nullOrStartsWithLetter($value, $message = '')
76
 * @method static void nullOrEndsWith($value, $suffix, $message = '')
77
 * @method static void nullOrRegex($value, $pattern, $message = '')
78
 * @method static void nullOrNotRegex($value, $pattern, $message = '')
79
 * @method static void nullOrUnicodeLetters($value, $message = '')
80
 * @method static void nullOrAlpha($value, $message = '')
81
 * @method static void nullOrDigits($value, $message = '')
82
 * @method static void nullOrAlnum($value, $message = '')
83
 * @method static void nullOrLower($value, $message = '')
84
 * @method static void nullOrUpper($value, $message = '')
85
 * @method static void nullOrLength($value, $length, $message = '')
86
 * @method static void nullOrMinLength($value, $min, $message = '')
87
 * @method static void nullOrMaxLength($value, $max, $message = '')
88
 * @method static void nullOrLengthBetween($value, $min, $max, $message = '')
89
 * @method static void nullOrFileExists($value, $message = '')
90
 * @method static void nullOrFile($value, $message = '')
91
 * @method static void nullOrDirectory($value, $message = '')
92
 * @method static void nullOrReadable($value, $message = '')
93
 * @method static void nullOrWritable($value, $message = '')
94
 * @method static void nullOrClassExists($value, $message = '')
95
 * @method static void nullOrSubclassOf($value, $class, $message = '')
96
 * @method static void nullOrInterfaceExists($value, $message = '')
97
 * @method static void nullOrImplementsInterface($value, $interface, $message = '')
98
 * @method static void nullOrPropertyExists($value, $property, $message = '')
99
 * @method static void nullOrPropertyNotExists($value, $property, $message = '')
100
 * @method static void nullOrMethodExists($value, $method, $message = '')
101
 * @method static void nullOrMethodNotExists($value, $method, $message = '')
102
 * @method static void nullOrKeyExists($value, $key, $message = '')
103
 * @method static void nullOrKeyNotExists($value, $key, $message = '')
104
 * @method static void nullOrValidArrayKey($value, $message = '')
105
 * @method static void nullOrCount($value, $key, $message = '')
106
 * @method static void nullOrMinCount($value, $min, $message = '')
107
 * @method static void nullOrMaxCount($value, $max, $message = '')
108
 * @method static void nullOrIsList($value, $message = '')
109
 * @method static void nullOrIsNonEmptyList($value, $message = '')
110
 * @method static void nullOrIsMap($value, $message = '')
111
 * @method static void nullOrIsNonEmptyMap($value, $message = '')
112
 * @method static void nullOrCountBetween($value, $min, $max, $message = '')
113
 * @method static void nullOrUuid($values, $message = '')
114
 * @method static void nullOrThrows($expression, $class = 'Exception', $message = '')
115
 * @method static void allString($values, $message = '')
116
 * @method static void allStringNotEmpty($values, $message = '')
117
 * @method static void allInteger($values, $message = '')
118
 * @method static void allIntegerish($values, $message = '')
119
 * @method static void allFloat($values, $message = '')
120
 * @method static void allNumeric($values, $message = '')
121
 * @method static void allNatural($values, $message = '')
122
 * @method static void allBoolean($values, $message = '')
123
 * @method static void allScalar($values, $message = '')
124
 * @method static void allObject($values, $message = '')
125
 * @method static void allResource($values, $type = null, $message = '')
126
 * @method static void allIsCallable($values, $message = '')
127
 * @method static void allIsArray($values, $message = '')
128
 * @method static void allIsTraversable($values, $message = '')
129
 * @method static void allIsArrayAccessible($values, $message = '')
130
 * @method static void allIsCountable($values, $message = '')
131
 * @method static void allIsIterable($values, $message = '')
132
 * @method static void allIsInstanceOf($values, $class, $message = '')
133
 * @method static void allNotInstanceOf($values, $class, $message = '')
134
 * @method static void allIsInstanceOfAny($values, $classes, $message = '')
135
 * @method static void allIsAOf($values, $class, $message = '')
136
 * @method static void allIsAnyOf($values, $class, $message = '')
137
 * @method static void allIsNotA($values, $class, $message = '')
138
 * @method static void allNull($values, $message = '')
139
 * @method static void allNotNull($values, $message = '')
140
 * @method static void allIsEmpty($values, $message = '')
141
 * @method static void allNotEmpty($values, $message = '')
142
 * @method static void allTrue($values, $message = '')
143
 * @method static void allFalse($values, $message = '')
144
 * @method static void allNotFalse($values, $message = '')
145
 * @method static void allIp($values, $message = '')
146
 * @method static void allIpv4($values, $message = '')
147
 * @method static void allIpv6($values, $message = '')
148
 * @method static void allEmail($values, $message = '')
149
 * @method static void allUniqueValues($values, $message = '')
150
 * @method static void allEq($values, $expect, $message = '')
151
 * @method static void allNotEq($values, $expect, $message = '')
152
 * @method static void allSame($values, $expect, $message = '')
153
 * @method static void allNotSame($values, $expect, $message = '')
154
 * @method static void allGreaterThan($values, $limit, $message = '')
155
 * @method static void allGreaterThanEq($values, $limit, $message = '')
156
 * @method static void allLessThan($values, $limit, $message = '')
157
 * @method static void allLessThanEq($values, $limit, $message = '')
158
 * @method static void allRange($values, $min, $max, $message = '')
159
 * @method static void allOneOf($values, $values, $message = '')
160
 * @method static void allContains($values, $subString, $message = '')
161
 * @method static void allNotContains($values, $subString, $message = '')
162
 * @method static void allNotWhitespaceOnly($values, $message = '')
163
 * @method static void allStartsWith($values, $prefix, $message = '')
164
 * @method static void allStartsWithLetter($values, $message = '')
165
 * @method static void allEndsWith($values, $suffix, $message = '')
166
 * @method static void allRegex($values, $pattern, $message = '')
167
 * @method static void allNotRegex($values, $pattern, $message = '')
168
 * @method static void allUnicodeLetters($values, $message = '')
169
 * @method static void allAlpha($values, $message = '')
170
 * @method static void allDigits($values, $message = '')
171
 * @method static void allAlnum($values, $message = '')
172
 * @method static void allLower($values, $message = '')
173
 * @method static void allUpper($values, $message = '')
174
 * @method static void allLength($values, $length, $message = '')
175
 * @method static void allMinLength($values, $min, $message = '')
176
 * @method static void allMaxLength($values, $max, $message = '')
177
 * @method static void allLengthBetween($values, $min, $max, $message = '')
178
 * @method static void allFileExists($values, $message = '')
179
 * @method static void allFile($values, $message = '')
180
 * @method static void allDirectory($values, $message = '')
181
 * @method static void allReadable($values, $message = '')
182
 * @method static void allWritable($values, $message = '')
183
 * @method static void allClassExists($values, $message = '')
184
 * @method static void allSubclassOf($values, $class, $message = '')
185
 * @method static void allInterfaceExists($values, $message = '')
186
 * @method static void allImplementsInterface($values, $interface, $message = '')
187
 * @method static void allPropertyExists($values, $property, $message = '')
188
 * @method static void allPropertyNotExists($values, $property, $message = '')
189
 * @method static void allMethodExists($values, $method, $message = '')
190
 * @method static void allMethodNotExists($values, $method, $message = '')
191
 * @method static void allKeyExists($values, $key, $message = '')
192
 * @method static void allKeyNotExists($values, $key, $message = '')
193
 * @method static void allValidArrayKey($values, $message = '')
194
 * @method static void allCount($values, $key, $message = '')
195
 * @method static void allMinCount($values, $min, $message = '')
196
 * @method static void allMaxCount($values, $max, $message = '')
197
 * @method static void allCountBetween($values, $min, $max, $message = '')
198
 * @method static void allIsList($values, $message = '')
199
 * @method static void allIsNonEmptyList($values, $message = '')
200
 * @method static void allIsMap($values, $message = '')
201
 * @method static void allIsNonEmptyMap($values, $message = '')
202
 * @method static void allUuid($values, $message = '')
203
 * @method static void allThrows($expressions, $class = 'Exception', $message = '')
204
 *
205
 * @since  1.0
206
 *
207
 * @author Bernhard Schussek <[email protected]>
208
 */
209
class Assert
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...
210
{
211
    /**
212
     * @psalm-pure
213
     * @psalm-assert string $value
214
     *
215
     * @param mixed  $value
216
     * @param string $message
217
     *
218
     * @throws InvalidArgumentException
219
     */
220 241
    public static function string($value, $message = '')
221
    {
222 241
        if (!\is_string($value)) {
223 45
            static::reportInvalidArgument(\sprintf(
224 45
                $message ?: 'Expected a string. Got: %s',
225 45
                static::typeToString($value)
226
            ));
227
        }
228 196
    }
229
230
    /**
231
     * @psalm-pure
232
     * @psalm-assert string $value
233
     * @psalm-assert !empty $value
234
     *
235
     * @param mixed  $value
236
     * @param string $message
237
     *
238
     * @throws InvalidArgumentException
239
     */
240 16
    public static function stringNotEmpty($value, $message = '')
241
    {
242 16
        static::string($value, $message);
243 12
        static::notEq($value, '', $message);
244 8
    }
245
246
    /**
247
     * @psalm-pure
248
     * @psalm-assert int $value
249
     *
250
     * @param mixed  $value
251
     * @param string $message
252
     *
253
     * @throws InvalidArgumentException
254
     */
255 17
    public static function integer($value, $message = '')
256
    {
257 17
        if (!\is_int($value)) {
258 13
            static::reportInvalidArgument(\sprintf(
259 13
                $message ?: 'Expected an integer. Got: %s',
260 13
                static::typeToString($value)
261
            ));
262
        }
263 4
    }
264
265
    /**
266
     * @psalm-pure
267
     * @psalm-assert numeric $value
268
     *
269
     * @param mixed  $value
270
     * @param string $message
271
     *
272
     * @throws InvalidArgumentException
273
     */
274 16
    public static function integerish($value, $message = '')
275
    {
276 16
        if (!\is_numeric($value) || $value != (int) $value) {
277 4
            static::reportInvalidArgument(\sprintf(
278 4
                $message ?: 'Expected an integerish value. Got: %s',
279 4
                static::typeToString($value)
280
            ));
281
        }
282 12
    }
283
284
    /**
285
     * @psalm-pure
286
     * @psalm-assert float $value
287
     *
288
     * @param mixed  $value
289
     * @param string $message
290
     *
291
     * @throws InvalidArgumentException
292
     */
293 16
    public static function float($value, $message = '')
294
    {
295 16
        if (!\is_float($value)) {
296 8
            static::reportInvalidArgument(\sprintf(
297 8
                $message ?: 'Expected a float. Got: %s',
298 8
                static::typeToString($value)
299
            ));
300
        }
301 8
    }
302
303
    /**
304
     * @psalm-pure
305
     * @psalm-assert numeric $value
306
     *
307
     * @param mixed  $value
308
     * @param string $message
309
     *
310
     * @throws InvalidArgumentException
311
     */
312 20
    public static function numeric($value, $message = '')
313
    {
314 20
        if (!\is_numeric($value)) {
315 4
            static::reportInvalidArgument(\sprintf(
316 4
                $message ?: 'Expected a numeric. Got: %s',
317 4
                static::typeToString($value)
318
            ));
319
        }
320 16
    }
321
322
    /**
323
     * @psalm-pure
324
     * @psalm-assert int $value
325
     *
326
     * @param mixed  $value
327
     * @param string $message
328
     *
329
     * @throws InvalidArgumentException
330
     */
331 24
    public static function natural($value, $message = '')
332
    {
333 24
        if (!\is_int($value) || $value < 0) {
334 16
            static::reportInvalidArgument(\sprintf(
335 16
                $message ?: 'Expected a non-negative integer. Got %s',
336 16
                static::valueToString($value)
337
            ));
338
        }
339 8
    }
340
341
    /**
342
     * @psalm-pure
343
     * @psalm-assert bool $value
344
     *
345
     * @param mixed  $value
346
     * @param string $message
347
     *
348
     * @throws InvalidArgumentException
349
     */
350 16
    public static function boolean($value, $message = '')
351
    {
352 16
        if (!\is_bool($value)) {
353 8
            static::reportInvalidArgument(\sprintf(
354 8
                $message ?: 'Expected a boolean. Got: %s',
355 8
                static::typeToString($value)
356
            ));
357
        }
358 8
    }
359
360
    /**
361
     * @psalm-pure
362
     * @psalm-assert scalar $value
363
     *
364
     * @param mixed  $value
365
     * @param string $message
366
     *
367
     * @throws InvalidArgumentException
368
     */
369 23
    public static function scalar($value, $message = '')
370
    {
371 23
        if (!\is_scalar($value)) {
372 11
            static::reportInvalidArgument(\sprintf(
373 11
                $message ?: 'Expected a scalar. Got: %s',
374 11
                static::typeToString($value)
375
            ));
376
        }
377 12
    }
378
379
    /**
380
     * @psalm-pure
381
     * @psalm-assert object $value
382
     *
383
     * @param mixed  $value
384
     * @param string $message
385
     *
386
     * @throws InvalidArgumentException
387
     */
388 23
    public static function object($value, $message = '')
389
    {
390 23
        if (!\is_object($value)) {
391 15
            static::reportInvalidArgument(\sprintf(
392 15
                $message ?: 'Expected an object. Got: %s',
393 15
                static::typeToString($value)
394
            ));
395
        }
396 8
    }
397
398
    /**
399
     * @psalm-pure
400
     * @psalm-assert resource $value
401
     *
402
     * @param mixed       $value
403
     * @param string|null $type    type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php
404
     * @param string      $message
405
     *
406
     * @throws InvalidArgumentException
407
     */
408 16
    public static function resource($value, $type = null, $message = '')
409
    {
410 16
        if (!\is_resource($value)) {
411 4
            static::reportInvalidArgument(\sprintf(
412 4
                $message ?: 'Expected a resource. Got: %s',
413 4
                static::typeToString($value)
414
            ));
415
        }
416
417 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...
418 4
            static::reportInvalidArgument(\sprintf(
419 4
                $message ?: 'Expected a resource of type %2$s. Got: %s',
420 4
                static::typeToString($value),
421 4
                $type
422
            ));
423
        }
424 8
    }
425
426
    /**
427
     * @psalm-pure
428
     * @psalm-assert callable $value
429
     *
430
     * @param mixed  $value
431
     * @param string $message
432
     *
433
     * @throws InvalidArgumentException
434
     */
435 20
    public static function isCallable($value, $message = '')
436
    {
437 20
        if (!\is_callable($value)) {
438 8
            static::reportInvalidArgument(\sprintf(
439 8
                $message ?: 'Expected a callable. Got: %s',
440 8
                static::typeToString($value)
441
            ));
442
        }
443 12
    }
444
445
    /**
446
     * @psalm-pure
447
     * @psalm-assert array $value
448
     *
449
     * @param mixed  $value
450
     * @param string $message
451
     *
452
     * @throws InvalidArgumentException
453
     */
454 20
    public static function isArray($value, $message = '')
455
    {
456 20
        if (!\is_array($value)) {
457 12
            static::reportInvalidArgument(\sprintf(
458 12
                $message ?: 'Expected an array. Got: %s',
459 12
                static::typeToString($value)
460
            ));
461
        }
462 8
    }
463
464
    /**
465
     * @psalm-pure
466
     * @psalm-assert iterable $value
467
     *
468
     * @deprecated use "isIterable" or "isInstanceOf" instead
469
     *
470
     * @param mixed  $value
471
     * @param string $message
472
     *
473
     * @throws InvalidArgumentException
474
     */
475 20
    public static function isTraversable($value, $message = '')
476
    {
477 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...
478 20
            \sprintf(
479 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.',
480 20
                __METHOD__
481
            ),
482 20
            \E_USER_DEPRECATED
483
        );
484
485 20
        if (!\is_array($value) && !($value instanceof Traversable)) {
486 8
            static::reportInvalidArgument(\sprintf(
487 8
                $message ?: 'Expected a traversable. Got: %s',
488 8
                static::typeToString($value)
489
            ));
490
        }
491 12
    }
492
493
    /**
494
     * @psalm-pure
495
     * @psalm-assert array|ArrayAccess $value
496
     *
497
     * @param mixed  $value
498
     * @param string $message
499
     *
500
     * @throws InvalidArgumentException
501
     */
502 20 View Code Duplication
    public static function isArrayAccessible($value, $message = '')
503
    {
504 20
        if (!\is_array($value) && !($value instanceof ArrayAccess)) {
505 8
            static::reportInvalidArgument(\sprintf(
506 8
                $message ?: 'Expected an array accessible. Got: %s',
507 8
                static::typeToString($value)
508
            ));
509
        }
510 12
    }
511
512
    /**
513
     * @psalm-pure
514
     * @psalm-assert countable $value
515
     *
516
     * @param mixed  $value
517
     * @param string $message
518
     *
519
     * @throws InvalidArgumentException
520
     */
521 28
    public static function isCountable($value, $message = '')
522
    {
523
        if (
524 28
            !\is_array($value)
525 28
            && !($value instanceof Countable)
526 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...
527 28
            && !($value instanceof SimpleXMLElement)
528
        ) {
529 12
            static::reportInvalidArgument(\sprintf(
530 12
                $message ?: 'Expected a countable. Got: %s',
531 12
                static::typeToString($value)
532
            ));
533
        }
534 16
    }
535
536
    /**
537
     * @psalm-pure
538
     * @psalm-assert iterable $value
539
     *
540
     * @param mixed  $value
541
     * @param string $message
542
     *
543
     * @throws InvalidArgumentException
544
     */
545 996 View Code Duplication
    public static function isIterable($value, $message = '')
546
    {
547 996
        if (!\is_array($value) && !($value instanceof Traversable)) {
548 8
            static::reportInvalidArgument(\sprintf(
549 8
                $message ?: 'Expected an iterable. Got: %s',
550 8
                static::typeToString($value)
551
            ));
552
        }
553 992
    }
554
555
    /**
556
     * @psalm-pure
557
     * @psalm-template ExpectedType of object
558
     * @psalm-param class-string<ExpectedType> $class
559
     * @psalm-assert ExpectedType $value
560
     *
561
     * @param mixed         $value
562
     * @param string|object $class
563
     * @param string        $message
564
     *
565
     * @throws InvalidArgumentException
566
     */
567 19
    public static function isInstanceOf($value, $class, $message = '')
568
    {
569 19
        if (!($value instanceof $class)) {
570 15
            static::reportInvalidArgument(\sprintf(
571 15
                $message ?: 'Expected an instance of %2$s. Got: %s',
572 15
                static::typeToString($value),
573 15
                $class
574
            ));
575
        }
576 4
    }
577
578
    /**
579
     * @psalm-pure
580
     * @psalm-template ExpectedType of object
581
     * @psalm-param class-string<ExpectedType> $class
582
     * @psalm-assert !ExpectedType $value
583
     *
584
     * @param mixed         $value
585
     * @param string|object $class
586
     * @param string        $message
587
     *
588
     * @throws InvalidArgumentException
589
     */
590 16
    public static function notInstanceOf($value, $class, $message = '')
591
    {
592 16
        if ($value instanceof $class) {
593 4
            static::reportInvalidArgument(\sprintf(
594 4
                $message ?: 'Expected an instance other than %2$s. Got: %s',
595 4
                static::typeToString($value),
596 4
                $class
597
            ));
598
        }
599 12
    }
600
601
    /**
602
     * @psalm-pure
603
     * @psalm-param array<class-string> $classes
604
     *
605
     * @param mixed                $value
606
     * @param array<object|string> $classes
607
     * @param string               $message
608
     *
609
     * @throws InvalidArgumentException
610
     */
611 20
    public static function isInstanceOfAny($value, array $classes, $message = '')
612
    {
613 20
        foreach ($classes as $class) {
614 20
            if ($value instanceof $class) {
615 8
                return;
616
            }
617
        }
618
619 12
        static::reportInvalidArgument(\sprintf(
620 12
            $message ?: 'Expected an instance of any of %2$s. Got: %s',
621 12
            static::typeToString($value),
622 12
            \implode(', ', \array_map(array('static', 'valueToString'), $classes))
623
        ));
624
    }
625
626
    /**
627
     * @psalm-pure
628
     * @psalm-template ExpectedType of object
629
     * @psalm-param class-string<ExpectedType> $class
630
     * @psalm-assert ExpectedType|class-string<ExpectedType> $value
631
     *
632
     * @param object|string $value
633
     * @param string        $class
634
     * @param string        $message
635
     *
636
     * @throws InvalidArgumentException
637
     */
638 20 View Code Duplication
    public static function isAOf($value, $class, $message = '')
639
    {
640 20
        static::string($class, 'Expected class as a string. Got: %s');
641
642 16
        if (!\is_a($value, $class, \is_string($value))) {
643 12
            static::reportInvalidArgument(sprintf(
644 12
                $message ?: 'Expected an instance of this class or to this class among his parents %2$s. Got: %s',
645 12
                static::typeToString($value),
646
                $class
647
            ));
648
        }
649 4
    }
650
651
    /**
652
     * @psalm-pure
653
     * @psalm-template UnexpectedType of object
654
     * @psalm-param class-string<UnexpectedType> $class
655
     * @psalm-assert !UnexpectedType $value
656
     * @psalm-assert !class-string<UnexpectedType> $value
657
     *
658
     * @param object|string $value
659
     * @param string        $class
660
     * @param string        $message
661
     *
662
     * @throws InvalidArgumentException
663
     */
664 20 View Code Duplication
    public static function isNotA($value, $class, $message = '')
665
    {
666 20
        static::string($class, 'Expected class as a string. Got: %s');
667
668 16
        if (\is_a($value, $class, \is_string($value))) {
669 4
            static::reportInvalidArgument(sprintf(
670 4
                $message ?: 'Expected an instance of this class or to this class among his parents other than %2$s. Got: %s',
671 4
                static::typeToString($value),
672
                $class
673
            ));
674
        }
675 12
    }
676
677
    /**
678
     * @psalm-pure
679
     * @psalm-param array<class-string> $classes
680
     *
681
     * @param object|string $value
682
     * @param string[]      $classes
683
     * @param string        $message
684
     *
685
     * @throws InvalidArgumentException
686
     */
687 24
    public static function isAnyOf($value, array $classes, $message = '')
688
    {
689 24
        foreach ($classes as $class) {
690 24
            static::string($class, 'Expected class as a string. Got: %s');
691
692 20
            if (\is_a($value, $class, \is_string($value))) {
693 8
                return;
694
            }
695
        }
696
697 12
        static::reportInvalidArgument(sprintf(
698 12
            $message ?: 'Expected an any of instance of this class or to this class among his parents other than %2$s. Got: %s',
699 12
            static::typeToString($value),
700 12
            \implode(', ', \array_map(array('static', 'valueToString'), $classes))
701
        ));
702
    }
703
704
    /**
705
     * @psalm-pure
706
     * @psalm-assert empty $value
707
     *
708
     * @param mixed  $value
709
     * @param string $message
710
     *
711
     * @throws InvalidArgumentException
712
     */
713 23
    public static function isEmpty($value, $message = '')
714
    {
715 23
        if (!empty($value)) {
716 8
            static::reportInvalidArgument(\sprintf(
717 8
                $message ?: 'Expected an empty value. Got: %s',
718 8
                static::valueToString($value)
719
            ));
720
        }
721 15
    }
722
723
    /**
724
     * @psalm-pure
725
     * @psalm-assert !empty $value
726
     *
727
     * @param mixed  $value
728
     * @param string $message
729
     *
730
     * @throws InvalidArgumentException
731
     */
732 55
    public static function notEmpty($value, $message = '')
733
    {
734 55
        if (empty($value)) {
735 23
            static::reportInvalidArgument(\sprintf(
736 23
                $message ?: 'Expected a non-empty value. Got: %s',
737 23
                static::valueToString($value)
738
            ));
739
        }
740 32
    }
741
742
    /**
743
     * @psalm-pure
744
     * @psalm-assert null $value
745
     *
746
     * @param mixed  $value
747
     * @param string $message
748
     *
749
     * @throws InvalidArgumentException
750
     */
751 11
    public static function null($value, $message = '')
752
    {
753 11
        if (null !== $value) {
754 8
            static::reportInvalidArgument(\sprintf(
755 8
                $message ?: 'Expected null. Got: %s',
756 8
                static::valueToString($value)
757
            ));
758
        }
759 3
    }
760
761
    /**
762
     * @psalm-pure
763
     * @psalm-assert !null $value
764
     *
765
     * @param mixed  $value
766
     * @param string $message
767
     *
768
     * @throws InvalidArgumentException
769
     */
770 11
    public static function notNull($value, $message = '')
771
    {
772 11
        if (null === $value) {
773 3
            static::reportInvalidArgument(
774 3
                $message ?: 'Expected a value other than null.'
775
            );
776
        }
777 8
    }
778
779
    /**
780
     * @psalm-pure
781
     * @psalm-assert true $value
782
     *
783
     * @param mixed  $value
784
     * @param string $message
785
     *
786
     * @throws InvalidArgumentException
787
     */
788 15
    public static function true($value, $message = '')
789
    {
790 15
        if (true !== $value) {
791 11
            static::reportInvalidArgument(\sprintf(
792 11
                $message ?: 'Expected a value to be true. Got: %s',
793 11
                static::valueToString($value)
794
            ));
795
        }
796 4
    }
797
798
    /**
799
     * @psalm-pure
800
     * @psalm-assert false $value
801
     *
802
     * @param mixed  $value
803
     * @param string $message
804
     *
805
     * @throws InvalidArgumentException
806
     */
807 19
    public static function false($value, $message = '')
808
    {
809 19
        if (false !== $value) {
810 15
            static::reportInvalidArgument(\sprintf(
811 15
                $message ?: 'Expected a value to be false. Got: %s',
812 15
                static::valueToString($value)
813
            ));
814
        }
815 4
    }
816
817
    /**
818
     * @psalm-assert !false $value
819
     *
820
     * @param mixed  $value
821
     * @param string $message
822
     *
823
     * @throws InvalidArgumentException
824
     */
825 19
    public static function notFalse($value, $message = '')
826
    {
827 19
        if (false === $value) {
828 4
            static::reportInvalidArgument(
829 4
                $message ?: 'Expected a value other than false.'
830
            );
831
        }
832 15
    }
833
834
    /**
835
     * @param mixed  $value
836
     * @param string $message
837
     *
838
     * @throws InvalidArgumentException
839
     */
840 51 View Code Duplication
    public static function ip($value, $message = '')
841
    {
842 51
        if (false === \filter_var($value, \FILTER_VALIDATE_IP)) {
843 19
            static::reportInvalidArgument(\sprintf(
844 19
                $message ?: 'Expected a value to be an IP. Got: %s',
845 19
                static::valueToString($value)
846
            ));
847
        }
848 32
    }
849
850
    /**
851
     * @param mixed  $value
852
     * @param string $message
853
     *
854
     * @throws InvalidArgumentException
855
     */
856 51 View Code Duplication
    public static function ipv4($value, $message = '')
857
    {
858 51
        if (false === \filter_var($value, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) {
859 35
            static::reportInvalidArgument(\sprintf(
860 35
                $message ?: 'Expected a value to be an IPv4. Got: %s',
861 35
                static::valueToString($value)
862
            ));
863
        }
864 16
    }
865
866
    /**
867
     * @param mixed  $value
868
     * @param string $message
869
     *
870
     * @throws InvalidArgumentException
871
     */
872 51 View Code Duplication
    public static function ipv6($value, $message = '')
873
    {
874 51
        if (false === \filter_var($value, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) {
875 31
            static::reportInvalidArgument(\sprintf(
876 31
                $message ?: 'Expected a value to be an IPv6. Got %s',
877 31
                static::valueToString($value)
878
            ));
879
        }
880 20
    }
881
882
    /**
883
     * @param mixed  $value
884
     * @param string $message
885
     *
886
     * @throws InvalidArgumentException
887
     */
888 20 View Code Duplication
    public static function email($value, $message = '')
889
    {
890 20
        if (false === \filter_var($value, FILTER_VALIDATE_EMAIL)) {
891 12
            static::reportInvalidArgument(\sprintf(
892 12
                $message ?: 'Expected a value to be a valid e-mail address. Got %s',
893 12
                static::valueToString($value)
894
            ));
895
        }
896 8
    }
897
898
    /**
899
     * Does non strict comparisons on the items, so ['3', 3] will not pass the assertion.
900
     *
901
     * @param array  $values
902
     * @param string $message
903
     *
904
     * @throws InvalidArgumentException
905
     */
906 12
    public static function uniqueValues(array $values, $message = '')
907
    {
908 12
        $allValues = \count($values);
909 12
        $uniqueValues = \count(\array_unique($values));
910
911 12
        if ($allValues !== $uniqueValues) {
912 8
            $difference = $allValues - $uniqueValues;
913
914 8
            static::reportInvalidArgument(\sprintf(
915 8
                $message ?: 'Expected an array of unique values, but %s of them %s duplicated',
916 8
                $difference,
917 8
                (1 === $difference ? 'is' : 'are')
918
            ));
919
        }
920 4
    }
921
922
    /**
923
     * @param mixed  $value
924
     * @param mixed  $expect
925
     * @param string $message
926
     *
927
     * @throws InvalidArgumentException
928
     */
929 33
    public static function eq($value, $expect, $message = '')
930
    {
931 33
        if ($expect != $value) {
932 17
            static::reportInvalidArgument(\sprintf(
933 17
                $message ?: 'Expected a value equal to %2$s. Got: %s',
934 17
                static::valueToString($value),
935 17
                static::valueToString($expect)
936
            ));
937
        }
938 16
    }
939
940
    /**
941
     * @param mixed  $value
942
     * @param mixed  $expect
943
     * @param string $message
944
     *
945
     * @throws InvalidArgumentException
946
     */
947 28
    public static function notEq($value, $expect, $message = '')
948
    {
949 28
        if ($expect == $value) {
950 16
            static::reportInvalidArgument(\sprintf(
951 16
                $message ?: 'Expected a different value than %s.',
952 16
                static::valueToString($expect)
953
            ));
954
        }
955 12
    }
956
957
    /**
958
     * @psalm-pure
959
     *
960
     * @param mixed  $value
961
     * @param mixed  $expect
962
     * @param string $message
963
     *
964
     * @throws InvalidArgumentException
965
     */
966 16
    public static function same($value, $expect, $message = '')
967
    {
968 16
        if ($expect !== $value) {
969 12
            static::reportInvalidArgument(\sprintf(
970 12
                $message ?: 'Expected a value identical to %2$s. Got: %s',
971 12
                static::valueToString($value),
972 12
                static::valueToString($expect)
973
            ));
974
        }
975 4
    }
976
977
    /**
978
     * @psalm-pure
979
     *
980
     * @param mixed  $value
981
     * @param mixed  $expect
982
     * @param string $message
983
     *
984
     * @throws InvalidArgumentException
985
     */
986 16
    public static function notSame($value, $expect, $message = '')
987
    {
988 16
        if ($expect === $value) {
989 4
            static::reportInvalidArgument(\sprintf(
990 4
                $message ?: 'Expected a value not identical to %s.',
991 4
                static::valueToString($expect)
992
            ));
993
        }
994 12
    }
995
996
    /**
997
     * @psalm-pure
998
     *
999
     * @param mixed  $value
1000
     * @param mixed  $limit
1001
     * @param string $message
1002
     *
1003
     * @throws InvalidArgumentException
1004
     */
1005 8
    public static function greaterThan($value, $limit, $message = '')
1006
    {
1007 8
        if ($value <= $limit) {
1008 4
            static::reportInvalidArgument(\sprintf(
1009 4
                $message ?: 'Expected a value greater than %2$s. Got: %s',
1010 4
                static::valueToString($value),
1011 4
                static::valueToString($limit)
1012
            ));
1013
        }
1014 4
    }
1015
1016
    /**
1017
     * @psalm-pure
1018
     *
1019
     * @param mixed  $value
1020
     * @param mixed  $limit
1021
     * @param string $message
1022
     *
1023
     * @throws InvalidArgumentException
1024
     */
1025 12
    public static function greaterThanEq($value, $limit, $message = '')
1026
    {
1027 12
        if ($value < $limit) {
1028 4
            static::reportInvalidArgument(\sprintf(
1029 4
                $message ?: 'Expected a value greater than or equal to %2$s. Got: %s',
1030 4
                static::valueToString($value),
1031 4
                static::valueToString($limit)
1032
            ));
1033
        }
1034 8
    }
1035
1036
    /**
1037
     * @psalm-pure
1038
     *
1039
     * @param mixed  $value
1040
     * @param mixed  $limit
1041
     * @param string $message
1042
     *
1043
     * @throws InvalidArgumentException
1044
     */
1045 8
    public static function lessThan($value, $limit, $message = '')
1046
    {
1047 8
        if ($value >= $limit) {
1048 4
            static::reportInvalidArgument(\sprintf(
1049 4
                $message ?: 'Expected a value less than %2$s. Got: %s',
1050 4
                static::valueToString($value),
1051 4
                static::valueToString($limit)
1052
            ));
1053
        }
1054 4
    }
1055
1056
    /**
1057
     * @psalm-pure
1058
     *
1059
     * @param mixed  $value
1060
     * @param mixed  $limit
1061
     * @param string $message
1062
     *
1063
     * @throws InvalidArgumentException
1064
     */
1065 12
    public static function lessThanEq($value, $limit, $message = '')
1066
    {
1067 12
        if ($value > $limit) {
1068 4
            static::reportInvalidArgument(\sprintf(
1069 4
                $message ?: 'Expected a value less than or equal to %2$s. Got: %s',
1070 4
                static::valueToString($value),
1071 4
                static::valueToString($limit)
1072
            ));
1073
        }
1074 8
    }
1075
1076
    /**
1077
     * Inclusive range, so Assert::(3, 3, 5) passes.
1078
     *
1079
     * @psalm-pure
1080
     *
1081
     * @param mixed  $value
1082
     * @param mixed  $min
1083
     * @param mixed  $max
1084
     * @param string $message
1085
     *
1086
     * @throws InvalidArgumentException
1087
     */
1088 16 View Code Duplication
    public static function range($value, $min, $max, $message = '')
1089
    {
1090 16
        if ($value < $min || $value > $max) {
1091 8
            static::reportInvalidArgument(\sprintf(
1092 8
                $message ?: 'Expected a value between %2$s and %3$s. Got: %s',
1093 8
                static::valueToString($value),
1094 8
                static::valueToString($min),
1095 8
                static::valueToString($max)
1096
            ));
1097
        }
1098 8
    }
1099
1100
    /**
1101
     * A more human-readable alias of Assert::inArray().
1102
     *
1103
     * @psalm-pure
1104
     *
1105
     * @param mixed  $value
1106
     * @param array  $values
1107
     * @param string $message
1108
     *
1109
     * @throws InvalidArgumentException
1110
     */
1111 8
    public static function oneOf($value, array $values, $message = '')
1112
    {
1113 8
        static::inArray($value, $values, $message);
1114 4
    }
1115
1116
    /**
1117
     * Does strict comparison, so Assert::inArray(3, ['3']) does not pass the assertion.
1118
     *
1119
     * @psalm-pure
1120
     *
1121
     * @param mixed  $value
1122
     * @param array  $values
1123
     * @param string $message
1124
     *
1125
     * @throws InvalidArgumentException
1126
     */
1127 16
    public static function inArray($value, array $values, $message = '')
1128
    {
1129 16
        if (!\in_array($value, $values, true)) {
1130 8
            static::reportInvalidArgument(\sprintf(
1131 8
                $message ?: 'Expected one of: %2$s. Got: %s',
1132 8
                static::valueToString($value),
1133 8
                \implode(', ', \array_map(array('static', 'valueToString'), $values))
1134
            ));
1135
        }
1136 8
    }
1137
1138
    /**
1139
     * @psalm-pure
1140
     *
1141
     * @param string $value
1142
     * @param string $subString
1143
     * @param string $message
1144
     *
1145
     * @throws InvalidArgumentException
1146
     */
1147 80 View Code Duplication
    public static function contains($value, $subString, $message = '')
1148
    {
1149 80
        if (false === \strpos($value, $subString)) {
1150 32
            static::reportInvalidArgument(\sprintf(
1151 32
                $message ?: 'Expected a value to contain %2$s. Got: %s',
1152 32
                static::valueToString($value),
1153 32
                static::valueToString($subString)
1154
            ));
1155
        }
1156 48
    }
1157
1158
    /**
1159
     * @psalm-pure
1160
     *
1161
     * @param string $value
1162
     * @param string $subString
1163
     * @param string $message
1164
     *
1165
     * @throws InvalidArgumentException
1166
     */
1167 80 View Code Duplication
    public static function notContains($value, $subString, $message = '')
1168
    {
1169 80
        if (false !== \strpos($value, $subString)) {
1170 48
            static::reportInvalidArgument(\sprintf(
1171 48
                $message ?: '%2$s was not expected to be contained in a value. Got: %s',
1172 48
                static::valueToString($value),
1173 48
                static::valueToString($subString)
1174
            ));
1175
        }
1176 32
    }
1177
1178
    /**
1179
     * @psalm-pure
1180
     *
1181
     * @param string $value
1182
     * @param string $message
1183
     *
1184
     * @throws InvalidArgumentException
1185
     */
1186 40
    public static function notWhitespaceOnly($value, $message = '')
1187
    {
1188 40
        if (\preg_match('/^\s*$/', $value)) {
1189 24
            static::reportInvalidArgument(\sprintf(
1190 24
                $message ?: 'Expected a non-whitespace string. Got: %s',
1191 24
                static::valueToString($value)
1192
            ));
1193
        }
1194 16
    }
1195
1196
    /**
1197
     * @psalm-pure
1198
     *
1199
     * @param string $value
1200
     * @param string $prefix
1201
     * @param string $message
1202
     *
1203
     * @throws InvalidArgumentException
1204
     */
1205 48 View Code Duplication
    public static function startsWith($value, $prefix, $message = '')
1206
    {
1207 48
        if (0 !== \strpos($value, $prefix)) {
1208 32
            static::reportInvalidArgument(\sprintf(
1209 32
                $message ?: 'Expected a value to start with %2$s. Got: %s',
1210 32
                static::valueToString($value),
1211 32
                static::valueToString($prefix)
1212
            ));
1213
        }
1214 16
    }
1215
1216
    /**
1217
     * @psalm-pure
1218
     *
1219
     * @param mixed  $value
1220
     * @param string $message
1221
     *
1222
     * @throws InvalidArgumentException
1223
     */
1224 35
    public static function startsWithLetter($value, $message = '')
1225
    {
1226 35
        static::string($value);
1227
1228 24
        $valid = isset($value[0]);
1229
1230 24
        if ($valid) {
1231 20
            $locale = \setlocale(LC_CTYPE, 0);
1232 20
            \setlocale(LC_CTYPE, 'C');
1233 20
            $valid = \ctype_alpha($value[0]);
1234 20
            \setlocale(LC_CTYPE, $locale);
1235
        }
1236
1237 24
        if (!$valid) {
1238 12
            static::reportInvalidArgument(\sprintf(
1239 12
                $message ?: 'Expected a value to start with a letter. Got: %s',
1240 12
                static::valueToString($value)
1241
            ));
1242
        }
1243 12
    }
1244
1245
    /**
1246
     * @psalm-pure
1247
     *
1248
     * @param string $value
1249
     * @param string $suffix
1250
     * @param string $message
1251
     *
1252
     * @throws InvalidArgumentException
1253
     */
1254 48 View Code Duplication
    public static function endsWith($value, $suffix, $message = '')
1255
    {
1256 48
        if ($suffix !== \substr($value, -\strlen($suffix))) {
1257 32
            static::reportInvalidArgument(\sprintf(
1258 32
                $message ?: 'Expected a value to end with %2$s. Got: %s',
1259 32
                static::valueToString($value),
1260 32
                static::valueToString($suffix)
1261
            ));
1262
        }
1263 16
    }
1264
1265
    /**
1266
     * @psalm-pure
1267
     *
1268
     * @param string $value
1269
     * @param string $pattern
1270
     * @param string $message
1271
     *
1272
     * @throws InvalidArgumentException
1273
     */
1274 12
    public static function regex($value, $pattern, $message = '')
1275
    {
1276 12
        if (!\preg_match($pattern, $value)) {
1277 8
            static::reportInvalidArgument(\sprintf(
1278 8
                $message ?: 'The value %s does not match the expected pattern.',
1279 8
                static::valueToString($value)
1280
            ));
1281
        }
1282 4
    }
1283
1284
    /**
1285
     * @psalm-pure
1286
     *
1287
     * @param string $value
1288
     * @param string $pattern
1289
     * @param string $message
1290
     *
1291
     * @throws InvalidArgumentException
1292
     */
1293 12
    public static function notRegex($value, $pattern, $message = '')
1294
    {
1295 12
        if (\preg_match($pattern, $value, $matches, PREG_OFFSET_CAPTURE)) {
1296 4
            static::reportInvalidArgument(\sprintf(
1297 4
                $message ?: 'The value %s matches the pattern %s (at offset %d).',
1298 4
                static::valueToString($value),
1299 4
                static::valueToString($pattern),
1300 4
                $matches[0][1]
1301
            ));
1302
        }
1303 8
    }
1304
1305
    /**
1306
     * @psalm-pure
1307
     *
1308
     * @param mixed  $value
1309
     * @param string $message
1310
     *
1311
     * @throws InvalidArgumentException
1312
     */
1313 28 View Code Duplication
    public static function unicodeLetters($value, $message = '')
1314
    {
1315 28
        static::string($value);
1316
1317 28
        if (!\preg_match('/^\p{L}+$/u', $value)) {
1318 16
            static::reportInvalidArgument(\sprintf(
1319 16
                $message ?: 'Expected a value to contain only Unicode letters. Got: %s',
1320 16
                static::valueToString($value)
1321
            ));
1322
        }
1323 12
    }
1324
1325
    /**
1326
     * @psalm-pure
1327
     *
1328
     * @param mixed  $value
1329
     * @param string $message
1330
     *
1331
     * @throws InvalidArgumentException
1332
     */
1333 20 View Code Duplication
    public static function alpha($value, $message = '')
1334
    {
1335 20
        static::string($value);
1336
1337 12
        $locale = \setlocale(LC_CTYPE, 0);
1338 12
        \setlocale(LC_CTYPE, 'C');
1339 12
        $valid = !\ctype_alpha($value);
1340 12
        \setlocale(LC_CTYPE, $locale);
1341
1342 12
        if ($valid) {
1343 8
            static::reportInvalidArgument(\sprintf(
1344 8
                $message ?: 'Expected a value to contain only letters. Got: %s',
1345 8
                static::valueToString($value)
1346
            ));
1347
        }
1348 4
    }
1349
1350
    /**
1351
     * @psalm-pure
1352
     *
1353
     * @param string $value
1354
     * @param string $message
1355
     *
1356
     * @throws InvalidArgumentException
1357
     */
1358 12 View Code Duplication
    public static function digits($value, $message = '')
1359
    {
1360 12
        $locale = \setlocale(LC_CTYPE, 0);
1361 12
        \setlocale(LC_CTYPE, 'C');
1362 12
        $valid = !\ctype_digit($value);
1363 12
        \setlocale(LC_CTYPE, $locale);
1364
1365 12
        if ($valid) {
1366 8
            static::reportInvalidArgument(\sprintf(
1367 8
                $message ?: 'Expected a value to contain digits only. Got: %s',
1368 8
                static::valueToString($value)
1369
            ));
1370
        }
1371 4
    }
1372
1373
    /**
1374
     * @psalm-pure
1375
     *
1376
     * @param string $value
1377
     * @param string $message
1378
     *
1379
     * @throws InvalidArgumentException
1380
     */
1381 12 View Code Duplication
    public static function alnum($value, $message = '')
1382
    {
1383 12
        $locale = \setlocale(LC_CTYPE, 0);
1384 12
        \setlocale(LC_CTYPE, 'C');
1385 12
        $valid = !\ctype_alnum($value);
1386 12
        \setlocale(LC_CTYPE, $locale);
1387
1388 12
        if ($valid) {
1389 8
            static::reportInvalidArgument(\sprintf(
1390 8
                $message ?: 'Expected a value to contain letters and digits only. Got: %s',
1391 8
                static::valueToString($value)
1392
            ));
1393
        }
1394 4
    }
1395
1396
    /**
1397
     * @psalm-pure
1398
     * @psalm-assert lowercase-string $value
1399
     *
1400
     * @param string $value
1401
     * @param string $message
1402
     *
1403
     * @throws InvalidArgumentException
1404
     */
1405 16 View Code Duplication
    public static function lower($value, $message = '')
1406
    {
1407 16
        $locale = \setlocale(LC_CTYPE, 0);
1408 16
        \setlocale(LC_CTYPE, 'C');
1409 16
        $valid = !\ctype_lower($value);
1410 16
        \setlocale(LC_CTYPE, $locale);
1411
1412 16
        if ($valid) {
1413 12
            static::reportInvalidArgument(\sprintf(
1414 12
                $message ?: 'Expected a value to contain lowercase characters only. Got: %s',
1415 12
                static::valueToString($value)
1416
            ));
1417
        }
1418 4
    }
1419
1420
    /**
1421
     * @psalm-pure
1422
     * @psalm-assert !lowercase-string $value
1423
     *
1424
     * @param string $value
1425
     * @param string $message
1426
     *
1427
     * @throws InvalidArgumentException
1428
     */
1429 16 View Code Duplication
    public static function upper($value, $message = '')
1430
    {
1431 16
        $locale = \setlocale(LC_CTYPE, 0);
1432 16
        \setlocale(LC_CTYPE, 'C');
1433 16
        $valid = !\ctype_upper($value);
1434 16
        \setlocale(LC_CTYPE, $locale);
1435
1436 16
        if ($valid) {
1437 12
            static::reportInvalidArgument(\sprintf(
1438 12
                $message ?: 'Expected a value to contain uppercase characters only. Got: %s',
1439 12
                static::valueToString($value)
1440
            ));
1441
        }
1442 4
    }
1443
1444
    /**
1445
     * @psalm-pure
1446
     *
1447
     * @param string $value
1448
     * @param int    $length
1449
     * @param string $message
1450
     *
1451
     * @throws InvalidArgumentException
1452
     */
1453 36
    public static function length($value, $length, $message = '')
1454
    {
1455 36
        if ($length !== static::strlen($value)) {
1456 24
            static::reportInvalidArgument(\sprintf(
1457 24
                $message ?: 'Expected a value to contain %2$s characters. Got: %s',
1458 24
                static::valueToString($value),
1459 24
                $length
1460
            ));
1461
        }
1462 12
    }
1463
1464
    /**
1465
     * Inclusive min.
1466
     *
1467
     * @psalm-pure
1468
     *
1469
     * @param string    $value
1470
     * @param int|float $min
1471
     * @param string    $message
1472
     *
1473
     * @throws InvalidArgumentException
1474
     */
1475 36
    public static function minLength($value, $min, $message = '')
1476
    {
1477 36
        if (static::strlen($value) < $min) {
1478 12
            static::reportInvalidArgument(\sprintf(
1479 12
                $message ?: 'Expected a value to contain at least %2$s characters. Got: %s',
1480 12
                static::valueToString($value),
1481 12
                $min
1482
            ));
1483
        }
1484 24
    }
1485
1486
    /**
1487
     * Inclusive max.
1488
     *
1489
     * @psalm-pure
1490
     *
1491
     * @param string    $value
1492
     * @param int|float $max
1493
     * @param string    $message
1494
     *
1495
     * @throws InvalidArgumentException
1496
     */
1497 36
    public static function maxLength($value, $max, $message = '')
1498
    {
1499 36
        if (static::strlen($value) > $max) {
1500 12
            static::reportInvalidArgument(\sprintf(
1501 12
                $message ?: 'Expected a value to contain at most %2$s characters. Got: %s',
1502 12
                static::valueToString($value),
1503 12
                $max
1504
            ));
1505
        }
1506 24
    }
1507
1508
    /**
1509
     * Inclusive , so Assert::lengthBetween('asd', 3, 5); passes the assertion.
1510
     *
1511
     * @psalm-pure
1512
     *
1513
     * @param string    $value
1514
     * @param int|float $min
1515
     * @param int|float $max
1516
     * @param string    $message
1517
     *
1518
     * @throws InvalidArgumentException
1519
     */
1520 60 View Code Duplication
    public static function lengthBetween($value, $min, $max, $message = '')
1521
    {
1522 60
        $length = static::strlen($value);
1523
1524 60
        if ($length < $min || $length > $max) {
1525 24
            static::reportInvalidArgument(\sprintf(
1526 24
                $message ?: 'Expected a value to contain between %2$s and %3$s characters. Got: %s',
1527 24
                static::valueToString($value),
1528 24
                $min,
1529 24
                $max
1530
            ));
1531
        }
1532 36
    }
1533
1534
    /**
1535
     * Will also pass if $value is a directory, use Assert::file() instead if you need to be sure it is a file.
1536
     *
1537
     * @param mixed  $value
1538
     * @param string $message
1539
     *
1540
     * @throws InvalidArgumentException
1541
     */
1542 36 View Code Duplication
    public static function fileExists($value, $message = '')
1543
    {
1544 36
        static::string($value);
1545
1546 36
        if (!\file_exists($value)) {
1547 12
            static::reportInvalidArgument(\sprintf(
1548 12
                $message ?: 'The file %s does not exist.',
1549 12
                static::valueToString($value)
1550
            ));
1551
        }
1552 24
    }
1553
1554
    /**
1555
     * @param mixed  $value
1556
     * @param string $message
1557
     *
1558
     * @throws InvalidArgumentException
1559
     */
1560 12 View Code Duplication
    public static function file($value, $message = '')
1561
    {
1562 12
        static::fileExists($value, $message);
1563
1564 8
        if (!\is_file($value)) {
1565 4
            static::reportInvalidArgument(\sprintf(
1566 4
                $message ?: 'The path %s is not a file.',
1567 4
                static::valueToString($value)
1568
            ));
1569
        }
1570 4
    }
1571
1572
    /**
1573
     * @param mixed  $value
1574
     * @param string $message
1575
     *
1576
     * @throws InvalidArgumentException
1577
     */
1578 12 View Code Duplication
    public static function directory($value, $message = '')
1579
    {
1580 12
        static::fileExists($value, $message);
1581
1582 8
        if (!\is_dir($value)) {
1583 4
            static::reportInvalidArgument(\sprintf(
1584 4
                $message ?: 'The path %s is no directory.',
1585 4
                static::valueToString($value)
1586
            ));
1587
        }
1588 4
    }
1589
1590
    /**
1591
     * @param string $value
1592
     * @param string $message
1593
     *
1594
     * @throws InvalidArgumentException
1595
     */
1596
    public static function readable($value, $message = '')
1597
    {
1598
        if (!\is_readable($value)) {
1599
            static::reportInvalidArgument(\sprintf(
1600
                $message ?: 'The path %s is not readable.',
1601
                static::valueToString($value)
1602
            ));
1603
        }
1604
    }
1605
1606
    /**
1607
     * @param string $value
1608
     * @param string $message
1609
     *
1610
     * @throws InvalidArgumentException
1611
     */
1612
    public static function writable($value, $message = '')
1613
    {
1614
        if (!\is_writable($value)) {
1615
            static::reportInvalidArgument(\sprintf(
1616
                $message ?: 'The path %s is not writable.',
1617
                static::valueToString($value)
1618
            ));
1619
        }
1620
    }
1621
1622
    /**
1623
     * @param mixed  $value
1624
     * @param string $message
1625
     *
1626
     * @throws InvalidArgumentException
1627
     */
1628 8
    public static function classExists($value, $message = '')
1629
    {
1630 8
        if (!\class_exists($value)) {
1631 4
            static::reportInvalidArgument(\sprintf(
1632 4
                $message ?: 'Expected an existing class name. Got: %s',
1633 4
                static::valueToString($value)
1634
            ));
1635
        }
1636 4
    }
1637
1638
    /**
1639
     * @psalm-pure
1640
     * @psalm-template ExpectedType of object
1641
     * @psalm-param class-string<ExpectedType> $class
1642
     * @psalm-assert class-string<ExpectedType>|ExpectedType $value
1643
     *
1644
     * @param mixed         $value
1645
     * @param string|object $class
1646
     * @param string        $message
1647
     *
1648
     * @throws InvalidArgumentException
1649
     */
1650 8
    public static function subclassOf($value, $class, $message = '')
1651
    {
1652 8
        if (!\is_subclass_of($value, $class)) {
1653 4
            static::reportInvalidArgument(\sprintf(
1654 4
                $message ?: 'Expected a sub-class of %2$s. Got: %s',
1655 4
                static::valueToString($value),
1656 4
                static::valueToString($class)
1657
            ));
1658
        }
1659 4
    }
1660
1661
    /**
1662
     * @param mixed  $value
1663
     * @param string $message
1664
     *
1665
     * @throws InvalidArgumentException
1666
     */
1667 8
    public static function interfaceExists($value, $message = '')
1668
    {
1669 8
        if (!\interface_exists($value)) {
1670 4
            static::reportInvalidArgument(\sprintf(
1671 4
                $message ?: 'Expected an existing interface name. got %s',
1672 4
                static::valueToString($value)
1673
            ));
1674
        }
1675 4
    }
1676
1677
    /**
1678
     * @psalm-pure
1679
     * @psalm-template ExpectedType of object
1680
     * @psalm-param class-string<ExpectedType> $interface
1681
     * @psalm-assert class-string<ExpectedType> $value
1682
     *
1683
     * @param mixed  $value
1684
     * @param mixed  $interface
1685
     * @param string $message
1686
     *
1687
     * @throws InvalidArgumentException
1688
     */
1689 8 View Code Duplication
    public static function implementsInterface($value, $interface, $message = '')
1690
    {
1691 8
        if (!\in_array($interface, \class_implements($value))) {
1692 4
            static::reportInvalidArgument(\sprintf(
1693 4
                $message ?: 'Expected an implementation of %2$s. Got: %s',
1694 4
                static::valueToString($value),
1695 4
                static::valueToString($interface)
1696
            ));
1697
        }
1698 4
    }
1699
1700
    /**
1701
     * @psalm-pure
1702
     * @psalm-param class-string|object $classOrObject
1703
     *
1704
     * @param string|object $classOrObject
1705
     * @param mixed         $property
1706
     * @param string        $message
1707
     *
1708
     * @throws InvalidArgumentException
1709
     */
1710 12 View Code Duplication
    public static function propertyExists($classOrObject, $property, $message = '')
1711
    {
1712 12
        if (!\property_exists($classOrObject, $property)) {
1713 4
            static::reportInvalidArgument(\sprintf(
1714 4
                $message ?: 'Expected the property %s to exist.',
1715 4
                static::valueToString($property)
1716
            ));
1717
        }
1718 8
    }
1719
1720
    /**
1721
     * @psalm-pure
1722
     * @psalm-param class-string|object $classOrObject
1723
     *
1724
     * @param string|object $classOrObject
1725
     * @param mixed         $property
1726
     * @param string        $message
1727
     *
1728
     * @throws InvalidArgumentException
1729
     */
1730 12 View Code Duplication
    public static function propertyNotExists($classOrObject, $property, $message = '')
1731
    {
1732 12
        if (\property_exists($classOrObject, $property)) {
1733 8
            static::reportInvalidArgument(\sprintf(
1734 8
                $message ?: 'Expected the property %s to not exist.',
1735 8
                static::valueToString($property)
1736
            ));
1737
        }
1738 4
    }
1739
1740
    /**
1741
     * @psalm-pure
1742
     * @psalm-param class-string|object $classOrObject
1743
     *
1744
     * @param string|object $classOrObject
1745
     * @param mixed         $method
1746
     * @param string        $message
1747
     *
1748
     * @throws InvalidArgumentException
1749
     */
1750 27 View Code Duplication
    public static function methodExists($classOrObject, $method, $message = '')
1751
    {
1752 27
        if (!\method_exists($classOrObject, $method)) {
1753 19
            static::reportInvalidArgument(\sprintf(
1754 19
                $message ?: 'Expected the method %s to exist.',
1755 19
                static::valueToString($method)
1756
            ));
1757
        }
1758 8
    }
1759
1760
    /**
1761
     * @psalm-pure
1762
     * @psalm-param class-string|object $classOrObject
1763
     *
1764
     * @param string|object $classOrObject
1765
     * @param mixed         $method
1766
     * @param string        $message
1767
     *
1768
     * @throws InvalidArgumentException
1769
     */
1770 27 View Code Duplication
    public static function methodNotExists($classOrObject, $method, $message = '')
1771
    {
1772 27
        if (\method_exists($classOrObject, $method)) {
1773 8
            static::reportInvalidArgument(\sprintf(
1774 8
                $message ?: 'Expected the method %s to not exist.',
1775 8
                static::valueToString($method)
1776
            ));
1777
        }
1778 19
    }
1779
1780
    /**
1781
     * @psalm-pure
1782
     *
1783
     * @param array      $array
1784
     * @param string|int $key
1785
     * @param string     $message
1786
     *
1787
     * @throws InvalidArgumentException
1788
     */
1789 12 View Code Duplication
    public static function keyExists($array, $key, $message = '')
1790
    {
1791 12
        if (!(isset($array[$key]) || \array_key_exists($key, $array))) {
1792 4
            static::reportInvalidArgument(\sprintf(
1793 4
                $message ?: 'Expected the key %s to exist.',
1794 4
                static::valueToString($key)
1795
            ));
1796
        }
1797 8
    }
1798
1799
    /**
1800
     * @psalm-pure
1801
     *
1802
     * @param array      $array
1803
     * @param string|int $key
1804
     * @param string     $message
1805
     *
1806
     * @throws InvalidArgumentException
1807
     */
1808 12 View Code Duplication
    public static function keyNotExists($array, $key, $message = '')
1809
    {
1810 12
        if (isset($array[$key]) || \array_key_exists($key, $array)) {
1811 8
            static::reportInvalidArgument(\sprintf(
1812 8
                $message ?: 'Expected the key %s to not exist.',
1813 8
                static::valueToString($key)
1814
            ));
1815
        }
1816 4
    }
1817
1818
    /**
1819
     * Checks if a value is a valid array key (int or string).
1820
     *
1821
     * @psalm-pure
1822
     * @psalm-assert array-key $value
1823
     *
1824
     * @param mixed  $value
1825
     * @param string $message
1826
     *
1827
     * @throws InvalidArgumentException
1828
     */
1829 28
    public static function validArrayKey($value, $message = '')
1830
    {
1831 28
        if (!(\is_int($value) || \is_string($value))) {
1832 20
            static::reportInvalidArgument(\sprintf(
1833 20
                $message ?: 'Expected string or integer. Got: %s',
1834 20
                static::typeToString($value)
1835
            ));
1836
        }
1837 8
    }
1838
1839
    /**
1840
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
1841
     *
1842
     * @param Countable|array $array
1843
     * @param int             $number
1844
     * @param string          $message
1845
     *
1846
     * @throws InvalidArgumentException
1847
     */
1848 8
    public static function count($array, $number, $message = '')
1849
    {
1850 8
        static::eq(
1851 8
            \count($array),
1852
            $number,
1853 8
            $message ?: \sprintf('Expected an array to contain %d elements. Got: %d.', $number, \count($array))
1854
        );
1855 4
    }
1856
1857
    /**
1858
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
1859
     *
1860
     * @param Countable|array $array
1861
     * @param int|float       $min
1862
     * @param string          $message
1863
     *
1864
     * @throws InvalidArgumentException
1865
     */
1866 12 View Code Duplication
    public static function minCount($array, $min, $message = '')
1867
    {
1868 12
        if (\count($array) < $min) {
1869 4
            static::reportInvalidArgument(\sprintf(
1870 4
                $message ?: 'Expected an array to contain at least %2$d elements. Got: %d',
1871 4
                \count($array),
1872 4
                $min
1873
            ));
1874
        }
1875 8
    }
1876
1877
    /**
1878
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
1879
     *
1880
     * @param Countable|array $array
1881
     * @param int|float       $max
1882
     * @param string          $message
1883
     *
1884
     * @throws InvalidArgumentException
1885
     */
1886 12 View Code Duplication
    public static function maxCount($array, $max, $message = '')
1887
    {
1888 12
        if (\count($array) > $max) {
1889 4
            static::reportInvalidArgument(\sprintf(
1890 4
                $message ?: 'Expected an array to contain at most %2$d elements. Got: %d',
1891 4
                \count($array),
1892 4
                $max
1893
            ));
1894
        }
1895 8
    }
1896
1897
    /**
1898
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
1899
     *
1900
     * @param Countable|array $array
1901
     * @param int|float       $min
1902
     * @param int|float       $max
1903
     * @param string          $message
1904
     *
1905
     * @throws InvalidArgumentException
1906
     */
1907 20
    public static function countBetween($array, $min, $max, $message = '')
1908
    {
1909 20
        $count = \count($array);
1910
1911 20
        if ($count < $min || $count > $max) {
1912 8
            static::reportInvalidArgument(\sprintf(
1913 8
                $message ?: 'Expected an array to contain between %2$d and %3$d elements. Got: %d',
1914 8
                $count,
1915 8
                $min,
1916 8
                $max
1917
            ));
1918
        }
1919 12
    }
1920
1921
    /**
1922
     * @psalm-pure
1923
     * @psalm-assert list $array
1924
     *
1925
     * @param mixed  $array
1926
     * @param string $message
1927
     *
1928
     * @throws InvalidArgumentException
1929
     */
1930 80 View Code Duplication
    public static function isList($array, $message = '')
1931
    {
1932 80
        if (!\is_array($array) || $array !== \array_values($array)) {
1933 32
            static::reportInvalidArgument(
1934 32
                $message ?: 'Expected list - non-associative array.'
1935
            );
1936
        }
1937 48
    }
1938
1939
    /**
1940
     * @psalm-pure
1941
     * @psalm-assert list $array
1942
     * @psalm-assert !empty $array
1943
     *
1944
     * @param mixed  $array
1945
     * @param string $message
1946
     *
1947
     * @throws InvalidArgumentException
1948
     */
1949 40
    public static function isNonEmptyList($array, $message = '')
1950
    {
1951 40
        static::isList($array, $message);
1952 24
        static::notEmpty($array, $message);
1953 20
    }
1954
1955
    /**
1956
     * @psalm-pure
1957
     * @psalm-template T
1958
     * @psalm-param mixed|array<T> $array
1959
     * @psalm-assert array<string, T> $array
1960
     *
1961
     * @param mixed  $array
1962
     * @param string $message
1963
     *
1964
     * @throws InvalidArgumentException
1965
     */
1966 32
    public static function isMap($array, $message = '')
1967
    {
1968
        if (
1969 32
            !\is_array($array) ||
1970 32
            \array_keys($array) !== \array_filter(\array_keys($array), '\is_string')
1971
        ) {
1972 16
            static::reportInvalidArgument(
1973 16
                $message ?: 'Expected map - associative array with string keys.'
1974
            );
1975
        }
1976 16
    }
1977
1978
    /**
1979
     * @psalm-pure
1980
     * @psalm-template T
1981
     * @psalm-param mixed|array<T> $array
1982
     * @psalm-assert array<string, T> $array
1983
     * @psalm-assert !empty $array
1984
     *
1985
     * @param mixed  $array
1986
     * @param string $message
1987
     *
1988
     * @throws InvalidArgumentException
1989
     */
1990 16
    public static function isNonEmptyMap($array, $message = '')
1991
    {
1992 16
        static::isMap($array, $message);
1993 8
        static::notEmpty($array, $message);
1994 4
    }
1995
1996
    /**
1997
     * @psalm-pure
1998
     *
1999
     * @param string $value
2000
     * @param string $message
2001
     *
2002
     * @throws InvalidArgumentException
2003
     */
2004 56
    public static function uuid($value, $message = '')
2005
    {
2006 56
        $value = \str_replace(array('urn:', 'uuid:', '{', '}'), '', $value);
2007
2008
        // The nil UUID is special form of UUID that is specified to have all
2009
        // 128 bits set to zero.
2010 56
        if ('00000000-0000-0000-0000-000000000000' === $value) {
2011 4
            return;
2012
        }
2013
2014 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)) {
2015 20
            static::reportInvalidArgument(\sprintf(
2016 20
                $message ?: 'Value %s is not a valid UUID.',
2017 20
                static::valueToString($value)
2018
            ));
2019
        }
2020 32
    }
2021
2022
    /**
2023
     * @psalm-param class-string<Throwable>
2024
     *
2025
     * @param Closure $expression
2026
     * @param string  $class
2027
     * @param string  $message
2028
     *
2029
     * @throws InvalidArgumentException
2030
     */
2031 24
    public static function throws(Closure $expression, $class = 'Exception', $message = '')
2032
    {
2033 24
        static::string($class);
2034
2035 24
        $actual = 'none';
2036
2037
        try {
2038 24
            $expression();
2039 24
        } catch (Exception $e) {
2040 20
            $actual = \get_class($e);
2041 20
            if ($e instanceof $class) {
2042 20
                return;
2043
            }
2044 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...
2045 4
            $actual = \get_class($e);
2046 4
            if ($e instanceof $class) {
2047 4
                return;
2048
            }
2049
        }
2050
2051 8
        static::reportInvalidArgument($message ?: \sprintf(
2052 8
            'Expected to throw "%s", got "%s"',
2053 8
            $class,
2054 8
            $actual
2055
        ));
2056
    }
2057
2058
    /**
2059
     * @throws BadMethodCallException
2060
     */
2061 1568
    public static function __callStatic($name, $arguments)
2062
    {
2063 1568
        if ('nullOr' === \substr($name, 0, 6)) {
2064 581
            if (null !== $arguments[0]) {
2065 477
                $method = \lcfirst(\substr($name, 6));
2066 477
                \call_user_func_array(array('static', $method), $arguments);
2067
            }
2068
2069 336
            return;
2070
        }
2071
2072 987
        if ('all' === \substr($name, 0, 3)) {
2073 986
            static::isIterable($arguments[0]);
2074
2075 986
            $method = \lcfirst(\substr($name, 3));
2076 986
            $args = $arguments;
2077
2078 986
            foreach ($arguments[0] as $entry) {
2079 986
                $args[0] = $entry;
2080
2081 986
                \call_user_func_array(array('static', $method), $args);
2082
            }
2083
2084 472
            return;
2085
        }
2086
2087 1
        throw new BadMethodCallException('No such method: '.$name);
2088
    }
2089
2090
    /**
2091
     * @param mixed $value
2092
     *
2093
     * @return string
2094
     */
2095 718
    protected static function valueToString($value)
2096
    {
2097 718
        if (null === $value) {
2098 20
            return 'null';
2099
        }
2100
2101 700
        if (true === $value) {
2102 15
            return 'true';
2103
        }
2104
2105 690
        if (false === $value) {
2106 25
            return 'false';
2107
        }
2108
2109 665
        if (\is_array($value)) {
2110 21
            return 'array';
2111
        }
2112
2113 644
        if (\is_object($value)) {
2114 2
            if (\method_exists($value, '__toString')) {
2115 1
                return \get_class($value).': '.self::valueToString($value->__toString());
2116
            }
2117
2118 1
            return \get_class($value);
2119
        }
2120
2121 643
        if (\is_resource($value)) {
2122 1
            return 'resource';
2123
        }
2124
2125 643
        if (\is_string($value)) {
2126 541
            return '"'.$value.'"';
2127
        }
2128
2129 114
        return (string) $value;
2130
    }
2131
2132
    /**
2133
     * @param mixed $value
2134
     *
2135
     * @return string
2136
     */
2137 251
    protected static function typeToString($value)
2138
    {
2139 251
        return \is_object($value) ? \get_class($value) : \gettype($value);
2140
    }
2141
2142 168
    protected static function strlen($value)
2143
    {
2144 168
        if (!\function_exists('mb_detect_encoding')) {
2145
            return \strlen($value);
2146
        }
2147
2148 168
        if (false === $encoding = \mb_detect_encoding($value)) {
2149
            return \strlen($value);
2150
        }
2151
2152 168
        return \mb_strlen($value, $encoding);
2153
    }
2154
2155
    /**
2156
     * @param string $message
2157
     *
2158
     * @throws InvalidArgumentException
2159
     *
2160
     * @psalm-pure this method is not supposed to perform side-effects
2161
     */
2162 1032
    protected static function reportInvalidArgument($message)
2163
    {
2164 1032
        throw new InvalidArgumentException($message);
2165
    }
2166
2167
    private function __construct()
2168
    {
2169
    }
2170
}
2171