Passed
Push — develop ( 30cf64...589229 )
by Guillaume
06:18 queued 04:10
created

Assert   F

Complexity

Total Complexity 242

Size/Duplication

Total Lines 2662
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 622
dl 0
loc 2662
rs 1.978
c 0
b 0
f 0
wmc 242

How to fix   Complexity   

Complex Class

Complex classes like Assert often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Assert, and based on these observations, apply Extract Interface, too.

1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of PHPUnit.
4
 *
5
 * (c) Sebastian Bergmann <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace PHPUnit\Framework;
11
12
use PHPUnit\Framework\Constraint\ArrayHasKey;
13
use PHPUnit\Framework\Constraint\Callback;
14
use PHPUnit\Framework\Constraint\ClassHasAttribute;
15
use PHPUnit\Framework\Constraint\ClassHasStaticAttribute;
16
use PHPUnit\Framework\Constraint\Constraint;
17
use PHPUnit\Framework\Constraint\Count;
18
use PHPUnit\Framework\Constraint\DirectoryExists;
19
use PHPUnit\Framework\Constraint\FileExists;
20
use PHPUnit\Framework\Constraint\GreaterThan;
21
use PHPUnit\Framework\Constraint\IsAnything;
22
use PHPUnit\Framework\Constraint\IsEmpty;
23
use PHPUnit\Framework\Constraint\IsEqual;
24
use PHPUnit\Framework\Constraint\IsEqualCanonicalizing;
25
use PHPUnit\Framework\Constraint\IsEqualIgnoringCase;
26
use PHPUnit\Framework\Constraint\IsEqualWithDelta;
27
use PHPUnit\Framework\Constraint\IsFalse;
28
use PHPUnit\Framework\Constraint\IsFinite;
29
use PHPUnit\Framework\Constraint\IsIdentical;
30
use PHPUnit\Framework\Constraint\IsInfinite;
31
use PHPUnit\Framework\Constraint\IsInstanceOf;
32
use PHPUnit\Framework\Constraint\IsJson;
33
use PHPUnit\Framework\Constraint\IsNan;
34
use PHPUnit\Framework\Constraint\IsNull;
35
use PHPUnit\Framework\Constraint\IsReadable;
36
use PHPUnit\Framework\Constraint\IsTrue;
37
use PHPUnit\Framework\Constraint\IsType;
38
use PHPUnit\Framework\Constraint\IsWritable;
39
use PHPUnit\Framework\Constraint\JsonMatches;
40
use PHPUnit\Framework\Constraint\LessThan;
41
use PHPUnit\Framework\Constraint\LogicalAnd;
42
use PHPUnit\Framework\Constraint\LogicalNot;
43
use PHPUnit\Framework\Constraint\LogicalOr;
44
use PHPUnit\Framework\Constraint\LogicalXor;
45
use PHPUnit\Framework\Constraint\ObjectHasAttribute;
46
use PHPUnit\Framework\Constraint\RegularExpression;
47
use PHPUnit\Framework\Constraint\SameSize;
48
use PHPUnit\Framework\Constraint\StringContains;
49
use PHPUnit\Framework\Constraint\StringEndsWith;
50
use PHPUnit\Framework\Constraint\StringMatchesFormatDescription;
51
use PHPUnit\Framework\Constraint\StringStartsWith;
52
use PHPUnit\Framework\Constraint\TraversableContainsEqual;
53
use PHPUnit\Framework\Constraint\TraversableContainsIdentical;
54
use PHPUnit\Framework\Constraint\TraversableContainsOnly;
55
use PHPUnit\Util\Type;
56
use PHPUnit\Util\Xml;
57
58
/**
59
 * A set of assertion methods.
60
 */
61
abstract class Assert
62
{
63
    /**
64
     * @var int
65
     */
66
    private static $count = 0;
67
68
    /**
69
     * Asserts that an array has a specified key.
70
     *
71
     * @param int|string         $key
72
     * @param array|\ArrayAccess $array
73
     *
74
     * @throws ExpectationFailedException
75
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
76
     * @throws Exception
77
     */
78
    public static function assertArrayHasKey($key, $array, string $message = ''): void
79
    {
80
        if (!(\is_int($key) || \is_string($key))) {
81
            throw InvalidArgumentException::create(
82
                1,
83
                'integer or string'
84
            );
85
        }
86
87
        if (!(\is_array($array) || $array instanceof \ArrayAccess)) {
88
            throw InvalidArgumentException::create(
89
                2,
90
                'array or ArrayAccess'
91
            );
92
        }
93
94
        $constraint = new ArrayHasKey($key);
95
96
        static::assertThat($array, $constraint, $message);
97
    }
98
99
    /**
100
     * Asserts that an array does not have a specified key.
101
     *
102
     * @param int|string         $key
103
     * @param array|\ArrayAccess $array
104
     *
105
     * @throws ExpectationFailedException
106
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
107
     * @throws Exception
108
     */
109
    public static function assertArrayNotHasKey($key, $array, string $message = ''): void
110
    {
111
        if (!(\is_int($key) || \is_string($key))) {
112
            throw InvalidArgumentException::create(
113
                1,
114
                'integer or string'
115
            );
116
        }
117
118
        if (!(\is_array($array) || $array instanceof \ArrayAccess)) {
119
            throw InvalidArgumentException::create(
120
                2,
121
                'array or ArrayAccess'
122
            );
123
        }
124
125
        $constraint = new LogicalNot(
126
            new ArrayHasKey($key)
127
        );
128
129
        static::assertThat($array, $constraint, $message);
130
    }
131
132
    /**
133
     * Asserts that a haystack contains a needle.
134
     *
135
     * @throws ExpectationFailedException
136
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
137
     * @throws Exception
138
     */
139
    public static function assertContains($needle, iterable $haystack, string $message = ''): void
140
    {
141
        $constraint = new TraversableContainsIdentical($needle);
142
143
        static::assertThat($haystack, $constraint, $message);
144
    }
145
146
    public static function assertContainsEquals($needle, iterable $haystack, string $message = ''): void
147
    {
148
        $constraint = new TraversableContainsEqual($needle);
149
150
        static::assertThat($haystack, $constraint, $message);
151
    }
152
153
    /**
154
     * Asserts that a haystack does not contain a needle.
155
     *
156
     * @throws ExpectationFailedException
157
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
158
     * @throws Exception
159
     */
160
    public static function assertNotContains($needle, iterable $haystack, string $message = ''): void
161
    {
162
        $constraint = new LogicalNot(
163
            new TraversableContainsIdentical($needle)
164
        );
165
166
        static::assertThat($haystack, $constraint, $message);
167
    }
168
169
    public static function assertNotContainsEquals($needle, iterable $haystack, string $message = ''): void
170
    {
171
        $constraint = new LogicalNot(new TraversableContainsEqual($needle));
172
173
        static::assertThat($haystack, $constraint, $message);
174
    }
175
176
    /**
177
     * Asserts that a haystack contains only values of a given type.
178
     *
179
     * @throws ExpectationFailedException
180
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
181
     */
182
    public static function assertContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void
183
    {
184
        if ($isNativeType === null) {
185
            $isNativeType = Type::isType($type);
186
        }
187
188
        static::assertThat(
189
            $haystack,
190
            new TraversableContainsOnly(
191
                $type,
192
                $isNativeType
193
            ),
194
            $message
195
        );
196
    }
197
198
    /**
199
     * Asserts that a haystack contains only instances of a given class name.
200
     *
201
     * @throws ExpectationFailedException
202
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
203
     */
204
    public static function assertContainsOnlyInstancesOf(string $className, iterable $haystack, string $message = ''): void
205
    {
206
        static::assertThat(
207
            $haystack,
208
            new TraversableContainsOnly(
209
                $className,
210
                false
211
            ),
212
            $message
213
        );
214
    }
215
216
    /**
217
     * Asserts that a haystack does not contain only values of a given type.
218
     *
219
     * @throws ExpectationFailedException
220
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
221
     */
222
    public static function assertNotContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void
223
    {
224
        if ($isNativeType === null) {
225
            $isNativeType = Type::isType($type);
226
        }
227
228
        static::assertThat(
229
            $haystack,
230
            new LogicalNot(
231
                new TraversableContainsOnly(
232
                    $type,
233
                    $isNativeType
234
                )
235
            ),
236
            $message
237
        );
238
    }
239
240
    /**
241
     * Asserts the number of elements of an array, Countable or Traversable.
242
     *
243
     * @param \Countable|iterable $haystack
244
     *
245
     * @throws ExpectationFailedException
246
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
247
     * @throws Exception
248
     */
249
    public static function assertCount(int $expectedCount, $haystack, string $message = ''): void
250
    {
251
        if (!$haystack instanceof \Countable && !\is_iterable($haystack)) {
252
            throw InvalidArgumentException::create(2, 'countable or iterable');
253
        }
254
255
        static::assertThat(
256
            $haystack,
257
            new Count($expectedCount),
258
            $message
259
        );
260
    }
261
262
    /**
263
     * Asserts the number of elements of an array, Countable or Traversable.
264
     *
265
     * @param \Countable|iterable $haystack
266
     *
267
     * @throws ExpectationFailedException
268
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
269
     * @throws Exception
270
     */
271
    public static function assertNotCount(int $expectedCount, $haystack, string $message = ''): void
272
    {
273
        if (!$haystack instanceof \Countable && !\is_iterable($haystack)) {
274
            throw InvalidArgumentException::create(2, 'countable or iterable');
275
        }
276
277
        $constraint = new LogicalNot(
278
            new Count($expectedCount)
279
        );
280
281
        static::assertThat($haystack, $constraint, $message);
282
    }
283
284
    /**
285
     * Asserts that two variables are equal.
286
     *
287
     * @throws ExpectationFailedException
288
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
289
     */
290
    public static function assertEquals($expected, $actual, string $message = ''): void
291
    {
292
        $constraint = new IsEqual($expected);
293
294
        static::assertThat($actual, $constraint, $message);
295
    }
296
297
    /**
298
     * Asserts that two variables are equal (canonicalizing).
299
     *
300
     * @throws ExpectationFailedException
301
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
302
     */
303
    public static function assertEqualsCanonicalizing($expected, $actual, string $message = ''): void
304
    {
305
        $constraint = new IsEqualCanonicalizing($expected);
306
307
        static::assertThat($actual, $constraint, $message);
308
    }
309
310
    /**
311
     * Asserts that two variables are equal (ignoring case).
312
     *
313
     * @throws ExpectationFailedException
314
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
315
     */
316
    public static function assertEqualsIgnoringCase($expected, $actual, string $message = ''): void
317
    {
318
        $constraint = new IsEqualIgnoringCase($expected);
319
320
        static::assertThat($actual, $constraint, $message);
321
    }
322
323
    /**
324
     * Asserts that two variables are equal (with delta).
325
     *
326
     * @throws ExpectationFailedException
327
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
328
     */
329
    public static function assertEqualsWithDelta($expected, $actual, float $delta, string $message = ''): void
330
    {
331
        $constraint = new IsEqualWithDelta(
332
            $expected,
333
            $delta
334
        );
335
336
        static::assertThat($actual, $constraint, $message);
337
    }
338
339
    /**
340
     * Asserts that two variables are not equal.
341
     *
342
     * @throws ExpectationFailedException
343
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
344
     */
345
    public static function assertNotEquals($expected, $actual, string $message = ''): void
346
    {
347
        $constraint = new LogicalNot(
348
            new IsEqual($expected)
349
        );
350
351
        static::assertThat($actual, $constraint, $message);
352
    }
353
354
    /**
355
     * Asserts that two variables are not equal (canonicalizing).
356
     *
357
     * @throws ExpectationFailedException
358
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
359
     */
360
    public static function assertNotEqualsCanonicalizing($expected, $actual, string $message = ''): void
361
    {
362
        $constraint = new LogicalNot(
363
            new IsEqualCanonicalizing($expected)
364
        );
365
366
        static::assertThat($actual, $constraint, $message);
367
    }
368
369
    /**
370
     * Asserts that two variables are not equal (ignoring case).
371
     *
372
     * @throws ExpectationFailedException
373
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
374
     */
375
    public static function assertNotEqualsIgnoringCase($expected, $actual, string $message = ''): void
376
    {
377
        $constraint = new LogicalNot(
378
            new IsEqualIgnoringCase($expected)
379
        );
380
381
        static::assertThat($actual, $constraint, $message);
382
    }
383
384
    /**
385
     * Asserts that two variables are not equal (with delta).
386
     *
387
     * @throws ExpectationFailedException
388
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
389
     */
390
    public static function assertNotEqualsWithDelta($expected, $actual, float $delta, string $message = ''): void
391
    {
392
        $constraint = new LogicalNot(
393
            new IsEqualWithDelta(
394
                $expected,
395
                $delta
396
            )
397
        );
398
399
        static::assertThat($actual, $constraint, $message);
400
    }
401
402
    /**
403
     * Asserts that a variable is empty.
404
     *
405
     * @throws ExpectationFailedException
406
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
407
     *
408
     * @psalm-assert empty $actual
409
     */
410
    public static function assertEmpty($actual, string $message = ''): void
411
    {
412
        static::assertThat($actual, static::isEmpty(), $message);
413
    }
414
415
    /**
416
     * Asserts that a variable is not empty.
417
     *
418
     * @throws ExpectationFailedException
419
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
420
     *
421
     * @psalm-assert !empty $actual
422
     */
423
    public static function assertNotEmpty($actual, string $message = ''): void
424
    {
425
        static::assertThat($actual, static::logicalNot(static::isEmpty()), $message);
426
    }
427
428
    /**
429
     * Asserts that a value is greater than another value.
430
     *
431
     * @throws ExpectationFailedException
432
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
433
     */
434
    public static function assertGreaterThan($expected, $actual, string $message = ''): void
435
    {
436
        static::assertThat($actual, static::greaterThan($expected), $message);
437
    }
438
439
    /**
440
     * Asserts that a value is greater than or equal to another value.
441
     *
442
     * @throws ExpectationFailedException
443
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
444
     */
445
    public static function assertGreaterThanOrEqual($expected, $actual, string $message = ''): void
446
    {
447
        static::assertThat(
448
            $actual,
449
            static::greaterThanOrEqual($expected),
450
            $message
451
        );
452
    }
453
454
    /**
455
     * Asserts that a value is smaller than another value.
456
     *
457
     * @throws ExpectationFailedException
458
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
459
     */
460
    public static function assertLessThan($expected, $actual, string $message = ''): void
461
    {
462
        static::assertThat($actual, static::lessThan($expected), $message);
463
    }
464
465
    /**
466
     * Asserts that a value is smaller than or equal to another value.
467
     *
468
     * @throws ExpectationFailedException
469
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
470
     */
471
    public static function assertLessThanOrEqual($expected, $actual, string $message = ''): void
472
    {
473
        static::assertThat($actual, static::lessThanOrEqual($expected), $message);
474
    }
475
476
    /**
477
     * Asserts that the contents of one file is equal to the contents of another
478
     * file.
479
     *
480
     * @throws ExpectationFailedException
481
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
482
     */
483
    public static function assertFileEquals(string $expected, string $actual, string $message = ''): void
484
    {
485
        static::assertFileExists($expected, $message);
486
        static::assertFileExists($actual, $message);
487
488
        $constraint = new IsEqual(\file_get_contents($expected));
489
490
        static::assertThat(\file_get_contents($actual), $constraint, $message);
491
    }
492
493
    /**
494
     * Asserts that the contents of one file is equal to the contents of another
495
     * file (canonicalizing).
496
     *
497
     * @throws ExpectationFailedException
498
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
499
     */
500
    public static function assertFileEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void
501
    {
502
        static::assertFileExists($expected, $message);
503
        static::assertFileExists($actual, $message);
504
505
        $constraint = new IsEqualCanonicalizing(
506
            \file_get_contents($expected)
507
        );
508
509
        static::assertThat(\file_get_contents($actual), $constraint, $message);
510
    }
511
512
    /**
513
     * Asserts that the contents of one file is equal to the contents of another
514
     * file (ignoring case).
515
     *
516
     * @throws ExpectationFailedException
517
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
518
     */
519
    public static function assertFileEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void
520
    {
521
        static::assertFileExists($expected, $message);
522
        static::assertFileExists($actual, $message);
523
524
        $constraint = new IsEqualIgnoringCase(\file_get_contents($expected));
525
526
        static::assertThat(\file_get_contents($actual), $constraint, $message);
527
    }
528
529
    /**
530
     * Asserts that the contents of one file is not equal to the contents of
531
     * another file.
532
     *
533
     * @throws ExpectationFailedException
534
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
535
     */
536
    public static function assertFileNotEquals(string $expected, string $actual, string $message = ''): void
537
    {
538
        static::assertFileExists($expected, $message);
539
        static::assertFileExists($actual, $message);
540
541
        $constraint = new LogicalNot(
542
            new IsEqual(\file_get_contents($expected))
543
        );
544
545
        static::assertThat(\file_get_contents($actual), $constraint, $message);
546
    }
547
548
    /**
549
     * Asserts that the contents of one file is not equal to the contents of another
550
     * file (canonicalizing).
551
     *
552
     * @throws ExpectationFailedException
553
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
554
     */
555
    public static function assertFileNotEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void
556
    {
557
        static::assertFileExists($expected, $message);
558
        static::assertFileExists($actual, $message);
559
560
        $constraint = new LogicalNot(
561
            new IsEqualCanonicalizing(\file_get_contents($expected))
562
        );
563
564
        static::assertThat(\file_get_contents($actual), $constraint, $message);
565
    }
566
567
    /**
568
     * Asserts that the contents of one file is not equal to the contents of another
569
     * file (ignoring case).
570
     *
571
     * @throws ExpectationFailedException
572
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
573
     */
574
    public static function assertFileNotEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void
575
    {
576
        static::assertFileExists($expected, $message);
577
        static::assertFileExists($actual, $message);
578
579
        $constraint = new LogicalNot(
580
            new IsEqualIgnoringCase(\file_get_contents($expected))
581
        );
582
583
        static::assertThat(\file_get_contents($actual), $constraint, $message);
584
    }
585
586
    /**
587
     * Asserts that the contents of a string is equal
588
     * to the contents of a file.
589
     *
590
     * @throws ExpectationFailedException
591
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
592
     */
593
    public static function assertStringEqualsFile(string $expectedFile, string $actualString, string $message = ''): void
594
    {
595
        static::assertFileExists($expectedFile, $message);
596
597
        $constraint = new IsEqual(\file_get_contents($expectedFile));
598
599
        static::assertThat($actualString, $constraint, $message);
600
    }
601
602
    /**
603
     * Asserts that the contents of a string is equal
604
     * to the contents of a file (canonicalizing).
605
     *
606
     * @throws ExpectationFailedException
607
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
608
     */
609
    public static function assertStringEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void
610
    {
611
        static::assertFileExists($expectedFile, $message);
612
613
        $constraint = new IsEqualCanonicalizing(\file_get_contents($expectedFile));
614
615
        static::assertThat($actualString, $constraint, $message);
616
    }
617
618
    /**
619
     * Asserts that the contents of a string is equal
620
     * to the contents of a file (ignoring case).
621
     *
622
     * @throws ExpectationFailedException
623
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
624
     */
625
    public static function assertStringEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void
626
    {
627
        static::assertFileExists($expectedFile, $message);
628
629
        $constraint = new IsEqualIgnoringCase(\file_get_contents($expectedFile));
630
631
        static::assertThat($actualString, $constraint, $message);
632
    }
633
634
    /**
635
     * Asserts that the contents of a string is not equal
636
     * to the contents of a file.
637
     *
638
     * @throws ExpectationFailedException
639
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
640
     */
641
    public static function assertStringNotEqualsFile(string $expectedFile, string $actualString, string $message = ''): void
642
    {
643
        static::assertFileExists($expectedFile, $message);
644
645
        $constraint = new LogicalNot(
646
            new IsEqual(\file_get_contents($expectedFile))
647
        );
648
649
        static::assertThat($actualString, $constraint, $message);
650
    }
651
652
    /**
653
     * Asserts that the contents of a string is not equal
654
     * to the contents of a file (canonicalizing).
655
     *
656
     * @throws ExpectationFailedException
657
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
658
     */
659
    public static function assertStringNotEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void
660
    {
661
        static::assertFileExists($expectedFile, $message);
662
663
        $constraint = new LogicalNot(
664
            new IsEqualCanonicalizing(\file_get_contents($expectedFile))
665
        );
666
667
        static::assertThat($actualString, $constraint, $message);
668
    }
669
670
    /**
671
     * Asserts that the contents of a string is not equal
672
     * to the contents of a file (ignoring case).
673
     *
674
     * @throws ExpectationFailedException
675
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
676
     */
677
    public static function assertStringNotEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void
678
    {
679
        static::assertFileExists($expectedFile, $message);
680
681
        $constraint = new LogicalNot(
682
            new IsEqualIgnoringCase(\file_get_contents($expectedFile))
683
        );
684
685
        static::assertThat($actualString, $constraint, $message);
686
    }
687
688
    /**
689
     * Asserts that a file/dir is readable.
690
     *
691
     * @throws ExpectationFailedException
692
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
693
     */
694
    public static function assertIsReadable(string $filename, string $message = ''): void
695
    {
696
        static::assertThat($filename, new IsReadable, $message);
697
    }
698
699
    /**
700
     * Asserts that a file/dir exists and is not readable.
701
     *
702
     * @throws ExpectationFailedException
703
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
704
     */
705
    public static function assertIsNotReadable(string $filename, string $message = ''): void
706
    {
707
        static::assertThat($filename, new LogicalNot(new IsReadable), $message);
708
    }
709
710
    /**
711
     * Asserts that a file/dir exists and is not readable.
712
     *
713
     * @throws ExpectationFailedException
714
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
715
     *
716
     * @codeCoverageIgnore
717
     *
718
     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4062
719
     */
720
    public static function assertNotIsReadable(string $filename, string $message = ''): void
721
    {
722
        self::createWarning('assertNotIsReadable() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertIsNotReadable() instead.');
723
724
        static::assertThat($filename, new LogicalNot(new IsReadable), $message);
725
    }
726
727
    /**
728
     * Asserts that a file/dir exists and is writable.
729
     *
730
     * @throws ExpectationFailedException
731
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
732
     */
733
    public static function assertIsWritable(string $filename, string $message = ''): void
734
    {
735
        static::assertThat($filename, new IsWritable, $message);
736
    }
737
738
    /**
739
     * Asserts that a file/dir exists and is not writable.
740
     *
741
     * @throws ExpectationFailedException
742
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
743
     */
744
    public static function assertIsNotWritable(string $filename, string $message = ''): void
745
    {
746
        static::assertThat($filename, new LogicalNot(new IsWritable), $message);
747
    }
748
749
    /**
750
     * Asserts that a file/dir exists and is not writable.
751
     *
752
     * @throws ExpectationFailedException
753
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
754
     *
755
     * @codeCoverageIgnore
756
     *
757
     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4065
758
     */
759
    public static function assertNotIsWritable(string $filename, string $message = ''): void
760
    {
761
        self::createWarning('assertNotIsWritable() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertIsNotWritable() instead.');
762
763
        static::assertThat($filename, new LogicalNot(new IsWritable), $message);
764
    }
765
766
    /**
767
     * Asserts that a directory exists.
768
     *
769
     * @throws ExpectationFailedException
770
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
771
     */
772
    public static function assertDirectoryExists(string $directory, string $message = ''): void
773
    {
774
        static::assertThat($directory, new DirectoryExists, $message);
775
    }
776
777
    /**
778
     * Asserts that a directory does not exist.
779
     *
780
     * @throws ExpectationFailedException
781
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
782
     */
783
    public static function assertDirectoryDoesNotExist(string $directory, string $message = ''): void
784
    {
785
        static::assertThat($directory, new LogicalNot(new DirectoryExists), $message);
786
    }
787
788
    /**
789
     * Asserts that a directory does not exist.
790
     *
791
     * @throws ExpectationFailedException
792
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
793
     *
794
     * @codeCoverageIgnore
795
     *
796
     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4068
797
     */
798
    public static function assertDirectoryNotExists(string $directory, string $message = ''): void
799
    {
800
        self::createWarning('assertDirectoryNotExists() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertDirectoryDoesNotExist() instead.');
801
802
        static::assertThat($directory, new LogicalNot(new DirectoryExists), $message);
803
    }
804
805
    /**
806
     * Asserts that a directory exists and is readable.
807
     *
808
     * @throws ExpectationFailedException
809
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
810
     */
811
    public static function assertDirectoryIsReadable(string $directory, string $message = ''): void
812
    {
813
        self::assertDirectoryExists($directory, $message);
814
        self::assertIsReadable($directory, $message);
815
    }
816
817
    /**
818
     * Asserts that a directory exists and is not readable.
819
     *
820
     * @throws ExpectationFailedException
821
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
822
     */
823
    public static function assertDirectoryIsNotReadable(string $directory, string $message = ''): void
824
    {
825
        self::assertDirectoryExists($directory, $message);
826
        self::assertIsNotReadable($directory, $message);
827
    }
828
829
    /**
830
     * Asserts that a directory exists and is not readable.
831
     *
832
     * @throws ExpectationFailedException
833
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
834
     *
835
     * @codeCoverageIgnore
836
     *
837
     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4071
838
     */
839
    public static function assertDirectoryNotIsReadable(string $directory, string $message = ''): void
840
    {
841
        self::createWarning('assertDirectoryNotIsReadable() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertDirectoryIsNotReadable() instead.');
842
843
        self::assertDirectoryExists($directory, $message);
844
        self::assertIsNotReadable($directory, $message);
845
    }
846
847
    /**
848
     * Asserts that a directory exists and is writable.
849
     *
850
     * @throws ExpectationFailedException
851
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
852
     */
853
    public static function assertDirectoryIsWritable(string $directory, string $message = ''): void
854
    {
855
        self::assertDirectoryExists($directory, $message);
856
        self::assertIsWritable($directory, $message);
857
    }
858
859
    /**
860
     * Asserts that a directory exists and is not writable.
861
     *
862
     * @throws ExpectationFailedException
863
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
864
     */
865
    public static function assertDirectoryIsNotWritable(string $directory, string $message = ''): void
866
    {
867
        self::assertDirectoryExists($directory, $message);
868
        self::assertIsNotWritable($directory, $message);
869
    }
870
871
    /**
872
     * Asserts that a directory exists and is not writable.
873
     *
874
     * @throws ExpectationFailedException
875
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
876
     *
877
     * @codeCoverageIgnore
878
     *
879
     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4074
880
     */
881
    public static function assertDirectoryNotIsWritable(string $directory, string $message = ''): void
882
    {
883
        self::createWarning('assertDirectoryNotIsWritable() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertDirectoryIsNotWritable() instead.');
884
885
        self::assertDirectoryExists($directory, $message);
886
        self::assertIsNotWritable($directory, $message);
887
    }
888
889
    /**
890
     * Asserts that a file exists.
891
     *
892
     * @throws ExpectationFailedException
893
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
894
     */
895
    public static function assertFileExists(string $filename, string $message = ''): void
896
    {
897
        static::assertThat($filename, new FileExists, $message);
898
    }
899
900
    /**
901
     * Asserts that a file does not exist.
902
     *
903
     * @throws ExpectationFailedException
904
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
905
     */
906
    public static function assertFileDoesNotExist(string $filename, string $message = ''): void
907
    {
908
        static::assertThat($filename, new LogicalNot(new FileExists), $message);
909
    }
910
911
    /**
912
     * Asserts that a file does not exist.
913
     *
914
     * @throws ExpectationFailedException
915
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
916
     *
917
     * @codeCoverageIgnore
918
     *
919
     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4077
920
     */
921
    public static function assertFileNotExists(string $filename, string $message = ''): void
922
    {
923
        self::createWarning('assertFileNotExists() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertFileDoesNotExist() instead.');
924
925
        static::assertThat($filename, new LogicalNot(new FileExists), $message);
926
    }
927
928
    /**
929
     * Asserts that a file exists and is readable.
930
     *
931
     * @throws ExpectationFailedException
932
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
933
     */
934
    public static function assertFileIsReadable(string $file, string $message = ''): void
935
    {
936
        self::assertFileExists($file, $message);
937
        self::assertIsReadable($file, $message);
938
    }
939
940
    /**
941
     * Asserts that a file exists and is not readable.
942
     *
943
     * @throws ExpectationFailedException
944
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
945
     */
946
    public static function assertFileIsNotReadable(string $file, string $message = ''): void
947
    {
948
        self::assertFileExists($file, $message);
949
        self::assertIsNotReadable($file, $message);
950
    }
951
952
    /**
953
     * Asserts that a file exists and is not readable.
954
     *
955
     * @throws ExpectationFailedException
956
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
957
     *
958
     * @codeCoverageIgnore
959
     *
960
     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4080
961
     */
962
    public static function assertFileNotIsReadable(string $file, string $message = ''): void
963
    {
964
        self::createWarning('assertFileNotIsReadable() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertFileIsNotReadable() instead.');
965
966
        self::assertFileExists($file, $message);
967
        self::assertIsNotReadable($file, $message);
968
    }
969
970
    /**
971
     * Asserts that a file exists and is writable.
972
     *
973
     * @throws ExpectationFailedException
974
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
975
     */
976
    public static function assertFileIsWritable(string $file, string $message = ''): void
977
    {
978
        self::assertFileExists($file, $message);
979
        self::assertIsWritable($file, $message);
980
    }
981
982
    /**
983
     * Asserts that a file exists and is not writable.
984
     *
985
     * @throws ExpectationFailedException
986
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
987
     */
988
    public static function assertFileIsNotWritable(string $file, string $message = ''): void
989
    {
990
        self::assertFileExists($file, $message);
991
        self::assertIsNotWritable($file, $message);
992
    }
993
994
    /**
995
     * Asserts that a file exists and is not writable.
996
     *
997
     * @throws ExpectationFailedException
998
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
999
     *
1000
     * @codeCoverageIgnore
1001
     *
1002
     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4083
1003
     */
1004
    public static function assertFileNotIsWritable(string $file, string $message = ''): void
1005
    {
1006
        self::createWarning('assertFileNotIsWritable() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertFileIsNotWritable() instead.');
1007
1008
        self::assertFileExists($file, $message);
1009
        self::assertIsNotWritable($file, $message);
1010
    }
1011
1012
    /**
1013
     * Asserts that a condition is true.
1014
     *
1015
     * @throws ExpectationFailedException
1016
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1017
     *
1018
     * @psalm-assert true $condition
1019
     */
1020
    public static function assertTrue($condition, string $message = ''): void
1021
    {
1022
        static::assertThat($condition, static::isTrue(), $message);
1023
    }
1024
1025
    /**
1026
     * Asserts that a condition is not true.
1027
     *
1028
     * @throws ExpectationFailedException
1029
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1030
     *
1031
     * @psalm-assert !true $condition
1032
     */
1033
    public static function assertNotTrue($condition, string $message = ''): void
1034
    {
1035
        static::assertThat($condition, static::logicalNot(static::isTrue()), $message);
1036
    }
1037
1038
    /**
1039
     * Asserts that a condition is false.
1040
     *
1041
     * @throws ExpectationFailedException
1042
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1043
     *
1044
     * @psalm-assert false $condition
1045
     */
1046
    public static function assertFalse($condition, string $message = ''): void
1047
    {
1048
        static::assertThat($condition, static::isFalse(), $message);
1049
    }
1050
1051
    /**
1052
     * Asserts that a condition is not false.
1053
     *
1054
     * @throws ExpectationFailedException
1055
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1056
     *
1057
     * @psalm-assert !false $condition
1058
     */
1059
    public static function assertNotFalse($condition, string $message = ''): void
1060
    {
1061
        static::assertThat($condition, static::logicalNot(static::isFalse()), $message);
1062
    }
1063
1064
    /**
1065
     * Asserts that a variable is null.
1066
     *
1067
     * @throws ExpectationFailedException
1068
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1069
     *
1070
     * @psalm-assert null $actual
1071
     */
1072
    public static function assertNull($actual, string $message = ''): void
1073
    {
1074
        static::assertThat($actual, static::isNull(), $message);
1075
    }
1076
1077
    /**
1078
     * Asserts that a variable is not null.
1079
     *
1080
     * @throws ExpectationFailedException
1081
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1082
     *
1083
     * @psalm-assert !null $actual
1084
     */
1085
    public static function assertNotNull($actual, string $message = ''): void
1086
    {
1087
        static::assertThat($actual, static::logicalNot(static::isNull()), $message);
1088
    }
1089
1090
    /**
1091
     * Asserts that a variable is finite.
1092
     *
1093
     * @throws ExpectationFailedException
1094
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1095
     */
1096
    public static function assertFinite($actual, string $message = ''): void
1097
    {
1098
        static::assertThat($actual, static::isFinite(), $message);
1099
    }
1100
1101
    /**
1102
     * Asserts that a variable is infinite.
1103
     *
1104
     * @throws ExpectationFailedException
1105
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1106
     */
1107
    public static function assertInfinite($actual, string $message = ''): void
1108
    {
1109
        static::assertThat($actual, static::isInfinite(), $message);
1110
    }
1111
1112
    /**
1113
     * Asserts that a variable is nan.
1114
     *
1115
     * @throws ExpectationFailedException
1116
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1117
     */
1118
    public static function assertNan($actual, string $message = ''): void
1119
    {
1120
        static::assertThat($actual, static::isNan(), $message);
1121
    }
1122
1123
    /**
1124
     * Asserts that a class has a specified attribute.
1125
     *
1126
     * @throws ExpectationFailedException
1127
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1128
     * @throws Exception
1129
     */
1130
    public static function assertClassHasAttribute(string $attributeName, string $className, string $message = ''): void
1131
    {
1132
        if (!self::isValidClassAttributeName($attributeName)) {
1133
            throw InvalidArgumentException::create(1, 'valid attribute name');
1134
        }
1135
1136
        if (!\class_exists($className)) {
1137
            throw InvalidArgumentException::create(2, 'class name');
1138
        }
1139
1140
        static::assertThat($className, new ClassHasAttribute($attributeName), $message);
1141
    }
1142
1143
    /**
1144
     * Asserts that a class does not have a specified attribute.
1145
     *
1146
     * @throws ExpectationFailedException
1147
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1148
     * @throws Exception
1149
     */
1150
    public static function assertClassNotHasAttribute(string $attributeName, string $className, string $message = ''): void
1151
    {
1152
        if (!self::isValidClassAttributeName($attributeName)) {
1153
            throw InvalidArgumentException::create(1, 'valid attribute name');
1154
        }
1155
1156
        if (!\class_exists($className)) {
1157
            throw InvalidArgumentException::create(2, 'class name');
1158
        }
1159
1160
        static::assertThat(
1161
            $className,
1162
            new LogicalNot(
1163
                new ClassHasAttribute($attributeName)
1164
            ),
1165
            $message
1166
        );
1167
    }
1168
1169
    /**
1170
     * Asserts that a class has a specified static attribute.
1171
     *
1172
     * @throws ExpectationFailedException
1173
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1174
     * @throws Exception
1175
     */
1176
    public static function assertClassHasStaticAttribute(string $attributeName, string $className, string $message = ''): void
1177
    {
1178
        if (!self::isValidClassAttributeName($attributeName)) {
1179
            throw InvalidArgumentException::create(1, 'valid attribute name');
1180
        }
1181
1182
        if (!\class_exists($className)) {
1183
            throw InvalidArgumentException::create(2, 'class name');
1184
        }
1185
1186
        static::assertThat(
1187
            $className,
1188
            new ClassHasStaticAttribute($attributeName),
1189
            $message
1190
        );
1191
    }
1192
1193
    /**
1194
     * Asserts that a class does not have a specified static attribute.
1195
     *
1196
     * @throws ExpectationFailedException
1197
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1198
     * @throws Exception
1199
     */
1200
    public static function assertClassNotHasStaticAttribute(string $attributeName, string $className, string $message = ''): void
1201
    {
1202
        if (!self::isValidClassAttributeName($attributeName)) {
1203
            throw InvalidArgumentException::create(1, 'valid attribute name');
1204
        }
1205
1206
        if (!\class_exists($className)) {
1207
            throw InvalidArgumentException::create(2, 'class name');
1208
        }
1209
1210
        static::assertThat(
1211
            $className,
1212
            new LogicalNot(
1213
                new ClassHasStaticAttribute($attributeName)
1214
            ),
1215
            $message
1216
        );
1217
    }
1218
1219
    /**
1220
     * Asserts that an object has a specified attribute.
1221
     *
1222
     * @param object $object
1223
     *
1224
     * @throws ExpectationFailedException
1225
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1226
     * @throws Exception
1227
     */
1228
    public static function assertObjectHasAttribute(string $attributeName, $object, string $message = ''): void
1229
    {
1230
        if (!self::isValidObjectAttributeName($attributeName)) {
1231
            throw InvalidArgumentException::create(1, 'valid attribute name');
1232
        }
1233
1234
        if (!\is_object($object)) {
1235
            throw InvalidArgumentException::create(2, 'object');
1236
        }
1237
1238
        static::assertThat(
1239
            $object,
1240
            new ObjectHasAttribute($attributeName),
1241
            $message
1242
        );
1243
    }
1244
1245
    /**
1246
     * Asserts that an object does not have a specified attribute.
1247
     *
1248
     * @param object $object
1249
     *
1250
     * @throws ExpectationFailedException
1251
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1252
     * @throws Exception
1253
     */
1254
    public static function assertObjectNotHasAttribute(string $attributeName, $object, string $message = ''): void
1255
    {
1256
        if (!self::isValidObjectAttributeName($attributeName)) {
1257
            throw InvalidArgumentException::create(1, 'valid attribute name');
1258
        }
1259
1260
        if (!\is_object($object)) {
1261
            throw InvalidArgumentException::create(2, 'object');
1262
        }
1263
1264
        static::assertThat(
1265
            $object,
1266
            new LogicalNot(
1267
                new ObjectHasAttribute($attributeName)
1268
            ),
1269
            $message
1270
        );
1271
    }
1272
1273
    /**
1274
     * Asserts that two variables have the same type and value.
1275
     * Used on objects, it asserts that two variables reference
1276
     * the same object.
1277
     *
1278
     * @throws ExpectationFailedException
1279
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1280
     *
1281
     * @psalm-template ExpectedType
1282
     * @psalm-param ExpectedType $expected
1283
     * @psalm-assert =ExpectedType $actual
1284
     */
1285
    public static function assertSame($expected, $actual, string $message = ''): void
1286
    {
1287
        static::assertThat(
1288
            $actual,
1289
            new IsIdentical($expected),
1290
            $message
1291
        );
1292
    }
1293
1294
    /**
1295
     * Asserts that two variables do not have the same type and value.
1296
     * Used on objects, it asserts that two variables do not reference
1297
     * the same object.
1298
     *
1299
     * @throws ExpectationFailedException
1300
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1301
     */
1302
    public static function assertNotSame($expected, $actual, string $message = ''): void
1303
    {
1304
        if (\is_bool($expected) && \is_bool($actual)) {
1305
            static::assertNotEquals($expected, $actual, $message);
1306
        }
1307
1308
        static::assertThat(
1309
            $actual,
1310
            new LogicalNot(
1311
                new IsIdentical($expected)
1312
            ),
1313
            $message
1314
        );
1315
    }
1316
1317
    /**
1318
     * Asserts that a variable is of a given type.
1319
     *
1320
     * @throws ExpectationFailedException
1321
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1322
     * @throws Exception
1323
     *
1324
     * @psalm-template ExpectedType of object
1325
     * @psalm-param class-string<ExpectedType> $expected
1326
     * @psalm-assert ExpectedType $actual
1327
     */
1328
    public static function assertInstanceOf(string $expected, $actual, string $message = ''): void
1329
    {
1330
        if (!\class_exists($expected) && !\interface_exists($expected)) {
1331
            throw InvalidArgumentException::create(1, 'class or interface name');
1332
        }
1333
1334
        static::assertThat(
1335
            $actual,
1336
            new IsInstanceOf($expected),
1337
            $message
1338
        );
1339
    }
1340
1341
    /**
1342
     * Asserts that a variable is not of a given type.
1343
     *
1344
     * @throws ExpectationFailedException
1345
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1346
     * @throws Exception
1347
     *
1348
     * @psalm-template ExpectedType of object
1349
     * @psalm-param class-string<ExpectedType> $expected
1350
     * @psalm-assert !ExpectedType $actual
1351
     */
1352
    public static function assertNotInstanceOf(string $expected, $actual, string $message = ''): void
1353
    {
1354
        if (!\class_exists($expected) && !\interface_exists($expected)) {
1355
            throw InvalidArgumentException::create(1, 'class or interface name');
1356
        }
1357
1358
        static::assertThat(
1359
            $actual,
1360
            new LogicalNot(
1361
                new IsInstanceOf($expected)
1362
            ),
1363
            $message
1364
        );
1365
    }
1366
1367
    /**
1368
     * Asserts that a variable is of type array.
1369
     *
1370
     * @throws ExpectationFailedException
1371
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1372
     *
1373
     * @psalm-assert array $actual
1374
     */
1375
    public static function assertIsArray($actual, string $message = ''): void
1376
    {
1377
        static::assertThat(
1378
            $actual,
1379
            new IsType(IsType::TYPE_ARRAY),
1380
            $message
1381
        );
1382
    }
1383
1384
    /**
1385
     * Asserts that a variable is of type bool.
1386
     *
1387
     * @throws ExpectationFailedException
1388
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1389
     *
1390
     * @psalm-assert bool $actual
1391
     */
1392
    public static function assertIsBool($actual, string $message = ''): void
1393
    {
1394
        static::assertThat(
1395
            $actual,
1396
            new IsType(IsType::TYPE_BOOL),
1397
            $message
1398
        );
1399
    }
1400
1401
    /**
1402
     * Asserts that a variable is of type float.
1403
     *
1404
     * @throws ExpectationFailedException
1405
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1406
     *
1407
     * @psalm-assert float $actual
1408
     */
1409
    public static function assertIsFloat($actual, string $message = ''): void
1410
    {
1411
        static::assertThat(
1412
            $actual,
1413
            new IsType(IsType::TYPE_FLOAT),
1414
            $message
1415
        );
1416
    }
1417
1418
    /**
1419
     * Asserts that a variable is of type int.
1420
     *
1421
     * @throws ExpectationFailedException
1422
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1423
     *
1424
     * @psalm-assert int $actual
1425
     */
1426
    public static function assertIsInt($actual, string $message = ''): void
1427
    {
1428
        static::assertThat(
1429
            $actual,
1430
            new IsType(IsType::TYPE_INT),
1431
            $message
1432
        );
1433
    }
1434
1435
    /**
1436
     * Asserts that a variable is of type numeric.
1437
     *
1438
     * @throws ExpectationFailedException
1439
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1440
     *
1441
     * @psalm-assert numeric $actual
1442
     */
1443
    public static function assertIsNumeric($actual, string $message = ''): void
1444
    {
1445
        static::assertThat(
1446
            $actual,
1447
            new IsType(IsType::TYPE_NUMERIC),
1448
            $message
1449
        );
1450
    }
1451
1452
    /**
1453
     * Asserts that a variable is of type object.
1454
     *
1455
     * @throws ExpectationFailedException
1456
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1457
     *
1458
     * @psalm-assert object $actual
1459
     */
1460
    public static function assertIsObject($actual, string $message = ''): void
1461
    {
1462
        static::assertThat(
1463
            $actual,
1464
            new IsType(IsType::TYPE_OBJECT),
1465
            $message
1466
        );
1467
    }
1468
1469
    /**
1470
     * Asserts that a variable is of type resource.
1471
     *
1472
     * @throws ExpectationFailedException
1473
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1474
     *
1475
     * @psalm-assert resource $actual
1476
     */
1477
    public static function assertIsResource($actual, string $message = ''): void
1478
    {
1479
        static::assertThat(
1480
            $actual,
1481
            new IsType(IsType::TYPE_RESOURCE),
1482
            $message
1483
        );
1484
    }
1485
1486
    /**
1487
     * Asserts that a variable is of type string.
1488
     *
1489
     * @throws ExpectationFailedException
1490
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1491
     *
1492
     * @psalm-assert string $actual
1493
     */
1494
    public static function assertIsString($actual, string $message = ''): void
1495
    {
1496
        static::assertThat(
1497
            $actual,
1498
            new IsType(IsType::TYPE_STRING),
1499
            $message
1500
        );
1501
    }
1502
1503
    /**
1504
     * Asserts that a variable is of type scalar.
1505
     *
1506
     * @throws ExpectationFailedException
1507
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1508
     *
1509
     * @psalm-assert scalar $actual
1510
     */
1511
    public static function assertIsScalar($actual, string $message = ''): void
1512
    {
1513
        static::assertThat(
1514
            $actual,
1515
            new IsType(IsType::TYPE_SCALAR),
1516
            $message
1517
        );
1518
    }
1519
1520
    /**
1521
     * Asserts that a variable is of type callable.
1522
     *
1523
     * @throws ExpectationFailedException
1524
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1525
     *
1526
     * @psalm-assert callable $actual
1527
     */
1528
    public static function assertIsCallable($actual, string $message = ''): void
1529
    {
1530
        static::assertThat(
1531
            $actual,
1532
            new IsType(IsType::TYPE_CALLABLE),
1533
            $message
1534
        );
1535
    }
1536
1537
    /**
1538
     * Asserts that a variable is of type iterable.
1539
     *
1540
     * @throws ExpectationFailedException
1541
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1542
     *
1543
     * @psalm-assert iterable $actual
1544
     */
1545
    public static function assertIsIterable($actual, string $message = ''): void
1546
    {
1547
        static::assertThat(
1548
            $actual,
1549
            new IsType(IsType::TYPE_ITERABLE),
1550
            $message
1551
        );
1552
    }
1553
1554
    /**
1555
     * Asserts that a variable is not of type array.
1556
     *
1557
     * @throws ExpectationFailedException
1558
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1559
     *
1560
     * @psalm-assert !array $actual
1561
     */
1562
    public static function assertIsNotArray($actual, string $message = ''): void
1563
    {
1564
        static::assertThat(
1565
            $actual,
1566
            new LogicalNot(new IsType(IsType::TYPE_ARRAY)),
1567
            $message
1568
        );
1569
    }
1570
1571
    /**
1572
     * Asserts that a variable is not of type bool.
1573
     *
1574
     * @throws ExpectationFailedException
1575
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1576
     *
1577
     * @psalm-assert !bool $actual
1578
     */
1579
    public static function assertIsNotBool($actual, string $message = ''): void
1580
    {
1581
        static::assertThat(
1582
            $actual,
1583
            new LogicalNot(new IsType(IsType::TYPE_BOOL)),
1584
            $message
1585
        );
1586
    }
1587
1588
    /**
1589
     * Asserts that a variable is not of type float.
1590
     *
1591
     * @throws ExpectationFailedException
1592
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1593
     *
1594
     * @psalm-assert !float $actual
1595
     */
1596
    public static function assertIsNotFloat($actual, string $message = ''): void
1597
    {
1598
        static::assertThat(
1599
            $actual,
1600
            new LogicalNot(new IsType(IsType::TYPE_FLOAT)),
1601
            $message
1602
        );
1603
    }
1604
1605
    /**
1606
     * Asserts that a variable is not of type int.
1607
     *
1608
     * @throws ExpectationFailedException
1609
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1610
     *
1611
     * @psalm-assert !int $actual
1612
     */
1613
    public static function assertIsNotInt($actual, string $message = ''): void
1614
    {
1615
        static::assertThat(
1616
            $actual,
1617
            new LogicalNot(new IsType(IsType::TYPE_INT)),
1618
            $message
1619
        );
1620
    }
1621
1622
    /**
1623
     * Asserts that a variable is not of type numeric.
1624
     *
1625
     * @throws ExpectationFailedException
1626
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1627
     *
1628
     * @psalm-assert !numeric $actual
1629
     */
1630
    public static function assertIsNotNumeric($actual, string $message = ''): void
1631
    {
1632
        static::assertThat(
1633
            $actual,
1634
            new LogicalNot(new IsType(IsType::TYPE_NUMERIC)),
1635
            $message
1636
        );
1637
    }
1638
1639
    /**
1640
     * Asserts that a variable is not of type object.
1641
     *
1642
     * @throws ExpectationFailedException
1643
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1644
     *
1645
     * @psalm-assert !object $actual
1646
     */
1647
    public static function assertIsNotObject($actual, string $message = ''): void
1648
    {
1649
        static::assertThat(
1650
            $actual,
1651
            new LogicalNot(new IsType(IsType::TYPE_OBJECT)),
1652
            $message
1653
        );
1654
    }
1655
1656
    /**
1657
     * Asserts that a variable is not of type resource.
1658
     *
1659
     * @throws ExpectationFailedException
1660
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1661
     *
1662
     * @psalm-assert !resource $actual
1663
     */
1664
    public static function assertIsNotResource($actual, string $message = ''): void
1665
    {
1666
        static::assertThat(
1667
            $actual,
1668
            new LogicalNot(new IsType(IsType::TYPE_RESOURCE)),
1669
            $message
1670
        );
1671
    }
1672
1673
    /**
1674
     * Asserts that a variable is not of type string.
1675
     *
1676
     * @throws ExpectationFailedException
1677
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1678
     *
1679
     * @psalm-assert !string $actual
1680
     */
1681
    public static function assertIsNotString($actual, string $message = ''): void
1682
    {
1683
        static::assertThat(
1684
            $actual,
1685
            new LogicalNot(new IsType(IsType::TYPE_STRING)),
1686
            $message
1687
        );
1688
    }
1689
1690
    /**
1691
     * Asserts that a variable is not of type scalar.
1692
     *
1693
     * @throws ExpectationFailedException
1694
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1695
     *
1696
     * @psalm-assert !scalar $actual
1697
     */
1698
    public static function assertIsNotScalar($actual, string $message = ''): void
1699
    {
1700
        static::assertThat(
1701
            $actual,
1702
            new LogicalNot(new IsType(IsType::TYPE_SCALAR)),
1703
            $message
1704
        );
1705
    }
1706
1707
    /**
1708
     * Asserts that a variable is not of type callable.
1709
     *
1710
     * @throws ExpectationFailedException
1711
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1712
     *
1713
     * @psalm-assert !callable $actual
1714
     */
1715
    public static function assertIsNotCallable($actual, string $message = ''): void
1716
    {
1717
        static::assertThat(
1718
            $actual,
1719
            new LogicalNot(new IsType(IsType::TYPE_CALLABLE)),
1720
            $message
1721
        );
1722
    }
1723
1724
    /**
1725
     * Asserts that a variable is not of type iterable.
1726
     *
1727
     * @throws ExpectationFailedException
1728
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1729
     *
1730
     * @psalm-assert !iterable $actual
1731
     */
1732
    public static function assertIsNotIterable($actual, string $message = ''): void
1733
    {
1734
        static::assertThat(
1735
            $actual,
1736
            new LogicalNot(new IsType(IsType::TYPE_ITERABLE)),
1737
            $message
1738
        );
1739
    }
1740
1741
    /**
1742
     * Asserts that a string matches a given regular expression.
1743
     *
1744
     * @throws ExpectationFailedException
1745
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1746
     */
1747
    public static function assertMatchesRegularExpression(string $pattern, string $string, string $message = ''): void
1748
    {
1749
        static::assertThat($string, new RegularExpression($pattern), $message);
1750
    }
1751
1752
    /**
1753
     * Asserts that a string matches a given regular expression.
1754
     *
1755
     * @throws ExpectationFailedException
1756
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1757
     *
1758
     * @codeCoverageIgnore
1759
     *
1760
     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4086
1761
     */
1762
    public static function assertRegExp(string $pattern, string $string, string $message = ''): void
1763
    {
1764
        self::createWarning('assertRegExp() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertMatchesRegularExpression() instead.');
1765
1766
        static::assertThat($string, new RegularExpression($pattern), $message);
1767
    }
1768
1769
    /**
1770
     * Asserts that a string does not match a given regular expression.
1771
     *
1772
     * @throws ExpectationFailedException
1773
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1774
     */
1775
    public static function assertDoesNotMatchRegularExpression(string $pattern, string $string, string $message = ''): void
1776
    {
1777
        static::assertThat(
1778
            $string,
1779
            new LogicalNot(
1780
                new RegularExpression($pattern)
1781
            ),
1782
            $message
1783
        );
1784
    }
1785
1786
    /**
1787
     * Asserts that a string does not match a given regular expression.
1788
     *
1789
     * @throws ExpectationFailedException
1790
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1791
     *
1792
     * @codeCoverageIgnore
1793
     *
1794
     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4089
1795
     */
1796
    public static function assertNotRegExp(string $pattern, string $string, string $message = ''): void
1797
    {
1798
        self::createWarning('assertNotRegExp() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertDoesNotMatchRegularExpression() instead.');
1799
1800
        static::assertThat(
1801
            $string,
1802
            new LogicalNot(
1803
                new RegularExpression($pattern)
1804
            ),
1805
            $message
1806
        );
1807
    }
1808
1809
    /**
1810
     * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
1811
     * is the same.
1812
     *
1813
     * @param \Countable|iterable $expected
1814
     * @param \Countable|iterable $actual
1815
     *
1816
     * @throws ExpectationFailedException
1817
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1818
     * @throws Exception
1819
     */
1820
    public static function assertSameSize($expected, $actual, string $message = ''): void
1821
    {
1822
        if (!$expected instanceof \Countable && !\is_iterable($expected)) {
1823
            throw InvalidArgumentException::create(1, 'countable or iterable');
1824
        }
1825
1826
        if (!$actual instanceof \Countable && !\is_iterable($actual)) {
1827
            throw InvalidArgumentException::create(2, 'countable or iterable');
1828
        }
1829
1830
        static::assertThat(
1831
            $actual,
1832
            new SameSize($expected),
1833
            $message
1834
        );
1835
    }
1836
1837
    /**
1838
     * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
1839
     * is not the same.
1840
     *
1841
     * @param \Countable|iterable $expected
1842
     * @param \Countable|iterable $actual
1843
     *
1844
     * @throws ExpectationFailedException
1845
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1846
     * @throws Exception
1847
     */
1848
    public static function assertNotSameSize($expected, $actual, string $message = ''): void
1849
    {
1850
        if (!$expected instanceof \Countable && !\is_iterable($expected)) {
1851
            throw InvalidArgumentException::create(1, 'countable or iterable');
1852
        }
1853
1854
        if (!$actual instanceof \Countable && !\is_iterable($actual)) {
1855
            throw InvalidArgumentException::create(2, 'countable or iterable');
1856
        }
1857
1858
        static::assertThat(
1859
            $actual,
1860
            new LogicalNot(
1861
                new SameSize($expected)
1862
            ),
1863
            $message
1864
        );
1865
    }
1866
1867
    /**
1868
     * Asserts that a string matches a given format string.
1869
     *
1870
     * @throws ExpectationFailedException
1871
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1872
     */
1873
    public static function assertStringMatchesFormat(string $format, string $string, string $message = ''): void
1874
    {
1875
        static::assertThat($string, new StringMatchesFormatDescription($format), $message);
1876
    }
1877
1878
    /**
1879
     * Asserts that a string does not match a given format string.
1880
     *
1881
     * @throws ExpectationFailedException
1882
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1883
     */
1884
    public static function assertStringNotMatchesFormat(string $format, string $string, string $message = ''): void
1885
    {
1886
        static::assertThat(
1887
            $string,
1888
            new LogicalNot(
1889
                new StringMatchesFormatDescription($format)
1890
            ),
1891
            $message
1892
        );
1893
    }
1894
1895
    /**
1896
     * Asserts that a string matches a given format file.
1897
     *
1898
     * @throws ExpectationFailedException
1899
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1900
     */
1901
    public static function assertStringMatchesFormatFile(string $formatFile, string $string, string $message = ''): void
1902
    {
1903
        static::assertFileExists($formatFile, $message);
1904
1905
        static::assertThat(
1906
            $string,
1907
            new StringMatchesFormatDescription(
1908
                \file_get_contents($formatFile)
1909
            ),
1910
            $message
1911
        );
1912
    }
1913
1914
    /**
1915
     * Asserts that a string does not match a given format string.
1916
     *
1917
     * @throws ExpectationFailedException
1918
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1919
     */
1920
    public static function assertStringNotMatchesFormatFile(string $formatFile, string $string, string $message = ''): void
1921
    {
1922
        static::assertFileExists($formatFile, $message);
1923
1924
        static::assertThat(
1925
            $string,
1926
            new LogicalNot(
1927
                new StringMatchesFormatDescription(
1928
                    \file_get_contents($formatFile)
1929
                )
1930
            ),
1931
            $message
1932
        );
1933
    }
1934
1935
    /**
1936
     * Asserts that a string starts with a given prefix.
1937
     *
1938
     * @throws ExpectationFailedException
1939
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1940
     */
1941
    public static function assertStringStartsWith(string $prefix, string $string, string $message = ''): void
1942
    {
1943
        static::assertThat($string, new StringStartsWith($prefix), $message);
1944
    }
1945
1946
    /**
1947
     * Asserts that a string starts not with a given prefix.
1948
     *
1949
     * @param string $prefix
1950
     * @param string $string
1951
     *
1952
     * @throws ExpectationFailedException
1953
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1954
     */
1955
    public static function assertStringStartsNotWith($prefix, $string, string $message = ''): void
1956
    {
1957
        static::assertThat(
1958
            $string,
1959
            new LogicalNot(
1960
                new StringStartsWith($prefix)
1961
            ),
1962
            $message
1963
        );
1964
    }
1965
1966
    /**
1967
     * @throws ExpectationFailedException
1968
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1969
     */
1970
    public static function assertStringContainsString(string $needle, string $haystack, string $message = ''): void
1971
    {
1972
        $constraint = new StringContains($needle, false);
1973
1974
        static::assertThat($haystack, $constraint, $message);
1975
    }
1976
1977
    /**
1978
     * @throws ExpectationFailedException
1979
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1980
     */
1981
    public static function assertStringContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void
1982
    {
1983
        $constraint = new StringContains($needle, true);
1984
1985
        static::assertThat($haystack, $constraint, $message);
1986
    }
1987
1988
    /**
1989
     * @throws ExpectationFailedException
1990
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
1991
     */
1992
    public static function assertStringNotContainsString(string $needle, string $haystack, string $message = ''): void
1993
    {
1994
        $constraint = new LogicalNot(new StringContains($needle));
1995
1996
        static::assertThat($haystack, $constraint, $message);
1997
    }
1998
1999
    /**
2000
     * @throws ExpectationFailedException
2001
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2002
     */
2003
    public static function assertStringNotContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void
2004
    {
2005
        $constraint = new LogicalNot(new StringContains($needle, true));
2006
2007
        static::assertThat($haystack, $constraint, $message);
2008
    }
2009
2010
    /**
2011
     * Asserts that a string ends with a given suffix.
2012
     *
2013
     * @throws ExpectationFailedException
2014
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2015
     */
2016
    public static function assertStringEndsWith(string $suffix, string $string, string $message = ''): void
2017
    {
2018
        static::assertThat($string, new StringEndsWith($suffix), $message);
2019
    }
2020
2021
    /**
2022
     * Asserts that a string ends not with a given suffix.
2023
     *
2024
     * @throws ExpectationFailedException
2025
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2026
     */
2027
    public static function assertStringEndsNotWith(string $suffix, string $string, string $message = ''): void
2028
    {
2029
        static::assertThat(
2030
            $string,
2031
            new LogicalNot(
2032
                new StringEndsWith($suffix)
2033
            ),
2034
            $message
2035
        );
2036
    }
2037
2038
    /**
2039
     * Asserts that two XML files are equal.
2040
     *
2041
     * @throws ExpectationFailedException
2042
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2043
     * @throws Exception
2044
     */
2045
    public static function assertXmlFileEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void
2046
    {
2047
        $expected = Xml::loadFile($expectedFile);
2048
        $actual   = Xml::loadFile($actualFile);
2049
2050
        static::assertEquals($expected, $actual, $message);
2051
    }
2052
2053
    /**
2054
     * Asserts that two XML files are not equal.
2055
     *
2056
     * @throws ExpectationFailedException
2057
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2058
     * @throws Exception
2059
     */
2060
    public static function assertXmlFileNotEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void
2061
    {
2062
        $expected = Xml::loadFile($expectedFile);
2063
        $actual   = Xml::loadFile($actualFile);
2064
2065
        static::assertNotEquals($expected, $actual, $message);
2066
    }
2067
2068
    /**
2069
     * Asserts that two XML documents are equal.
2070
     *
2071
     * @param \DOMDocument|string $actualXml
2072
     *
2073
     * @throws ExpectationFailedException
2074
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2075
     * @throws Exception
2076
     */
2077
    public static function assertXmlStringEqualsXmlFile(string $expectedFile, $actualXml, string $message = ''): void
2078
    {
2079
        $expected = Xml::loadFile($expectedFile);
2080
        $actual   = Xml::load($actualXml);
2081
2082
        static::assertEquals($expected, $actual, $message);
2083
    }
2084
2085
    /**
2086
     * Asserts that two XML documents are not equal.
2087
     *
2088
     * @param \DOMDocument|string $actualXml
2089
     *
2090
     * @throws ExpectationFailedException
2091
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2092
     * @throws Exception
2093
     */
2094
    public static function assertXmlStringNotEqualsXmlFile(string $expectedFile, $actualXml, string $message = ''): void
2095
    {
2096
        $expected = Xml::loadFile($expectedFile);
2097
        $actual   = Xml::load($actualXml);
2098
2099
        static::assertNotEquals($expected, $actual, $message);
2100
    }
2101
2102
    /**
2103
     * Asserts that two XML documents are equal.
2104
     *
2105
     * @param \DOMDocument|string $expectedXml
2106
     * @param \DOMDocument|string $actualXml
2107
     *
2108
     * @throws ExpectationFailedException
2109
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2110
     * @throws Exception
2111
     */
2112
    public static function assertXmlStringEqualsXmlString($expectedXml, $actualXml, string $message = ''): void
2113
    {
2114
        $expected = Xml::load($expectedXml);
2115
        $actual   = Xml::load($actualXml);
2116
2117
        static::assertEquals($expected, $actual, $message);
2118
    }
2119
2120
    /**
2121
     * Asserts that two XML documents are not equal.
2122
     *
2123
     * @param \DOMDocument|string $expectedXml
2124
     * @param \DOMDocument|string $actualXml
2125
     *
2126
     * @throws ExpectationFailedException
2127
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2128
     * @throws Exception
2129
     */
2130
    public static function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, string $message = ''): void
2131
    {
2132
        $expected = Xml::load($expectedXml);
2133
        $actual   = Xml::load($actualXml);
2134
2135
        static::assertNotEquals($expected, $actual, $message);
2136
    }
2137
2138
    /**
2139
     * Asserts that a hierarchy of DOMElements matches.
2140
     *
2141
     * @throws AssertionFailedError
2142
     * @throws ExpectationFailedException
2143
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2144
     *
2145
     * @codeCoverageIgnore
2146
     *
2147
     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4091
2148
     */
2149
    public static function assertEqualXMLStructure(\DOMElement $expectedElement, \DOMElement $actualElement, bool $checkAttributes = false, string $message = ''): void
2150
    {
2151
        self::createWarning('assertEqualXMLStructure() is deprecated and will be removed in PHPUnit 10.');
2152
2153
        $expectedElement = Xml::import($expectedElement);
2154
        $actualElement   = Xml::import($actualElement);
2155
2156
        static::assertSame(
2157
            $expectedElement->tagName,
2158
            $actualElement->tagName,
2159
            $message
2160
        );
2161
2162
        if ($checkAttributes) {
2163
            static::assertSame(
2164
                $expectedElement->attributes->length,
2165
                $actualElement->attributes->length,
2166
                \sprintf(
2167
                    '%s%sNumber of attributes on node "%s" does not match',
2168
                    $message,
2169
                    !empty($message) ? "\n" : '',
2170
                    $expectedElement->tagName
2171
                )
2172
            );
2173
2174
            for ($i = 0; $i < $expectedElement->attributes->length; $i++) {
2175
                $expectedAttribute = $expectedElement->attributes->item($i);
2176
                $actualAttribute   = $actualElement->attributes->getNamedItem($expectedAttribute->name);
2177
2178
                \assert($expectedAttribute instanceof \DOMAttr);
2179
2180
                if (!$actualAttribute) {
2181
                    static::fail(
2182
                        \sprintf(
2183
                            '%s%sCould not find attribute "%s" on node "%s"',
2184
                            $message,
2185
                            !empty($message) ? "\n" : '',
2186
                            $expectedAttribute->name,
2187
                            $expectedElement->tagName
2188
                        )
2189
                    );
2190
                }
2191
            }
2192
        }
2193
2194
        Xml::removeCharacterDataNodes($expectedElement);
2195
        Xml::removeCharacterDataNodes($actualElement);
2196
2197
        static::assertSame(
2198
            $expectedElement->childNodes->length,
2199
            $actualElement->childNodes->length,
2200
            \sprintf(
2201
                '%s%sNumber of child nodes of "%s" differs',
2202
                $message,
2203
                !empty($message) ? "\n" : '',
2204
                $expectedElement->tagName
2205
            )
2206
        );
2207
2208
        for ($i = 0; $i < $expectedElement->childNodes->length; $i++) {
2209
            static::assertEqualXMLStructure(
2210
                $expectedElement->childNodes->item($i),
2211
                $actualElement->childNodes->item($i),
2212
                $checkAttributes,
2213
                $message
2214
            );
2215
        }
2216
    }
2217
2218
    /**
2219
     * Evaluates a PHPUnit\Framework\Constraint matcher object.
2220
     *
2221
     * @throws ExpectationFailedException
2222
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2223
     */
2224
    public static function assertThat($value, Constraint $constraint, string $message = ''): void
2225
    {
2226
        self::$count += \count($constraint);
2227
2228
        $constraint->evaluate($value, $message);
2229
    }
2230
2231
    /**
2232
     * Asserts that a string is a valid JSON string.
2233
     *
2234
     * @throws ExpectationFailedException
2235
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2236
     */
2237
    public static function assertJson(string $actualJson, string $message = ''): void
2238
    {
2239
        static::assertThat($actualJson, static::isJson(), $message);
2240
    }
2241
2242
    /**
2243
     * Asserts that two given JSON encoded objects or arrays are equal.
2244
     *
2245
     * @throws ExpectationFailedException
2246
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2247
     */
2248
    public static function assertJsonStringEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void
2249
    {
2250
        static::assertJson($expectedJson, $message);
2251
        static::assertJson($actualJson, $message);
2252
2253
        static::assertThat($actualJson, new JsonMatches($expectedJson), $message);
2254
    }
2255
2256
    /**
2257
     * Asserts that two given JSON encoded objects or arrays are not equal.
2258
     *
2259
     * @param string $expectedJson
2260
     * @param string $actualJson
2261
     *
2262
     * @throws ExpectationFailedException
2263
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2264
     */
2265
    public static function assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, string $message = ''): void
2266
    {
2267
        static::assertJson($expectedJson, $message);
2268
        static::assertJson($actualJson, $message);
2269
2270
        static::assertThat(
2271
            $actualJson,
2272
            new LogicalNot(
2273
                new JsonMatches($expectedJson)
2274
            ),
2275
            $message
2276
        );
2277
    }
2278
2279
    /**
2280
     * Asserts that the generated JSON encoded object and the content of the given file are equal.
2281
     *
2282
     * @throws ExpectationFailedException
2283
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2284
     */
2285
    public static function assertJsonStringEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void
2286
    {
2287
        static::assertFileExists($expectedFile, $message);
2288
        $expectedJson = \file_get_contents($expectedFile);
2289
2290
        static::assertJson($expectedJson, $message);
2291
        static::assertJson($actualJson, $message);
2292
2293
        static::assertThat($actualJson, new JsonMatches($expectedJson), $message);
2294
    }
2295
2296
    /**
2297
     * Asserts that the generated JSON encoded object and the content of the given file are not equal.
2298
     *
2299
     * @throws ExpectationFailedException
2300
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2301
     */
2302
    public static function assertJsonStringNotEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void
2303
    {
2304
        static::assertFileExists($expectedFile, $message);
2305
        $expectedJson = \file_get_contents($expectedFile);
2306
2307
        static::assertJson($expectedJson, $message);
2308
        static::assertJson($actualJson, $message);
2309
2310
        static::assertThat(
2311
            $actualJson,
2312
            new LogicalNot(
2313
                new JsonMatches($expectedJson)
2314
            ),
2315
            $message
2316
        );
2317
    }
2318
2319
    /**
2320
     * Asserts that two JSON files are equal.
2321
     *
2322
     * @throws ExpectationFailedException
2323
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2324
     */
2325
    public static function assertJsonFileEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void
2326
    {
2327
        static::assertFileExists($expectedFile, $message);
2328
        static::assertFileExists($actualFile, $message);
2329
2330
        $actualJson   = \file_get_contents($actualFile);
2331
        $expectedJson = \file_get_contents($expectedFile);
2332
2333
        static::assertJson($expectedJson, $message);
2334
        static::assertJson($actualJson, $message);
2335
2336
        $constraintExpected = new JsonMatches(
2337
            $expectedJson
2338
        );
2339
2340
        $constraintActual = new JsonMatches($actualJson);
2341
2342
        static::assertThat($expectedJson, $constraintActual, $message);
2343
        static::assertThat($actualJson, $constraintExpected, $message);
2344
    }
2345
2346
    /**
2347
     * Asserts that two JSON files are not equal.
2348
     *
2349
     * @throws ExpectationFailedException
2350
     * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
2351
     */
2352
    public static function assertJsonFileNotEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void
2353
    {
2354
        static::assertFileExists($expectedFile, $message);
2355
        static::assertFileExists($actualFile, $message);
2356
2357
        $actualJson   = \file_get_contents($actualFile);
2358
        $expectedJson = \file_get_contents($expectedFile);
2359
2360
        static::assertJson($expectedJson, $message);
2361
        static::assertJson($actualJson, $message);
2362
2363
        $constraintExpected = new JsonMatches(
2364
            $expectedJson
2365
        );
2366
2367
        $constraintActual = new JsonMatches($actualJson);
2368
2369
        static::assertThat($expectedJson, new LogicalNot($constraintActual), $message);
2370
        static::assertThat($actualJson, new LogicalNot($constraintExpected), $message);
2371
    }
2372
2373
    /**
2374
     * @throws Exception
2375
     */
2376
    public static function logicalAnd(): LogicalAnd
2377
    {
2378
        $constraints = \func_get_args();
2379
2380
        $constraint = new LogicalAnd;
2381
        $constraint->setConstraints($constraints);
2382
2383
        return $constraint;
2384
    }
2385
2386
    public static function logicalOr(): LogicalOr
2387
    {
2388
        $constraints = \func_get_args();
2389
2390
        $constraint = new LogicalOr;
2391
        $constraint->setConstraints($constraints);
2392
2393
        return $constraint;
2394
    }
2395
2396
    public static function logicalNot(Constraint $constraint): LogicalNot
2397
    {
2398
        return new LogicalNot($constraint);
2399
    }
2400
2401
    public static function logicalXor(): LogicalXor
2402
    {
2403
        $constraints = \func_get_args();
2404
2405
        $constraint = new LogicalXor;
2406
        $constraint->setConstraints($constraints);
2407
2408
        return $constraint;
2409
    }
2410
2411
    public static function anything(): IsAnything
2412
    {
2413
        return new IsAnything;
2414
    }
2415
2416
    public static function isTrue(): IsTrue
2417
    {
2418
        return new IsTrue;
2419
    }
2420
2421
    public static function callback(callable $callback): Callback
2422
    {
2423
        return new Callback($callback);
2424
    }
2425
2426
    public static function isFalse(): IsFalse
2427
    {
2428
        return new IsFalse;
2429
    }
2430
2431
    public static function isJson(): IsJson
2432
    {
2433
        return new IsJson;
2434
    }
2435
2436
    public static function isNull(): IsNull
2437
    {
2438
        return new IsNull;
2439
    }
2440
2441
    public static function isFinite(): IsFinite
2442
    {
2443
        return new IsFinite;
2444
    }
2445
2446
    public static function isInfinite(): IsInfinite
2447
    {
2448
        return new IsInfinite;
2449
    }
2450
2451
    public static function isNan(): IsNan
2452
    {
2453
        return new IsNan;
2454
    }
2455
2456
    public static function containsEqual($value): TraversableContainsEqual
2457
    {
2458
        return new TraversableContainsEqual($value);
2459
    }
2460
2461
    public static function containsIdentical($value): TraversableContainsIdentical
2462
    {
2463
        return new TraversableContainsIdentical($value);
2464
    }
2465
2466
    public static function containsOnly(string $type): TraversableContainsOnly
2467
    {
2468
        return new TraversableContainsOnly($type);
2469
    }
2470
2471
    public static function containsOnlyInstancesOf(string $className): TraversableContainsOnly
2472
    {
2473
        return new TraversableContainsOnly($className, false);
2474
    }
2475
2476
    /**
2477
     * @param int|string $key
2478
     */
2479
    public static function arrayHasKey($key): ArrayHasKey
2480
    {
2481
        return new ArrayHasKey($key);
2482
    }
2483
2484
    public static function equalTo($value): IsEqual
2485
    {
2486
        return new IsEqual($value, 0.0, false, false);
2487
    }
2488
2489
    public static function equalToCanonicalizing($value): IsEqualCanonicalizing
2490
    {
2491
        return new IsEqualCanonicalizing($value);
2492
    }
2493
2494
    public static function equalToIgnoringCase($value): IsEqualIgnoringCase
2495
    {
2496
        return new IsEqualIgnoringCase($value);
2497
    }
2498
2499
    public static function equalToWithDelta($value, float $delta): IsEqualWithDelta
2500
    {
2501
        return new IsEqualWithDelta($value, $delta);
2502
    }
2503
2504
    public static function isEmpty(): IsEmpty
2505
    {
2506
        return new IsEmpty;
2507
    }
2508
2509
    public static function isWritable(): IsWritable
2510
    {
2511
        return new IsWritable;
2512
    }
2513
2514
    public static function isReadable(): IsReadable
2515
    {
2516
        return new IsReadable;
2517
    }
2518
2519
    public static function directoryExists(): DirectoryExists
2520
    {
2521
        return new DirectoryExists;
2522
    }
2523
2524
    public static function fileExists(): FileExists
2525
    {
2526
        return new FileExists;
2527
    }
2528
2529
    public static function greaterThan($value): GreaterThan
2530
    {
2531
        return new GreaterThan($value);
2532
    }
2533
2534
    public static function greaterThanOrEqual($value): LogicalOr
2535
    {
2536
        return static::logicalOr(
2537
            new IsEqual($value),
2538
            new GreaterThan($value)
2539
        );
2540
    }
2541
2542
    public static function classHasAttribute(string $attributeName): ClassHasAttribute
2543
    {
2544
        return new ClassHasAttribute($attributeName);
2545
    }
2546
2547
    public static function classHasStaticAttribute(string $attributeName): ClassHasStaticAttribute
2548
    {
2549
        return new ClassHasStaticAttribute($attributeName);
2550
    }
2551
2552
    public static function objectHasAttribute($attributeName): ObjectHasAttribute
2553
    {
2554
        return new ObjectHasAttribute($attributeName);
2555
    }
2556
2557
    public static function identicalTo($value): IsIdentical
2558
    {
2559
        return new IsIdentical($value);
2560
    }
2561
2562
    public static function isInstanceOf(string $className): IsInstanceOf
2563
    {
2564
        return new IsInstanceOf($className);
2565
    }
2566
2567
    public static function isType(string $type): IsType
2568
    {
2569
        return new IsType($type);
2570
    }
2571
2572
    public static function lessThan($value): LessThan
2573
    {
2574
        return new LessThan($value);
2575
    }
2576
2577
    public static function lessThanOrEqual($value): LogicalOr
2578
    {
2579
        return static::logicalOr(
2580
            new IsEqual($value),
2581
            new LessThan($value)
2582
        );
2583
    }
2584
2585
    public static function matchesRegularExpression(string $pattern): RegularExpression
2586
    {
2587
        return new RegularExpression($pattern);
2588
    }
2589
2590
    public static function matches(string $string): StringMatchesFormatDescription
2591
    {
2592
        return new StringMatchesFormatDescription($string);
2593
    }
2594
2595
    public static function stringStartsWith($prefix): StringStartsWith
2596
    {
2597
        return new StringStartsWith($prefix);
2598
    }
2599
2600
    public static function stringContains(string $string, bool $case = true): StringContains
2601
    {
2602
        return new StringContains($string, $case);
2603
    }
2604
2605
    public static function stringEndsWith(string $suffix): StringEndsWith
2606
    {
2607
        return new StringEndsWith($suffix);
2608
    }
2609
2610
    public static function countOf(int $count): Count
2611
    {
2612
        return new Count($count);
2613
    }
2614
2615
    /**
2616
     * Fails a test with the given message.
2617
     *
2618
     * @throws AssertionFailedError
2619
     *
2620
     * @psalm-return never-return
2621
     */
2622
    public static function fail(string $message = ''): void
2623
    {
2624
        self::$count++;
2625
2626
        throw new AssertionFailedError($message);
2627
    }
2628
2629
    /**
2630
     * Mark the test as incomplete.
2631
     *
2632
     * @throws IncompleteTestError
2633
     *
2634
     * @psalm-return never-return
2635
     */
2636
    public static function markTestIncomplete(string $message = ''): void
2637
    {
2638
        throw new IncompleteTestError($message);
2639
    }
2640
2641
    /**
2642
     * Mark the test as skipped.
2643
     *
2644
     * @throws SkippedTestError
2645
     * @throws SyntheticSkippedError
2646
     *
2647
     * @psalm-return never-return
2648
     */
2649
    public static function markTestSkipped(string $message = ''): void
2650
    {
2651
        if ($hint = self::detectLocationHint($message)) {
2652
            $trace = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS);
2653
            \array_unshift($trace, $hint);
2654
2655
            throw new SyntheticSkippedError($hint['message'], 0, $hint['file'], (int) $hint['line'], $trace);
2656
        }
2657
2658
        throw new SkippedTestError($message);
2659
    }
2660
2661
    /**
2662
     * Return the current assertion count.
2663
     */
2664
    public static function getCount(): int
2665
    {
2666
        return self::$count;
2667
    }
2668
2669
    /**
2670
     * Reset the assertion counter.
2671
     */
2672
    public static function resetCount(): void
2673
    {
2674
        self::$count = 0;
2675
    }
2676
2677
    private static function detectLocationHint(string $message): ?array
2678
    {
2679
        $hint  = null;
2680
        $lines = \preg_split('/\r\n|\r|\n/', $message);
2681
2682
        while (\strpos($lines[0], '__OFFSET') !== false) {
2683
            $offset = \explode('=', \array_shift($lines));
2684
2685
            if ($offset[0] === '__OFFSET_FILE') {
2686
                $hint['file'] = $offset[1];
2687
            }
2688
2689
            if ($offset[0] === '__OFFSET_LINE') {
2690
                $hint['line'] = $offset[1];
2691
            }
2692
        }
2693
2694
        if ($hint) {
2695
            $hint['message'] = \implode(\PHP_EOL, $lines);
2696
        }
2697
2698
        return $hint;
2699
    }
2700
2701
    private static function isValidObjectAttributeName(string $attributeName): bool
2702
    {
2703
        return (bool) \preg_match('/[^\x00-\x1f\x7f-\x9f]+/', $attributeName);
2704
    }
2705
2706
    private static function isValidClassAttributeName(string $attributeName): bool
2707
    {
2708
        return (bool) \preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName);
2709
    }
2710
2711
    /**
2712
     * @codeCoverageIgnore
2713
     */
2714
    private static function createWarning(string $warning): void
2715
    {
2716
        foreach (\debug_backtrace() as $step) {
2717
            if (isset($step['object']) && $step['object'] instanceof TestCase) {
2718
                \assert($step['object'] instanceof TestCase);
2719
2720
                $step['object']->addWarning($warning);
2721
2722
                break;
2723
            }
2724
        }
2725
    }
2726
}
2727