Completed
Push — master ( 01e071...007090 )
by Ehsan
01:46 queued 13s
created

Assert   F

Complexity

Total Complexity 296

Size/Duplication

Total Lines 2942
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 47

Importance

Changes 0
Metric Value
dl 0
loc 2942
rs 0.5217
c 0
b 0
f 0
wmc 296
lcom 1
cbo 47

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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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