Failed Conditions
Pull Request — master (#176)
by Ruud
04:06 queued 01:34
created

src/Assert.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

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

1
<?php
2
3
/*
4
 * This file is part of the webmozart/assert package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Webmozart\Assert;
13
14
use ArrayAccess;
15
use BadMethodCallException;
16
use Closure;
17
use Countable;
18
use Exception;
19
use InvalidArgumentException;
20
use ResourceBundle;
21
use SimpleXMLElement;
22
use Throwable;
23
use Traversable;
24
25
/**
26
 * Efficient assertions to validate the input/output of your methods.
27
 *
28
 * @method static void nullOrString($value, $message = '')
29
 * @method static void nullOrStringNotEmpty($value, $message = '')
30
 * @method static void nullOrInteger($value, $message = '')
31
 * @method static void nullOrIntegerish($value, $message = '')
32
 * @method static void nullOrFloat($value, $message = '')
33
 * @method static void nullOrNumeric($value, $message = '')
34
 * @method static void nullOrNatural($value, $message = '')
35
 * @method static void nullOrBoolean($value, $message = '')
36
 * @method static void nullOrScalar($value, $message = '')
37
 * @method static void nullOrObject($value, $message = '')
38
 * @method static void nullOrResource($value, $type = null, $message = '')
39
 * @method static void nullOrIsCallable($value, $message = '')
40
 * @method static void nullOrIsArray($value, $message = '')
41
 * @method static void nullOrIsTraversable($value, $message = '')
42
 * @method static void nullOrIsArrayAccessible($value, $message = '')
43
 * @method static void nullOrIsCountable($value, $message = '')
44
 * @method static void nullOrIsIterable($value, $message = '')
45
 * @method static void nullOrIsInstanceOf($value, $class, $message = '')
46
 * @method static void nullOrNotInstanceOf($value, $class, $message = '')
47
 * @method static void nullOrIsInstanceOfAny($value, $classes, $message = '')
48
 * @method static void nullOrIsAOf($value, $classes, $message = '')
49
 * @method static void nullOrIsAnyOf($value, $classes, $message = '')
50
 * @method static void nullOrIsNotA($value, $classes, $message = '')
51
 * @method static void nullOrIsEmpty($value, $message = '')
52
 * @method static void nullOrNotEmpty($value, $message = '')
53
 * @method static void nullOrTrue($value, $message = '')
54
 * @method static void nullOrFalse($value, $message = '')
55
 * @method static void nullOrNotFalse($value, $message = '')
56
 * @method static void nullOrIp($value, $message = '')
57
 * @method static void nullOrIpv4($value, $message = '')
58
 * @method static void nullOrIpv6($value, $message = '')
59
 * @method static void nullOrEmail($value, $message = '')
60
 * @method static void nullOrUniqueValues($values, $message = '')
61
 * @method static void nullOrEq($value, $expect, $message = '')
62
 * @method static void nullOrNotEq($value, $expect, $message = '')
63
 * @method static void nullOrSame($value, $expect, $message = '')
64
 * @method static void nullOrNotSame($value, $expect, $message = '')
65
 * @method static void nullOrGreaterThan($value, $limit, $message = '')
66
 * @method static void nullOrGreaterThanEq($value, $limit, $message = '')
67
 * @method static void nullOrLessThan($value, $limit, $message = '')
68
 * @method static void nullOrLessThanEq($value, $limit, $message = '')
69
 * @method static void nullOrRange($value, $min, $max, $message = '')
70
 * @method static void nullOrOneOf($value, $values, $message = '')
71
 * @method static void nullOrContains($value, $subString, $message = '')
72
 * @method static void nullOrNotContains($value, $subString, $message = '')
73
 * @method static void nullOrNotWhitespaceOnly($value, $message = '')
74
 * @method static void nullOrStartsWith($value, $prefix, $message = '')
75
 * @method static void nullOrStartsWithLetter($value, $message = '')
76
 * @method static void nullOrEndsWith($value, $suffix, $message = '')
77
 * @method static void nullOrRegex($value, $pattern, $message = '')
78
 * @method static void nullOrNotRegex($value, $pattern, $message = '')
79
 * @method static void nullOrUnicodeLetters($value, $message = '')
80
 * @method static void nullOrAlpha($value, $message = '')
81
 * @method static void nullOrDigits($value, $message = '')
82
 * @method static void nullOrAlnum($value, $message = '')
83
 * @method static void nullOrLower($value, $message = '')
84
 * @method static void nullOrUpper($value, $message = '')
85
 * @method static void nullOrLength($value, $length, $message = '')
86
 * @method static void nullOrMinLength($value, $min, $message = '')
87
 * @method static void nullOrMaxLength($value, $max, $message = '')
88
 * @method static void nullOrLengthBetween($value, $min, $max, $message = '')
89
 * @method static void nullOrFileExists($value, $message = '')
90
 * @method static void nullOrFile($value, $message = '')
91
 * @method static void nullOrDirectory($value, $message = '')
92
 * @method static void nullOrReadable($value, $message = '')
93
 * @method static void nullOrWritable($value, $message = '')
94
 * @method static void nullOrClassExists($value, $message = '')
95
 * @method static void nullOrSubclassOf($value, $class, $message = '')
96
 * @method static void nullOrInterfaceExists($value, $message = '')
97
 * @method static void nullOrImplementsInterface($value, $interface, $message = '')
98
 * @method static void nullOrPropertyExists($value, $property, $message = '')
99
 * @method static void nullOrPropertyNotExists($value, $property, $message = '')
100
 * @method static void nullOrMethodExists($value, $method, $message = '')
101
 * @method static void nullOrMethodNotExists($value, $method, $message = '')
102
 * @method static void nullOrKeyExists($value, $key, $message = '')
103
 * @method static void nullOrKeyNotExists($value, $key, $message = '')
104
 * @method static void nullOrValidArrayKey($value, $message = '')
105
 * @method static void nullOrCount($value, $key, $message = '')
106
 * @method static void nullOrMinCount($value, $min, $message = '')
107
 * @method static void nullOrMaxCount($value, $max, $message = '')
108
 * @method static void nullOrIsList($value, $message = '')
109
 * @method static void nullOrIsNonEmptyList($value, $message = '')
110
 * @method static void nullOrIsMap($value, $message = '')
111
 * @method static void nullOrIsNonEmptyMap($value, $message = '')
112
 * @method static void nullOrCountBetween($value, $min, $max, $message = '')
113
 * @method static void nullOrUuid($values, $message = '')
114
 * @method static void nullOrThrows($expression, $class = 'Exception', $message = '')
115
 * @method static void allString($values, $message = '')
116
 * @method static void allStringNotEmpty($values, $message = '')
117
 * @method static void allInteger($values, $message = '')
118
 * @method static void allIntegerish($values, $message = '')
119
 * @method static void allFloat($values, $message = '')
120
 * @method static void allNumeric($values, $message = '')
121
 * @method static void allNatural($values, $message = '')
122
 * @method static void allBoolean($values, $message = '')
123
 * @method static void allScalar($values, $message = '')
124
 * @method static void allObject($values, $message = '')
125
 * @method static void allResource($values, $type = null, $message = '')
126
 * @method static void allIsCallable($values, $message = '')
127
 * @method static void allIsArray($values, $message = '')
128
 * @method static void allIsTraversable($values, $message = '')
129
 * @method static void allIsArrayAccessible($values, $message = '')
130
 * @method static void allIsCountable($values, $message = '')
131
 * @method static void allIsIterable($values, $message = '')
132
 * @method static void allIsInstanceOf($values, $class, $message = '')
133
 * @method static void allNotInstanceOf($values, $class, $message = '')
134
 * @method static void allIsInstanceOfAny($values, $classes, $message = '')
135
 * @method static void allIsAOf($values, $class, $message = '')
136
 * @method static void allIsAnyOf($values, $class, $message = '')
137
 * @method static void allIsNotA($values, $class, $message = '')
138
 * @method static void allNull($values, $message = '')
139
 * @method static void allNotNull($values, $message = '')
140
 * @method static void allIsEmpty($values, $message = '')
141
 * @method static void allNotEmpty($values, $message = '')
142
 * @method static void allTrue($values, $message = '')
143
 * @method static void allFalse($values, $message = '')
144
 * @method static void allNotFalse($values, $message = '')
145
 * @method static void allIp($values, $message = '')
146
 * @method static void allIpv4($values, $message = '')
147
 * @method static void allIpv6($values, $message = '')
148
 * @method static void allEmail($values, $message = '')
149
 * @method static void allUniqueValues($values, $message = '')
150
 * @method static void allEq($values, $expect, $message = '')
151
 * @method static void allNotEq($values, $expect, $message = '')
152
 * @method static void allSame($values, $expect, $message = '')
153
 * @method static void allNotSame($values, $expect, $message = '')
154
 * @method static void allGreaterThan($values, $limit, $message = '')
155
 * @method static void allGreaterThanEq($values, $limit, $message = '')
156
 * @method static void allLessThan($values, $limit, $message = '')
157
 * @method static void allLessThanEq($values, $limit, $message = '')
158
 * @method static void allRange($values, $min, $max, $message = '')
159
 * @method static void allOneOf($values, $values, $message = '')
160
 * @method static void allContains($values, $subString, $message = '')
161
 * @method static void allNotContains($values, $subString, $message = '')
162
 * @method static void allNotWhitespaceOnly($values, $message = '')
163
 * @method static void allStartsWith($values, $prefix, $message = '')
164
 * @method static void allStartsWithLetter($values, $message = '')
165
 * @method static void allEndsWith($values, $suffix, $message = '')
166
 * @method static void allRegex($values, $pattern, $message = '')
167
 * @method static void allNotRegex($values, $pattern, $message = '')
168
 * @method static void allUnicodeLetters($values, $message = '')
169
 * @method static void allAlpha($values, $message = '')
170
 * @method static void allDigits($values, $message = '')
171
 * @method static void allAlnum($values, $message = '')
172
 * @method static void allLower($values, $message = '')
173
 * @method static void allUpper($values, $message = '')
174
 * @method static void allLength($values, $length, $message = '')
175
 * @method static void allMinLength($values, $min, $message = '')
176
 * @method static void allMaxLength($values, $max, $message = '')
177
 * @method static void allLengthBetween($values, $min, $max, $message = '')
178
 * @method static void allFileExists($values, $message = '')
179
 * @method static void allFile($values, $message = '')
180
 * @method static void allDirectory($values, $message = '')
181
 * @method static void allReadable($values, $message = '')
182
 * @method static void allWritable($values, $message = '')
183
 * @method static void allClassExists($values, $message = '')
184
 * @method static void allSubclassOf($values, $class, $message = '')
185
 * @method static void allInterfaceExists($values, $message = '')
186
 * @method static void allImplementsInterface($values, $interface, $message = '')
187
 * @method static void allPropertyExists($values, $property, $message = '')
188
 * @method static void allPropertyNotExists($values, $property, $message = '')
189
 * @method static void allMethodExists($values, $method, $message = '')
190
 * @method static void allMethodNotExists($values, $method, $message = '')
191
 * @method static void allKeyExists($values, $key, $message = '')
192
 * @method static void allKeyNotExists($values, $key, $message = '')
193
 * @method static void allValidArrayKey($values, $message = '')
194
 * @method static void allCount($values, $key, $message = '')
195
 * @method static void allMinCount($values, $min, $message = '')
196
 * @method static void allMaxCount($values, $max, $message = '')
197
 * @method static void allCountBetween($values, $min, $max, $message = '')
198
 * @method static void allIsList($values, $message = '')
199
 * @method static void allIsNonEmptyList($values, $message = '')
200
 * @method static void allIsMap($values, $message = '')
201
 * @method static void allIsNonEmptyMap($values, $message = '')
202
 * @method static void allUuid($values, $message = '')
203
 * @method static void allThrows($expressions, $class = 'Exception', $message = '')
204
 *
205
 * @since  1.0
206
 *
207
 * @author Bernhard Schussek <[email protected]>
208
 */
209
class Assert
210
{
211
    /**
212
     * @psalm-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)) {
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(
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)
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 992 View Code Duplication
    public static function isIterable($value, $message = '')
546
    {
547 992
        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 988
    }
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 9
    public static function lessThan($value, $limit, $message = '')
1046
    {
1047 9
        if ($value >= $limit) {
1048 5
            static::reportInvalidArgument(\sprintf(
1049 5
                $message ?: 'Expected a value less than %2$s. Got: %s',
1050 5
                static::valueToString($value),
1051 5
                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
     * Does strict comparison, so Assert::oneOf(3, ['3']) does not pass the assertion.
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
        if (!\in_array($value, $values, true)) {
1114 4
            static::reportInvalidArgument(\sprintf(
1115 4
                $message ?: 'Expected one of: %2$s. Got: %s',
1116 4
                static::valueToString($value),
1117 4
                \implode(', ', \array_map(array('static', 'valueToString'), $values))
1118
            ));
1119
        }
1120 4
    }
1121
1122
    /**
1123
     * @psalm-pure
1124
     *
1125
     * @param string $value
1126
     * @param string $subString
1127
     * @param string $message
1128
     *
1129
     * @throws InvalidArgumentException
1130
     */
1131 80 View Code Duplication
    public static function contains($value, $subString, $message = '')
1132
    {
1133 80
        if (false === \strpos($value, $subString)) {
1134 32
            static::reportInvalidArgument(\sprintf(
1135 32
                $message ?: 'Expected a value to contain %2$s. Got: %s',
1136 32
                static::valueToString($value),
1137 32
                static::valueToString($subString)
1138
            ));
1139
        }
1140 48
    }
1141
1142
    /**
1143
     * @psalm-pure
1144
     *
1145
     * @param string $value
1146
     * @param string $subString
1147
     * @param string $message
1148
     *
1149
     * @throws InvalidArgumentException
1150
     */
1151 80 View Code Duplication
    public static function notContains($value, $subString, $message = '')
1152
    {
1153 80
        if (false !== \strpos($value, $subString)) {
1154 48
            static::reportInvalidArgument(\sprintf(
1155 48
                $message ?: '%2$s was not expected to be contained in a value. Got: %s',
1156 48
                static::valueToString($value),
1157 48
                static::valueToString($subString)
1158
            ));
1159
        }
1160 32
    }
1161
1162
    /**
1163
     * @psalm-pure
1164
     *
1165
     * @param string $value
1166
     * @param string $message
1167
     *
1168
     * @throws InvalidArgumentException
1169
     */
1170 40
    public static function notWhitespaceOnly($value, $message = '')
1171
    {
1172 40
        if (\preg_match('/^\s*$/', $value)) {
1173 24
            static::reportInvalidArgument(\sprintf(
1174 24
                $message ?: 'Expected a non-whitespace string. Got: %s',
1175 24
                static::valueToString($value)
1176
            ));
1177
        }
1178 16
    }
1179
1180
    /**
1181
     * @psalm-pure
1182
     *
1183
     * @param string $value
1184
     * @param string $prefix
1185
     * @param string $message
1186
     *
1187
     * @throws InvalidArgumentException
1188
     */
1189 48 View Code Duplication
    public static function startsWith($value, $prefix, $message = '')
1190
    {
1191 48
        if (0 !== \strpos($value, $prefix)) {
1192 32
            static::reportInvalidArgument(\sprintf(
1193 32
                $message ?: 'Expected a value to start with %2$s. Got: %s',
1194 32
                static::valueToString($value),
1195 32
                static::valueToString($prefix)
1196
            ));
1197
        }
1198 16
    }
1199
1200
    /**
1201
     * @psalm-pure
1202
     *
1203
     * @param mixed  $value
1204
     * @param string $message
1205
     *
1206
     * @throws InvalidArgumentException
1207
     */
1208 35
    public static function startsWithLetter($value, $message = '')
1209
    {
1210 35
        static::string($value);
1211
1212 24
        $valid = isset($value[0]);
1213
1214 24
        if ($valid) {
1215 20
            $locale = \setlocale(LC_CTYPE, 0);
1216 20
            \setlocale(LC_CTYPE, 'C');
1217 20
            $valid = \ctype_alpha($value[0]);
1218 20
            \setlocale(LC_CTYPE, $locale);
1219
        }
1220
1221 24
        if (!$valid) {
1222 12
            static::reportInvalidArgument(\sprintf(
1223 12
                $message ?: 'Expected a value to start with a letter. Got: %s',
1224 12
                static::valueToString($value)
1225
            ));
1226
        }
1227 12
    }
1228
1229
    /**
1230
     * @psalm-pure
1231
     *
1232
     * @param string $value
1233
     * @param string $suffix
1234
     * @param string $message
1235
     *
1236
     * @throws InvalidArgumentException
1237
     */
1238 48 View Code Duplication
    public static function endsWith($value, $suffix, $message = '')
1239
    {
1240 48
        if ($suffix !== \substr($value, -\strlen($suffix))) {
1241 32
            static::reportInvalidArgument(\sprintf(
1242 32
                $message ?: 'Expected a value to end with %2$s. Got: %s',
1243 32
                static::valueToString($value),
1244 32
                static::valueToString($suffix)
1245
            ));
1246
        }
1247 16
    }
1248
1249
    /**
1250
     * @psalm-pure
1251
     *
1252
     * @param string $value
1253
     * @param string $pattern
1254
     * @param string $message
1255
     *
1256
     * @throws InvalidArgumentException
1257
     */
1258 12
    public static function regex($value, $pattern, $message = '')
1259
    {
1260 12
        if (!\preg_match($pattern, $value)) {
1261 8
            static::reportInvalidArgument(\sprintf(
1262 8
                $message ?: 'The value %s does not match the expected pattern.',
1263 8
                static::valueToString($value)
1264
            ));
1265
        }
1266 4
    }
1267
1268
    /**
1269
     * @psalm-pure
1270
     *
1271
     * @param string $value
1272
     * @param string $pattern
1273
     * @param string $message
1274
     *
1275
     * @throws InvalidArgumentException
1276
     */
1277 12
    public static function notRegex($value, $pattern, $message = '')
1278
    {
1279 12
        if (\preg_match($pattern, $value, $matches, PREG_OFFSET_CAPTURE)) {
1280 4
            static::reportInvalidArgument(\sprintf(
1281 4
                $message ?: 'The value %s matches the pattern %s (at offset %d).',
1282 4
                static::valueToString($value),
1283 4
                static::valueToString($pattern),
1284 4
                $matches[0][1]
1285
            ));
1286
        }
1287 8
    }
1288
1289
    /**
1290
     * @psalm-pure
1291
     *
1292
     * @param mixed  $value
1293
     * @param string $message
1294
     *
1295
     * @throws InvalidArgumentException
1296
     */
1297 28 View Code Duplication
    public static function unicodeLetters($value, $message = '')
1298
    {
1299 28
        static::string($value);
1300
1301 28
        if (!\preg_match('/^\p{L}+$/u', $value)) {
1302 16
            static::reportInvalidArgument(\sprintf(
1303 16
                $message ?: 'Expected a value to contain only Unicode letters. Got: %s',
1304 16
                static::valueToString($value)
1305
            ));
1306
        }
1307 12
    }
1308
1309
    /**
1310
     * @psalm-pure
1311
     *
1312
     * @param mixed  $value
1313
     * @param string $message
1314
     *
1315
     * @throws InvalidArgumentException
1316
     */
1317 20 View Code Duplication
    public static function alpha($value, $message = '')
1318
    {
1319 20
        static::string($value);
1320
1321 12
        $locale = \setlocale(LC_CTYPE, 0);
1322 12
        \setlocale(LC_CTYPE, 'C');
1323 12
        $valid = !\ctype_alpha($value);
1324 12
        \setlocale(LC_CTYPE, $locale);
1325
1326 12
        if ($valid) {
1327 8
            static::reportInvalidArgument(\sprintf(
1328 8
                $message ?: 'Expected a value to contain only letters. Got: %s',
1329 8
                static::valueToString($value)
1330
            ));
1331
        }
1332 4
    }
1333
1334
    /**
1335
     * @psalm-pure
1336
     *
1337
     * @param string $value
1338
     * @param string $message
1339
     *
1340
     * @throws InvalidArgumentException
1341
     */
1342 12 View Code Duplication
    public static function digits($value, $message = '')
1343
    {
1344 12
        $locale = \setlocale(LC_CTYPE, 0);
1345 12
        \setlocale(LC_CTYPE, 'C');
1346 12
        $valid = !\ctype_digit($value);
1347 12
        \setlocale(LC_CTYPE, $locale);
1348
1349 12
        if ($valid) {
1350 8
            static::reportInvalidArgument(\sprintf(
1351 8
                $message ?: 'Expected a value to contain digits only. Got: %s',
1352 8
                static::valueToString($value)
1353
            ));
1354
        }
1355 4
    }
1356
1357
    /**
1358
     * @psalm-pure
1359
     *
1360
     * @param string $value
1361
     * @param string $message
1362
     *
1363
     * @throws InvalidArgumentException
1364
     */
1365 12 View Code Duplication
    public static function alnum($value, $message = '')
1366
    {
1367 12
        $locale = \setlocale(LC_CTYPE, 0);
1368 12
        \setlocale(LC_CTYPE, 'C');
1369 12
        $valid = !\ctype_alnum($value);
1370 12
        \setlocale(LC_CTYPE, $locale);
1371
1372 12
        if ($valid) {
1373 8
            static::reportInvalidArgument(\sprintf(
1374 8
                $message ?: 'Expected a value to contain letters and digits only. Got: %s',
1375 8
                static::valueToString($value)
1376
            ));
1377
        }
1378 4
    }
1379
1380
    /**
1381
     * @psalm-pure
1382
     * @psalm-assert lowercase-string $value
1383
     *
1384
     * @param string $value
1385
     * @param string $message
1386
     *
1387
     * @throws InvalidArgumentException
1388
     */
1389 16 View Code Duplication
    public static function lower($value, $message = '')
1390
    {
1391 16
        $locale = \setlocale(LC_CTYPE, 0);
1392 16
        \setlocale(LC_CTYPE, 'C');
1393 16
        $valid = !\ctype_lower($value);
1394 16
        \setlocale(LC_CTYPE, $locale);
1395
1396 16
        if ($valid) {
1397 12
            static::reportInvalidArgument(\sprintf(
1398 12
                $message ?: 'Expected a value to contain lowercase characters only. Got: %s',
1399 12
                static::valueToString($value)
1400
            ));
1401
        }
1402 4
    }
1403
1404
    /**
1405
     * @psalm-pure
1406
     * @psalm-assert !lowercase-string $value
1407
     *
1408
     * @param string $value
1409
     * @param string $message
1410
     *
1411
     * @throws InvalidArgumentException
1412
     */
1413 16 View Code Duplication
    public static function upper($value, $message = '')
1414
    {
1415 16
        $locale = \setlocale(LC_CTYPE, 0);
1416 16
        \setlocale(LC_CTYPE, 'C');
1417 16
        $valid = !\ctype_upper($value);
1418 16
        \setlocale(LC_CTYPE, $locale);
1419
1420 16
        if ($valid) {
1421 12
            static::reportInvalidArgument(\sprintf(
1422 12
                $message ?: 'Expected a value to contain uppercase characters only. Got: %s',
1423 12
                static::valueToString($value)
1424
            ));
1425
        }
1426 4
    }
1427
1428
    /**
1429
     * @psalm-pure
1430
     *
1431
     * @param string $value
1432
     * @param int    $length
1433
     * @param string $message
1434
     *
1435
     * @throws InvalidArgumentException
1436
     */
1437 36
    public static function length($value, $length, $message = '')
1438
    {
1439 36
        if ($length !== static::strlen($value)) {
1440 24
            static::reportInvalidArgument(\sprintf(
1441 24
                $message ?: 'Expected a value to contain %2$s characters. Got: %s',
1442 24
                static::valueToString($value),
1443 24
                $length
1444
            ));
1445
        }
1446 12
    }
1447
1448
    /**
1449
     * Inclusive min.
1450
     *
1451
     * @psalm-pure
1452
     *
1453
     * @param string    $value
1454
     * @param int|float $min
1455
     * @param string    $message
1456
     *
1457
     * @throws InvalidArgumentException
1458
     */
1459 36
    public static function minLength($value, $min, $message = '')
1460
    {
1461 36
        if (static::strlen($value) < $min) {
1462 12
            static::reportInvalidArgument(\sprintf(
1463 12
                $message ?: 'Expected a value to contain at least %2$s characters. Got: %s',
1464 12
                static::valueToString($value),
1465 12
                $min
1466
            ));
1467
        }
1468 24
    }
1469
1470
    /**
1471
     * Inclusive max.
1472
     *
1473
     * @psalm-pure
1474
     *
1475
     * @param string    $value
1476
     * @param int|float $max
1477
     * @param string    $message
1478
     *
1479
     * @throws InvalidArgumentException
1480
     */
1481 36
    public static function maxLength($value, $max, $message = '')
1482
    {
1483 36
        if (static::strlen($value) > $max) {
1484 12
            static::reportInvalidArgument(\sprintf(
1485 12
                $message ?: 'Expected a value to contain at most %2$s characters. Got: %s',
1486 12
                static::valueToString($value),
1487 12
                $max
1488
            ));
1489
        }
1490 24
    }
1491
1492
    /**
1493
     * Inclusive , so Assert::lengthBetween('asd', 3, 5); passes the assertion.
1494
     *
1495
     * @psalm-pure
1496
     *
1497
     * @param string    $value
1498
     * @param int|float $min
1499
     * @param int|float $max
1500
     * @param string    $message
1501
     *
1502
     * @throws InvalidArgumentException
1503
     */
1504 60 View Code Duplication
    public static function lengthBetween($value, $min, $max, $message = '')
1505
    {
1506 60
        $length = static::strlen($value);
1507
1508 60
        if ($length < $min || $length > $max) {
1509 24
            static::reportInvalidArgument(\sprintf(
1510 24
                $message ?: 'Expected a value to contain between %2$s and %3$s characters. Got: %s',
1511 24
                static::valueToString($value),
1512 24
                $min,
1513 24
                $max
1514
            ));
1515
        }
1516 36
    }
1517
1518
    /**
1519
     * Will also pass if $value is a directory, use Assert::file() instead if you need to be sure it is a file.
1520
     *
1521
     * @param mixed  $value
1522
     * @param string $message
1523
     *
1524
     * @throws InvalidArgumentException
1525
     */
1526 36 View Code Duplication
    public static function fileExists($value, $message = '')
1527
    {
1528 36
        static::string($value);
1529
1530 36
        if (!\file_exists($value)) {
1531 12
            static::reportInvalidArgument(\sprintf(
1532 12
                $message ?: 'The file %s does not exist.',
1533 12
                static::valueToString($value)
1534
            ));
1535
        }
1536 24
    }
1537
1538
    /**
1539
     * @param mixed  $value
1540
     * @param string $message
1541
     *
1542
     * @throws InvalidArgumentException
1543
     */
1544 12 View Code Duplication
    public static function file($value, $message = '')
1545
    {
1546 12
        static::fileExists($value, $message);
1547
1548 8
        if (!\is_file($value)) {
1549 4
            static::reportInvalidArgument(\sprintf(
1550 4
                $message ?: 'The path %s is not a file.',
1551 4
                static::valueToString($value)
1552
            ));
1553
        }
1554 4
    }
1555
1556
    /**
1557
     * @param mixed  $value
1558
     * @param string $message
1559
     *
1560
     * @throws InvalidArgumentException
1561
     */
1562 12 View Code Duplication
    public static function directory($value, $message = '')
1563
    {
1564 12
        static::fileExists($value, $message);
1565
1566 8
        if (!\is_dir($value)) {
1567 4
            static::reportInvalidArgument(\sprintf(
1568 4
                $message ?: 'The path %s is no directory.',
1569 4
                static::valueToString($value)
1570
            ));
1571
        }
1572 4
    }
1573
1574
    /**
1575
     * @param string $value
1576
     * @param string $message
1577
     *
1578
     * @throws InvalidArgumentException
1579
     */
1580
    public static function readable($value, $message = '')
1581
    {
1582
        if (!\is_readable($value)) {
1583
            static::reportInvalidArgument(\sprintf(
1584
                $message ?: 'The path %s is not readable.',
1585
                static::valueToString($value)
1586
            ));
1587
        }
1588
    }
1589
1590
    /**
1591
     * @param string $value
1592
     * @param string $message
1593
     *
1594
     * @throws InvalidArgumentException
1595
     */
1596
    public static function writable($value, $message = '')
1597
    {
1598
        if (!\is_writable($value)) {
1599
            static::reportInvalidArgument(\sprintf(
1600
                $message ?: 'The path %s is not writable.',
1601
                static::valueToString($value)
1602
            ));
1603
        }
1604
    }
1605
1606
    /**
1607
     * @param mixed  $value
1608
     * @param string $message
1609
     *
1610
     * @throws InvalidArgumentException
1611
     */
1612 8
    public static function classExists($value, $message = '')
1613
    {
1614 8
        if (!\class_exists($value)) {
1615 4
            static::reportInvalidArgument(\sprintf(
1616 4
                $message ?: 'Expected an existing class name. Got: %s',
1617 4
                static::valueToString($value)
1618
            ));
1619
        }
1620 4
    }
1621
1622
    /**
1623
     * @psalm-pure
1624
     * @psalm-template ExpectedType of object
1625
     * @psalm-param class-string<ExpectedType> $class
1626
     * @psalm-assert class-string<ExpectedType>|ExpectedType $value
1627
     *
1628
     * @param mixed         $value
1629
     * @param string|object $class
1630
     * @param string        $message
1631
     *
1632
     * @throws InvalidArgumentException
1633
     */
1634 8
    public static function subclassOf($value, $class, $message = '')
1635
    {
1636 8
        if (!\is_subclass_of($value, $class)) {
1637 4
            static::reportInvalidArgument(\sprintf(
1638 4
                $message ?: 'Expected a sub-class of %2$s. Got: %s',
1639 4
                static::valueToString($value),
1640 4
                static::valueToString($class)
1641
            ));
1642
        }
1643 4
    }
1644
1645
    /**
1646
     * @param mixed  $value
1647
     * @param string $message
1648
     *
1649
     * @throws InvalidArgumentException
1650
     */
1651 8
    public static function interfaceExists($value, $message = '')
1652
    {
1653 8
        if (!\interface_exists($value)) {
1654 4
            static::reportInvalidArgument(\sprintf(
1655 4
                $message ?: 'Expected an existing interface name. got %s',
1656 4
                static::valueToString($value)
1657
            ));
1658
        }
1659 4
    }
1660
1661
    /**
1662
     * @psalm-pure
1663
     * @psalm-template ExpectedType of object
1664
     * @psalm-param class-string<ExpectedType> $interface
1665
     * @psalm-assert class-string<ExpectedType> $value
1666
     *
1667
     * @param mixed  $value
1668
     * @param mixed  $interface
1669
     * @param string $message
1670
     *
1671
     * @throws InvalidArgumentException
1672
     */
1673 8 View Code Duplication
    public static function implementsInterface($value, $interface, $message = '')
1674
    {
1675 8
        if (!\in_array($interface, \class_implements($value))) {
1676 4
            static::reportInvalidArgument(\sprintf(
1677 4
                $message ?: 'Expected an implementation of %2$s. Got: %s',
1678 4
                static::valueToString($value),
1679 4
                static::valueToString($interface)
1680
            ));
1681
        }
1682 4
    }
1683
1684
    /**
1685
     * @psalm-pure
1686
     * @psalm-param class-string|object $classOrObject
1687
     *
1688
     * @param string|object $classOrObject
1689
     * @param mixed         $property
1690
     * @param string        $message
1691
     *
1692
     * @throws InvalidArgumentException
1693
     */
1694 12 View Code Duplication
    public static function propertyExists($classOrObject, $property, $message = '')
1695
    {
1696 12
        if (!\property_exists($classOrObject, $property)) {
1697 4
            static::reportInvalidArgument(\sprintf(
1698 4
                $message ?: 'Expected the property %s to exist.',
1699 4
                static::valueToString($property)
1700
            ));
1701
        }
1702 8
    }
1703
1704
    /**
1705
     * @psalm-pure
1706
     * @psalm-param class-string|object $classOrObject
1707
     *
1708
     * @param string|object $classOrObject
1709
     * @param mixed         $property
1710
     * @param string        $message
1711
     *
1712
     * @throws InvalidArgumentException
1713
     */
1714 12 View Code Duplication
    public static function propertyNotExists($classOrObject, $property, $message = '')
1715
    {
1716 12
        if (\property_exists($classOrObject, $property)) {
1717 8
            static::reportInvalidArgument(\sprintf(
1718 8
                $message ?: 'Expected the property %s to not exist.',
1719 8
                static::valueToString($property)
1720
            ));
1721
        }
1722 4
    }
1723
1724
    /**
1725
     * @psalm-pure
1726
     * @psalm-param class-string|object $classOrObject
1727
     *
1728
     * @param string|object $classOrObject
1729
     * @param mixed         $method
1730
     * @param string        $message
1731
     *
1732
     * @throws InvalidArgumentException
1733
     */
1734 27 View Code Duplication
    public static function methodExists($classOrObject, $method, $message = '')
1735
    {
1736 27
        if (!\method_exists($classOrObject, $method)) {
1737 19
            static::reportInvalidArgument(\sprintf(
1738 19
                $message ?: 'Expected the method %s to exist.',
1739 19
                static::valueToString($method)
1740
            ));
1741
        }
1742 8
    }
1743
1744
    /**
1745
     * @psalm-pure
1746
     * @psalm-param class-string|object $classOrObject
1747
     *
1748
     * @param string|object $classOrObject
1749
     * @param mixed         $method
1750
     * @param string        $message
1751
     *
1752
     * @throws InvalidArgumentException
1753
     */
1754 27 View Code Duplication
    public static function methodNotExists($classOrObject, $method, $message = '')
1755
    {
1756 27
        if (\method_exists($classOrObject, $method)) {
1757 8
            static::reportInvalidArgument(\sprintf(
1758 8
                $message ?: 'Expected the method %s to not exist.',
1759 8
                static::valueToString($method)
1760
            ));
1761
        }
1762 19
    }
1763
1764
    /**
1765
     * @psalm-pure
1766
     *
1767
     * @param array      $array
1768
     * @param string|int $key
1769
     * @param string     $message
1770
     *
1771
     * @throws InvalidArgumentException
1772
     */
1773 12 View Code Duplication
    public static function keyExists($array, $key, $message = '')
1774
    {
1775 12
        if (!(isset($array[$key]) || \array_key_exists($key, $array))) {
1776 4
            static::reportInvalidArgument(\sprintf(
1777 4
                $message ?: 'Expected the key %s to exist.',
1778 4
                static::valueToString($key)
1779
            ));
1780
        }
1781 8
    }
1782
1783
    /**
1784
     * @psalm-pure
1785
     *
1786
     * @param array      $array
1787
     * @param string|int $key
1788
     * @param string     $message
1789
     *
1790
     * @throws InvalidArgumentException
1791
     */
1792 12 View Code Duplication
    public static function keyNotExists($array, $key, $message = '')
1793
    {
1794 12
        if (isset($array[$key]) || \array_key_exists($key, $array)) {
1795 8
            static::reportInvalidArgument(\sprintf(
1796 8
                $message ?: 'Expected the key %s to not exist.',
1797 8
                static::valueToString($key)
1798
            ));
1799
        }
1800 4
    }
1801
1802
    /**
1803
     * Checks if a value is a valid array key (int or string).
1804
     *
1805
     * @psalm-pure
1806
     * @psalm-assert array-key $value
1807
     *
1808
     * @param mixed  $value
1809
     * @param string $message
1810
     *
1811
     * @throws InvalidArgumentException
1812
     */
1813 28
    public static function validArrayKey($value, $message = '')
1814
    {
1815 28
        if (!(\is_int($value) || \is_string($value))) {
1816 20
            static::reportInvalidArgument(\sprintf(
1817 20
                $message ?: 'Expected string or integer. Got: %s',
1818 20
                static::typeToString($value)
1819
            ));
1820
        }
1821 8
    }
1822
1823
    /**
1824
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
1825
     *
1826
     * @param Countable|array $array
1827
     * @param int             $number
1828
     * @param string          $message
1829
     *
1830
     * @throws InvalidArgumentException
1831
     */
1832 8
    public static function count($array, $number, $message = '')
1833
    {
1834 8
        static::eq(
1835 8
            \count($array),
1836
            $number,
1837 8
            $message ?: \sprintf('Expected an array to contain %d elements. Got: %d.', $number, \count($array))
1838
        );
1839 4
    }
1840
1841
    /**
1842
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
1843
     *
1844
     * @param Countable|array $array
1845
     * @param int|float       $min
1846
     * @param string          $message
1847
     *
1848
     * @throws InvalidArgumentException
1849
     */
1850 12 View Code Duplication
    public static function minCount($array, $min, $message = '')
1851
    {
1852 12
        if (\count($array) < $min) {
1853 4
            static::reportInvalidArgument(\sprintf(
1854 4
                $message ?: 'Expected an array to contain at least %2$d elements. Got: %d',
1855 4
                \count($array),
1856 4
                $min
1857
            ));
1858
        }
1859 8
    }
1860
1861
    /**
1862
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
1863
     *
1864
     * @param Countable|array $array
1865
     * @param int|float       $max
1866
     * @param string          $message
1867
     *
1868
     * @throws InvalidArgumentException
1869
     */
1870 12 View Code Duplication
    public static function maxCount($array, $max, $message = '')
1871
    {
1872 12
        if (\count($array) > $max) {
1873 4
            static::reportInvalidArgument(\sprintf(
1874 4
                $message ?: 'Expected an array to contain at most %2$d elements. Got: %d',
1875 4
                \count($array),
1876 4
                $max
1877
            ));
1878
        }
1879 8
    }
1880
1881
    /**
1882
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
1883
     *
1884
     * @param Countable|array $array
1885
     * @param int|float       $min
1886
     * @param int|float       $max
1887
     * @param string          $message
1888
     *
1889
     * @throws InvalidArgumentException
1890
     */
1891 20
    public static function countBetween($array, $min, $max, $message = '')
1892
    {
1893 20
        $count = \count($array);
1894
1895 20
        if ($count < $min || $count > $max) {
1896 8
            static::reportInvalidArgument(\sprintf(
1897 8
                $message ?: 'Expected an array to contain between %2$d and %3$d elements. Got: %d',
1898 8
                $count,
1899 8
                $min,
1900 8
                $max
1901
            ));
1902
        }
1903 12
    }
1904
1905
    /**
1906
     * @psalm-pure
1907
     * @psalm-assert list $array
1908
     *
1909
     * @param mixed  $array
1910
     * @param string $message
1911
     *
1912
     * @throws InvalidArgumentException
1913
     */
1914 80 View Code Duplication
    public static function isList($array, $message = '')
1915
    {
1916 80
        if (!\is_array($array) || $array !== \array_values($array)) {
1917 32
            static::reportInvalidArgument(
1918 32
                $message ?: 'Expected list - non-associative array.'
1919
            );
1920
        }
1921 48
    }
1922
1923
    /**
1924
     * @psalm-pure
1925
     * @psalm-assert list $array
1926
     * @psalm-assert !empty $array
1927
     *
1928
     * @param mixed  $array
1929
     * @param string $message
1930
     *
1931
     * @throws InvalidArgumentException
1932
     */
1933 40
    public static function isNonEmptyList($array, $message = '')
1934
    {
1935 40
        static::isList($array, $message);
1936 24
        static::notEmpty($array, $message);
1937 20
    }
1938
1939
    /**
1940
     * @psalm-pure
1941
     * @psalm-template T
1942
     * @psalm-param mixed|array<T> $array
1943
     * @psalm-assert array<string, T> $array
1944
     *
1945
     * @param mixed  $array
1946
     * @param string $message
1947
     *
1948
     * @throws InvalidArgumentException
1949
     */
1950 32
    public static function isMap($array, $message = '')
1951
    {
1952
        if (
1953 32
            !\is_array($array) ||
1954 32
            \array_keys($array) !== \array_filter(\array_keys($array), '\is_string')
1955
        ) {
1956 16
            static::reportInvalidArgument(
1957 16
                $message ?: 'Expected map - associative array with string keys.'
1958
            );
1959
        }
1960 16
    }
1961
1962
    /**
1963
     * @psalm-pure
1964
     * @psalm-template T
1965
     * @psalm-param mixed|array<T> $array
1966
     * @psalm-assert array<string, T> $array
1967
     * @psalm-assert !empty $array
1968
     *
1969
     * @param mixed  $array
1970
     * @param string $message
1971
     *
1972
     * @throws InvalidArgumentException
1973
     */
1974 16
    public static function isNonEmptyMap($array, $message = '')
1975
    {
1976 16
        static::isMap($array, $message);
1977 8
        static::notEmpty($array, $message);
1978 4
    }
1979
1980
    /**
1981
     * @psalm-pure
1982
     *
1983
     * @param string $value
1984
     * @param string $message
1985
     *
1986
     * @throws InvalidArgumentException
1987
     */
1988 56
    public static function uuid($value, $message = '')
1989
    {
1990 56
        $value = \str_replace(array('urn:', 'uuid:', '{', '}'), '', $value);
1991
1992
        // The nil UUID is special form of UUID that is specified to have all
1993
        // 128 bits set to zero.
1994 56
        if ('00000000-0000-0000-0000-000000000000' === $value) {
1995 4
            return;
1996
        }
1997
1998 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)) {
1999 20
            static::reportInvalidArgument(\sprintf(
2000 20
                $message ?: 'Value %s is not a valid UUID.',
2001 20
                static::valueToString($value)
2002
            ));
2003
        }
2004 32
    }
2005
2006
    /**
2007
     * @psalm-param class-string<Throwable>
2008
     *
2009
     * @param Closure $expression
2010
     * @param string  $class
2011
     * @param string  $message
2012
     *
2013
     * @throws InvalidArgumentException
2014
     */
2015 24
    public static function throws(Closure $expression, $class = 'Exception', $message = '')
2016
    {
2017 24
        static::string($class);
2018
2019 24
        $actual = 'none';
2020
2021
        try {
2022 24
            $expression();
2023 24
        } catch (Exception $e) {
2024 20
            $actual = \get_class($e);
2025 20
            if ($e instanceof $class) {
2026 20
                return;
2027
            }
2028 4
        } catch (Throwable $e) {
2029 4
            $actual = \get_class($e);
2030 4
            if ($e instanceof $class) {
2031 4
                return;
2032
            }
2033
        }
2034
2035 8
        static::reportInvalidArgument($message ?: \sprintf(
2036 8
            'Expected to throw "%s", got "%s"',
2037 8
            $class,
2038 8
            $actual
2039
        ));
2040
    }
2041
2042
    /**
2043
     * @throws BadMethodCallException
2044
     */
2045 1561
    public static function __callStatic($name, $arguments)
2046
    {
2047 1561
        if ('nullOr' === \substr($name, 0, 6)) {
2048 578
            if (null !== $arguments[0]) {
2049 475
                $method = \lcfirst(\substr($name, 6));
2050 475
                \call_user_func_array(array('static', $method), $arguments);
2051
            }
2052
2053 334
            return;
2054
        }
2055
2056 983
        if ('all' === \substr($name, 0, 3)) {
2057 982
            static::isIterable($arguments[0]);
2058
2059 982
            $method = \lcfirst(\substr($name, 3));
2060 982
            $args = $arguments;
2061
2062 982
            foreach ($arguments[0] as $entry) {
2063 982
                $args[0] = $entry;
2064
2065 982
                \call_user_func_array(array('static', $method), $args);
2066
            }
2067
2068 470
            return;
2069
        }
2070
2071 1
        throw new BadMethodCallException('No such method: '.$name);
2072
    }
2073
2074
    /**
2075
     * @param mixed $value
2076
     *
2077
     * @return string
2078
     */
2079 715
    protected static function valueToString($value)
2080
    {
2081 715
        if (null === $value) {
2082 20
            return 'null';
2083
        }
2084
2085 697
        if (true === $value) {
2086 15
            return 'true';
2087
        }
2088
2089 687
        if (false === $value) {
2090 25
            return 'false';
2091
        }
2092
2093 662
        if (\is_array($value)) {
2094 21
            return 'array';
2095
        }
2096
2097 641
        if (\is_object($value)) {
2098 3
            if (\method_exists($value, '__toString')) {
2099 1
                return \get_class($value).': '.self::valueToString($value->__toString());
2100
            }
2101
2102 2
            if ($value instanceof \DateTime || $value instanceof \DateTimeImmutable) {
0 ignored issues
show
The class DateTimeImmutable does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
2103 1
                return \get_class($value).': '.self::valueToString($value->format('c'));
2104
            }
2105
2106 1
            return \get_class($value);
2107
        }
2108
2109 640
        if (\is_resource($value)) {
2110 1
            return 'resource';
2111
        }
2112
2113 640
        if (\is_string($value)) {
2114 538
            return '"'.$value.'"';
2115
        }
2116
2117 110
        return (string) $value;
2118
    }
2119
2120
    /**
2121
     * @param mixed $value
2122
     *
2123
     * @return string
2124
     */
2125 251
    protected static function typeToString($value)
2126
    {
2127 251
        return \is_object($value) ? \get_class($value) : \gettype($value);
2128
    }
2129
2130 168
    protected static function strlen($value)
2131
    {
2132 168
        if (!\function_exists('mb_detect_encoding')) {
2133
            return \strlen($value);
2134
        }
2135
2136 168
        if (false === $encoding = \mb_detect_encoding($value)) {
2137
            return \strlen($value);
2138
        }
2139
2140 168
        return \mb_strlen($value, $encoding);
2141
    }
2142
2143
    /**
2144
     * @param string $message
2145
     *
2146
     * @throws InvalidArgumentException
2147
     *
2148
     * @psalm-pure this method is not supposed to perform side-effects
2149
     */
2150 1029
    protected static function reportInvalidArgument($message)
2151
    {
2152 1029
        throw new InvalidArgumentException($message);
2153
    }
2154
2155
    private function __construct()
2156
    {
2157
    }
2158
}
2159