summaryrefslogtreecommitdiff
path: root/vendor/phpunit/phpunit/src/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/phpunit/phpunit/src/Framework')
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Assert.php2854
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Assert/Functions.php3035
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Boolean/IsFalse.php35
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Boolean/IsTrue.php35
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Callback.php52
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/Count.php142
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/GreaterThan.php50
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/IsEmpty.php70
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/LessThan.php50
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/SameSize.php21
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Constraint.php269
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqual.php138
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqualCanonicalizing.php108
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqualIgnoringCase.php108
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqualWithDelta.php100
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Exception/Exception.php85
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Exception/ExceptionCode.php67
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Exception/ExceptionMessage.php78
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Exception/ExceptionMessageRegularExpression.php74
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Filesystem/DirectoryExists.php54
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Filesystem/FileExists.php54
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Filesystem/IsReadable.php54
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Filesystem/IsWritable.php54
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsAnything.php51
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php137
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php109
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php72
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Math/IsFinite.php37
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Math/IsInfinite.php37
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Math/IsNan.php37
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Object/ClassHasAttribute.php88
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Object/ClassHasStaticAttribute.php59
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Object/ObjectEquals.php151
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Object/ObjectHasAttribute.php29
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Operator/BinaryOperator.php148
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Operator/LogicalAnd.php51
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Operator/LogicalNot.php136
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Operator/LogicalOr.php51
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Operator/LogicalXor.php63
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Operator/Operator.php55
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Operator/UnaryOperator.php140
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/String/IsJson.php77
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/String/RegularExpression.php51
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/String/StringContains.php85
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/String/StringEndsWith.php48
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/String/StringMatchesFormatDescription.php109
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/String/StringStartsWith.php53
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/ArrayHasKey.php77
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/TraversableContains.php63
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/TraversableContainsEqual.php40
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/TraversableContainsIdentical.php39
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/TraversableContainsOnly.php91
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Type/IsInstanceOf.php87
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Type/IsNull.php35
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Type/IsType.php210
-rw-r--r--vendor/phpunit/phpunit/src/Framework/DataProviderTestSuite.php75
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Error/Deprecated.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Error/Error.php26
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Error/Notice.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Error/Warning.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/ErrorTestCase.php66
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/ActualValueIsNotAnObjectException.php32
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/AssertionFailedError.php24
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/CodeCoverageException.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotAcceptParameterTypeException.php38
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotDeclareBoolReturnTypeException.php37
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotDeclareExactlyOneParameterException.php37
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotDeclareParameterTypeException.php37
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotExistException.php37
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/CoveredCodeNotExecutedException.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/Error.php24
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/Exception.php81
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/ExpectationFailedException.php42
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/IncompleteTestError.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/InvalidArgumentException.php46
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/InvalidCoversTargetException.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/InvalidDataProviderException.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/MissingCoversAnnotationException.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/NoChildTestSuiteException.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/OutputError.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/PHPTAssertionFailedError.php32
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/RiskyTestError.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/SkippedTestError.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/SkippedTestSuiteError.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/SyntheticError.php61
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/SyntheticSkippedError.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/UnintentionallyCoveredCodeError.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception/Warning.php24
-rw-r--r--vendor/phpunit/phpunit/src/Framework/ExceptionWrapper.php122
-rw-r--r--vendor/phpunit/phpunit/src/Framework/ExecutionOrderDependency.php206
-rw-r--r--vendor/phpunit/phpunit/src/Framework/IncompleteTest.php19
-rw-r--r--vendor/phpunit/phpunit/src/Framework/IncompleteTestCase.php66
-rw-r--r--vendor/phpunit/phpunit/src/Framework/InvalidParameterGroupException.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Api/Api.php97
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Api/Method.php30
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Api/MockedCloneMethod.php21
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Api/UnmockedCloneMethod.php23
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Identity.php25
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationMocker.php306
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationStubber.php65
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Builder/MethodNameMatch.php26
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php58
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Stub.php24
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/ConfigurableMethod.php53
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/BadMethodCallException.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/CannotUseAddMethodsException.php29
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/CannotUseOnlyMethodsException.php29
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ClassAlreadyExistsException.php28
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ClassIsFinalException.php28
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ConfigurableMethodsAlreadyInitializedException.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/DuplicateMethodException.php32
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/Exception.php19
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/IncompatibleReturnValueException.php33
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/InvalidMethodNameException.php28
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MatchBuilderNotFoundException.php28
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MatcherAlreadyRegisteredException.php28
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MethodCannotBeConfiguredException.php28
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MethodNameAlreadyConfiguredException.php21
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MethodNameNotConfiguredException.php21
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MethodParametersAlreadyConfiguredException.php21
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/OriginalConstructorInvocationRequiredException.php21
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ReflectionException.php19
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ReturnValueNotConfiguredException.php27
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/RuntimeException.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/SoapExtensionNotAvailableException.php23
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/UnknownClassException.php28
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/UnknownTraitException.php28
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Exception/UnknownTypeException.php28
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Generator.php1004
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Generator/deprecation.tpl2
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_class.tpl6
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method.tpl22
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method_void.tpl20
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_static_method.tpl5
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method.tpl22
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method_void.tpl22
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Generator/trait_class.tpl6
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_class.tpl9
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_method.tpl4
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Invocation.php254
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/InvocationHandler.php186
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Matcher.php272
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/MethodNameConstraint.php48
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php516
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/MockClass.php69
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/MockMethod.php398
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/MockMethodSet.php45
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/MockObject.php27
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/MockTrait.php54
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/MockType.php21
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Rule/AnyInvokedCount.php36
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Rule/AnyParameters.php31
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Rule/ConsecutiveParameters.php130
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvocationOrder.php47
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtIndex.php75
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastCount.php64
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastOnce.php50
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtMostCount.php64
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedCount.php102
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Rule/MethodName.php68
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Rule/Parameters.php160
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Rule/ParametersRule.php28
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Stub.php26
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ConsecutiveCalls.php57
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Stub/Exception.php46
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnArgument.php41
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnCallback.php59
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnReference.php45
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnSelf.php32
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnStub.php45
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnValueMap.php53
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Stub/Stub.php27
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MockObject/Verifiable.php26
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Reorderable.php28
-rw-r--r--vendor/phpunit/phpunit/src/Framework/SelfDescribing.php21
-rw-r--r--vendor/phpunit/phpunit/src/Framework/SkippedTest.php19
-rw-r--r--vendor/phpunit/phpunit/src/Framework/SkippedTestCase.php66
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Test.php23
-rw-r--r--vendor/phpunit/phpunit/src/Framework/TestBuilder.php239
-rw-r--r--vendor/phpunit/phpunit/src/Framework/TestCase.php2581
-rw-r--r--vendor/phpunit/phpunit/src/Framework/TestFailure.php155
-rw-r--r--vendor/phpunit/phpunit/src/Framework/TestListener.php45
-rw-r--r--vendor/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php59
-rw-r--r--vendor/phpunit/phpunit/src/Framework/TestResult.php1318
-rw-r--r--vendor/phpunit/phpunit/src/Framework/TestSuite.php914
-rw-r--r--vendor/phpunit/phpunit/src/Framework/TestSuiteIterator.php83
-rw-r--r--vendor/phpunit/phpunit/src/Framework/WarningTestCase.php66
187 files changed, 22791 insertions, 0 deletions
diff --git a/vendor/phpunit/phpunit/src/Framework/Assert.php b/vendor/phpunit/phpunit/src/Framework/Assert.php
new file mode 100644
index 000000000..8053f2840
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Assert.php
@@ -0,0 +1,2854 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use const DEBUG_BACKTRACE_IGNORE_ARGS;
+use const PHP_EOL;
+use function array_shift;
+use function array_unshift;
+use function assert;
+use function class_exists;
+use function count;
+use function debug_backtrace;
+use function explode;
+use function file_get_contents;
+use function func_get_args;
+use function implode;
+use function interface_exists;
+use function is_array;
+use function is_bool;
+use function is_int;
+use function is_iterable;
+use function is_object;
+use function is_string;
+use function preg_match;
+use function preg_split;
+use function sprintf;
+use function strpos;
+use ArrayAccess;
+use Countable;
+use DOMAttr;
+use DOMDocument;
+use DOMElement;
+use PHPUnit\Framework\Constraint\ArrayHasKey;
+use PHPUnit\Framework\Constraint\Callback;
+use PHPUnit\Framework\Constraint\ClassHasAttribute;
+use PHPUnit\Framework\Constraint\ClassHasStaticAttribute;
+use PHPUnit\Framework\Constraint\Constraint;
+use PHPUnit\Framework\Constraint\Count;
+use PHPUnit\Framework\Constraint\DirectoryExists;
+use PHPUnit\Framework\Constraint\FileExists;
+use PHPUnit\Framework\Constraint\GreaterThan;
+use PHPUnit\Framework\Constraint\IsAnything;
+use PHPUnit\Framework\Constraint\IsEmpty;
+use PHPUnit\Framework\Constraint\IsEqual;
+use PHPUnit\Framework\Constraint\IsEqualCanonicalizing;
+use PHPUnit\Framework\Constraint\IsEqualIgnoringCase;
+use PHPUnit\Framework\Constraint\IsEqualWithDelta;
+use PHPUnit\Framework\Constraint\IsFalse;
+use PHPUnit\Framework\Constraint\IsFinite;
+use PHPUnit\Framework\Constraint\IsIdentical;
+use PHPUnit\Framework\Constraint\IsInfinite;
+use PHPUnit\Framework\Constraint\IsInstanceOf;
+use PHPUnit\Framework\Constraint\IsJson;
+use PHPUnit\Framework\Constraint\IsNan;
+use PHPUnit\Framework\Constraint\IsNull;
+use PHPUnit\Framework\Constraint\IsReadable;
+use PHPUnit\Framework\Constraint\IsTrue;
+use PHPUnit\Framework\Constraint\IsType;
+use PHPUnit\Framework\Constraint\IsWritable;
+use PHPUnit\Framework\Constraint\JsonMatches;
+use PHPUnit\Framework\Constraint\LessThan;
+use PHPUnit\Framework\Constraint\LogicalAnd;
+use PHPUnit\Framework\Constraint\LogicalNot;
+use PHPUnit\Framework\Constraint\LogicalOr;
+use PHPUnit\Framework\Constraint\LogicalXor;
+use PHPUnit\Framework\Constraint\ObjectEquals;
+use PHPUnit\Framework\Constraint\ObjectHasAttribute;
+use PHPUnit\Framework\Constraint\RegularExpression;
+use PHPUnit\Framework\Constraint\SameSize;
+use PHPUnit\Framework\Constraint\StringContains;
+use PHPUnit\Framework\Constraint\StringEndsWith;
+use PHPUnit\Framework\Constraint\StringMatchesFormatDescription;
+use PHPUnit\Framework\Constraint\StringStartsWith;
+use PHPUnit\Framework\Constraint\TraversableContainsEqual;
+use PHPUnit\Framework\Constraint\TraversableContainsIdentical;
+use PHPUnit\Framework\Constraint\TraversableContainsOnly;
+use PHPUnit\Util\Type;
+use PHPUnit\Util\Xml;
+use PHPUnit\Util\Xml\Loader as XmlLoader;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+abstract class Assert
+{
+ /**
+ * @var int
+ */
+ private static $count = 0;
+
+ /**
+ * Asserts that an array has a specified key.
+ *
+ * @param int|string $key
+ * @param array|ArrayAccess $array
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ */
+ public static function assertArrayHasKey($key, $array, string $message = ''): void
+ {
+ if (!(is_int($key) || is_string($key))) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'integer or string'
+ );
+ }
+
+ if (!(is_array($array) || $array instanceof ArrayAccess)) {
+ throw InvalidArgumentException::create(
+ 2,
+ 'array or ArrayAccess'
+ );
+ }
+
+ $constraint = new ArrayHasKey($key);
+
+ static::assertThat($array, $constraint, $message);
+ }
+
+ /**
+ * Asserts that an array does not have a specified key.
+ *
+ * @param int|string $key
+ * @param array|ArrayAccess $array
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ */
+ public static function assertArrayNotHasKey($key, $array, string $message = ''): void
+ {
+ if (!(is_int($key) || is_string($key))) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'integer or string'
+ );
+ }
+
+ if (!(is_array($array) || $array instanceof ArrayAccess)) {
+ throw InvalidArgumentException::create(
+ 2,
+ 'array or ArrayAccess'
+ );
+ }
+
+ $constraint = new LogicalNot(
+ new ArrayHasKey($key)
+ );
+
+ static::assertThat($array, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a haystack contains a needle.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ */
+ public static function assertContains($needle, iterable $haystack, string $message = ''): void
+ {
+ $constraint = new TraversableContainsIdentical($needle);
+
+ static::assertThat($haystack, $constraint, $message);
+ }
+
+ public static function assertContainsEquals($needle, iterable $haystack, string $message = ''): void
+ {
+ $constraint = new TraversableContainsEqual($needle);
+
+ static::assertThat($haystack, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a haystack does not contain a needle.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ */
+ public static function assertNotContains($needle, iterable $haystack, string $message = ''): void
+ {
+ $constraint = new LogicalNot(
+ new TraversableContainsIdentical($needle)
+ );
+
+ static::assertThat($haystack, $constraint, $message);
+ }
+
+ public static function assertNotContainsEquals($needle, iterable $haystack, string $message = ''): void
+ {
+ $constraint = new LogicalNot(new TraversableContainsEqual($needle));
+
+ static::assertThat($haystack, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a haystack contains only values of a given type.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void
+ {
+ if ($isNativeType === null) {
+ $isNativeType = Type::isType($type);
+ }
+
+ static::assertThat(
+ $haystack,
+ new TraversableContainsOnly(
+ $type,
+ $isNativeType
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a haystack contains only instances of a given class name.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertContainsOnlyInstancesOf(string $className, iterable $haystack, string $message = ''): void
+ {
+ static::assertThat(
+ $haystack,
+ new TraversableContainsOnly(
+ $className,
+ false
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a haystack does not contain only values of a given type.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertNotContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void
+ {
+ if ($isNativeType === null) {
+ $isNativeType = Type::isType($type);
+ }
+
+ static::assertThat(
+ $haystack,
+ new LogicalNot(
+ new TraversableContainsOnly(
+ $type,
+ $isNativeType
+ )
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts the number of elements of an array, Countable or Traversable.
+ *
+ * @param Countable|iterable $haystack
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ */
+ public static function assertCount(int $expectedCount, $haystack, string $message = ''): void
+ {
+ if (!$haystack instanceof Countable && !is_iterable($haystack)) {
+ throw InvalidArgumentException::create(2, 'countable or iterable');
+ }
+
+ static::assertThat(
+ $haystack,
+ new Count($expectedCount),
+ $message
+ );
+ }
+
+ /**
+ * Asserts the number of elements of an array, Countable or Traversable.
+ *
+ * @param Countable|iterable $haystack
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ */
+ public static function assertNotCount(int $expectedCount, $haystack, string $message = ''): void
+ {
+ if (!$haystack instanceof Countable && !is_iterable($haystack)) {
+ throw InvalidArgumentException::create(2, 'countable or iterable');
+ }
+
+ $constraint = new LogicalNot(
+ new Count($expectedCount)
+ );
+
+ static::assertThat($haystack, $constraint, $message);
+ }
+
+ /**
+ * Asserts that two variables are equal.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertEquals($expected, $actual, string $message = ''): void
+ {
+ $constraint = new IsEqual($expected);
+
+ static::assertThat($actual, $constraint, $message);
+ }
+
+ /**
+ * Asserts that two variables are equal (canonicalizing).
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertEqualsCanonicalizing($expected, $actual, string $message = ''): void
+ {
+ $constraint = new IsEqualCanonicalizing($expected);
+
+ static::assertThat($actual, $constraint, $message);
+ }
+
+ /**
+ * Asserts that two variables are equal (ignoring case).
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertEqualsIgnoringCase($expected, $actual, string $message = ''): void
+ {
+ $constraint = new IsEqualIgnoringCase($expected);
+
+ static::assertThat($actual, $constraint, $message);
+ }
+
+ /**
+ * Asserts that two variables are equal (with delta).
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertEqualsWithDelta($expected, $actual, float $delta, string $message = ''): void
+ {
+ $constraint = new IsEqualWithDelta(
+ $expected,
+ $delta
+ );
+
+ static::assertThat($actual, $constraint, $message);
+ }
+
+ /**
+ * Asserts that two variables are not equal.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertNotEquals($expected, $actual, string $message = ''): void
+ {
+ $constraint = new LogicalNot(
+ new IsEqual($expected)
+ );
+
+ static::assertThat($actual, $constraint, $message);
+ }
+
+ /**
+ * Asserts that two variables are not equal (canonicalizing).
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertNotEqualsCanonicalizing($expected, $actual, string $message = ''): void
+ {
+ $constraint = new LogicalNot(
+ new IsEqualCanonicalizing($expected)
+ );
+
+ static::assertThat($actual, $constraint, $message);
+ }
+
+ /**
+ * Asserts that two variables are not equal (ignoring case).
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertNotEqualsIgnoringCase($expected, $actual, string $message = ''): void
+ {
+ $constraint = new LogicalNot(
+ new IsEqualIgnoringCase($expected)
+ );
+
+ static::assertThat($actual, $constraint, $message);
+ }
+
+ /**
+ * Asserts that two variables are not equal (with delta).
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertNotEqualsWithDelta($expected, $actual, float $delta, string $message = ''): void
+ {
+ $constraint = new LogicalNot(
+ new IsEqualWithDelta(
+ $expected,
+ $delta
+ )
+ );
+
+ static::assertThat($actual, $constraint, $message);
+ }
+
+ /**
+ * @throws ExpectationFailedException
+ */
+ public static function assertObjectEquals(object $expected, object $actual, string $method = 'equals', string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ static::objectEquals($expected, $method),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is empty.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert empty $actual
+ */
+ public static function assertEmpty($actual, string $message = ''): void
+ {
+ static::assertThat($actual, static::isEmpty(), $message);
+ }
+
+ /**
+ * Asserts that a variable is not empty.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert !empty $actual
+ */
+ public static function assertNotEmpty($actual, string $message = ''): void
+ {
+ static::assertThat($actual, static::logicalNot(static::isEmpty()), $message);
+ }
+
+ /**
+ * Asserts that a value is greater than another value.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertGreaterThan($expected, $actual, string $message = ''): void
+ {
+ static::assertThat($actual, static::greaterThan($expected), $message);
+ }
+
+ /**
+ * Asserts that a value is greater than or equal to another value.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertGreaterThanOrEqual($expected, $actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ static::greaterThanOrEqual($expected),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a value is smaller than another value.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertLessThan($expected, $actual, string $message = ''): void
+ {
+ static::assertThat($actual, static::lessThan($expected), $message);
+ }
+
+ /**
+ * Asserts that a value is smaller than or equal to another value.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertLessThanOrEqual($expected, $actual, string $message = ''): void
+ {
+ static::assertThat($actual, static::lessThanOrEqual($expected), $message);
+ }
+
+ /**
+ * Asserts that the contents of one file is equal to the contents of another
+ * file.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertFileEquals(string $expected, string $actual, string $message = ''): void
+ {
+ static::assertFileExists($expected, $message);
+ static::assertFileExists($actual, $message);
+
+ $constraint = new IsEqual(file_get_contents($expected));
+
+ static::assertThat(file_get_contents($actual), $constraint, $message);
+ }
+
+ /**
+ * Asserts that the contents of one file is equal to the contents of another
+ * file (canonicalizing).
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertFileEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void
+ {
+ static::assertFileExists($expected, $message);
+ static::assertFileExists($actual, $message);
+
+ $constraint = new IsEqualCanonicalizing(
+ file_get_contents($expected)
+ );
+
+ static::assertThat(file_get_contents($actual), $constraint, $message);
+ }
+
+ /**
+ * Asserts that the contents of one file is equal to the contents of another
+ * file (ignoring case).
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertFileEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void
+ {
+ static::assertFileExists($expected, $message);
+ static::assertFileExists($actual, $message);
+
+ $constraint = new IsEqualIgnoringCase(file_get_contents($expected));
+
+ static::assertThat(file_get_contents($actual), $constraint, $message);
+ }
+
+ /**
+ * Asserts that the contents of one file is not equal to the contents of
+ * another file.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertFileNotEquals(string $expected, string $actual, string $message = ''): void
+ {
+ static::assertFileExists($expected, $message);
+ static::assertFileExists($actual, $message);
+
+ $constraint = new LogicalNot(
+ new IsEqual(file_get_contents($expected))
+ );
+
+ static::assertThat(file_get_contents($actual), $constraint, $message);
+ }
+
+ /**
+ * Asserts that the contents of one file is not equal to the contents of another
+ * file (canonicalizing).
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertFileNotEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void
+ {
+ static::assertFileExists($expected, $message);
+ static::assertFileExists($actual, $message);
+
+ $constraint = new LogicalNot(
+ new IsEqualCanonicalizing(file_get_contents($expected))
+ );
+
+ static::assertThat(file_get_contents($actual), $constraint, $message);
+ }
+
+ /**
+ * Asserts that the contents of one file is not equal to the contents of another
+ * file (ignoring case).
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertFileNotEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void
+ {
+ static::assertFileExists($expected, $message);
+ static::assertFileExists($actual, $message);
+
+ $constraint = new LogicalNot(
+ new IsEqualIgnoringCase(file_get_contents($expected))
+ );
+
+ static::assertThat(file_get_contents($actual), $constraint, $message);
+ }
+
+ /**
+ * Asserts that the contents of a string is equal
+ * to the contents of a file.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringEqualsFile(string $expectedFile, string $actualString, string $message = ''): void
+ {
+ static::assertFileExists($expectedFile, $message);
+
+ $constraint = new IsEqual(file_get_contents($expectedFile));
+
+ static::assertThat($actualString, $constraint, $message);
+ }
+
+ /**
+ * Asserts that the contents of a string is equal
+ * to the contents of a file (canonicalizing).
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void
+ {
+ static::assertFileExists($expectedFile, $message);
+
+ $constraint = new IsEqualCanonicalizing(file_get_contents($expectedFile));
+
+ static::assertThat($actualString, $constraint, $message);
+ }
+
+ /**
+ * Asserts that the contents of a string is equal
+ * to the contents of a file (ignoring case).
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void
+ {
+ static::assertFileExists($expectedFile, $message);
+
+ $constraint = new IsEqualIgnoringCase(file_get_contents($expectedFile));
+
+ static::assertThat($actualString, $constraint, $message);
+ }
+
+ /**
+ * Asserts that the contents of a string is not equal
+ * to the contents of a file.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringNotEqualsFile(string $expectedFile, string $actualString, string $message = ''): void
+ {
+ static::assertFileExists($expectedFile, $message);
+
+ $constraint = new LogicalNot(
+ new IsEqual(file_get_contents($expectedFile))
+ );
+
+ static::assertThat($actualString, $constraint, $message);
+ }
+
+ /**
+ * Asserts that the contents of a string is not equal
+ * to the contents of a file (canonicalizing).
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringNotEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void
+ {
+ static::assertFileExists($expectedFile, $message);
+
+ $constraint = new LogicalNot(
+ new IsEqualCanonicalizing(file_get_contents($expectedFile))
+ );
+
+ static::assertThat($actualString, $constraint, $message);
+ }
+
+ /**
+ * Asserts that the contents of a string is not equal
+ * to the contents of a file (ignoring case).
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringNotEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void
+ {
+ static::assertFileExists($expectedFile, $message);
+
+ $constraint = new LogicalNot(
+ new IsEqualIgnoringCase(file_get_contents($expectedFile))
+ );
+
+ static::assertThat($actualString, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a file/dir is readable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertIsReadable(string $filename, string $message = ''): void
+ {
+ static::assertThat($filename, new IsReadable, $message);
+ }
+
+ /**
+ * Asserts that a file/dir exists and is not readable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertIsNotReadable(string $filename, string $message = ''): void
+ {
+ static::assertThat($filename, new LogicalNot(new IsReadable), $message);
+ }
+
+ /**
+ * Asserts that a file/dir exists and is not readable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4062
+ */
+ public static function assertNotIsReadable(string $filename, string $message = ''): void
+ {
+ self::createWarning('assertNotIsReadable() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertIsNotReadable() instead.');
+
+ static::assertThat($filename, new LogicalNot(new IsReadable), $message);
+ }
+
+ /**
+ * Asserts that a file/dir exists and is writable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertIsWritable(string $filename, string $message = ''): void
+ {
+ static::assertThat($filename, new IsWritable, $message);
+ }
+
+ /**
+ * Asserts that a file/dir exists and is not writable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertIsNotWritable(string $filename, string $message = ''): void
+ {
+ static::assertThat($filename, new LogicalNot(new IsWritable), $message);
+ }
+
+ /**
+ * Asserts that a file/dir exists and is not writable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4065
+ */
+ public static function assertNotIsWritable(string $filename, string $message = ''): void
+ {
+ self::createWarning('assertNotIsWritable() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertIsNotWritable() instead.');
+
+ static::assertThat($filename, new LogicalNot(new IsWritable), $message);
+ }
+
+ /**
+ * Asserts that a directory exists.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertDirectoryExists(string $directory, string $message = ''): void
+ {
+ static::assertThat($directory, new DirectoryExists, $message);
+ }
+
+ /**
+ * Asserts that a directory does not exist.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertDirectoryDoesNotExist(string $directory, string $message = ''): void
+ {
+ static::assertThat($directory, new LogicalNot(new DirectoryExists), $message);
+ }
+
+ /**
+ * Asserts that a directory does not exist.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4068
+ */
+ public static function assertDirectoryNotExists(string $directory, string $message = ''): void
+ {
+ self::createWarning('assertDirectoryNotExists() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertDirectoryDoesNotExist() instead.');
+
+ static::assertThat($directory, new LogicalNot(new DirectoryExists), $message);
+ }
+
+ /**
+ * Asserts that a directory exists and is readable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertDirectoryIsReadable(string $directory, string $message = ''): void
+ {
+ self::assertDirectoryExists($directory, $message);
+ self::assertIsReadable($directory, $message);
+ }
+
+ /**
+ * Asserts that a directory exists and is not readable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertDirectoryIsNotReadable(string $directory, string $message = ''): void
+ {
+ self::assertDirectoryExists($directory, $message);
+ self::assertIsNotReadable($directory, $message);
+ }
+
+ /**
+ * Asserts that a directory exists and is not readable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4071
+ */
+ public static function assertDirectoryNotIsReadable(string $directory, string $message = ''): void
+ {
+ self::createWarning('assertDirectoryNotIsReadable() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertDirectoryIsNotReadable() instead.');
+
+ self::assertDirectoryExists($directory, $message);
+ self::assertIsNotReadable($directory, $message);
+ }
+
+ /**
+ * Asserts that a directory exists and is writable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertDirectoryIsWritable(string $directory, string $message = ''): void
+ {
+ self::assertDirectoryExists($directory, $message);
+ self::assertIsWritable($directory, $message);
+ }
+
+ /**
+ * Asserts that a directory exists and is not writable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertDirectoryIsNotWritable(string $directory, string $message = ''): void
+ {
+ self::assertDirectoryExists($directory, $message);
+ self::assertIsNotWritable($directory, $message);
+ }
+
+ /**
+ * Asserts that a directory exists and is not writable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4074
+ */
+ public static function assertDirectoryNotIsWritable(string $directory, string $message = ''): void
+ {
+ self::createWarning('assertDirectoryNotIsWritable() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertDirectoryIsNotWritable() instead.');
+
+ self::assertDirectoryExists($directory, $message);
+ self::assertIsNotWritable($directory, $message);
+ }
+
+ /**
+ * Asserts that a file exists.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertFileExists(string $filename, string $message = ''): void
+ {
+ static::assertThat($filename, new FileExists, $message);
+ }
+
+ /**
+ * Asserts that a file does not exist.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertFileDoesNotExist(string $filename, string $message = ''): void
+ {
+ static::assertThat($filename, new LogicalNot(new FileExists), $message);
+ }
+
+ /**
+ * Asserts that a file does not exist.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4077
+ */
+ public static function assertFileNotExists(string $filename, string $message = ''): void
+ {
+ self::createWarning('assertFileNotExists() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertFileDoesNotExist() instead.');
+
+ static::assertThat($filename, new LogicalNot(new FileExists), $message);
+ }
+
+ /**
+ * Asserts that a file exists and is readable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertFileIsReadable(string $file, string $message = ''): void
+ {
+ self::assertFileExists($file, $message);
+ self::assertIsReadable($file, $message);
+ }
+
+ /**
+ * Asserts that a file exists and is not readable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertFileIsNotReadable(string $file, string $message = ''): void
+ {
+ self::assertFileExists($file, $message);
+ self::assertIsNotReadable($file, $message);
+ }
+
+ /**
+ * Asserts that a file exists and is not readable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4080
+ */
+ public static function assertFileNotIsReadable(string $file, string $message = ''): void
+ {
+ self::createWarning('assertFileNotIsReadable() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertFileIsNotReadable() instead.');
+
+ self::assertFileExists($file, $message);
+ self::assertIsNotReadable($file, $message);
+ }
+
+ /**
+ * Asserts that a file exists and is writable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertFileIsWritable(string $file, string $message = ''): void
+ {
+ self::assertFileExists($file, $message);
+ self::assertIsWritable($file, $message);
+ }
+
+ /**
+ * Asserts that a file exists and is not writable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertFileIsNotWritable(string $file, string $message = ''): void
+ {
+ self::assertFileExists($file, $message);
+ self::assertIsNotWritable($file, $message);
+ }
+
+ /**
+ * Asserts that a file exists and is not writable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4083
+ */
+ public static function assertFileNotIsWritable(string $file, string $message = ''): void
+ {
+ self::createWarning('assertFileNotIsWritable() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertFileIsNotWritable() instead.');
+
+ self::assertFileExists($file, $message);
+ self::assertIsNotWritable($file, $message);
+ }
+
+ /**
+ * Asserts that a condition is true.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert true $condition
+ */
+ public static function assertTrue($condition, string $message = ''): void
+ {
+ static::assertThat($condition, static::isTrue(), $message);
+ }
+
+ /**
+ * Asserts that a condition is not true.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert !true $condition
+ */
+ public static function assertNotTrue($condition, string $message = ''): void
+ {
+ static::assertThat($condition, static::logicalNot(static::isTrue()), $message);
+ }
+
+ /**
+ * Asserts that a condition is false.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert false $condition
+ */
+ public static function assertFalse($condition, string $message = ''): void
+ {
+ static::assertThat($condition, static::isFalse(), $message);
+ }
+
+ /**
+ * Asserts that a condition is not false.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert !false $condition
+ */
+ public static function assertNotFalse($condition, string $message = ''): void
+ {
+ static::assertThat($condition, static::logicalNot(static::isFalse()), $message);
+ }
+
+ /**
+ * Asserts that a variable is null.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert null $actual
+ */
+ public static function assertNull($actual, string $message = ''): void
+ {
+ static::assertThat($actual, static::isNull(), $message);
+ }
+
+ /**
+ * Asserts that a variable is not null.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert !null $actual
+ */
+ public static function assertNotNull($actual, string $message = ''): void
+ {
+ static::assertThat($actual, static::logicalNot(static::isNull()), $message);
+ }
+
+ /**
+ * Asserts that a variable is finite.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertFinite($actual, string $message = ''): void
+ {
+ static::assertThat($actual, static::isFinite(), $message);
+ }
+
+ /**
+ * Asserts that a variable is infinite.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertInfinite($actual, string $message = ''): void
+ {
+ static::assertThat($actual, static::isInfinite(), $message);
+ }
+
+ /**
+ * Asserts that a variable is nan.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertNan($actual, string $message = ''): void
+ {
+ static::assertThat($actual, static::isNan(), $message);
+ }
+
+ /**
+ * Asserts that a class has a specified attribute.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ */
+ public static function assertClassHasAttribute(string $attributeName, string $className, string $message = ''): void
+ {
+ if (!self::isValidClassAttributeName($attributeName)) {
+ throw InvalidArgumentException::create(1, 'valid attribute name');
+ }
+
+ if (!class_exists($className)) {
+ throw InvalidArgumentException::create(2, 'class name');
+ }
+
+ static::assertThat($className, new ClassHasAttribute($attributeName), $message);
+ }
+
+ /**
+ * Asserts that a class does not have a specified attribute.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ */
+ public static function assertClassNotHasAttribute(string $attributeName, string $className, string $message = ''): void
+ {
+ if (!self::isValidClassAttributeName($attributeName)) {
+ throw InvalidArgumentException::create(1, 'valid attribute name');
+ }
+
+ if (!class_exists($className)) {
+ throw InvalidArgumentException::create(2, 'class name');
+ }
+
+ static::assertThat(
+ $className,
+ new LogicalNot(
+ new ClassHasAttribute($attributeName)
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a class has a specified static attribute.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ */
+ public static function assertClassHasStaticAttribute(string $attributeName, string $className, string $message = ''): void
+ {
+ if (!self::isValidClassAttributeName($attributeName)) {
+ throw InvalidArgumentException::create(1, 'valid attribute name');
+ }
+
+ if (!class_exists($className)) {
+ throw InvalidArgumentException::create(2, 'class name');
+ }
+
+ static::assertThat(
+ $className,
+ new ClassHasStaticAttribute($attributeName),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a class does not have a specified static attribute.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ */
+ public static function assertClassNotHasStaticAttribute(string $attributeName, string $className, string $message = ''): void
+ {
+ if (!self::isValidClassAttributeName($attributeName)) {
+ throw InvalidArgumentException::create(1, 'valid attribute name');
+ }
+
+ if (!class_exists($className)) {
+ throw InvalidArgumentException::create(2, 'class name');
+ }
+
+ static::assertThat(
+ $className,
+ new LogicalNot(
+ new ClassHasStaticAttribute($attributeName)
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that an object has a specified attribute.
+ *
+ * @param object $object
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ */
+ public static function assertObjectHasAttribute(string $attributeName, $object, string $message = ''): void
+ {
+ if (!self::isValidObjectAttributeName($attributeName)) {
+ throw InvalidArgumentException::create(1, 'valid attribute name');
+ }
+
+ if (!is_object($object)) {
+ throw InvalidArgumentException::create(2, 'object');
+ }
+
+ static::assertThat(
+ $object,
+ new ObjectHasAttribute($attributeName),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that an object does not have a specified attribute.
+ *
+ * @param object $object
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ */
+ public static function assertObjectNotHasAttribute(string $attributeName, $object, string $message = ''): void
+ {
+ if (!self::isValidObjectAttributeName($attributeName)) {
+ throw InvalidArgumentException::create(1, 'valid attribute name');
+ }
+
+ if (!is_object($object)) {
+ throw InvalidArgumentException::create(2, 'object');
+ }
+
+ static::assertThat(
+ $object,
+ new LogicalNot(
+ new ObjectHasAttribute($attributeName)
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that two variables have the same type and value.
+ * Used on objects, it asserts that two variables reference
+ * the same object.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-template ExpectedType
+ * @psalm-param ExpectedType $expected
+ * @psalm-assert =ExpectedType $actual
+ */
+ public static function assertSame($expected, $actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new IsIdentical($expected),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that two variables do not have the same type and value.
+ * Used on objects, it asserts that two variables do not reference
+ * the same object.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertNotSame($expected, $actual, string $message = ''): void
+ {
+ if (is_bool($expected) && is_bool($actual)) {
+ static::assertNotEquals($expected, $actual, $message);
+ }
+
+ static::assertThat(
+ $actual,
+ new LogicalNot(
+ new IsIdentical($expected)
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is of a given type.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ *
+ * @psalm-template ExpectedType of object
+ * @psalm-param class-string<ExpectedType> $expected
+ * @psalm-assert =ExpectedType $actual
+ */
+ public static function assertInstanceOf(string $expected, $actual, string $message = ''): void
+ {
+ if (!class_exists($expected) && !interface_exists($expected)) {
+ throw InvalidArgumentException::create(1, 'class or interface name');
+ }
+
+ static::assertThat(
+ $actual,
+ new IsInstanceOf($expected),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is not of a given type.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ *
+ * @psalm-template ExpectedType of object
+ * @psalm-param class-string<ExpectedType> $expected
+ * @psalm-assert !ExpectedType $actual
+ */
+ public static function assertNotInstanceOf(string $expected, $actual, string $message = ''): void
+ {
+ if (!class_exists($expected) && !interface_exists($expected)) {
+ throw InvalidArgumentException::create(1, 'class or interface name');
+ }
+
+ static::assertThat(
+ $actual,
+ new LogicalNot(
+ new IsInstanceOf($expected)
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is of type array.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert array $actual
+ */
+ public static function assertIsArray($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new IsType(IsType::TYPE_ARRAY),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is of type bool.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert bool $actual
+ */
+ public static function assertIsBool($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new IsType(IsType::TYPE_BOOL),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is of type float.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert float $actual
+ */
+ public static function assertIsFloat($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new IsType(IsType::TYPE_FLOAT),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is of type int.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert int $actual
+ */
+ public static function assertIsInt($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new IsType(IsType::TYPE_INT),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is of type numeric.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert numeric $actual
+ */
+ public static function assertIsNumeric($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new IsType(IsType::TYPE_NUMERIC),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is of type object.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert object $actual
+ */
+ public static function assertIsObject($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new IsType(IsType::TYPE_OBJECT),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is of type resource.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert resource $actual
+ */
+ public static function assertIsResource($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new IsType(IsType::TYPE_RESOURCE),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is of type resource and is closed.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert resource $actual
+ */
+ public static function assertIsClosedResource($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new IsType(IsType::TYPE_CLOSED_RESOURCE),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is of type string.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert string $actual
+ */
+ public static function assertIsString($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new IsType(IsType::TYPE_STRING),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is of type scalar.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert scalar $actual
+ */
+ public static function assertIsScalar($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new IsType(IsType::TYPE_SCALAR),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is of type callable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert callable $actual
+ */
+ public static function assertIsCallable($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new IsType(IsType::TYPE_CALLABLE),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is of type iterable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert iterable $actual
+ */
+ public static function assertIsIterable($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new IsType(IsType::TYPE_ITERABLE),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is not of type array.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert !array $actual
+ */
+ public static function assertIsNotArray($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new LogicalNot(new IsType(IsType::TYPE_ARRAY)),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is not of type bool.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert !bool $actual
+ */
+ public static function assertIsNotBool($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new LogicalNot(new IsType(IsType::TYPE_BOOL)),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is not of type float.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert !float $actual
+ */
+ public static function assertIsNotFloat($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new LogicalNot(new IsType(IsType::TYPE_FLOAT)),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is not of type int.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert !int $actual
+ */
+ public static function assertIsNotInt($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new LogicalNot(new IsType(IsType::TYPE_INT)),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is not of type numeric.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert !numeric $actual
+ */
+ public static function assertIsNotNumeric($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new LogicalNot(new IsType(IsType::TYPE_NUMERIC)),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is not of type object.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert !object $actual
+ */
+ public static function assertIsNotObject($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new LogicalNot(new IsType(IsType::TYPE_OBJECT)),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is not of type resource.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert !resource $actual
+ */
+ public static function assertIsNotResource($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new LogicalNot(new IsType(IsType::TYPE_RESOURCE)),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is not of type resource.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert !resource $actual
+ */
+ public static function assertIsNotClosedResource($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new LogicalNot(new IsType(IsType::TYPE_CLOSED_RESOURCE)),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is not of type string.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert !string $actual
+ */
+ public static function assertIsNotString($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new LogicalNot(new IsType(IsType::TYPE_STRING)),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is not of type scalar.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert !scalar $actual
+ */
+ public static function assertIsNotScalar($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new LogicalNot(new IsType(IsType::TYPE_SCALAR)),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is not of type callable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert !callable $actual
+ */
+ public static function assertIsNotCallable($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new LogicalNot(new IsType(IsType::TYPE_CALLABLE)),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is not of type iterable.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-assert !iterable $actual
+ */
+ public static function assertIsNotIterable($actual, string $message = ''): void
+ {
+ static::assertThat(
+ $actual,
+ new LogicalNot(new IsType(IsType::TYPE_ITERABLE)),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a string matches a given regular expression.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertMatchesRegularExpression(string $pattern, string $string, string $message = ''): void
+ {
+ static::assertThat($string, new RegularExpression($pattern), $message);
+ }
+
+ /**
+ * Asserts that a string matches a given regular expression.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4086
+ */
+ public static function assertRegExp(string $pattern, string $string, string $message = ''): void
+ {
+ self::createWarning('assertRegExp() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertMatchesRegularExpression() instead.');
+
+ static::assertThat($string, new RegularExpression($pattern), $message);
+ }
+
+ /**
+ * Asserts that a string does not match a given regular expression.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertDoesNotMatchRegularExpression(string $pattern, string $string, string $message = ''): void
+ {
+ static::assertThat(
+ $string,
+ new LogicalNot(
+ new RegularExpression($pattern)
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a string does not match a given regular expression.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4089
+ */
+ public static function assertNotRegExp(string $pattern, string $string, string $message = ''): void
+ {
+ self::createWarning('assertNotRegExp() is deprecated and will be removed in PHPUnit 10. Refactor your code to use assertDoesNotMatchRegularExpression() instead.');
+
+ static::assertThat(
+ $string,
+ new LogicalNot(
+ new RegularExpression($pattern)
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
+ * is the same.
+ *
+ * @param Countable|iterable $expected
+ * @param Countable|iterable $actual
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ */
+ public static function assertSameSize($expected, $actual, string $message = ''): void
+ {
+ if (!$expected instanceof Countable && !is_iterable($expected)) {
+ throw InvalidArgumentException::create(1, 'countable or iterable');
+ }
+
+ if (!$actual instanceof Countable && !is_iterable($actual)) {
+ throw InvalidArgumentException::create(2, 'countable or iterable');
+ }
+
+ static::assertThat(
+ $actual,
+ new SameSize($expected),
+ $message
+ );
+ }
+
+ /**
+ * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
+ * is not the same.
+ *
+ * @param Countable|iterable $expected
+ * @param Countable|iterable $actual
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ */
+ public static function assertNotSameSize($expected, $actual, string $message = ''): void
+ {
+ if (!$expected instanceof Countable && !is_iterable($expected)) {
+ throw InvalidArgumentException::create(1, 'countable or iterable');
+ }
+
+ if (!$actual instanceof Countable && !is_iterable($actual)) {
+ throw InvalidArgumentException::create(2, 'countable or iterable');
+ }
+
+ static::assertThat(
+ $actual,
+ new LogicalNot(
+ new SameSize($expected)
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a string matches a given format string.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringMatchesFormat(string $format, string $string, string $message = ''): void
+ {
+ static::assertThat($string, new StringMatchesFormatDescription($format), $message);
+ }
+
+ /**
+ * Asserts that a string does not match a given format string.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringNotMatchesFormat(string $format, string $string, string $message = ''): void
+ {
+ static::assertThat(
+ $string,
+ new LogicalNot(
+ new StringMatchesFormatDescription($format)
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a string matches a given format file.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringMatchesFormatFile(string $formatFile, string $string, string $message = ''): void
+ {
+ static::assertFileExists($formatFile, $message);
+
+ static::assertThat(
+ $string,
+ new StringMatchesFormatDescription(
+ file_get_contents($formatFile)
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a string does not match a given format string.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringNotMatchesFormatFile(string $formatFile, string $string, string $message = ''): void
+ {
+ static::assertFileExists($formatFile, $message);
+
+ static::assertThat(
+ $string,
+ new LogicalNot(
+ new StringMatchesFormatDescription(
+ file_get_contents($formatFile)
+ )
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a string starts with a given prefix.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringStartsWith(string $prefix, string $string, string $message = ''): void
+ {
+ static::assertThat($string, new StringStartsWith($prefix), $message);
+ }
+
+ /**
+ * Asserts that a string starts not with a given prefix.
+ *
+ * @param string $prefix
+ * @param string $string
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringStartsNotWith($prefix, $string, string $message = ''): void
+ {
+ static::assertThat(
+ $string,
+ new LogicalNot(
+ new StringStartsWith($prefix)
+ ),
+ $message
+ );
+ }
+
+ /**
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringContainsString(string $needle, string $haystack, string $message = ''): void
+ {
+ $constraint = new StringContains($needle, false);
+
+ static::assertThat($haystack, $constraint, $message);
+ }
+
+ /**
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void
+ {
+ $constraint = new StringContains($needle, true);
+
+ static::assertThat($haystack, $constraint, $message);
+ }
+
+ /**
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringNotContainsString(string $needle, string $haystack, string $message = ''): void
+ {
+ $constraint = new LogicalNot(new StringContains($needle));
+
+ static::assertThat($haystack, $constraint, $message);
+ }
+
+ /**
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringNotContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void
+ {
+ $constraint = new LogicalNot(new StringContains($needle, true));
+
+ static::assertThat($haystack, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a string ends with a given suffix.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringEndsWith(string $suffix, string $string, string $message = ''): void
+ {
+ static::assertThat($string, new StringEndsWith($suffix), $message);
+ }
+
+ /**
+ * Asserts that a string ends not with a given suffix.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertStringEndsNotWith(string $suffix, string $string, string $message = ''): void
+ {
+ static::assertThat(
+ $string,
+ new LogicalNot(
+ new StringEndsWith($suffix)
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that two XML files are equal.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ * @throws ExpectationFailedException
+ */
+ public static function assertXmlFileEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void
+ {
+ $expected = (new XmlLoader)->loadFile($expectedFile);
+ $actual = (new XmlLoader)->loadFile($actualFile);
+
+ static::assertEquals($expected, $actual, $message);
+ }
+
+ /**
+ * Asserts that two XML files are not equal.
+ *
+ * @throws \PHPUnit\Util\Exception
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertXmlFileNotEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void
+ {
+ $expected = (new XmlLoader)->loadFile($expectedFile);
+ $actual = (new XmlLoader)->loadFile($actualFile);
+
+ static::assertNotEquals($expected, $actual, $message);
+ }
+
+ /**
+ * Asserts that two XML documents are equal.
+ *
+ * @param DOMDocument|string $actualXml
+ *
+ * @throws \PHPUnit\Util\Xml\Exception
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertXmlStringEqualsXmlFile(string $expectedFile, $actualXml, string $message = ''): void
+ {
+ if (!is_string($actualXml)) {
+ self::createWarning('Passing an argument of type DOMDocument for the $actualXml parameter is deprecated. Support for this will be removed in PHPUnit 10.');
+
+ $actual = $actualXml;
+ } else {
+ $actual = (new XmlLoader)->load($actualXml);
+ }
+
+ $expected = (new XmlLoader)->loadFile($expectedFile);
+
+ static::assertEquals($expected, $actual, $message);
+ }
+
+ /**
+ * Asserts that two XML documents are not equal.
+ *
+ * @param DOMDocument|string $actualXml
+ *
+ * @throws \PHPUnit\Util\Xml\Exception
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertXmlStringNotEqualsXmlFile(string $expectedFile, $actualXml, string $message = ''): void
+ {
+ if (!is_string($actualXml)) {
+ self::createWarning('Passing an argument of type DOMDocument for the $actualXml parameter is deprecated. Support for this will be removed in PHPUnit 10.');
+
+ $actual = $actualXml;
+ } else {
+ $actual = (new XmlLoader)->load($actualXml);
+ }
+
+ $expected = (new XmlLoader)->loadFile($expectedFile);
+
+ static::assertNotEquals($expected, $actual, $message);
+ }
+
+ /**
+ * Asserts that two XML documents are equal.
+ *
+ * @param DOMDocument|string $expectedXml
+ * @param DOMDocument|string $actualXml
+ *
+ * @throws \PHPUnit\Util\Xml\Exception
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertXmlStringEqualsXmlString($expectedXml, $actualXml, string $message = ''): void
+ {
+ if (!is_string($expectedXml)) {
+ self::createWarning('Passing an argument of type DOMDocument for the $expectedXml parameter is deprecated. Support for this will be removed in PHPUnit 10.');
+
+ $expected = $expectedXml;
+ } else {
+ $expected = (new XmlLoader)->load($expectedXml);
+ }
+
+ if (!is_string($actualXml)) {
+ self::createWarning('Passing an argument of type DOMDocument for the $actualXml parameter is deprecated. Support for this will be removed in PHPUnit 10.');
+
+ $actual = $actualXml;
+ } else {
+ $actual = (new XmlLoader)->load($actualXml);
+ }
+
+ static::assertEquals($expected, $actual, $message);
+ }
+
+ /**
+ * Asserts that two XML documents are not equal.
+ *
+ * @param DOMDocument|string $expectedXml
+ * @param DOMDocument|string $actualXml
+ *
+ * @throws \PHPUnit\Util\Xml\Exception
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, string $message = ''): void
+ {
+ if (!is_string($expectedXml)) {
+ self::createWarning('Passing an argument of type DOMDocument for the $expectedXml parameter is deprecated. Support for this will be removed in PHPUnit 10.');
+
+ $expected = $expectedXml;
+ } else {
+ $expected = (new XmlLoader)->load($expectedXml);
+ }
+
+ if (!is_string($actualXml)) {
+ self::createWarning('Passing an argument of type DOMDocument for the $actualXml parameter is deprecated. Support for this will be removed in PHPUnit 10.');
+
+ $actual = $actualXml;
+ } else {
+ $actual = (new XmlLoader)->load($actualXml);
+ }
+
+ static::assertNotEquals($expected, $actual, $message);
+ }
+
+ /**
+ * Asserts that a hierarchy of DOMElements matches.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws AssertionFailedError
+ * @throws ExpectationFailedException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4091
+ */
+ public static function assertEqualXMLStructure(DOMElement $expectedElement, DOMElement $actualElement, bool $checkAttributes = false, string $message = ''): void
+ {
+ self::createWarning('assertEqualXMLStructure() is deprecated and will be removed in PHPUnit 10.');
+
+ $expectedElement = Xml::import($expectedElement);
+ $actualElement = Xml::import($actualElement);
+
+ static::assertSame(
+ $expectedElement->tagName,
+ $actualElement->tagName,
+ $message
+ );
+
+ if ($checkAttributes) {
+ static::assertSame(
+ $expectedElement->attributes->length,
+ $actualElement->attributes->length,
+ sprintf(
+ '%s%sNumber of attributes on node "%s" does not match',
+ $message,
+ !empty($message) ? "\n" : '',
+ $expectedElement->tagName
+ )
+ );
+
+ for ($i = 0; $i < $expectedElement->attributes->length; $i++) {
+ $expectedAttribute = $expectedElement->attributes->item($i);
+ $actualAttribute = $actualElement->attributes->getNamedItem($expectedAttribute->name);
+
+ assert($expectedAttribute instanceof DOMAttr);
+
+ if (!$actualAttribute) {
+ static::fail(
+ sprintf(
+ '%s%sCould not find attribute "%s" on node "%s"',
+ $message,
+ !empty($message) ? "\n" : '',
+ $expectedAttribute->name,
+ $expectedElement->tagName
+ )
+ );
+ }
+ }
+ }
+
+ Xml::removeCharacterDataNodes($expectedElement);
+ Xml::removeCharacterDataNodes($actualElement);
+
+ static::assertSame(
+ $expectedElement->childNodes->length,
+ $actualElement->childNodes->length,
+ sprintf(
+ '%s%sNumber of child nodes of "%s" differs',
+ $message,
+ !empty($message) ? "\n" : '',
+ $expectedElement->tagName
+ )
+ );
+
+ for ($i = 0; $i < $expectedElement->childNodes->length; $i++) {
+ static::assertEqualXMLStructure(
+ $expectedElement->childNodes->item($i),
+ $actualElement->childNodes->item($i),
+ $checkAttributes,
+ $message
+ );
+ }
+ }
+
+ /**
+ * Evaluates a PHPUnit\Framework\Constraint matcher object.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertThat($value, Constraint $constraint, string $message = ''): void
+ {
+ self::$count += count($constraint);
+
+ $constraint->evaluate($value, $message);
+ }
+
+ /**
+ * Asserts that a string is a valid JSON string.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertJson(string $actualJson, string $message = ''): void
+ {
+ static::assertThat($actualJson, static::isJson(), $message);
+ }
+
+ /**
+ * Asserts that two given JSON encoded objects or arrays are equal.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertJsonStringEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void
+ {
+ static::assertJson($expectedJson, $message);
+ static::assertJson($actualJson, $message);
+
+ static::assertThat($actualJson, new JsonMatches($expectedJson), $message);
+ }
+
+ /**
+ * Asserts that two given JSON encoded objects or arrays are not equal.
+ *
+ * @param string $expectedJson
+ * @param string $actualJson
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, string $message = ''): void
+ {
+ static::assertJson($expectedJson, $message);
+ static::assertJson($actualJson, $message);
+
+ static::assertThat(
+ $actualJson,
+ new LogicalNot(
+ new JsonMatches($expectedJson)
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that the generated JSON encoded object and the content of the given file are equal.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertJsonStringEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void
+ {
+ static::assertFileExists($expectedFile, $message);
+ $expectedJson = file_get_contents($expectedFile);
+
+ static::assertJson($expectedJson, $message);
+ static::assertJson($actualJson, $message);
+
+ static::assertThat($actualJson, new JsonMatches($expectedJson), $message);
+ }
+
+ /**
+ * Asserts that the generated JSON encoded object and the content of the given file are not equal.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertJsonStringNotEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void
+ {
+ static::assertFileExists($expectedFile, $message);
+ $expectedJson = file_get_contents($expectedFile);
+
+ static::assertJson($expectedJson, $message);
+ static::assertJson($actualJson, $message);
+
+ static::assertThat(
+ $actualJson,
+ new LogicalNot(
+ new JsonMatches($expectedJson)
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that two JSON files are equal.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertJsonFileEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void
+ {
+ static::assertFileExists($expectedFile, $message);
+ static::assertFileExists($actualFile, $message);
+
+ $actualJson = file_get_contents($actualFile);
+ $expectedJson = file_get_contents($expectedFile);
+
+ static::assertJson($expectedJson, $message);
+ static::assertJson($actualJson, $message);
+
+ $constraintExpected = new JsonMatches(
+ $expectedJson
+ );
+
+ $constraintActual = new JsonMatches($actualJson);
+
+ static::assertThat($expectedJson, $constraintActual, $message);
+ static::assertThat($actualJson, $constraintExpected, $message);
+ }
+
+ /**
+ * Asserts that two JSON files are not equal.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public static function assertJsonFileNotEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void
+ {
+ static::assertFileExists($expectedFile, $message);
+ static::assertFileExists($actualFile, $message);
+
+ $actualJson = file_get_contents($actualFile);
+ $expectedJson = file_get_contents($expectedFile);
+
+ static::assertJson($expectedJson, $message);
+ static::assertJson($actualJson, $message);
+
+ $constraintExpected = new JsonMatches(
+ $expectedJson
+ );
+
+ $constraintActual = new JsonMatches($actualJson);
+
+ static::assertThat($expectedJson, new LogicalNot($constraintActual), $message);
+ static::assertThat($actualJson, new LogicalNot($constraintExpected), $message);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public static function logicalAnd(): LogicalAnd
+ {
+ $constraints = func_get_args();
+
+ $constraint = new LogicalAnd;
+ $constraint->setConstraints($constraints);
+
+ return $constraint;
+ }
+
+ public static function logicalOr(): LogicalOr
+ {
+ $constraints = func_get_args();
+
+ $constraint = new LogicalOr;
+ $constraint->setConstraints($constraints);
+
+ return $constraint;
+ }
+
+ public static function logicalNot(Constraint $constraint): LogicalNot
+ {
+ return new LogicalNot($constraint);
+ }
+
+ public static function logicalXor(): LogicalXor
+ {
+ $constraints = func_get_args();
+
+ $constraint = new LogicalXor;
+ $constraint->setConstraints($constraints);
+
+ return $constraint;
+ }
+
+ public static function anything(): IsAnything
+ {
+ return new IsAnything;
+ }
+
+ public static function isTrue(): IsTrue
+ {
+ return new IsTrue;
+ }
+
+ /**
+ * @psalm-template CallbackInput of mixed
+ *
+ * @psalm-param callable(CallbackInput $callback): bool $callback
+ *
+ * @psalm-return Callback<CallbackInput>
+ */
+ public static function callback(callable $callback): Callback
+ {
+ return new Callback($callback);
+ }
+
+ public static function isFalse(): IsFalse
+ {
+ return new IsFalse;
+ }
+
+ public static function isJson(): IsJson
+ {
+ return new IsJson;
+ }
+
+ public static function isNull(): IsNull
+ {
+ return new IsNull;
+ }
+
+ public static function isFinite(): IsFinite
+ {
+ return new IsFinite;
+ }
+
+ public static function isInfinite(): IsInfinite
+ {
+ return new IsInfinite;
+ }
+
+ public static function isNan(): IsNan
+ {
+ return new IsNan;
+ }
+
+ public static function containsEqual($value): TraversableContainsEqual
+ {
+ return new TraversableContainsEqual($value);
+ }
+
+ public static function containsIdentical($value): TraversableContainsIdentical
+ {
+ return new TraversableContainsIdentical($value);
+ }
+
+ public static function containsOnly(string $type): TraversableContainsOnly
+ {
+ return new TraversableContainsOnly($type);
+ }
+
+ public static function containsOnlyInstancesOf(string $className): TraversableContainsOnly
+ {
+ return new TraversableContainsOnly($className, false);
+ }
+
+ /**
+ * @param int|string $key
+ */
+ public static function arrayHasKey($key): ArrayHasKey
+ {
+ return new ArrayHasKey($key);
+ }
+
+ public static function equalTo($value): IsEqual
+ {
+ return new IsEqual($value, 0.0, false, false);
+ }
+
+ public static function equalToCanonicalizing($value): IsEqualCanonicalizing
+ {
+ return new IsEqualCanonicalizing($value);
+ }
+
+ public static function equalToIgnoringCase($value): IsEqualIgnoringCase
+ {
+ return new IsEqualIgnoringCase($value);
+ }
+
+ public static function equalToWithDelta($value, float $delta): IsEqualWithDelta
+ {
+ return new IsEqualWithDelta($value, $delta);
+ }
+
+ public static function isEmpty(): IsEmpty
+ {
+ return new IsEmpty;
+ }
+
+ public static function isWritable(): IsWritable
+ {
+ return new IsWritable;
+ }
+
+ public static function isReadable(): IsReadable
+ {
+ return new IsReadable;
+ }
+
+ public static function directoryExists(): DirectoryExists
+ {
+ return new DirectoryExists;
+ }
+
+ public static function fileExists(): FileExists
+ {
+ return new FileExists;
+ }
+
+ public static function greaterThan($value): GreaterThan
+ {
+ return new GreaterThan($value);
+ }
+
+ public static function greaterThanOrEqual($value): LogicalOr
+ {
+ return static::logicalOr(
+ new IsEqual($value),
+ new GreaterThan($value)
+ );
+ }
+
+ public static function classHasAttribute(string $attributeName): ClassHasAttribute
+ {
+ return new ClassHasAttribute($attributeName);
+ }
+
+ public static function classHasStaticAttribute(string $attributeName): ClassHasStaticAttribute
+ {
+ return new ClassHasStaticAttribute($attributeName);
+ }
+
+ public static function objectHasAttribute($attributeName): ObjectHasAttribute
+ {
+ return new ObjectHasAttribute($attributeName);
+ }
+
+ public static function identicalTo($value): IsIdentical
+ {
+ return new IsIdentical($value);
+ }
+
+ public static function isInstanceOf(string $className): IsInstanceOf
+ {
+ return new IsInstanceOf($className);
+ }
+
+ public static function isType(string $type): IsType
+ {
+ return new IsType($type);
+ }
+
+ public static function lessThan($value): LessThan
+ {
+ return new LessThan($value);
+ }
+
+ public static function lessThanOrEqual($value): LogicalOr
+ {
+ return static::logicalOr(
+ new IsEqual($value),
+ new LessThan($value)
+ );
+ }
+
+ public static function matchesRegularExpression(string $pattern): RegularExpression
+ {
+ return new RegularExpression($pattern);
+ }
+
+ public static function matches(string $string): StringMatchesFormatDescription
+ {
+ return new StringMatchesFormatDescription($string);
+ }
+
+ public static function stringStartsWith($prefix): StringStartsWith
+ {
+ return new StringStartsWith($prefix);
+ }
+
+ public static function stringContains(string $string, bool $case = true): StringContains
+ {
+ return new StringContains($string, $case);
+ }
+
+ public static function stringEndsWith(string $suffix): StringEndsWith
+ {
+ return new StringEndsWith($suffix);
+ }
+
+ public static function countOf(int $count): Count
+ {
+ return new Count($count);
+ }
+
+ public static function objectEquals(object $object, string $method = 'equals'): ObjectEquals
+ {
+ return new ObjectEquals($object, $method);
+ }
+
+ /**
+ * Fails a test with the given message.
+ *
+ * @throws AssertionFailedError
+ *
+ * @psalm-return never-return
+ */
+ public static function fail(string $message = ''): void
+ {
+ self::$count++;
+
+ throw new AssertionFailedError($message);
+ }
+
+ /**
+ * Mark the test as incomplete.
+ *
+ * @throws IncompleteTestError
+ *
+ * @psalm-return never-return
+ */
+ public static function markTestIncomplete(string $message = ''): void
+ {
+ throw new IncompleteTestError($message);
+ }
+
+ /**
+ * Mark the test as skipped.
+ *
+ * @throws SkippedTestError
+ * @throws SyntheticSkippedError
+ *
+ * @psalm-return never-return
+ */
+ public static function markTestSkipped(string $message = ''): void
+ {
+ if ($hint = self::detectLocationHint($message)) {
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+ array_unshift($trace, $hint);
+
+ throw new SyntheticSkippedError($hint['message'], 0, $hint['file'], (int) $hint['line'], $trace);
+ }
+
+ throw new SkippedTestError($message);
+ }
+
+ /**
+ * Return the current assertion count.
+ */
+ public static function getCount(): int
+ {
+ return self::$count;
+ }
+
+ /**
+ * Reset the assertion counter.
+ */
+ public static function resetCount(): void
+ {
+ self::$count = 0;
+ }
+
+ private static function detectLocationHint(string $message): ?array
+ {
+ $hint = null;
+ $lines = preg_split('/\r\n|\r|\n/', $message);
+
+ while (strpos($lines[0], '__OFFSET') !== false) {
+ $offset = explode('=', array_shift($lines));
+
+ if ($offset[0] === '__OFFSET_FILE') {
+ $hint['file'] = $offset[1];
+ }
+
+ if ($offset[0] === '__OFFSET_LINE') {
+ $hint['line'] = $offset[1];
+ }
+ }
+
+ if ($hint) {
+ $hint['message'] = implode(PHP_EOL, $lines);
+ }
+
+ return $hint;
+ }
+
+ private static function isValidObjectAttributeName(string $attributeName): bool
+ {
+ return (bool) preg_match('/[^\x00-\x1f\x7f-\x9f]+/', $attributeName);
+ }
+
+ private static function isValidClassAttributeName(string $attributeName): bool
+ {
+ return (bool) preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName);
+ }
+
+ /**
+ * @codeCoverageIgnore
+ */
+ private static function createWarning(string $warning): void
+ {
+ foreach (debug_backtrace() as $step) {
+ if (isset($step['object']) && $step['object'] instanceof TestCase) {
+ assert($step['object'] instanceof TestCase);
+
+ $step['object']->addWarning($warning);
+
+ break;
+ }
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Assert/Functions.php b/vendor/phpunit/phpunit/src/Framework/Assert/Functions.php
new file mode 100644
index 000000000..7c4831d0f
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Assert/Functions.php
@@ -0,0 +1,3035 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use function func_get_args;
+use ArrayAccess;
+use Countable;
+use DOMDocument;
+use DOMElement;
+use PHPUnit\Framework\Constraint\ArrayHasKey;
+use PHPUnit\Framework\Constraint\Callback;
+use PHPUnit\Framework\Constraint\ClassHasAttribute;
+use PHPUnit\Framework\Constraint\ClassHasStaticAttribute;
+use PHPUnit\Framework\Constraint\Constraint;
+use PHPUnit\Framework\Constraint\Count;
+use PHPUnit\Framework\Constraint\DirectoryExists;
+use PHPUnit\Framework\Constraint\FileExists;
+use PHPUnit\Framework\Constraint\GreaterThan;
+use PHPUnit\Framework\Constraint\IsAnything;
+use PHPUnit\Framework\Constraint\IsEmpty;
+use PHPUnit\Framework\Constraint\IsEqual;
+use PHPUnit\Framework\Constraint\IsEqualCanonicalizing;
+use PHPUnit\Framework\Constraint\IsEqualIgnoringCase;
+use PHPUnit\Framework\Constraint\IsEqualWithDelta;
+use PHPUnit\Framework\Constraint\IsFalse;
+use PHPUnit\Framework\Constraint\IsFinite;
+use PHPUnit\Framework\Constraint\IsIdentical;
+use PHPUnit\Framework\Constraint\IsInfinite;
+use PHPUnit\Framework\Constraint\IsInstanceOf;
+use PHPUnit\Framework\Constraint\IsJson;
+use PHPUnit\Framework\Constraint\IsNan;
+use PHPUnit\Framework\Constraint\IsNull;
+use PHPUnit\Framework\Constraint\IsReadable;
+use PHPUnit\Framework\Constraint\IsTrue;
+use PHPUnit\Framework\Constraint\IsType;
+use PHPUnit\Framework\Constraint\IsWritable;
+use PHPUnit\Framework\Constraint\LessThan;
+use PHPUnit\Framework\Constraint\LogicalAnd;
+use PHPUnit\Framework\Constraint\LogicalNot;
+use PHPUnit\Framework\Constraint\LogicalOr;
+use PHPUnit\Framework\Constraint\LogicalXor;
+use PHPUnit\Framework\Constraint\ObjectEquals;
+use PHPUnit\Framework\Constraint\ObjectHasAttribute;
+use PHPUnit\Framework\Constraint\RegularExpression;
+use PHPUnit\Framework\Constraint\StringContains;
+use PHPUnit\Framework\Constraint\StringEndsWith;
+use PHPUnit\Framework\Constraint\StringMatchesFormatDescription;
+use PHPUnit\Framework\Constraint\StringStartsWith;
+use PHPUnit\Framework\Constraint\TraversableContainsEqual;
+use PHPUnit\Framework\Constraint\TraversableContainsIdentical;
+use PHPUnit\Framework\Constraint\TraversableContainsOnly;
+use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount as AnyInvokedCountMatcher;
+use PHPUnit\Framework\MockObject\Rule\InvokedAtIndex as InvokedAtIndexMatcher;
+use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastCount as InvokedAtLeastCountMatcher;
+use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastOnce as InvokedAtLeastOnceMatcher;
+use PHPUnit\Framework\MockObject\Rule\InvokedAtMostCount as InvokedAtMostCountMatcher;
+use PHPUnit\Framework\MockObject\Rule\InvokedCount as InvokedCountMatcher;
+use PHPUnit\Framework\MockObject\Stub\ConsecutiveCalls as ConsecutiveCallsStub;
+use PHPUnit\Framework\MockObject\Stub\Exception as ExceptionStub;
+use PHPUnit\Framework\MockObject\Stub\ReturnArgument as ReturnArgumentStub;
+use PHPUnit\Framework\MockObject\Stub\ReturnCallback as ReturnCallbackStub;
+use PHPUnit\Framework\MockObject\Stub\ReturnSelf as ReturnSelfStub;
+use PHPUnit\Framework\MockObject\Stub\ReturnStub;
+use PHPUnit\Framework\MockObject\Stub\ReturnValueMap as ReturnValueMapStub;
+use Throwable;
+
+if (!function_exists('PHPUnit\Framework\assertArrayHasKey')) {
+ /**
+ * Asserts that an array has a specified key.
+ *
+ * @param int|string $key
+ * @param array|ArrayAccess $array
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertArrayHasKey
+ */
+ function assertArrayHasKey($key, $array, string $message = ''): void
+ {
+ Assert::assertArrayHasKey(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertArrayNotHasKey')) {
+ /**
+ * Asserts that an array does not have a specified key.
+ *
+ * @param int|string $key
+ * @param array|ArrayAccess $array
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertArrayNotHasKey
+ */
+ function assertArrayNotHasKey($key, $array, string $message = ''): void
+ {
+ Assert::assertArrayNotHasKey(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertContains')) {
+ /**
+ * Asserts that a haystack contains a needle.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertContains
+ */
+ function assertContains($needle, iterable $haystack, string $message = ''): void
+ {
+ Assert::assertContains(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertContainsEquals')) {
+ function assertContainsEquals($needle, iterable $haystack, string $message = ''): void
+ {
+ Assert::assertContainsEquals(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotContains')) {
+ /**
+ * Asserts that a haystack does not contain a needle.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotContains
+ */
+ function assertNotContains($needle, iterable $haystack, string $message = ''): void
+ {
+ Assert::assertNotContains(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotContainsEquals')) {
+ function assertNotContainsEquals($needle, iterable $haystack, string $message = ''): void
+ {
+ Assert::assertNotContainsEquals(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertContainsOnly')) {
+ /**
+ * Asserts that a haystack contains only values of a given type.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertContainsOnly
+ */
+ function assertContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void
+ {
+ Assert::assertContainsOnly(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertContainsOnlyInstancesOf')) {
+ /**
+ * Asserts that a haystack contains only instances of a given class name.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertContainsOnlyInstancesOf
+ */
+ function assertContainsOnlyInstancesOf(string $className, iterable $haystack, string $message = ''): void
+ {
+ Assert::assertContainsOnlyInstancesOf(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotContainsOnly')) {
+ /**
+ * Asserts that a haystack does not contain only values of a given type.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotContainsOnly
+ */
+ function assertNotContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void
+ {
+ Assert::assertNotContainsOnly(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertCount')) {
+ /**
+ * Asserts the number of elements of an array, Countable or Traversable.
+ *
+ * @param Countable|iterable $haystack
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertCount
+ */
+ function assertCount(int $expectedCount, $haystack, string $message = ''): void
+ {
+ Assert::assertCount(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotCount')) {
+ /**
+ * Asserts the number of elements of an array, Countable or Traversable.
+ *
+ * @param Countable|iterable $haystack
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotCount
+ */
+ function assertNotCount(int $expectedCount, $haystack, string $message = ''): void
+ {
+ Assert::assertNotCount(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertEquals')) {
+ /**
+ * Asserts that two variables are equal.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertEquals
+ */
+ function assertEquals($expected, $actual, string $message = ''): void
+ {
+ Assert::assertEquals(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertEqualsCanonicalizing')) {
+ /**
+ * Asserts that two variables are equal (canonicalizing).
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertEqualsCanonicalizing
+ */
+ function assertEqualsCanonicalizing($expected, $actual, string $message = ''): void
+ {
+ Assert::assertEqualsCanonicalizing(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertEqualsIgnoringCase')) {
+ /**
+ * Asserts that two variables are equal (ignoring case).
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertEqualsIgnoringCase
+ */
+ function assertEqualsIgnoringCase($expected, $actual, string $message = ''): void
+ {
+ Assert::assertEqualsIgnoringCase(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertEqualsWithDelta')) {
+ /**
+ * Asserts that two variables are equal (with delta).
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertEqualsWithDelta
+ */
+ function assertEqualsWithDelta($expected, $actual, float $delta, string $message = ''): void
+ {
+ Assert::assertEqualsWithDelta(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotEquals')) {
+ /**
+ * Asserts that two variables are not equal.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotEquals
+ */
+ function assertNotEquals($expected, $actual, string $message = ''): void
+ {
+ Assert::assertNotEquals(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotEqualsCanonicalizing')) {
+ /**
+ * Asserts that two variables are not equal (canonicalizing).
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotEqualsCanonicalizing
+ */
+ function assertNotEqualsCanonicalizing($expected, $actual, string $message = ''): void
+ {
+ Assert::assertNotEqualsCanonicalizing(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotEqualsIgnoringCase')) {
+ /**
+ * Asserts that two variables are not equal (ignoring case).
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotEqualsIgnoringCase
+ */
+ function assertNotEqualsIgnoringCase($expected, $actual, string $message = ''): void
+ {
+ Assert::assertNotEqualsIgnoringCase(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotEqualsWithDelta')) {
+ /**
+ * Asserts that two variables are not equal (with delta).
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotEqualsWithDelta
+ */
+ function assertNotEqualsWithDelta($expected, $actual, float $delta, string $message = ''): void
+ {
+ Assert::assertNotEqualsWithDelta(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertObjectEquals')) {
+ /**
+ * @throws ExpectationFailedException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertObjectEquals
+ */
+ function assertObjectEquals(object $expected, object $actual, string $method = 'equals', string $message = ''): void
+ {
+ Assert::assertObjectEquals(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertEmpty')) {
+ /**
+ * Asserts that a variable is empty.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert empty $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertEmpty
+ */
+ function assertEmpty($actual, string $message = ''): void
+ {
+ Assert::assertEmpty(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotEmpty')) {
+ /**
+ * Asserts that a variable is not empty.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert !empty $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotEmpty
+ */
+ function assertNotEmpty($actual, string $message = ''): void
+ {
+ Assert::assertNotEmpty(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertGreaterThan')) {
+ /**
+ * Asserts that a value is greater than another value.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertGreaterThan
+ */
+ function assertGreaterThan($expected, $actual, string $message = ''): void
+ {
+ Assert::assertGreaterThan(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertGreaterThanOrEqual')) {
+ /**
+ * Asserts that a value is greater than or equal to another value.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertGreaterThanOrEqual
+ */
+ function assertGreaterThanOrEqual($expected, $actual, string $message = ''): void
+ {
+ Assert::assertGreaterThanOrEqual(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertLessThan')) {
+ /**
+ * Asserts that a value is smaller than another value.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertLessThan
+ */
+ function assertLessThan($expected, $actual, string $message = ''): void
+ {
+ Assert::assertLessThan(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertLessThanOrEqual')) {
+ /**
+ * Asserts that a value is smaller than or equal to another value.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertLessThanOrEqual
+ */
+ function assertLessThanOrEqual($expected, $actual, string $message = ''): void
+ {
+ Assert::assertLessThanOrEqual(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFileEquals')) {
+ /**
+ * Asserts that the contents of one file is equal to the contents of another
+ * file.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFileEquals
+ */
+ function assertFileEquals(string $expected, string $actual, string $message = ''): void
+ {
+ Assert::assertFileEquals(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFileEqualsCanonicalizing')) {
+ /**
+ * Asserts that the contents of one file is equal to the contents of another
+ * file (canonicalizing).
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFileEqualsCanonicalizing
+ */
+ function assertFileEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void
+ {
+ Assert::assertFileEqualsCanonicalizing(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFileEqualsIgnoringCase')) {
+ /**
+ * Asserts that the contents of one file is equal to the contents of another
+ * file (ignoring case).
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFileEqualsIgnoringCase
+ */
+ function assertFileEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void
+ {
+ Assert::assertFileEqualsIgnoringCase(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFileNotEquals')) {
+ /**
+ * Asserts that the contents of one file is not equal to the contents of
+ * another file.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFileNotEquals
+ */
+ function assertFileNotEquals(string $expected, string $actual, string $message = ''): void
+ {
+ Assert::assertFileNotEquals(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFileNotEqualsCanonicalizing')) {
+ /**
+ * Asserts that the contents of one file is not equal to the contents of another
+ * file (canonicalizing).
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFileNotEqualsCanonicalizing
+ */
+ function assertFileNotEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void
+ {
+ Assert::assertFileNotEqualsCanonicalizing(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFileNotEqualsIgnoringCase')) {
+ /**
+ * Asserts that the contents of one file is not equal to the contents of another
+ * file (ignoring case).
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFileNotEqualsIgnoringCase
+ */
+ function assertFileNotEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void
+ {
+ Assert::assertFileNotEqualsIgnoringCase(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringEqualsFile')) {
+ /**
+ * Asserts that the contents of a string is equal
+ * to the contents of a file.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringEqualsFile
+ */
+ function assertStringEqualsFile(string $expectedFile, string $actualString, string $message = ''): void
+ {
+ Assert::assertStringEqualsFile(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringEqualsFileCanonicalizing')) {
+ /**
+ * Asserts that the contents of a string is equal
+ * to the contents of a file (canonicalizing).
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringEqualsFileCanonicalizing
+ */
+ function assertStringEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void
+ {
+ Assert::assertStringEqualsFileCanonicalizing(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringEqualsFileIgnoringCase')) {
+ /**
+ * Asserts that the contents of a string is equal
+ * to the contents of a file (ignoring case).
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringEqualsFileIgnoringCase
+ */
+ function assertStringEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void
+ {
+ Assert::assertStringEqualsFileIgnoringCase(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringNotEqualsFile')) {
+ /**
+ * Asserts that the contents of a string is not equal
+ * to the contents of a file.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringNotEqualsFile
+ */
+ function assertStringNotEqualsFile(string $expectedFile, string $actualString, string $message = ''): void
+ {
+ Assert::assertStringNotEqualsFile(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringNotEqualsFileCanonicalizing')) {
+ /**
+ * Asserts that the contents of a string is not equal
+ * to the contents of a file (canonicalizing).
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringNotEqualsFileCanonicalizing
+ */
+ function assertStringNotEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void
+ {
+ Assert::assertStringNotEqualsFileCanonicalizing(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringNotEqualsFileIgnoringCase')) {
+ /**
+ * Asserts that the contents of a string is not equal
+ * to the contents of a file (ignoring case).
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringNotEqualsFileIgnoringCase
+ */
+ function assertStringNotEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void
+ {
+ Assert::assertStringNotEqualsFileIgnoringCase(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsReadable')) {
+ /**
+ * Asserts that a file/dir is readable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsReadable
+ */
+ function assertIsReadable(string $filename, string $message = ''): void
+ {
+ Assert::assertIsReadable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsNotReadable')) {
+ /**
+ * Asserts that a file/dir exists and is not readable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsNotReadable
+ */
+ function assertIsNotReadable(string $filename, string $message = ''): void
+ {
+ Assert::assertIsNotReadable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotIsReadable')) {
+ /**
+ * Asserts that a file/dir exists and is not readable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4062
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotIsReadable
+ */
+ function assertNotIsReadable(string $filename, string $message = ''): void
+ {
+ Assert::assertNotIsReadable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsWritable')) {
+ /**
+ * Asserts that a file/dir exists and is writable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsWritable
+ */
+ function assertIsWritable(string $filename, string $message = ''): void
+ {
+ Assert::assertIsWritable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsNotWritable')) {
+ /**
+ * Asserts that a file/dir exists and is not writable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsNotWritable
+ */
+ function assertIsNotWritable(string $filename, string $message = ''): void
+ {
+ Assert::assertIsNotWritable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotIsWritable')) {
+ /**
+ * Asserts that a file/dir exists and is not writable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4065
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotIsWritable
+ */
+ function assertNotIsWritable(string $filename, string $message = ''): void
+ {
+ Assert::assertNotIsWritable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertDirectoryExists')) {
+ /**
+ * Asserts that a directory exists.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertDirectoryExists
+ */
+ function assertDirectoryExists(string $directory, string $message = ''): void
+ {
+ Assert::assertDirectoryExists(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertDirectoryDoesNotExist')) {
+ /**
+ * Asserts that a directory does not exist.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertDirectoryDoesNotExist
+ */
+ function assertDirectoryDoesNotExist(string $directory, string $message = ''): void
+ {
+ Assert::assertDirectoryDoesNotExist(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertDirectoryNotExists')) {
+ /**
+ * Asserts that a directory does not exist.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4068
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertDirectoryNotExists
+ */
+ function assertDirectoryNotExists(string $directory, string $message = ''): void
+ {
+ Assert::assertDirectoryNotExists(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertDirectoryIsReadable')) {
+ /**
+ * Asserts that a directory exists and is readable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertDirectoryIsReadable
+ */
+ function assertDirectoryIsReadable(string $directory, string $message = ''): void
+ {
+ Assert::assertDirectoryIsReadable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertDirectoryIsNotReadable')) {
+ /**
+ * Asserts that a directory exists and is not readable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertDirectoryIsNotReadable
+ */
+ function assertDirectoryIsNotReadable(string $directory, string $message = ''): void
+ {
+ Assert::assertDirectoryIsNotReadable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertDirectoryNotIsReadable')) {
+ /**
+ * Asserts that a directory exists and is not readable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4071
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertDirectoryNotIsReadable
+ */
+ function assertDirectoryNotIsReadable(string $directory, string $message = ''): void
+ {
+ Assert::assertDirectoryNotIsReadable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertDirectoryIsWritable')) {
+ /**
+ * Asserts that a directory exists and is writable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertDirectoryIsWritable
+ */
+ function assertDirectoryIsWritable(string $directory, string $message = ''): void
+ {
+ Assert::assertDirectoryIsWritable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertDirectoryIsNotWritable')) {
+ /**
+ * Asserts that a directory exists and is not writable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertDirectoryIsNotWritable
+ */
+ function assertDirectoryIsNotWritable(string $directory, string $message = ''): void
+ {
+ Assert::assertDirectoryIsNotWritable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertDirectoryNotIsWritable')) {
+ /**
+ * Asserts that a directory exists and is not writable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4074
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertDirectoryNotIsWritable
+ */
+ function assertDirectoryNotIsWritable(string $directory, string $message = ''): void
+ {
+ Assert::assertDirectoryNotIsWritable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFileExists')) {
+ /**
+ * Asserts that a file exists.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFileExists
+ */
+ function assertFileExists(string $filename, string $message = ''): void
+ {
+ Assert::assertFileExists(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFileDoesNotExist')) {
+ /**
+ * Asserts that a file does not exist.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFileDoesNotExist
+ */
+ function assertFileDoesNotExist(string $filename, string $message = ''): void
+ {
+ Assert::assertFileDoesNotExist(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFileNotExists')) {
+ /**
+ * Asserts that a file does not exist.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4077
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFileNotExists
+ */
+ function assertFileNotExists(string $filename, string $message = ''): void
+ {
+ Assert::assertFileNotExists(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFileIsReadable')) {
+ /**
+ * Asserts that a file exists and is readable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFileIsReadable
+ */
+ function assertFileIsReadable(string $file, string $message = ''): void
+ {
+ Assert::assertFileIsReadable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFileIsNotReadable')) {
+ /**
+ * Asserts that a file exists and is not readable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFileIsNotReadable
+ */
+ function assertFileIsNotReadable(string $file, string $message = ''): void
+ {
+ Assert::assertFileIsNotReadable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFileNotIsReadable')) {
+ /**
+ * Asserts that a file exists and is not readable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4080
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFileNotIsReadable
+ */
+ function assertFileNotIsReadable(string $file, string $message = ''): void
+ {
+ Assert::assertFileNotIsReadable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFileIsWritable')) {
+ /**
+ * Asserts that a file exists and is writable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFileIsWritable
+ */
+ function assertFileIsWritable(string $file, string $message = ''): void
+ {
+ Assert::assertFileIsWritable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFileIsNotWritable')) {
+ /**
+ * Asserts that a file exists and is not writable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFileIsNotWritable
+ */
+ function assertFileIsNotWritable(string $file, string $message = ''): void
+ {
+ Assert::assertFileIsNotWritable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFileNotIsWritable')) {
+ /**
+ * Asserts that a file exists and is not writable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4083
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFileNotIsWritable
+ */
+ function assertFileNotIsWritable(string $file, string $message = ''): void
+ {
+ Assert::assertFileNotIsWritable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertTrue')) {
+ /**
+ * Asserts that a condition is true.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert true $condition
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertTrue
+ */
+ function assertTrue($condition, string $message = ''): void
+ {
+ Assert::assertTrue(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotTrue')) {
+ /**
+ * Asserts that a condition is not true.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert !true $condition
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotTrue
+ */
+ function assertNotTrue($condition, string $message = ''): void
+ {
+ Assert::assertNotTrue(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFalse')) {
+ /**
+ * Asserts that a condition is false.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert false $condition
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFalse
+ */
+ function assertFalse($condition, string $message = ''): void
+ {
+ Assert::assertFalse(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotFalse')) {
+ /**
+ * Asserts that a condition is not false.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert !false $condition
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotFalse
+ */
+ function assertNotFalse($condition, string $message = ''): void
+ {
+ Assert::assertNotFalse(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNull')) {
+ /**
+ * Asserts that a variable is null.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert null $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNull
+ */
+ function assertNull($actual, string $message = ''): void
+ {
+ Assert::assertNull(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotNull')) {
+ /**
+ * Asserts that a variable is not null.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert !null $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotNull
+ */
+ function assertNotNull($actual, string $message = ''): void
+ {
+ Assert::assertNotNull(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertFinite')) {
+ /**
+ * Asserts that a variable is finite.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertFinite
+ */
+ function assertFinite($actual, string $message = ''): void
+ {
+ Assert::assertFinite(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertInfinite')) {
+ /**
+ * Asserts that a variable is infinite.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertInfinite
+ */
+ function assertInfinite($actual, string $message = ''): void
+ {
+ Assert::assertInfinite(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNan')) {
+ /**
+ * Asserts that a variable is nan.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNan
+ */
+ function assertNan($actual, string $message = ''): void
+ {
+ Assert::assertNan(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertClassHasAttribute')) {
+ /**
+ * Asserts that a class has a specified attribute.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertClassHasAttribute
+ */
+ function assertClassHasAttribute(string $attributeName, string $className, string $message = ''): void
+ {
+ Assert::assertClassHasAttribute(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertClassNotHasAttribute')) {
+ /**
+ * Asserts that a class does not have a specified attribute.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertClassNotHasAttribute
+ */
+ function assertClassNotHasAttribute(string $attributeName, string $className, string $message = ''): void
+ {
+ Assert::assertClassNotHasAttribute(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertClassHasStaticAttribute')) {
+ /**
+ * Asserts that a class has a specified static attribute.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertClassHasStaticAttribute
+ */
+ function assertClassHasStaticAttribute(string $attributeName, string $className, string $message = ''): void
+ {
+ Assert::assertClassHasStaticAttribute(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertClassNotHasStaticAttribute')) {
+ /**
+ * Asserts that a class does not have a specified static attribute.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertClassNotHasStaticAttribute
+ */
+ function assertClassNotHasStaticAttribute(string $attributeName, string $className, string $message = ''): void
+ {
+ Assert::assertClassNotHasStaticAttribute(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertObjectHasAttribute')) {
+ /**
+ * Asserts that an object has a specified attribute.
+ *
+ * @param object $object
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertObjectHasAttribute
+ */
+ function assertObjectHasAttribute(string $attributeName, $object, string $message = ''): void
+ {
+ Assert::assertObjectHasAttribute(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertObjectNotHasAttribute')) {
+ /**
+ * Asserts that an object does not have a specified attribute.
+ *
+ * @param object $object
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertObjectNotHasAttribute
+ */
+ function assertObjectNotHasAttribute(string $attributeName, $object, string $message = ''): void
+ {
+ Assert::assertObjectNotHasAttribute(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertSame')) {
+ /**
+ * Asserts that two variables have the same type and value.
+ * Used on objects, it asserts that two variables reference
+ * the same object.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-template ExpectedType
+ * @psalm-param ExpectedType $expected
+ * @psalm-assert =ExpectedType $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertSame
+ */
+ function assertSame($expected, $actual, string $message = ''): void
+ {
+ Assert::assertSame(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotSame')) {
+ /**
+ * Asserts that two variables do not have the same type and value.
+ * Used on objects, it asserts that two variables do not reference
+ * the same object.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotSame
+ */
+ function assertNotSame($expected, $actual, string $message = ''): void
+ {
+ Assert::assertNotSame(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertInstanceOf')) {
+ /**
+ * Asserts that a variable is of a given type.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @psalm-template ExpectedType of object
+ * @psalm-param class-string<ExpectedType> $expected
+ * @psalm-assert =ExpectedType $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertInstanceOf
+ */
+ function assertInstanceOf(string $expected, $actual, string $message = ''): void
+ {
+ Assert::assertInstanceOf(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotInstanceOf')) {
+ /**
+ * Asserts that a variable is not of a given type.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @psalm-template ExpectedType of object
+ * @psalm-param class-string<ExpectedType> $expected
+ * @psalm-assert !ExpectedType $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotInstanceOf
+ */
+ function assertNotInstanceOf(string $expected, $actual, string $message = ''): void
+ {
+ Assert::assertNotInstanceOf(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsArray')) {
+ /**
+ * Asserts that a variable is of type array.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert array $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsArray
+ */
+ function assertIsArray($actual, string $message = ''): void
+ {
+ Assert::assertIsArray(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsBool')) {
+ /**
+ * Asserts that a variable is of type bool.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert bool $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsBool
+ */
+ function assertIsBool($actual, string $message = ''): void
+ {
+ Assert::assertIsBool(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsFloat')) {
+ /**
+ * Asserts that a variable is of type float.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert float $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsFloat
+ */
+ function assertIsFloat($actual, string $message = ''): void
+ {
+ Assert::assertIsFloat(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsInt')) {
+ /**
+ * Asserts that a variable is of type int.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert int $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsInt
+ */
+ function assertIsInt($actual, string $message = ''): void
+ {
+ Assert::assertIsInt(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsNumeric')) {
+ /**
+ * Asserts that a variable is of type numeric.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert numeric $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsNumeric
+ */
+ function assertIsNumeric($actual, string $message = ''): void
+ {
+ Assert::assertIsNumeric(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsObject')) {
+ /**
+ * Asserts that a variable is of type object.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert object $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsObject
+ */
+ function assertIsObject($actual, string $message = ''): void
+ {
+ Assert::assertIsObject(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsResource')) {
+ /**
+ * Asserts that a variable is of type resource.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert resource $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsResource
+ */
+ function assertIsResource($actual, string $message = ''): void
+ {
+ Assert::assertIsResource(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsClosedResource')) {
+ /**
+ * Asserts that a variable is of type resource and is closed.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert resource $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsClosedResource
+ */
+ function assertIsClosedResource($actual, string $message = ''): void
+ {
+ Assert::assertIsClosedResource(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsString')) {
+ /**
+ * Asserts that a variable is of type string.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert string $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsString
+ */
+ function assertIsString($actual, string $message = ''): void
+ {
+ Assert::assertIsString(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsScalar')) {
+ /**
+ * Asserts that a variable is of type scalar.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert scalar $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsScalar
+ */
+ function assertIsScalar($actual, string $message = ''): void
+ {
+ Assert::assertIsScalar(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsCallable')) {
+ /**
+ * Asserts that a variable is of type callable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert callable $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsCallable
+ */
+ function assertIsCallable($actual, string $message = ''): void
+ {
+ Assert::assertIsCallable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsIterable')) {
+ /**
+ * Asserts that a variable is of type iterable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert iterable $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsIterable
+ */
+ function assertIsIterable($actual, string $message = ''): void
+ {
+ Assert::assertIsIterable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsNotArray')) {
+ /**
+ * Asserts that a variable is not of type array.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert !array $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsNotArray
+ */
+ function assertIsNotArray($actual, string $message = ''): void
+ {
+ Assert::assertIsNotArray(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsNotBool')) {
+ /**
+ * Asserts that a variable is not of type bool.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert !bool $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsNotBool
+ */
+ function assertIsNotBool($actual, string $message = ''): void
+ {
+ Assert::assertIsNotBool(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsNotFloat')) {
+ /**
+ * Asserts that a variable is not of type float.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert !float $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsNotFloat
+ */
+ function assertIsNotFloat($actual, string $message = ''): void
+ {
+ Assert::assertIsNotFloat(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsNotInt')) {
+ /**
+ * Asserts that a variable is not of type int.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert !int $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsNotInt
+ */
+ function assertIsNotInt($actual, string $message = ''): void
+ {
+ Assert::assertIsNotInt(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsNotNumeric')) {
+ /**
+ * Asserts that a variable is not of type numeric.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert !numeric $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsNotNumeric
+ */
+ function assertIsNotNumeric($actual, string $message = ''): void
+ {
+ Assert::assertIsNotNumeric(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsNotObject')) {
+ /**
+ * Asserts that a variable is not of type object.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert !object $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsNotObject
+ */
+ function assertIsNotObject($actual, string $message = ''): void
+ {
+ Assert::assertIsNotObject(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsNotResource')) {
+ /**
+ * Asserts that a variable is not of type resource.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert !resource $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsNotResource
+ */
+ function assertIsNotResource($actual, string $message = ''): void
+ {
+ Assert::assertIsNotResource(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsNotClosedResource')) {
+ /**
+ * Asserts that a variable is not of type resource.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert !resource $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsNotClosedResource
+ */
+ function assertIsNotClosedResource($actual, string $message = ''): void
+ {
+ Assert::assertIsNotClosedResource(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsNotString')) {
+ /**
+ * Asserts that a variable is not of type string.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert !string $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsNotString
+ */
+ function assertIsNotString($actual, string $message = ''): void
+ {
+ Assert::assertIsNotString(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsNotScalar')) {
+ /**
+ * Asserts that a variable is not of type scalar.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert !scalar $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsNotScalar
+ */
+ function assertIsNotScalar($actual, string $message = ''): void
+ {
+ Assert::assertIsNotScalar(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsNotCallable')) {
+ /**
+ * Asserts that a variable is not of type callable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert !callable $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsNotCallable
+ */
+ function assertIsNotCallable($actual, string $message = ''): void
+ {
+ Assert::assertIsNotCallable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertIsNotIterable')) {
+ /**
+ * Asserts that a variable is not of type iterable.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @psalm-assert !iterable $actual
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertIsNotIterable
+ */
+ function assertIsNotIterable($actual, string $message = ''): void
+ {
+ Assert::assertIsNotIterable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertMatchesRegularExpression')) {
+ /**
+ * Asserts that a string matches a given regular expression.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertMatchesRegularExpression
+ */
+ function assertMatchesRegularExpression(string $pattern, string $string, string $message = ''): void
+ {
+ Assert::assertMatchesRegularExpression(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertRegExp')) {
+ /**
+ * Asserts that a string matches a given regular expression.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4086
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertRegExp
+ */
+ function assertRegExp(string $pattern, string $string, string $message = ''): void
+ {
+ Assert::assertRegExp(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertDoesNotMatchRegularExpression')) {
+ /**
+ * Asserts that a string does not match a given regular expression.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertDoesNotMatchRegularExpression
+ */
+ function assertDoesNotMatchRegularExpression(string $pattern, string $string, string $message = ''): void
+ {
+ Assert::assertDoesNotMatchRegularExpression(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotRegExp')) {
+ /**
+ * Asserts that a string does not match a given regular expression.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4089
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotRegExp
+ */
+ function assertNotRegExp(string $pattern, string $string, string $message = ''): void
+ {
+ Assert::assertNotRegExp(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertSameSize')) {
+ /**
+ * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
+ * is the same.
+ *
+ * @param Countable|iterable $expected
+ * @param Countable|iterable $actual
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertSameSize
+ */
+ function assertSameSize($expected, $actual, string $message = ''): void
+ {
+ Assert::assertSameSize(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertNotSameSize')) {
+ /**
+ * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
+ * is not the same.
+ *
+ * @param Countable|iterable $expected
+ * @param Countable|iterable $actual
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertNotSameSize
+ */
+ function assertNotSameSize($expected, $actual, string $message = ''): void
+ {
+ Assert::assertNotSameSize(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringMatchesFormat')) {
+ /**
+ * Asserts that a string matches a given format string.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringMatchesFormat
+ */
+ function assertStringMatchesFormat(string $format, string $string, string $message = ''): void
+ {
+ Assert::assertStringMatchesFormat(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringNotMatchesFormat')) {
+ /**
+ * Asserts that a string does not match a given format string.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringNotMatchesFormat
+ */
+ function assertStringNotMatchesFormat(string $format, string $string, string $message = ''): void
+ {
+ Assert::assertStringNotMatchesFormat(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringMatchesFormatFile')) {
+ /**
+ * Asserts that a string matches a given format file.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringMatchesFormatFile
+ */
+ function assertStringMatchesFormatFile(string $formatFile, string $string, string $message = ''): void
+ {
+ Assert::assertStringMatchesFormatFile(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringNotMatchesFormatFile')) {
+ /**
+ * Asserts that a string does not match a given format string.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringNotMatchesFormatFile
+ */
+ function assertStringNotMatchesFormatFile(string $formatFile, string $string, string $message = ''): void
+ {
+ Assert::assertStringNotMatchesFormatFile(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringStartsWith')) {
+ /**
+ * Asserts that a string starts with a given prefix.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringStartsWith
+ */
+ function assertStringStartsWith(string $prefix, string $string, string $message = ''): void
+ {
+ Assert::assertStringStartsWith(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringStartsNotWith')) {
+ /**
+ * Asserts that a string starts not with a given prefix.
+ *
+ * @param string $prefix
+ * @param string $string
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringStartsNotWith
+ */
+ function assertStringStartsNotWith($prefix, $string, string $message = ''): void
+ {
+ Assert::assertStringStartsNotWith(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringContainsString')) {
+ /**
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringContainsString
+ */
+ function assertStringContainsString(string $needle, string $haystack, string $message = ''): void
+ {
+ Assert::assertStringContainsString(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringContainsStringIgnoringCase')) {
+ /**
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringContainsStringIgnoringCase
+ */
+ function assertStringContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void
+ {
+ Assert::assertStringContainsStringIgnoringCase(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringNotContainsString')) {
+ /**
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringNotContainsString
+ */
+ function assertStringNotContainsString(string $needle, string $haystack, string $message = ''): void
+ {
+ Assert::assertStringNotContainsString(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringNotContainsStringIgnoringCase')) {
+ /**
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringNotContainsStringIgnoringCase
+ */
+ function assertStringNotContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void
+ {
+ Assert::assertStringNotContainsStringIgnoringCase(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringEndsWith')) {
+ /**
+ * Asserts that a string ends with a given suffix.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringEndsWith
+ */
+ function assertStringEndsWith(string $suffix, string $string, string $message = ''): void
+ {
+ Assert::assertStringEndsWith(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertStringEndsNotWith')) {
+ /**
+ * Asserts that a string ends not with a given suffix.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertStringEndsNotWith
+ */
+ function assertStringEndsNotWith(string $suffix, string $string, string $message = ''): void
+ {
+ Assert::assertStringEndsNotWith(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertXmlFileEqualsXmlFile')) {
+ /**
+ * Asserts that two XML files are equal.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertXmlFileEqualsXmlFile
+ */
+ function assertXmlFileEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void
+ {
+ Assert::assertXmlFileEqualsXmlFile(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertXmlFileNotEqualsXmlFile')) {
+ /**
+ * Asserts that two XML files are not equal.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws \PHPUnit\Util\Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertXmlFileNotEqualsXmlFile
+ */
+ function assertXmlFileNotEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void
+ {
+ Assert::assertXmlFileNotEqualsXmlFile(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertXmlStringEqualsXmlFile')) {
+ /**
+ * Asserts that two XML documents are equal.
+ *
+ * @param DOMDocument|string $actualXml
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws \PHPUnit\Util\Xml\Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertXmlStringEqualsXmlFile
+ */
+ function assertXmlStringEqualsXmlFile(string $expectedFile, $actualXml, string $message = ''): void
+ {
+ Assert::assertXmlStringEqualsXmlFile(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertXmlStringNotEqualsXmlFile')) {
+ /**
+ * Asserts that two XML documents are not equal.
+ *
+ * @param DOMDocument|string $actualXml
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws \PHPUnit\Util\Xml\Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertXmlStringNotEqualsXmlFile
+ */
+ function assertXmlStringNotEqualsXmlFile(string $expectedFile, $actualXml, string $message = ''): void
+ {
+ Assert::assertXmlStringNotEqualsXmlFile(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertXmlStringEqualsXmlString')) {
+ /**
+ * Asserts that two XML documents are equal.
+ *
+ * @param DOMDocument|string $expectedXml
+ * @param DOMDocument|string $actualXml
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws \PHPUnit\Util\Xml\Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertXmlStringEqualsXmlString
+ */
+ function assertXmlStringEqualsXmlString($expectedXml, $actualXml, string $message = ''): void
+ {
+ Assert::assertXmlStringEqualsXmlString(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertXmlStringNotEqualsXmlString')) {
+ /**
+ * Asserts that two XML documents are not equal.
+ *
+ * @param DOMDocument|string $expectedXml
+ * @param DOMDocument|string $actualXml
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws \PHPUnit\Util\Xml\Exception
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertXmlStringNotEqualsXmlString
+ */
+ function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, string $message = ''): void
+ {
+ Assert::assertXmlStringNotEqualsXmlString(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertEqualXMLStructure')) {
+ /**
+ * Asserts that a hierarchy of DOMElements matches.
+ *
+ * @throws AssertionFailedError
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @codeCoverageIgnore
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4091
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertEqualXMLStructure
+ */
+ function assertEqualXMLStructure(DOMElement $expectedElement, DOMElement $actualElement, bool $checkAttributes = false, string $message = ''): void
+ {
+ Assert::assertEqualXMLStructure(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertThat')) {
+ /**
+ * Evaluates a PHPUnit\Framework\Constraint matcher object.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertThat
+ */
+ function assertThat($value, Constraint $constraint, string $message = ''): void
+ {
+ Assert::assertThat(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertJson')) {
+ /**
+ * Asserts that a string is a valid JSON string.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertJson
+ */
+ function assertJson(string $actualJson, string $message = ''): void
+ {
+ Assert::assertJson(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertJsonStringEqualsJsonString')) {
+ /**
+ * Asserts that two given JSON encoded objects or arrays are equal.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertJsonStringEqualsJsonString
+ */
+ function assertJsonStringEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void
+ {
+ Assert::assertJsonStringEqualsJsonString(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertJsonStringNotEqualsJsonString')) {
+ /**
+ * Asserts that two given JSON encoded objects or arrays are not equal.
+ *
+ * @param string $expectedJson
+ * @param string $actualJson
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertJsonStringNotEqualsJsonString
+ */
+ function assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, string $message = ''): void
+ {
+ Assert::assertJsonStringNotEqualsJsonString(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertJsonStringEqualsJsonFile')) {
+ /**
+ * Asserts that the generated JSON encoded object and the content of the given file are equal.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertJsonStringEqualsJsonFile
+ */
+ function assertJsonStringEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void
+ {
+ Assert::assertJsonStringEqualsJsonFile(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertJsonStringNotEqualsJsonFile')) {
+ /**
+ * Asserts that the generated JSON encoded object and the content of the given file are not equal.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertJsonStringNotEqualsJsonFile
+ */
+ function assertJsonStringNotEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void
+ {
+ Assert::assertJsonStringNotEqualsJsonFile(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertJsonFileEqualsJsonFile')) {
+ /**
+ * Asserts that two JSON files are equal.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertJsonFileEqualsJsonFile
+ */
+ function assertJsonFileEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void
+ {
+ Assert::assertJsonFileEqualsJsonFile(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\assertJsonFileNotEqualsJsonFile')) {
+ /**
+ * Asserts that two JSON files are not equal.
+ *
+ * @throws ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @see Assert::assertJsonFileNotEqualsJsonFile
+ */
+ function assertJsonFileNotEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void
+ {
+ Assert::assertJsonFileNotEqualsJsonFile(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\logicalAnd')) {
+ function logicalAnd(): LogicalAnd
+ {
+ return Assert::logicalAnd(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\logicalOr')) {
+ function logicalOr(): LogicalOr
+ {
+ return Assert::logicalOr(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\logicalNot')) {
+ function logicalNot(Constraint $constraint): LogicalNot
+ {
+ return Assert::logicalNot(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\logicalXor')) {
+ function logicalXor(): LogicalXor
+ {
+ return Assert::logicalXor(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\anything')) {
+ function anything(): IsAnything
+ {
+ return Assert::anything(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\isTrue')) {
+ function isTrue(): IsTrue
+ {
+ return Assert::isTrue(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\callback')) {
+ function callback(callable $callback): Callback
+ {
+ return Assert::callback(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\isFalse')) {
+ function isFalse(): IsFalse
+ {
+ return Assert::isFalse(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\isJson')) {
+ function isJson(): IsJson
+ {
+ return Assert::isJson(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\isNull')) {
+ function isNull(): IsNull
+ {
+ return Assert::isNull(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\isFinite')) {
+ function isFinite(): IsFinite
+ {
+ return Assert::isFinite(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\isInfinite')) {
+ function isInfinite(): IsInfinite
+ {
+ return Assert::isInfinite(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\isNan')) {
+ function isNan(): IsNan
+ {
+ return Assert::isNan(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\containsEqual')) {
+ function containsEqual($value): TraversableContainsEqual
+ {
+ return Assert::containsEqual(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\containsIdentical')) {
+ function containsIdentical($value): TraversableContainsIdentical
+ {
+ return Assert::containsIdentical(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\containsOnly')) {
+ function containsOnly(string $type): TraversableContainsOnly
+ {
+ return Assert::containsOnly(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\containsOnlyInstancesOf')) {
+ function containsOnlyInstancesOf(string $className): TraversableContainsOnly
+ {
+ return Assert::containsOnlyInstancesOf(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\arrayHasKey')) {
+ function arrayHasKey($key): ArrayHasKey
+ {
+ return Assert::arrayHasKey(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\equalTo')) {
+ function equalTo($value): IsEqual
+ {
+ return Assert::equalTo(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\equalToCanonicalizing')) {
+ function equalToCanonicalizing($value): IsEqualCanonicalizing
+ {
+ return Assert::equalToCanonicalizing(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\equalToIgnoringCase')) {
+ function equalToIgnoringCase($value): IsEqualIgnoringCase
+ {
+ return Assert::equalToIgnoringCase(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\equalToWithDelta')) {
+ function equalToWithDelta($value, float $delta): IsEqualWithDelta
+ {
+ return Assert::equalToWithDelta(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\isEmpty')) {
+ function isEmpty(): IsEmpty
+ {
+ return Assert::isEmpty(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\isWritable')) {
+ function isWritable(): IsWritable
+ {
+ return Assert::isWritable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\isReadable')) {
+ function isReadable(): IsReadable
+ {
+ return Assert::isReadable(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\directoryExists')) {
+ function directoryExists(): DirectoryExists
+ {
+ return Assert::directoryExists(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\fileExists')) {
+ function fileExists(): FileExists
+ {
+ return Assert::fileExists(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\greaterThan')) {
+ function greaterThan($value): GreaterThan
+ {
+ return Assert::greaterThan(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\greaterThanOrEqual')) {
+ function greaterThanOrEqual($value): LogicalOr
+ {
+ return Assert::greaterThanOrEqual(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\classHasAttribute')) {
+ function classHasAttribute(string $attributeName): ClassHasAttribute
+ {
+ return Assert::classHasAttribute(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\classHasStaticAttribute')) {
+ function classHasStaticAttribute(string $attributeName): ClassHasStaticAttribute
+ {
+ return Assert::classHasStaticAttribute(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\objectHasAttribute')) {
+ function objectHasAttribute($attributeName): ObjectHasAttribute
+ {
+ return Assert::objectHasAttribute(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\identicalTo')) {
+ function identicalTo($value): IsIdentical
+ {
+ return Assert::identicalTo(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\isInstanceOf')) {
+ function isInstanceOf(string $className): IsInstanceOf
+ {
+ return Assert::isInstanceOf(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\isType')) {
+ function isType(string $type): IsType
+ {
+ return Assert::isType(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\lessThan')) {
+ function lessThan($value): LessThan
+ {
+ return Assert::lessThan(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\lessThanOrEqual')) {
+ function lessThanOrEqual($value): LogicalOr
+ {
+ return Assert::lessThanOrEqual(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\matchesRegularExpression')) {
+ function matchesRegularExpression(string $pattern): RegularExpression
+ {
+ return Assert::matchesRegularExpression(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\matches')) {
+ function matches(string $string): StringMatchesFormatDescription
+ {
+ return Assert::matches(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\stringStartsWith')) {
+ function stringStartsWith($prefix): StringStartsWith
+ {
+ return Assert::stringStartsWith(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\stringContains')) {
+ function stringContains(string $string, bool $case = true): StringContains
+ {
+ return Assert::stringContains(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\stringEndsWith')) {
+ function stringEndsWith(string $suffix): StringEndsWith
+ {
+ return Assert::stringEndsWith(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\countOf')) {
+ function countOf(int $count): Count
+ {
+ return Assert::countOf(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\objectEquals')) {
+ function objectEquals(object $object, string $method = 'equals'): ObjectEquals
+ {
+ return Assert::objectEquals(...func_get_args());
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\any')) {
+ /**
+ * Returns a matcher that matches when the method is executed
+ * zero or more times.
+ */
+ function any(): AnyInvokedCountMatcher
+ {
+ return new AnyInvokedCountMatcher;
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\never')) {
+ /**
+ * Returns a matcher that matches when the method is never executed.
+ */
+ function never(): InvokedCountMatcher
+ {
+ return new InvokedCountMatcher(0);
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\atLeast')) {
+ /**
+ * Returns a matcher that matches when the method is executed
+ * at least N times.
+ */
+ function atLeast(int $requiredInvocations): InvokedAtLeastCountMatcher
+ {
+ return new InvokedAtLeastCountMatcher(
+ $requiredInvocations
+ );
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\atLeastOnce')) {
+ /**
+ * Returns a matcher that matches when the method is executed at least once.
+ */
+ function atLeastOnce(): InvokedAtLeastOnceMatcher
+ {
+ return new InvokedAtLeastOnceMatcher;
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\once')) {
+ /**
+ * Returns a matcher that matches when the method is executed exactly once.
+ */
+ function once(): InvokedCountMatcher
+ {
+ return new InvokedCountMatcher(1);
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\exactly')) {
+ /**
+ * Returns a matcher that matches when the method is executed
+ * exactly $count times.
+ */
+ function exactly(int $count): InvokedCountMatcher
+ {
+ return new InvokedCountMatcher($count);
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\atMost')) {
+ /**
+ * Returns a matcher that matches when the method is executed
+ * at most N times.
+ */
+ function atMost(int $allowedInvocations): InvokedAtMostCountMatcher
+ {
+ return new InvokedAtMostCountMatcher($allowedInvocations);
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\at')) {
+ /**
+ * Returns a matcher that matches when the method is executed
+ * at the given index.
+ */
+ function at(int $index): InvokedAtIndexMatcher
+ {
+ return new InvokedAtIndexMatcher($index);
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\returnValue')) {
+ function returnValue($value): ReturnStub
+ {
+ return new ReturnStub($value);
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\returnValueMap')) {
+ function returnValueMap(array $valueMap): ReturnValueMapStub
+ {
+ return new ReturnValueMapStub($valueMap);
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\returnArgument')) {
+ function returnArgument(int $argumentIndex): ReturnArgumentStub
+ {
+ return new ReturnArgumentStub($argumentIndex);
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\returnCallback')) {
+ function returnCallback($callback): ReturnCallbackStub
+ {
+ return new ReturnCallbackStub($callback);
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\returnSelf')) {
+ /**
+ * Returns the current object.
+ *
+ * This method is useful when mocking a fluent interface.
+ */
+ function returnSelf(): ReturnSelfStub
+ {
+ return new ReturnSelfStub;
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\throwException')) {
+ function throwException(Throwable $exception): ExceptionStub
+ {
+ return new ExceptionStub($exception);
+ }
+}
+
+if (!function_exists('PHPUnit\Framework\onConsecutiveCalls')) {
+ function onConsecutiveCalls(): ConsecutiveCallsStub
+ {
+ $args = func_get_args();
+
+ return new ConsecutiveCallsStub($args);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Boolean/IsFalse.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Boolean/IsFalse.php
new file mode 100644
index 000000000..212e2bcb4
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Boolean/IsFalse.php
@@ -0,0 +1,35 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsFalse extends Constraint
+{
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'is false';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return $other === false;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Boolean/IsTrue.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Boolean/IsTrue.php
new file mode 100644
index 000000000..e1d6b2691
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Boolean/IsTrue.php
@@ -0,0 +1,35 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsTrue extends Constraint
+{
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'is true';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return $other === true;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Callback.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Callback.php
new file mode 100644
index 000000000..b7cf95a12
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Callback.php
@@ -0,0 +1,52 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+/**
+ * @psalm-template CallbackInput of mixed
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class Callback extends Constraint
+{
+ /**
+ * @var callable
+ *
+ * @psalm-var callable(CallbackInput $input): bool
+ */
+ private $callback;
+
+ /** @psalm-param callable(CallbackInput $input): bool $callback */
+ public function __construct(callable $callback)
+ {
+ $this->callback = $callback;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'is accepted by specified callback';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $value. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ *
+ * @psalm-param CallbackInput $other
+ */
+ protected function matches($other): bool
+ {
+ return ($this->callback)($other);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/Count.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/Count.php
new file mode 100644
index 000000000..8e27fbfd4
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/Count.php
@@ -0,0 +1,142 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function count;
+use function is_array;
+use function iterator_count;
+use function sprintf;
+use Countable;
+use EmptyIterator;
+use Generator;
+use Iterator;
+use IteratorAggregate;
+use PHPUnit\Framework\Exception;
+use Traversable;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+class Count extends Constraint
+{
+ /**
+ * @var int
+ */
+ private $expectedCount;
+
+ public function __construct(int $expected)
+ {
+ $this->expectedCount = $expected;
+ }
+
+ public function toString(): string
+ {
+ return sprintf(
+ 'count matches %d',
+ $this->expectedCount
+ );
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @throws Exception
+ */
+ protected function matches($other): bool
+ {
+ return $this->expectedCount === $this->getCountOf($other);
+ }
+
+ /**
+ * @throws Exception
+ */
+ protected function getCountOf($other): ?int
+ {
+ if ($other instanceof Countable || is_array($other)) {
+ return count($other);
+ }
+
+ if ($other instanceof EmptyIterator) {
+ return 0;
+ }
+
+ if ($other instanceof Traversable) {
+ while ($other instanceof IteratorAggregate) {
+ try {
+ $other = $other->getIterator();
+ } catch (\Exception $e) {
+ throw new Exception(
+ $e->getMessage(),
+ $e->getCode(),
+ $e
+ );
+ }
+ }
+
+ $iterator = $other;
+
+ if ($iterator instanceof Generator) {
+ return $this->getCountOfGenerator($iterator);
+ }
+
+ if (!$iterator instanceof Iterator) {
+ return iterator_count($iterator);
+ }
+
+ $key = $iterator->key();
+ $count = iterator_count($iterator);
+
+ // Manually rewind $iterator to previous key, since iterator_count
+ // moves pointer.
+ if ($key !== null) {
+ $iterator->rewind();
+
+ while ($iterator->valid() && $key !== $iterator->key()) {
+ $iterator->next();
+ }
+ }
+
+ return $count;
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the total number of iterations from a generator.
+ * This will fully exhaust the generator.
+ */
+ protected function getCountOfGenerator(Generator $generator): int
+ {
+ for ($count = 0; $generator->valid(); $generator->next()) {
+ $count++;
+ }
+
+ return $count;
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ */
+ protected function failureDescription($other): string
+ {
+ return sprintf(
+ 'actual size %d matches expected size %d',
+ (int) $this->getCountOf($other),
+ $this->expectedCount
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/GreaterThan.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/GreaterThan.php
new file mode 100644
index 000000000..31df50201
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/GreaterThan.php
@@ -0,0 +1,50 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class GreaterThan extends Constraint
+{
+ /**
+ * @var float|int
+ */
+ private $value;
+
+ /**
+ * @param float|int $value
+ */
+ public function __construct($value)
+ {
+ $this->value = $value;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ public function toString(): string
+ {
+ return 'is greater than ' . $this->exporter()->export($this->value);
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return $this->value < $other;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/IsEmpty.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/IsEmpty.php
new file mode 100644
index 000000000..e6371d536
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/IsEmpty.php
@@ -0,0 +1,70 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function count;
+use function gettype;
+use function sprintf;
+use function strpos;
+use Countable;
+use EmptyIterator;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsEmpty extends Constraint
+{
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'is empty';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ if ($other instanceof EmptyIterator) {
+ return true;
+ }
+
+ if ($other instanceof Countable) {
+ return count($other) === 0;
+ }
+
+ return empty($other);
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ */
+ protected function failureDescription($other): string
+ {
+ $type = gettype($other);
+
+ return sprintf(
+ '%s %s %s',
+ strpos($type, 'a') === 0 || strpos($type, 'o') === 0 ? 'an' : 'a',
+ $type,
+ $this->toString()
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/LessThan.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/LessThan.php
new file mode 100644
index 000000000..c7884ba1d
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/LessThan.php
@@ -0,0 +1,50 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class LessThan extends Constraint
+{
+ /**
+ * @var float|int
+ */
+ private $value;
+
+ /**
+ * @param float|int $value
+ */
+ public function __construct($value)
+ {
+ $this->value = $value;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ public function toString(): string
+ {
+ return 'is less than ' . $this->exporter()->export($this->value);
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return $this->value > $other;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/SameSize.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/SameSize.php
new file mode 100644
index 000000000..a54679425
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Cardinality/SameSize.php
@@ -0,0 +1,21 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class SameSize extends Count
+{
+ public function __construct(iterable $expected)
+ {
+ parent::__construct((int) $this->getCountOf($expected));
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Constraint.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Constraint.php
new file mode 100644
index 000000000..f4fab056e
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Constraint.php
@@ -0,0 +1,269 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function sprintf;
+use Countable;
+use PHPUnit\Framework\ExpectationFailedException;
+use PHPUnit\Framework\SelfDescribing;
+use SebastianBergmann\Comparator\ComparisonFailure;
+use SebastianBergmann\Exporter\Exporter;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+abstract class Constraint implements Countable, SelfDescribing
+{
+ /**
+ * @var ?Exporter
+ */
+ private $exporter;
+
+ /**
+ * Evaluates the constraint for parameter $other.
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public function evaluate($other, string $description = '', bool $returnResult = false): ?bool
+ {
+ $success = false;
+
+ if ($this->matches($other)) {
+ $success = true;
+ }
+
+ if ($returnResult) {
+ return $success;
+ }
+
+ if (!$success) {
+ $this->fail($other, $description);
+ }
+
+ return null;
+ }
+
+ /**
+ * Counts the number of constraint elements.
+ */
+ public function count(): int
+ {
+ return 1;
+ }
+
+ protected function exporter(): Exporter
+ {
+ if ($this->exporter === null) {
+ $this->exporter = new Exporter;
+ }
+
+ return $this->exporter;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * This method can be overridden to implement the evaluation algorithm.
+ *
+ * @param mixed $other value or object to evaluate
+ * @codeCoverageIgnore
+ */
+ protected function matches($other): bool
+ {
+ return false;
+ }
+
+ /**
+ * Throws an exception for the given compared value and test description.
+ *
+ * @param mixed $other evaluated value or object
+ * @param string $description Additional information about the test
+ * @param ComparisonFailure $comparisonFailure
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-return never-return
+ */
+ protected function fail($other, $description, ComparisonFailure $comparisonFailure = null): void
+ {
+ $failureDescription = sprintf(
+ 'Failed asserting that %s.',
+ $this->failureDescription($other)
+ );
+
+ $additionalFailureDescription = $this->additionalFailureDescription($other);
+
+ if ($additionalFailureDescription) {
+ $failureDescription .= "\n" . $additionalFailureDescription;
+ }
+
+ if (!empty($description)) {
+ $failureDescription = $description . "\n" . $failureDescription;
+ }
+
+ throw new ExpectationFailedException(
+ $failureDescription,
+ $comparisonFailure
+ );
+ }
+
+ /**
+ * Return additional failure description where needed.
+ *
+ * The function can be overridden to provide additional failure
+ * information like a diff
+ *
+ * @param mixed $other evaluated value or object
+ */
+ protected function additionalFailureDescription($other): string
+ {
+ return '';
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * To provide additional failure information additionalFailureDescription
+ * can be used.
+ *
+ * @param mixed $other evaluated value or object
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ protected function failureDescription($other): string
+ {
+ return $this->exporter()->export($other) . ' ' . $this->toString();
+ }
+
+ /**
+ * Returns a custom string representation of the constraint object when it
+ * appears in context of an $operator expression.
+ *
+ * The purpose of this method is to provide meaningful descriptive string
+ * in context of operators such as LogicalNot. Native PHPUnit constraints
+ * are supported out of the box by LogicalNot, but externally developed
+ * ones had no way to provide correct strings in this context.
+ *
+ * The method shall return empty string, when it does not handle
+ * customization by itself.
+ *
+ * @param Operator $operator the $operator of the expression
+ * @param mixed $role role of $this constraint in the $operator expression
+ */
+ protected function toStringInContext(Operator $operator, $role): string
+ {
+ return '';
+ }
+
+ /**
+ * Returns the description of the failure when this constraint appears in
+ * context of an $operator expression.
+ *
+ * The purpose of this method is to provide meaningful failure description
+ * in context of operators such as LogicalNot. Native PHPUnit constraints
+ * are supported out of the box by LogicalNot, but externally developed
+ * ones had no way to provide correct messages in this context.
+ *
+ * The method shall return empty string, when it does not handle
+ * customization by itself.
+ *
+ * @param Operator $operator the $operator of the expression
+ * @param mixed $role role of $this constraint in the $operator expression
+ * @param mixed $other evaluated value or object
+ */
+ protected function failureDescriptionInContext(Operator $operator, $role, $other): string
+ {
+ $string = $this->toStringInContext($operator, $role);
+
+ if ($string === '') {
+ return '';
+ }
+
+ return $this->exporter()->export($other) . ' ' . $string;
+ }
+
+ /**
+ * Reduces the sub-expression starting at $this by skipping degenerate
+ * sub-expression and returns first descendant constraint that starts
+ * a non-reducible sub-expression.
+ *
+ * Returns $this for terminal constraints and for operators that start
+ * non-reducible sub-expression, or the nearest descendant of $this that
+ * starts a non-reducible sub-expression.
+ *
+ * A constraint expression may be modelled as a tree with non-terminal
+ * nodes (operators) and terminal nodes. For example:
+ *
+ * LogicalOr (operator, non-terminal)
+ * + LogicalAnd (operator, non-terminal)
+ * | + IsType('int') (terminal)
+ * | + GreaterThan(10) (terminal)
+ * + LogicalNot (operator, non-terminal)
+ * + IsType('array') (terminal)
+ *
+ * A degenerate sub-expression is a part of the tree, that effectively does
+ * not contribute to the evaluation of the expression it appears in. An example
+ * of degenerate sub-expression is a BinaryOperator constructed with single
+ * operand or nested BinaryOperators, each with single operand. An
+ * expression involving a degenerate sub-expression is equivalent to a
+ * reduced expression with the degenerate sub-expression removed, for example
+ *
+ * LogicalAnd (operator)
+ * + LogicalOr (degenerate operator)
+ * | + LogicalAnd (degenerate operator)
+ * | + IsType('int') (terminal)
+ * + GreaterThan(10) (terminal)
+ *
+ * is equivalent to
+ *
+ * LogicalAnd (operator)
+ * + IsType('int') (terminal)
+ * + GreaterThan(10) (terminal)
+ *
+ * because the subexpression
+ *
+ * + LogicalOr
+ * + LogicalAnd
+ * + -
+ *
+ * is degenerate. Calling reduce() on the LogicalOr object above, as well
+ * as on LogicalAnd, shall return the IsType('int') instance.
+ *
+ * Other specific reductions can be implemented, for example cascade of
+ * LogicalNot operators
+ *
+ * + LogicalNot
+ * + LogicalNot
+ * +LogicalNot
+ * + IsTrue
+ *
+ * can be reduced to
+ *
+ * LogicalNot
+ * + IsTrue
+ */
+ protected function reduce(): self
+ {
+ return $this;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqual.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqual.php
new file mode 100644
index 000000000..6a61ebfba
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqual.php
@@ -0,0 +1,138 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function is_string;
+use function sprintf;
+use function strpos;
+use function trim;
+use PHPUnit\Framework\ExpectationFailedException;
+use SebastianBergmann\Comparator\ComparisonFailure;
+use SebastianBergmann\Comparator\Factory as ComparatorFactory;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsEqual extends Constraint
+{
+ /**
+ * @var mixed
+ */
+ private $value;
+
+ /**
+ * @var float
+ */
+ private $delta;
+
+ /**
+ * @var bool
+ */
+ private $canonicalize;
+
+ /**
+ * @var bool
+ */
+ private $ignoreCase;
+
+ public function __construct($value, float $delta = 0.0, bool $canonicalize = false, bool $ignoreCase = false)
+ {
+ $this->value = $value;
+ $this->delta = $delta;
+ $this->canonicalize = $canonicalize;
+ $this->ignoreCase = $ignoreCase;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other.
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @throws ExpectationFailedException
+ *
+ * @return bool
+ */
+ public function evaluate($other, string $description = '', bool $returnResult = false): ?bool
+ {
+ // If $this->value and $other are identical, they are also equal.
+ // This is the most common path and will allow us to skip
+ // initialization of all the comparators.
+ if ($this->value === $other) {
+ return true;
+ }
+
+ $comparatorFactory = ComparatorFactory::getInstance();
+
+ try {
+ $comparator = $comparatorFactory->getComparatorFor(
+ $this->value,
+ $other
+ );
+
+ $comparator->assertEquals(
+ $this->value,
+ $other,
+ $this->delta,
+ $this->canonicalize,
+ $this->ignoreCase
+ );
+ } catch (ComparisonFailure $f) {
+ if ($returnResult) {
+ return false;
+ }
+
+ throw new ExpectationFailedException(
+ trim($description . "\n" . $f->getMessage()),
+ $f
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ public function toString(): string
+ {
+ $delta = '';
+
+ if (is_string($this->value)) {
+ if (strpos($this->value, "\n") !== false) {
+ return 'is equal to <text>';
+ }
+
+ return sprintf(
+ "is equal to '%s'",
+ $this->value
+ );
+ }
+
+ if ($this->delta != 0) {
+ $delta = sprintf(
+ ' with delta <%F>',
+ $this->delta
+ );
+ }
+
+ return sprintf(
+ 'is equal to %s%s',
+ $this->exporter()->export($this->value),
+ $delta
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqualCanonicalizing.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqualCanonicalizing.php
new file mode 100644
index 000000000..57bb91ca1
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqualCanonicalizing.php
@@ -0,0 +1,108 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function is_string;
+use function sprintf;
+use function strpos;
+use function trim;
+use PHPUnit\Framework\ExpectationFailedException;
+use SebastianBergmann\Comparator\ComparisonFailure;
+use SebastianBergmann\Comparator\Factory as ComparatorFactory;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsEqualCanonicalizing extends Constraint
+{
+ /**
+ * @var mixed
+ */
+ private $value;
+
+ public function __construct($value)
+ {
+ $this->value = $value;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other.
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @throws ExpectationFailedException
+ */
+ public function evaluate($other, string $description = '', bool $returnResult = false): ?bool
+ {
+ // If $this->value and $other are identical, they are also equal.
+ // This is the most common path and will allow us to skip
+ // initialization of all the comparators.
+ if ($this->value === $other) {
+ return true;
+ }
+
+ $comparatorFactory = ComparatorFactory::getInstance();
+
+ try {
+ $comparator = $comparatorFactory->getComparatorFor(
+ $this->value,
+ $other
+ );
+
+ $comparator->assertEquals(
+ $this->value,
+ $other,
+ 0.0,
+ true,
+ false
+ );
+ } catch (ComparisonFailure $f) {
+ if ($returnResult) {
+ return false;
+ }
+
+ throw new ExpectationFailedException(
+ trim($description . "\n" . $f->getMessage()),
+ $f
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ public function toString(): string
+ {
+ if (is_string($this->value)) {
+ if (strpos($this->value, "\n") !== false) {
+ return 'is equal to <text>';
+ }
+
+ return sprintf(
+ "is equal to '%s'",
+ $this->value
+ );
+ }
+
+ return sprintf(
+ 'is equal to %s',
+ $this->exporter()->export($this->value)
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqualIgnoringCase.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqualIgnoringCase.php
new file mode 100644
index 000000000..d657e96a2
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqualIgnoringCase.php
@@ -0,0 +1,108 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function is_string;
+use function sprintf;
+use function strpos;
+use function trim;
+use PHPUnit\Framework\ExpectationFailedException;
+use SebastianBergmann\Comparator\ComparisonFailure;
+use SebastianBergmann\Comparator\Factory as ComparatorFactory;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsEqualIgnoringCase extends Constraint
+{
+ /**
+ * @var mixed
+ */
+ private $value;
+
+ public function __construct($value)
+ {
+ $this->value = $value;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other.
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @throws ExpectationFailedException
+ */
+ public function evaluate($other, string $description = '', bool $returnResult = false): ?bool
+ {
+ // If $this->value and $other are identical, they are also equal.
+ // This is the most common path and will allow us to skip
+ // initialization of all the comparators.
+ if ($this->value === $other) {
+ return true;
+ }
+
+ $comparatorFactory = ComparatorFactory::getInstance();
+
+ try {
+ $comparator = $comparatorFactory->getComparatorFor(
+ $this->value,
+ $other
+ );
+
+ $comparator->assertEquals(
+ $this->value,
+ $other,
+ 0.0,
+ false,
+ true
+ );
+ } catch (ComparisonFailure $f) {
+ if ($returnResult) {
+ return false;
+ }
+
+ throw new ExpectationFailedException(
+ trim($description . "\n" . $f->getMessage()),
+ $f
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ public function toString(): string
+ {
+ if (is_string($this->value)) {
+ if (strpos($this->value, "\n") !== false) {
+ return 'is equal to <text>';
+ }
+
+ return sprintf(
+ "is equal to '%s'",
+ $this->value
+ );
+ }
+
+ return sprintf(
+ 'is equal to %s',
+ $this->exporter()->export($this->value)
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqualWithDelta.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqualWithDelta.php
new file mode 100644
index 000000000..0370b5118
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqualWithDelta.php
@@ -0,0 +1,100 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function sprintf;
+use function trim;
+use PHPUnit\Framework\ExpectationFailedException;
+use SebastianBergmann\Comparator\ComparisonFailure;
+use SebastianBergmann\Comparator\Factory as ComparatorFactory;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsEqualWithDelta extends Constraint
+{
+ /**
+ * @var mixed
+ */
+ private $value;
+
+ /**
+ * @var float
+ */
+ private $delta;
+
+ public function __construct($value, float $delta)
+ {
+ $this->value = $value;
+ $this->delta = $delta;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other.
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @throws ExpectationFailedException
+ */
+ public function evaluate($other, string $description = '', bool $returnResult = false): ?bool
+ {
+ // If $this->value and $other are identical, they are also equal.
+ // This is the most common path and will allow us to skip
+ // initialization of all the comparators.
+ if ($this->value === $other) {
+ return true;
+ }
+
+ $comparatorFactory = ComparatorFactory::getInstance();
+
+ try {
+ $comparator = $comparatorFactory->getComparatorFor(
+ $this->value,
+ $other
+ );
+
+ $comparator->assertEquals(
+ $this->value,
+ $other,
+ $this->delta
+ );
+ } catch (ComparisonFailure $f) {
+ if ($returnResult) {
+ return false;
+ }
+
+ throw new ExpectationFailedException(
+ trim($description . "\n" . $f->getMessage()),
+ $f
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ public function toString(): string
+ {
+ return sprintf(
+ 'is equal to %s with delta <%F>>',
+ $this->exporter()->export($this->value),
+ $this->delta
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Exception/Exception.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Exception/Exception.php
new file mode 100644
index 000000000..860c0030f
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Exception/Exception.php
@@ -0,0 +1,85 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function get_class;
+use function sprintf;
+use PHPUnit\Util\Filter;
+use Throwable;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class Exception extends Constraint
+{
+ /**
+ * @var string
+ */
+ private $className;
+
+ public function __construct(string $className)
+ {
+ $this->className = $className;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return sprintf(
+ 'exception of type "%s"',
+ $this->className
+ );
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return $other instanceof $this->className;
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ */
+ protected function failureDescription($other): string
+ {
+ if ($other !== null) {
+ $message = '';
+
+ if ($other instanceof Throwable) {
+ $message = '. Message was: "' . $other->getMessage() . '" at'
+ . "\n" . Filter::getFilteredStacktrace($other);
+ }
+
+ return sprintf(
+ 'exception of type "%s" matches expected exception "%s"%s',
+ get_class($other),
+ $this->className,
+ $message
+ );
+ }
+
+ return sprintf(
+ 'exception of type "%s" is thrown',
+ $this->className
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Exception/ExceptionCode.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Exception/ExceptionCode.php
new file mode 100644
index 000000000..b8054a949
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Exception/ExceptionCode.php
@@ -0,0 +1,67 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function sprintf;
+use Throwable;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class ExceptionCode extends Constraint
+{
+ /**
+ * @var int|string
+ */
+ private $expectedCode;
+
+ /**
+ * @param int|string $expected
+ */
+ public function __construct($expected)
+ {
+ $this->expectedCode = $expected;
+ }
+
+ public function toString(): string
+ {
+ return 'exception code is ';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param Throwable $other
+ */
+ protected function matches($other): bool
+ {
+ return (string) $other->getCode() === (string) $this->expectedCode;
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ protected function failureDescription($other): string
+ {
+ return sprintf(
+ '%s is equal to expected exception code %s',
+ $this->exporter()->export($other->getCode()),
+ $this->exporter()->export($this->expectedCode)
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Exception/ExceptionMessage.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Exception/ExceptionMessage.php
new file mode 100644
index 000000000..030beff98
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Exception/ExceptionMessage.php
@@ -0,0 +1,78 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function sprintf;
+use function strpos;
+use Throwable;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class ExceptionMessage extends Constraint
+{
+ /**
+ * @var string
+ */
+ private $expectedMessage;
+
+ public function __construct(string $expected)
+ {
+ $this->expectedMessage = $expected;
+ }
+
+ public function toString(): string
+ {
+ if ($this->expectedMessage === '') {
+ return 'exception message is empty';
+ }
+
+ return 'exception message contains ';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param Throwable $other
+ */
+ protected function matches($other): bool
+ {
+ if ($this->expectedMessage === '') {
+ return $other->getMessage() === '';
+ }
+
+ return strpos((string) $other->getMessage(), $this->expectedMessage) !== false;
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ */
+ protected function failureDescription($other): string
+ {
+ if ($this->expectedMessage === '') {
+ return sprintf(
+ "exception message is empty but is '%s'",
+ $other->getMessage()
+ );
+ }
+
+ return sprintf(
+ "exception message '%s' contains '%s'",
+ $other->getMessage(),
+ $this->expectedMessage
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Exception/ExceptionMessageRegularExpression.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Exception/ExceptionMessageRegularExpression.php
new file mode 100644
index 000000000..fd0db1c8f
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Exception/ExceptionMessageRegularExpression.php
@@ -0,0 +1,74 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function sprintf;
+use Exception;
+use PHPUnit\Util\RegularExpression as RegularExpressionUtil;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class ExceptionMessageRegularExpression extends Constraint
+{
+ /**
+ * @var string
+ */
+ private $expectedMessageRegExp;
+
+ public function __construct(string $expected)
+ {
+ $this->expectedMessageRegExp = $expected;
+ }
+
+ public function toString(): string
+ {
+ return 'exception message matches ';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param \PHPUnit\Framework\Exception $other
+ *
+ * @throws \PHPUnit\Framework\Exception
+ * @throws Exception
+ */
+ protected function matches($other): bool
+ {
+ $match = RegularExpressionUtil::safeMatch($this->expectedMessageRegExp, $other->getMessage());
+
+ if ($match === false) {
+ throw new \PHPUnit\Framework\Exception(
+ "Invalid expected exception message regex given: '{$this->expectedMessageRegExp}'"
+ );
+ }
+
+ return $match === 1;
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ */
+ protected function failureDescription($other): string
+ {
+ return sprintf(
+ "exception message '%s' matches '%s'",
+ $other->getMessage(),
+ $this->expectedMessageRegExp
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Filesystem/DirectoryExists.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Filesystem/DirectoryExists.php
new file mode 100644
index 000000000..ef4b2baf0
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Filesystem/DirectoryExists.php
@@ -0,0 +1,54 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function is_dir;
+use function sprintf;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class DirectoryExists extends Constraint
+{
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'directory exists';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return is_dir($other);
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ */
+ protected function failureDescription($other): string
+ {
+ return sprintf(
+ 'directory "%s" exists',
+ $other
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Filesystem/FileExists.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Filesystem/FileExists.php
new file mode 100644
index 000000000..41b3136e9
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Filesystem/FileExists.php
@@ -0,0 +1,54 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function file_exists;
+use function sprintf;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class FileExists extends Constraint
+{
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'file exists';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return file_exists($other);
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ */
+ protected function failureDescription($other): string
+ {
+ return sprintf(
+ 'file "%s" exists',
+ $other
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Filesystem/IsReadable.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Filesystem/IsReadable.php
new file mode 100644
index 000000000..e33d7e045
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Filesystem/IsReadable.php
@@ -0,0 +1,54 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function is_readable;
+use function sprintf;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsReadable extends Constraint
+{
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'is readable';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return is_readable($other);
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ */
+ protected function failureDescription($other): string
+ {
+ return sprintf(
+ '"%s" is readable',
+ $other
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Filesystem/IsWritable.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Filesystem/IsWritable.php
new file mode 100644
index 000000000..93981224a
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Filesystem/IsWritable.php
@@ -0,0 +1,54 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function is_writable;
+use function sprintf;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsWritable extends Constraint
+{
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'is writable';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return is_writable($other);
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ */
+ protected function failureDescription($other): string
+ {
+ return sprintf(
+ '"%s" is writable',
+ $other
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsAnything.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsAnything.php
new file mode 100644
index 000000000..db84a7431
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsAnything.php
@@ -0,0 +1,51 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use PHPUnit\Framework\ExpectationFailedException;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsAnything extends Constraint
+{
+ /**
+ * Evaluates the constraint for parameter $other.
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @throws ExpectationFailedException
+ */
+ public function evaluate($other, string $description = '', bool $returnResult = false): ?bool
+ {
+ return $returnResult ? true : null;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'is anything';
+ }
+
+ /**
+ * Counts the number of constraint elements.
+ */
+ public function count(): int
+ {
+ return 0;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php
new file mode 100644
index 000000000..565f1a3a8
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php
@@ -0,0 +1,137 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use const PHP_FLOAT_EPSILON;
+use function abs;
+use function get_class;
+use function is_array;
+use function is_float;
+use function is_infinite;
+use function is_nan;
+use function is_object;
+use function is_string;
+use function sprintf;
+use PHPUnit\Framework\ExpectationFailedException;
+use SebastianBergmann\Comparator\ComparisonFailure;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsIdentical extends Constraint
+{
+ /**
+ * @var mixed
+ */
+ private $value;
+
+ public function __construct($value)
+ {
+ $this->value = $value;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other.
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public function evaluate($other, string $description = '', bool $returnResult = false): ?bool
+ {
+ if (is_float($this->value) && is_float($other) &&
+ !is_infinite($this->value) && !is_infinite($other) &&
+ !is_nan($this->value) && !is_nan($other)) {
+ $success = abs($this->value - $other) < PHP_FLOAT_EPSILON;
+ } else {
+ $success = $this->value === $other;
+ }
+
+ if ($returnResult) {
+ return $success;
+ }
+
+ if (!$success) {
+ $f = null;
+
+ // if both values are strings, make sure a diff is generated
+ if (is_string($this->value) && is_string($other)) {
+ $f = new ComparisonFailure(
+ $this->value,
+ $other,
+ sprintf("'%s'", $this->value),
+ sprintf("'%s'", $other)
+ );
+ }
+
+ // if both values are array, make sure a diff is generated
+ if (is_array($this->value) && is_array($other)) {
+ $f = new ComparisonFailure(
+ $this->value,
+ $other,
+ $this->exporter()->export($this->value),
+ $this->exporter()->export($other)
+ );
+ }
+
+ $this->fail($other, $description, $f);
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ public function toString(): string
+ {
+ if (is_object($this->value)) {
+ return 'is identical to an object of class "' .
+ get_class($this->value) . '"';
+ }
+
+ return 'is identical to ' . $this->exporter()->export($this->value);
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ protected function failureDescription($other): string
+ {
+ if (is_object($this->value) && is_object($other)) {
+ return 'two variables reference the same object';
+ }
+
+ if (is_string($this->value) && is_string($other)) {
+ return 'two strings are identical';
+ }
+
+ if (is_array($this->value) && is_array($other)) {
+ return 'two arrays are identical';
+ }
+
+ return parent::failureDescription($other);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php b/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php
new file mode 100644
index 000000000..23a4de7e9
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php
@@ -0,0 +1,109 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function json_decode;
+use function sprintf;
+use PHPUnit\Framework\ExpectationFailedException;
+use PHPUnit\Util\Json;
+use SebastianBergmann\Comparator\ComparisonFailure;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class JsonMatches extends Constraint
+{
+ /**
+ * @var string
+ */
+ private $value;
+
+ public function __construct(string $value)
+ {
+ $this->value = $value;
+ }
+
+ /**
+ * Returns a string representation of the object.
+ */
+ public function toString(): string
+ {
+ return sprintf(
+ 'matches JSON string "%s"',
+ $this->value
+ );
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * This method can be overridden to implement the evaluation algorithm.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ [$error, $recodedOther] = Json::canonicalize($other);
+
+ if ($error) {
+ return false;
+ }
+
+ [$error, $recodedValue] = Json::canonicalize($this->value);
+
+ if ($error) {
+ return false;
+ }
+
+ return $recodedOther == $recodedValue;
+ }
+
+ /**
+ * Throws an exception for the given compared value and test description.
+ *
+ * @param mixed $other evaluated value or object
+ * @param string $description Additional information about the test
+ * @param ComparisonFailure $comparisonFailure
+ *
+ * @throws \PHPUnit\Framework\Exception
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ *
+ * @psalm-return never-return
+ */
+ protected function fail($other, $description, ComparisonFailure $comparisonFailure = null): void
+ {
+ if ($comparisonFailure === null) {
+ [$error, $recodedOther] = Json::canonicalize($other);
+
+ if ($error) {
+ parent::fail($other, $description);
+ }
+
+ [$error, $recodedValue] = Json::canonicalize($this->value);
+
+ if ($error) {
+ parent::fail($other, $description);
+ }
+
+ $comparisonFailure = new ComparisonFailure(
+ json_decode($this->value),
+ json_decode($other),
+ Json::prettify($recodedValue),
+ Json::prettify($recodedOther),
+ false,
+ 'Failed asserting that two json values are equal.'
+ );
+ }
+
+ parent::fail($other, $description, $comparisonFailure);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php b/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php
new file mode 100644
index 000000000..8ded556ce
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php
@@ -0,0 +1,72 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use const JSON_ERROR_CTRL_CHAR;
+use const JSON_ERROR_DEPTH;
+use const JSON_ERROR_NONE;
+use const JSON_ERROR_STATE_MISMATCH;
+use const JSON_ERROR_SYNTAX;
+use const JSON_ERROR_UTF8;
+use function strtolower;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class JsonMatchesErrorMessageProvider
+{
+ /**
+ * Translates JSON error to a human readable string.
+ */
+ public static function determineJsonError(string $error, string $prefix = ''): ?string
+ {
+ switch ($error) {
+ case JSON_ERROR_NONE:
+ return null;
+ case JSON_ERROR_DEPTH:
+ return $prefix . 'Maximum stack depth exceeded';
+ case JSON_ERROR_STATE_MISMATCH:
+ return $prefix . 'Underflow or the modes mismatch';
+ case JSON_ERROR_CTRL_CHAR:
+ return $prefix . 'Unexpected control character found';
+ case JSON_ERROR_SYNTAX:
+ return $prefix . 'Syntax error, malformed JSON';
+ case JSON_ERROR_UTF8:
+ return $prefix . 'Malformed UTF-8 characters, possibly incorrectly encoded';
+
+ default:
+ return $prefix . 'Unknown error';
+ }
+ }
+
+ /**
+ * Translates a given type to a human readable message prefix.
+ */
+ public static function translateTypeToPrefix(string $type): string
+ {
+ switch (strtolower($type)) {
+ case 'expected':
+ $prefix = 'Expected value JSON decode error - ';
+
+ break;
+ case 'actual':
+ $prefix = 'Actual value JSON decode error - ';
+
+ break;
+
+ default:
+ $prefix = '';
+
+ break;
+ }
+
+ return $prefix;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Math/IsFinite.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Math/IsFinite.php
new file mode 100644
index 000000000..9a2f32866
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Math/IsFinite.php
@@ -0,0 +1,37 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function is_finite;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsFinite extends Constraint
+{
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'is finite';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return is_finite($other);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Math/IsInfinite.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Math/IsInfinite.php
new file mode 100644
index 000000000..c718514c2
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Math/IsInfinite.php
@@ -0,0 +1,37 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function is_infinite;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsInfinite extends Constraint
+{
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'is infinite';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return is_infinite($other);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Math/IsNan.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Math/IsNan.php
new file mode 100644
index 000000000..0062c5b5c
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Math/IsNan.php
@@ -0,0 +1,37 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function is_nan;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsNan extends Constraint
+{
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'is nan';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return is_nan($other);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Object/ClassHasAttribute.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Object/ClassHasAttribute.php
new file mode 100644
index 000000000..daa14027d
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Object/ClassHasAttribute.php
@@ -0,0 +1,88 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function get_class;
+use function is_object;
+use function sprintf;
+use PHPUnit\Framework\Exception;
+use ReflectionClass;
+use ReflectionException;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+class ClassHasAttribute extends Constraint
+{
+ /**
+ * @var string
+ */
+ private $attributeName;
+
+ public function __construct(string $attributeName)
+ {
+ $this->attributeName = $attributeName;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return sprintf(
+ 'has attribute "%s"',
+ $this->attributeName
+ );
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ try {
+ return (new ReflectionClass($other))->hasProperty($this->attributeName);
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ */
+ protected function failureDescription($other): string
+ {
+ return sprintf(
+ '%sclass "%s" %s',
+ is_object($other) ? 'object of ' : '',
+ is_object($other) ? get_class($other) : $other,
+ $this->toString()
+ );
+ }
+
+ protected function attributeName(): string
+ {
+ return $this->attributeName;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Object/ClassHasStaticAttribute.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Object/ClassHasStaticAttribute.php
new file mode 100644
index 000000000..cacd0d752
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Object/ClassHasStaticAttribute.php
@@ -0,0 +1,59 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function sprintf;
+use PHPUnit\Framework\Exception;
+use ReflectionClass;
+use ReflectionException;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class ClassHasStaticAttribute extends ClassHasAttribute
+{
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return sprintf(
+ 'has static attribute "%s"',
+ $this->attributeName()
+ );
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ try {
+ $class = new ReflectionClass($other);
+
+ if ($class->hasProperty($this->attributeName())) {
+ return $class->getProperty($this->attributeName())->isStatic();
+ }
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ return false;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Object/ObjectEquals.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Object/ObjectEquals.php
new file mode 100644
index 000000000..30f3a330c
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Object/ObjectEquals.php
@@ -0,0 +1,151 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function get_class;
+use function is_object;
+use PHPUnit\Framework\ActualValueIsNotAnObjectException;
+use PHPUnit\Framework\ComparisonMethodDoesNotAcceptParameterTypeException;
+use PHPUnit\Framework\ComparisonMethodDoesNotDeclareBoolReturnTypeException;
+use PHPUnit\Framework\ComparisonMethodDoesNotDeclareExactlyOneParameterException;
+use PHPUnit\Framework\ComparisonMethodDoesNotDeclareParameterTypeException;
+use PHPUnit\Framework\ComparisonMethodDoesNotExistException;
+use ReflectionNamedType;
+use ReflectionObject;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class ObjectEquals extends Constraint
+{
+ /**
+ * @var object
+ */
+ private $expected;
+
+ /**
+ * @var string
+ */
+ private $method;
+
+ public function __construct(object $object, string $method = 'equals')
+ {
+ $this->expected = $object;
+ $this->method = $method;
+ }
+
+ public function toString(): string
+ {
+ return 'two objects are equal';
+ }
+
+ /**
+ * @throws ActualValueIsNotAnObjectException
+ * @throws ComparisonMethodDoesNotAcceptParameterTypeException
+ * @throws ComparisonMethodDoesNotDeclareBoolReturnTypeException
+ * @throws ComparisonMethodDoesNotDeclareExactlyOneParameterException
+ * @throws ComparisonMethodDoesNotDeclareParameterTypeException
+ * @throws ComparisonMethodDoesNotExistException
+ */
+ protected function matches($other): bool
+ {
+ if (!is_object($other)) {
+ throw new ActualValueIsNotAnObjectException;
+ }
+
+ $object = new ReflectionObject($other);
+
+ if (!$object->hasMethod($this->method)) {
+ throw new ComparisonMethodDoesNotExistException(
+ get_class($other),
+ $this->method
+ );
+ }
+
+ /** @noinspection PhpUnhandledExceptionInspection */
+ $method = $object->getMethod($this->method);
+
+ if (!$method->hasReturnType()) {
+ throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException(
+ get_class($other),
+ $this->method
+ );
+ }
+
+ $returnType = $method->getReturnType();
+
+ if (!$returnType instanceof ReflectionNamedType) {
+ throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException(
+ get_class($other),
+ $this->method
+ );
+ }
+
+ if ($returnType->allowsNull()) {
+ throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException(
+ get_class($other),
+ $this->method
+ );
+ }
+
+ if ($returnType->getName() !== 'bool') {
+ throw new ComparisonMethodDoesNotDeclareBoolReturnTypeException(
+ get_class($other),
+ $this->method
+ );
+ }
+
+ if ($method->getNumberOfParameters() !== 1 || $method->getNumberOfRequiredParameters() !== 1) {
+ throw new ComparisonMethodDoesNotDeclareExactlyOneParameterException(
+ get_class($other),
+ $this->method
+ );
+ }
+
+ $parameter = $method->getParameters()[0];
+
+ if (!$parameter->hasType()) {
+ throw new ComparisonMethodDoesNotDeclareParameterTypeException(
+ get_class($other),
+ $this->method
+ );
+ }
+
+ $type = $parameter->getType();
+
+ if (!$type instanceof ReflectionNamedType) {
+ throw new ComparisonMethodDoesNotDeclareParameterTypeException(
+ get_class($other),
+ $this->method
+ );
+ }
+
+ $typeName = $type->getName();
+
+ if ($typeName === 'self') {
+ $typeName = get_class($other);
+ }
+
+ if (!$this->expected instanceof $typeName) {
+ throw new ComparisonMethodDoesNotAcceptParameterTypeException(
+ get_class($other),
+ $this->method,
+ get_class($this->expected)
+ );
+ }
+
+ return $other->{$this->method}($this->expected);
+ }
+
+ protected function failureDescription($other): string
+ {
+ return $this->toString();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Object/ObjectHasAttribute.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Object/ObjectHasAttribute.php
new file mode 100644
index 000000000..5fbc0888c
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Object/ObjectHasAttribute.php
@@ -0,0 +1,29 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use ReflectionObject;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class ObjectHasAttribute extends ClassHasAttribute
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return (new ReflectionObject($other))->hasProperty($this->attributeName());
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/BinaryOperator.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/BinaryOperator.php
new file mode 100644
index 000000000..11c86b526
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/BinaryOperator.php
@@ -0,0 +1,148 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function array_map;
+use function array_values;
+use function count;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+abstract class BinaryOperator extends Operator
+{
+ /**
+ * @var Constraint[]
+ */
+ private $constraints = [];
+
+ public static function fromConstraints(Constraint ...$constraints): self
+ {
+ $constraint = new static;
+
+ $constraint->constraints = $constraints;
+
+ return $constraint;
+ }
+
+ /**
+ * @param mixed[] $constraints
+ */
+ public function setConstraints(array $constraints): void
+ {
+ $this->constraints = array_map(function ($constraint): Constraint
+ {
+ return $this->checkConstraint($constraint);
+ }, array_values($constraints));
+ }
+
+ /**
+ * Returns the number of operands (constraints).
+ */
+ final public function arity(): int
+ {
+ return count($this->constraints);
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ $reduced = $this->reduce();
+
+ if ($reduced !== $this) {
+ return $reduced->toString();
+ }
+
+ $text = '';
+
+ foreach ($this->constraints as $key => $constraint) {
+ $constraint = $constraint->reduce();
+
+ $text .= $this->constraintToString($constraint, $key);
+ }
+
+ return $text;
+ }
+
+ /**
+ * Counts the number of constraint elements.
+ */
+ public function count(): int
+ {
+ $count = 0;
+
+ foreach ($this->constraints as $constraint) {
+ $count += count($constraint);
+ }
+
+ return $count;
+ }
+
+ /**
+ * Returns the nested constraints.
+ */
+ final protected function constraints(): array
+ {
+ return $this->constraints;
+ }
+
+ /**
+ * Returns true if the $constraint needs to be wrapped with braces.
+ */
+ final protected function constraintNeedsParentheses(Constraint $constraint): bool
+ {
+ return $this->arity() > 1 && parent::constraintNeedsParentheses($constraint);
+ }
+
+ /**
+ * Reduces the sub-expression starting at $this by skipping degenerate
+ * sub-expression and returns first descendant constraint that starts
+ * a non-reducible sub-expression.
+ *
+ * See Constraint::reduce() for more.
+ */
+ protected function reduce(): Constraint
+ {
+ if ($this->arity() === 1 && $this->constraints[0] instanceof Operator) {
+ return $this->constraints[0]->reduce();
+ }
+
+ return parent::reduce();
+ }
+
+ /**
+ * Returns string representation of given operand in context of this operator.
+ *
+ * @param Constraint $constraint operand constraint
+ * @param int $position position of $constraint in this expression
+ */
+ private function constraintToString(Constraint $constraint, int $position): string
+ {
+ $prefix = '';
+
+ if ($position > 0) {
+ $prefix = (' ' . $this->operator() . ' ');
+ }
+
+ if ($this->constraintNeedsParentheses($constraint)) {
+ return $prefix . '( ' . $constraint->toString() . ' )';
+ }
+
+ $string = $constraint->toStringInContext($this, $position);
+
+ if ($string === '') {
+ $string = $constraint->toString();
+ }
+
+ return $prefix . $string;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/LogicalAnd.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/LogicalAnd.php
new file mode 100644
index 000000000..a1af4dd32
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/LogicalAnd.php
@@ -0,0 +1,51 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class LogicalAnd extends BinaryOperator
+{
+ /**
+ * Returns the name of this operator.
+ */
+ public function operator(): string
+ {
+ return 'and';
+ }
+
+ /**
+ * Returns this operator's precedence.
+ *
+ * @see https://www.php.net/manual/en/language.operators.precedence.php
+ */
+ public function precedence(): int
+ {
+ return 22;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ foreach ($this->constraints() as $constraint) {
+ if (!$constraint->evaluate($other, '', true)) {
+ return false;
+ }
+ }
+
+ return [] !== $this->constraints();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/LogicalNot.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/LogicalNot.php
new file mode 100644
index 000000000..7560ce2a1
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/LogicalNot.php
@@ -0,0 +1,136 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function array_map;
+use function count;
+use function preg_match;
+use function preg_quote;
+use function preg_replace;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class LogicalNot extends UnaryOperator
+{
+ public static function negate(string $string): string
+ {
+ $positives = [
+ 'contains ',
+ 'exists',
+ 'has ',
+ 'is ',
+ 'are ',
+ 'matches ',
+ 'starts with ',
+ 'ends with ',
+ 'reference ',
+ 'not not ',
+ ];
+
+ $negatives = [
+ 'does not contain ',
+ 'does not exist',
+ 'does not have ',
+ 'is not ',
+ 'are not ',
+ 'does not match ',
+ 'starts not with ',
+ 'ends not with ',
+ 'don\'t reference ',
+ 'not ',
+ ];
+
+ preg_match('/(\'[\w\W]*\')([\w\W]*)("[\w\W]*")/i', $string, $matches);
+
+ $positives = array_map(static function (string $s)
+ {
+ return '/\\b' . preg_quote($s, '/') . '/';
+ }, $positives);
+
+ if (count($matches) > 0) {
+ $nonInput = $matches[2];
+
+ $negatedString = preg_replace(
+ '/' . preg_quote($nonInput, '/') . '/',
+ preg_replace(
+ $positives,
+ $negatives,
+ $nonInput
+ ),
+ $string
+ );
+ } else {
+ $negatedString = preg_replace(
+ $positives,
+ $negatives,
+ $string
+ );
+ }
+
+ return $negatedString;
+ }
+
+ /**
+ * Returns the name of this operator.
+ */
+ public function operator(): string
+ {
+ return 'not';
+ }
+
+ /**
+ * Returns this operator's precedence.
+ *
+ * @see https://www.php.net/manual/en/language.operators.precedence.php
+ */
+ public function precedence(): int
+ {
+ return 5;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return !$this->constraint()->evaluate($other, '', true);
+ }
+
+ /**
+ * Applies additional transformation to strings returned by toString() or
+ * failureDescription().
+ */
+ protected function transformString(string $string): string
+ {
+ return self::negate($string);
+ }
+
+ /**
+ * Reduces the sub-expression starting at $this by skipping degenerate
+ * sub-expression and returns first descendant constraint that starts
+ * a non-reducible sub-expression.
+ *
+ * See Constraint::reduce() for more.
+ */
+ protected function reduce(): Constraint
+ {
+ $constraint = $this->constraint();
+
+ if ($constraint instanceof self) {
+ return $constraint->constraint()->reduce();
+ }
+
+ return parent::reduce();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/LogicalOr.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/LogicalOr.php
new file mode 100644
index 000000000..2932de675
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/LogicalOr.php
@@ -0,0 +1,51 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class LogicalOr extends BinaryOperator
+{
+ /**
+ * Returns the name of this operator.
+ */
+ public function operator(): string
+ {
+ return 'or';
+ }
+
+ /**
+ * Returns this operator's precedence.
+ *
+ * @see https://www.php.net/manual/en/language.operators.precedence.php
+ */
+ public function precedence(): int
+ {
+ return 24;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ public function matches($other): bool
+ {
+ foreach ($this->constraints() as $constraint) {
+ if ($constraint->evaluate($other, '', true)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/LogicalXor.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/LogicalXor.php
new file mode 100644
index 000000000..fbdb479bc
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/LogicalXor.php
@@ -0,0 +1,63 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function array_reduce;
+use function array_shift;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class LogicalXor extends BinaryOperator
+{
+ /**
+ * Returns the name of this operator.
+ */
+ public function operator(): string
+ {
+ return 'xor';
+ }
+
+ /**
+ * Returns this operator's precedence.
+ *
+ * @see https://www.php.net/manual/en/language.operators.precedence.php.
+ */
+ public function precedence(): int
+ {
+ return 23;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ public function matches($other): bool
+ {
+ $constraints = $this->constraints();
+
+ $initial = array_shift($constraints);
+
+ if ($initial === null) {
+ return false;
+ }
+
+ return array_reduce(
+ $constraints,
+ static function (bool $matches, Constraint $constraint) use ($other): bool
+ {
+ return $matches xor $constraint->evaluate($other, '', true);
+ },
+ $initial->evaluate($other, '', true)
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/Operator.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/Operator.php
new file mode 100644
index 000000000..3f51a0f40
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/Operator.php
@@ -0,0 +1,55 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+abstract class Operator extends Constraint
+{
+ /**
+ * Returns the name of this operator.
+ */
+ abstract public function operator(): string;
+
+ /**
+ * Returns this operator's precedence.
+ *
+ * @see https://www.php.net/manual/en/language.operators.precedence.php
+ */
+ abstract public function precedence(): int;
+
+ /**
+ * Returns the number of operands.
+ */
+ abstract public function arity(): int;
+
+ /**
+ * Validates $constraint argument.
+ */
+ protected function checkConstraint($constraint): Constraint
+ {
+ if (!$constraint instanceof Constraint) {
+ return new IsEqual($constraint);
+ }
+
+ return $constraint;
+ }
+
+ /**
+ * Returns true if the $constraint needs to be wrapped with braces.
+ */
+ protected function constraintNeedsParentheses(Constraint $constraint): bool
+ {
+ return $constraint instanceof self &&
+ $constraint->arity() > 1 &&
+ $this->precedence() <= $constraint->precedence();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/UnaryOperator.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/UnaryOperator.php
new file mode 100644
index 000000000..0a7a5fa2f
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Operator/UnaryOperator.php
@@ -0,0 +1,140 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function count;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+abstract class UnaryOperator extends Operator
+{
+ /**
+ * @var Constraint
+ */
+ private $constraint;
+
+ /**
+ * @param Constraint|mixed $constraint
+ */
+ public function __construct($constraint)
+ {
+ $this->constraint = $this->checkConstraint($constraint);
+ }
+
+ /**
+ * Returns the number of operands (constraints).
+ */
+ public function arity(): int
+ {
+ return 1;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ $reduced = $this->reduce();
+
+ if ($reduced !== $this) {
+ return $reduced->toString();
+ }
+
+ $constraint = $this->constraint->reduce();
+
+ if ($this->constraintNeedsParentheses($constraint)) {
+ return $this->operator() . '( ' . $constraint->toString() . ' )';
+ }
+
+ $string = $constraint->toStringInContext($this, 0);
+
+ if ($string === '') {
+ return $this->transformString($constraint->toString());
+ }
+
+ return $string;
+ }
+
+ /**
+ * Counts the number of constraint elements.
+ */
+ public function count(): int
+ {
+ return count($this->constraint);
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ protected function failureDescription($other): string
+ {
+ $reduced = $this->reduce();
+
+ if ($reduced !== $this) {
+ return $reduced->failureDescription($other);
+ }
+
+ $constraint = $this->constraint->reduce();
+
+ if ($this->constraintNeedsParentheses($constraint)) {
+ return $this->operator() . '( ' . $constraint->failureDescription($other) . ' )';
+ }
+
+ $string = $constraint->failureDescriptionInContext($this, 0, $other);
+
+ if ($string === '') {
+ return $this->transformString($constraint->failureDescription($other));
+ }
+
+ return $string;
+ }
+
+ /**
+ * Transforms string returned by the memeber constraint's toString() or
+ * failureDescription() such that it reflects constraint's participation in
+ * this expression.
+ *
+ * The method may be overwritten in a subclass to apply default
+ * transformation in case the operand constraint does not provide its own
+ * custom strings via toStringInContext() or failureDescriptionInContext().
+ *
+ * @param string $string the string to be transformed
+ */
+ protected function transformString(string $string): string
+ {
+ return $string;
+ }
+
+ /**
+ * Provides access to $this->constraint for subclasses.
+ */
+ final protected function constraint(): Constraint
+ {
+ return $this->constraint;
+ }
+
+ /**
+ * Returns true if the $constraint needs to be wrapped with parentheses.
+ */
+ protected function constraintNeedsParentheses(Constraint $constraint): bool
+ {
+ $constraint = $constraint->reduce();
+
+ return $constraint instanceof self || parent::constraintNeedsParentheses($constraint);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/String/IsJson.php b/vendor/phpunit/phpunit/src/Framework/Constraint/String/IsJson.php
new file mode 100644
index 000000000..97b294617
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/String/IsJson.php
@@ -0,0 +1,77 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function json_decode;
+use function json_last_error;
+use function sprintf;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsJson extends Constraint
+{
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'is valid JSON';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ if ($other === '') {
+ return false;
+ }
+
+ json_decode($other);
+
+ if (json_last_error()) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ protected function failureDescription($other): string
+ {
+ if ($other === '') {
+ return 'an empty string is valid JSON';
+ }
+
+ json_decode($other);
+ $error = (string) JsonMatchesErrorMessageProvider::determineJsonError(
+ (string) json_last_error()
+ );
+
+ return sprintf(
+ '%s is valid JSON (%s)',
+ $this->exporter()->shortenedExport($other),
+ $error
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/String/RegularExpression.php b/vendor/phpunit/phpunit/src/Framework/Constraint/String/RegularExpression.php
new file mode 100644
index 000000000..8e609e795
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/String/RegularExpression.php
@@ -0,0 +1,51 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function preg_match;
+use function sprintf;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+class RegularExpression extends Constraint
+{
+ /**
+ * @var string
+ */
+ private $pattern;
+
+ public function __construct(string $pattern)
+ {
+ $this->pattern = $pattern;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return sprintf(
+ 'matches PCRE pattern "%s"',
+ $this->pattern
+ );
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return preg_match($this->pattern, $other) > 0;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/String/StringContains.php b/vendor/phpunit/phpunit/src/Framework/Constraint/String/StringContains.php
new file mode 100644
index 000000000..6279f37ba
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/String/StringContains.php
@@ -0,0 +1,85 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function mb_stripos;
+use function mb_strtolower;
+use function sprintf;
+use function strpos;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class StringContains extends Constraint
+{
+ /**
+ * @var string
+ */
+ private $string;
+
+ /**
+ * @var bool
+ */
+ private $ignoreCase;
+
+ public function __construct(string $string, bool $ignoreCase = false)
+ {
+ $this->string = $string;
+ $this->ignoreCase = $ignoreCase;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ if ($this->ignoreCase) {
+ $string = mb_strtolower($this->string, 'UTF-8');
+ } else {
+ $string = $this->string;
+ }
+
+ return sprintf(
+ 'contains "%s"',
+ $string
+ );
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ if ('' === $this->string) {
+ return true;
+ }
+
+ if ($this->ignoreCase) {
+ /*
+ * We must use the multi byte safe version so we can accurately compare non latin upper characters with
+ * their lowercase equivalents.
+ */
+ return mb_stripos($other, $this->string, 0, 'UTF-8') !== false;
+ }
+
+ /*
+ * Use the non multi byte safe functions to see if the string is contained in $other.
+ *
+ * This function is very fast and we don't care about the character position in the string.
+ *
+ * Additionally, we want this method to be binary safe so we can check if some binary data is in other binary
+ * data.
+ */
+ return strpos($other, $this->string) !== false;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/String/StringEndsWith.php b/vendor/phpunit/phpunit/src/Framework/Constraint/String/StringEndsWith.php
new file mode 100644
index 000000000..bb4ce23be
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/String/StringEndsWith.php
@@ -0,0 +1,48 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function strlen;
+use function substr;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class StringEndsWith extends Constraint
+{
+ /**
+ * @var string
+ */
+ private $suffix;
+
+ public function __construct(string $suffix)
+ {
+ $this->suffix = $suffix;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'ends with "' . $this->suffix . '"';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return substr($other, 0 - strlen($this->suffix)) === $this->suffix;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/String/StringMatchesFormatDescription.php b/vendor/phpunit/phpunit/src/Framework/Constraint/String/StringMatchesFormatDescription.php
new file mode 100644
index 000000000..c4f7324ec
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/String/StringMatchesFormatDescription.php
@@ -0,0 +1,109 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use const DIRECTORY_SEPARATOR;
+use function explode;
+use function implode;
+use function preg_match;
+use function preg_quote;
+use function preg_replace;
+use function strtr;
+use SebastianBergmann\Diff\Differ;
+use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class StringMatchesFormatDescription extends RegularExpression
+{
+ /**
+ * @var string
+ */
+ private $string;
+
+ public function __construct(string $string)
+ {
+ parent::__construct(
+ $this->createPatternFromFormat(
+ $this->convertNewlines($string)
+ )
+ );
+
+ $this->string = $string;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return parent::matches(
+ $this->convertNewlines($other)
+ );
+ }
+
+ protected function failureDescription($other): string
+ {
+ return 'string matches format description';
+ }
+
+ protected function additionalFailureDescription($other): string
+ {
+ $from = explode("\n", $this->string);
+ $to = explode("\n", $this->convertNewlines($other));
+
+ foreach ($from as $index => $line) {
+ if (isset($to[$index]) && $line !== $to[$index]) {
+ $line = $this->createPatternFromFormat($line);
+
+ if (preg_match($line, $to[$index]) > 0) {
+ $from[$index] = $to[$index];
+ }
+ }
+ }
+
+ $this->string = implode("\n", $from);
+ $other = implode("\n", $to);
+
+ return (new Differ(new UnifiedDiffOutputBuilder("--- Expected\n+++ Actual\n")))->diff($this->string, $other);
+ }
+
+ private function createPatternFromFormat(string $string): string
+ {
+ $string = strtr(
+ preg_quote($string, '/'),
+ [
+ '%%' => '%',
+ '%e' => '\\' . DIRECTORY_SEPARATOR,
+ '%s' => '[^\r\n]+',
+ '%S' => '[^\r\n]*',
+ '%a' => '.+',
+ '%A' => '.*',
+ '%w' => '\s*',
+ '%i' => '[+-]?\d+',
+ '%d' => '\d+',
+ '%x' => '[0-9a-fA-F]+',
+ '%f' => '[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?',
+ '%c' => '.',
+ ]
+ );
+
+ return '/^' . $string . '$/s';
+ }
+
+ private function convertNewlines(string $text): string
+ {
+ return preg_replace('/\r\n/', "\n", $text);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/String/StringStartsWith.php b/vendor/phpunit/phpunit/src/Framework/Constraint/String/StringStartsWith.php
new file mode 100644
index 000000000..089545c12
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/String/StringStartsWith.php
@@ -0,0 +1,53 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function strlen;
+use function strpos;
+use PHPUnit\Framework\InvalidArgumentException;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class StringStartsWith extends Constraint
+{
+ /**
+ * @var string
+ */
+ private $prefix;
+
+ public function __construct(string $prefix)
+ {
+ if (strlen($prefix) === 0) {
+ throw InvalidArgumentException::create(1, 'non-empty string');
+ }
+
+ $this->prefix = $prefix;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'starts with "' . $this->prefix . '"';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return strpos((string) $other, $this->prefix) === 0;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/ArrayHasKey.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/ArrayHasKey.php
new file mode 100644
index 000000000..44cada3a7
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/ArrayHasKey.php
@@ -0,0 +1,77 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function array_key_exists;
+use function is_array;
+use ArrayAccess;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class ArrayHasKey extends Constraint
+{
+ /**
+ * @var int|string
+ */
+ private $key;
+
+ /**
+ * @param int|string $key
+ */
+ public function __construct($key)
+ {
+ $this->key = $key;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ public function toString(): string
+ {
+ return 'has the key ' . $this->exporter()->export($this->key);
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ if (is_array($other)) {
+ return array_key_exists($this->key, $other);
+ }
+
+ if ($other instanceof ArrayAccess) {
+ return $other->offsetExists($this->key);
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ protected function failureDescription($other): string
+ {
+ return 'an array ' . $this->toString();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/TraversableContains.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/TraversableContains.php
new file mode 100644
index 000000000..39660a985
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/TraversableContains.php
@@ -0,0 +1,63 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function is_array;
+use function sprintf;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+abstract class TraversableContains extends Constraint
+{
+ /**
+ * @var mixed
+ */
+ private $value;
+
+ public function __construct($value)
+ {
+ $this->value = $value;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ public function toString(): string
+ {
+ return 'contains ' . $this->exporter()->export($this->value);
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ protected function failureDescription($other): string
+ {
+ return sprintf(
+ '%s %s',
+ is_array($other) ? 'an array' : 'a traversable',
+ $this->toString()
+ );
+ }
+
+ protected function value()
+ {
+ return $this->value;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/TraversableContainsEqual.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/TraversableContainsEqual.php
new file mode 100644
index 000000000..c315e709a
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/TraversableContainsEqual.php
@@ -0,0 +1,40 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use SplObjectStorage;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class TraversableContainsEqual extends TraversableContains
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ if ($other instanceof SplObjectStorage) {
+ return $other->contains($this->value());
+ }
+
+ foreach ($other as $element) {
+ /* @noinspection TypeUnsafeComparisonInspection */
+ if ($this->value() == $element) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/TraversableContainsIdentical.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/TraversableContainsIdentical.php
new file mode 100644
index 000000000..a3437dbc9
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/TraversableContainsIdentical.php
@@ -0,0 +1,39 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use SplObjectStorage;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class TraversableContainsIdentical extends TraversableContains
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ if ($other instanceof SplObjectStorage) {
+ return $other->contains($this->value());
+ }
+
+ foreach ($other as $element) {
+ if ($this->value() === $element) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/TraversableContainsOnly.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/TraversableContainsOnly.php
new file mode 100644
index 000000000..cf4a46b42
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Traversable/TraversableContainsOnly.php
@@ -0,0 +1,91 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use PHPUnit\Framework\ExpectationFailedException;
+use Traversable;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class TraversableContainsOnly extends Constraint
+{
+ /**
+ * @var Constraint
+ */
+ private $constraint;
+
+ /**
+ * @var string
+ */
+ private $type;
+
+ /**
+ * @throws \PHPUnit\Framework\Exception
+ */
+ public function __construct(string $type, bool $isNativeType = true)
+ {
+ if ($isNativeType) {
+ $this->constraint = new IsType($type);
+ } else {
+ $this->constraint = new IsInstanceOf(
+ $type
+ );
+ }
+
+ $this->type = $type;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other.
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @param mixed|Traversable $other
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public function evaluate($other, string $description = '', bool $returnResult = false): ?bool
+ {
+ $success = true;
+
+ foreach ($other as $item) {
+ if (!$this->constraint->evaluate($item, '', true)) {
+ $success = false;
+
+ break;
+ }
+ }
+
+ if ($returnResult) {
+ return $success;
+ }
+
+ if (!$success) {
+ $this->fail($other, $description);
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'contains only values of type "' . $this->type . '"';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Type/IsInstanceOf.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Type/IsInstanceOf.php
new file mode 100644
index 000000000..f0fa02b99
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Type/IsInstanceOf.php
@@ -0,0 +1,87 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function sprintf;
+use ReflectionClass;
+use ReflectionException;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsInstanceOf extends Constraint
+{
+ /**
+ * @var string
+ */
+ private $className;
+
+ public function __construct(string $className)
+ {
+ $this->className = $className;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return sprintf(
+ 'is instance of %s "%s"',
+ $this->getType(),
+ $this->className
+ );
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return $other instanceof $this->className;
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other evaluated value or object
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ protected function failureDescription($other): string
+ {
+ return sprintf(
+ '%s is an instance of %s "%s"',
+ $this->exporter()->shortenedExport($other),
+ $this->getType(),
+ $this->className
+ );
+ }
+
+ private function getType(): string
+ {
+ try {
+ $reflection = new ReflectionClass($this->className);
+
+ if ($reflection->isInterface()) {
+ return 'interface';
+ }
+ } catch (ReflectionException $e) {
+ }
+
+ return 'class';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Type/IsNull.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Type/IsNull.php
new file mode 100644
index 000000000..b9fcdd7a7
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Type/IsNull.php
@@ -0,0 +1,35 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsNull extends Constraint
+{
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return 'is null';
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ return $other === null;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Type/IsType.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Type/IsType.php
new file mode 100644
index 000000000..5bc691d74
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Type/IsType.php
@@ -0,0 +1,210 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Constraint;
+
+use function gettype;
+use function is_array;
+use function is_bool;
+use function is_callable;
+use function is_float;
+use function is_int;
+use function is_iterable;
+use function is_numeric;
+use function is_object;
+use function is_scalar;
+use function is_string;
+use function sprintf;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class IsType extends Constraint
+{
+ /**
+ * @var string
+ */
+ public const TYPE_ARRAY = 'array';
+
+ /**
+ * @var string
+ */
+ public const TYPE_BOOL = 'bool';
+
+ /**
+ * @var string
+ */
+ public const TYPE_FLOAT = 'float';
+
+ /**
+ * @var string
+ */
+ public const TYPE_INT = 'int';
+
+ /**
+ * @var string
+ */
+ public const TYPE_NULL = 'null';
+
+ /**
+ * @var string
+ */
+ public const TYPE_NUMERIC = 'numeric';
+
+ /**
+ * @var string
+ */
+ public const TYPE_OBJECT = 'object';
+
+ /**
+ * @var string
+ */
+ public const TYPE_RESOURCE = 'resource';
+
+ /**
+ * @var string
+ */
+ public const TYPE_CLOSED_RESOURCE = 'resource (closed)';
+
+ /**
+ * @var string
+ */
+ public const TYPE_STRING = 'string';
+
+ /**
+ * @var string
+ */
+ public const TYPE_SCALAR = 'scalar';
+
+ /**
+ * @var string
+ */
+ public const TYPE_CALLABLE = 'callable';
+
+ /**
+ * @var string
+ */
+ public const TYPE_ITERABLE = 'iterable';
+
+ /**
+ * @var array<string,bool>
+ */
+ private const KNOWN_TYPES = [
+ 'array' => true,
+ 'boolean' => true,
+ 'bool' => true,
+ 'double' => true,
+ 'float' => true,
+ 'integer' => true,
+ 'int' => true,
+ 'null' => true,
+ 'numeric' => true,
+ 'object' => true,
+ 'real' => true,
+ 'resource' => true,
+ 'resource (closed)' => true,
+ 'string' => true,
+ 'scalar' => true,
+ 'callable' => true,
+ 'iterable' => true,
+ ];
+
+ /**
+ * @var string
+ */
+ private $type;
+
+ /**
+ * @throws \PHPUnit\Framework\Exception
+ */
+ public function __construct(string $type)
+ {
+ if (!isset(self::KNOWN_TYPES[$type])) {
+ throw new \PHPUnit\Framework\Exception(
+ sprintf(
+ 'Type specified for PHPUnit\Framework\Constraint\IsType <%s> ' .
+ 'is not a valid type.',
+ $type
+ )
+ );
+ }
+
+ $this->type = $type;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ */
+ public function toString(): string
+ {
+ return sprintf(
+ 'is of type "%s"',
+ $this->type
+ );
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other value or object to evaluate
+ */
+ protected function matches($other): bool
+ {
+ switch ($this->type) {
+ case 'numeric':
+ return is_numeric($other);
+
+ case 'integer':
+ case 'int':
+ return is_int($other);
+
+ case 'double':
+ case 'float':
+ case 'real':
+ return is_float($other);
+
+ case 'string':
+ return is_string($other);
+
+ case 'boolean':
+ case 'bool':
+ return is_bool($other);
+
+ case 'null':
+ return null === $other;
+
+ case 'array':
+ return is_array($other);
+
+ case 'object':
+ return is_object($other);
+
+ case 'resource':
+ $type = gettype($other);
+
+ return $type === 'resource' || $type === 'resource (closed)';
+
+ case 'resource (closed)':
+ return gettype($other) === 'resource (closed)';
+
+ case 'scalar':
+ return is_scalar($other);
+
+ case 'callable':
+ return is_callable($other);
+
+ case 'iterable':
+ return is_iterable($other);
+
+ default:
+ return false;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/DataProviderTestSuite.php b/vendor/phpunit/phpunit/src/Framework/DataProviderTestSuite.php
new file mode 100644
index 000000000..18b549996
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/DataProviderTestSuite.php
@@ -0,0 +1,75 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use function explode;
+use PHPUnit\Util\Test as TestUtil;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class DataProviderTestSuite extends TestSuite
+{
+ /**
+ * @var list<ExecutionOrderDependency>
+ */
+ private $dependencies = [];
+
+ /**
+ * @param list<ExecutionOrderDependency> $dependencies
+ */
+ public function setDependencies(array $dependencies): void
+ {
+ $this->dependencies = $dependencies;
+
+ foreach ($this->tests as $test) {
+ if (!$test instanceof TestCase) {
+ // @codeCoverageIgnoreStart
+ continue;
+ // @codeCoverageIgnoreStart
+ }
+ $test->setDependencies($dependencies);
+ }
+ }
+
+ /**
+ * @return list<ExecutionOrderDependency>
+ */
+ public function provides(): array
+ {
+ if ($this->providedTests === null) {
+ $this->providedTests = [new ExecutionOrderDependency($this->getName())];
+ }
+
+ return $this->providedTests;
+ }
+
+ /**
+ * @return list<ExecutionOrderDependency>
+ */
+ public function requires(): array
+ {
+ // A DataProviderTestSuite does not have to traverse its child tests
+ // as these are inherited and cannot reference dataProvider rows directly
+ return $this->dependencies;
+ }
+
+ /**
+ * Returns the size of the each test created using the data provider(s).
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ public function getSize(): int
+ {
+ [$className, $methodName] = explode('::', $this->getName());
+
+ return TestUtil::getSize($className, $methodName);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Error/Deprecated.php b/vendor/phpunit/phpunit/src/Framework/Error/Deprecated.php
new file mode 100644
index 000000000..db62195f8
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Error/Deprecated.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Error;
+
+/**
+ * @internal
+ */
+final class Deprecated extends Error
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Error/Error.php b/vendor/phpunit/phpunit/src/Framework/Error/Error.php
new file mode 100644
index 000000000..2990b360e
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Error/Error.php
@@ -0,0 +1,26 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Error;
+
+use PHPUnit\Framework\Exception;
+
+/**
+ * @internal
+ */
+class Error extends Exception
+{
+ public function __construct(string $message, int $code, string $file, int $line, \Exception $previous = null)
+ {
+ parent::__construct($message, $code, $previous);
+
+ $this->file = $file;
+ $this->line = $line;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Error/Notice.php b/vendor/phpunit/phpunit/src/Framework/Error/Notice.php
new file mode 100644
index 000000000..54e5e31ea
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Error/Notice.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Error;
+
+/**
+ * @internal
+ */
+final class Notice extends Error
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Error/Warning.php b/vendor/phpunit/phpunit/src/Framework/Error/Warning.php
new file mode 100644
index 000000000..0c0c0064f
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Error/Warning.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\Error;
+
+/**
+ * @internal
+ */
+final class Warning extends Error
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/ErrorTestCase.php b/vendor/phpunit/phpunit/src/Framework/ErrorTestCase.php
new file mode 100644
index 000000000..841247d72
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/ErrorTestCase.php
@@ -0,0 +1,66 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ErrorTestCase extends TestCase
+{
+ /**
+ * @var bool
+ */
+ protected $backupGlobals = false;
+
+ /**
+ * @var bool
+ */
+ protected $backupStaticAttributes = false;
+
+ /**
+ * @var bool
+ */
+ protected $runTestInSeparateProcess = false;
+
+ /**
+ * @var string
+ */
+ private $message;
+
+ public function __construct(string $message = '')
+ {
+ $this->message = $message;
+
+ parent::__construct('Error');
+ }
+
+ public function getMessage(): string
+ {
+ return $this->message;
+ }
+
+ /**
+ * Returns a string representation of the test case.
+ */
+ public function toString(): string
+ {
+ return 'Error';
+ }
+
+ /**
+ * @throws Exception
+ *
+ * @psalm-return never-return
+ */
+ protected function runTest(): void
+ {
+ throw new Error($this->message);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/ActualValueIsNotAnObjectException.php b/vendor/phpunit/phpunit/src/Framework/Exception/ActualValueIsNotAnObjectException.php
new file mode 100644
index 000000000..adae28294
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/ActualValueIsNotAnObjectException.php
@@ -0,0 +1,32 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use const PHP_EOL;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ActualValueIsNotAnObjectException extends Exception
+{
+ public function __construct()
+ {
+ parent::__construct(
+ 'Actual value is not an object',
+ 0,
+ null
+ );
+ }
+
+ public function __toString(): string
+ {
+ return $this->getMessage() . PHP_EOL;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/AssertionFailedError.php b/vendor/phpunit/phpunit/src/Framework/Exception/AssertionFailedError.php
new file mode 100644
index 000000000..0ba25286f
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/AssertionFailedError.php
@@ -0,0 +1,24 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+class AssertionFailedError extends Exception implements SelfDescribing
+{
+ /**
+ * Wrapper for getMessage() which is declared as final.
+ */
+ public function toString(): string
+ {
+ return $this->getMessage();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/CodeCoverageException.php b/vendor/phpunit/phpunit/src/Framework/Exception/CodeCoverageException.php
new file mode 100644
index 000000000..36b072313
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/CodeCoverageException.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+class CodeCoverageException extends Exception
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotAcceptParameterTypeException.php b/vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotAcceptParameterTypeException.php
new file mode 100644
index 000000000..ebd68f34c
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotAcceptParameterTypeException.php
@@ -0,0 +1,38 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use const PHP_EOL;
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ComparisonMethodDoesNotAcceptParameterTypeException extends Exception
+{
+ public function __construct(string $className, string $methodName, string $type)
+ {
+ parent::__construct(
+ sprintf(
+ '%s is not an accepted argument type for comparison method %s::%s().',
+ $type,
+ $className,
+ $methodName
+ ),
+ 0,
+ null
+ );
+ }
+
+ public function __toString(): string
+ {
+ return $this->getMessage() . PHP_EOL;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotDeclareBoolReturnTypeException.php b/vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotDeclareBoolReturnTypeException.php
new file mode 100644
index 000000000..20189cde4
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotDeclareBoolReturnTypeException.php
@@ -0,0 +1,37 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use const PHP_EOL;
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ComparisonMethodDoesNotDeclareBoolReturnTypeException extends Exception
+{
+ public function __construct(string $className, string $methodName)
+ {
+ parent::__construct(
+ sprintf(
+ 'Comparison method %s::%s() does not declare bool return type.',
+ $className,
+ $methodName
+ ),
+ 0,
+ null
+ );
+ }
+
+ public function __toString(): string
+ {
+ return $this->getMessage() . PHP_EOL;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotDeclareExactlyOneParameterException.php b/vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotDeclareExactlyOneParameterException.php
new file mode 100644
index 000000000..bd09d87cc
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotDeclareExactlyOneParameterException.php
@@ -0,0 +1,37 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use const PHP_EOL;
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ComparisonMethodDoesNotDeclareExactlyOneParameterException extends Exception
+{
+ public function __construct(string $className, string $methodName)
+ {
+ parent::__construct(
+ sprintf(
+ 'Comparison method %s::%s() does not declare exactly one parameter.',
+ $className,
+ $methodName
+ ),
+ 0,
+ null
+ );
+ }
+
+ public function __toString(): string
+ {
+ return $this->getMessage() . PHP_EOL;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotDeclareParameterTypeException.php b/vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotDeclareParameterTypeException.php
new file mode 100644
index 000000000..9bbb112ea
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotDeclareParameterTypeException.php
@@ -0,0 +1,37 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use const PHP_EOL;
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ComparisonMethodDoesNotDeclareParameterTypeException extends Exception
+{
+ public function __construct(string $className, string $methodName)
+ {
+ parent::__construct(
+ sprintf(
+ 'Parameter of comparison method %s::%s() does not have a declared type.',
+ $className,
+ $methodName
+ ),
+ 0,
+ null
+ );
+ }
+
+ public function __toString(): string
+ {
+ return $this->getMessage() . PHP_EOL;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotExistException.php b/vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotExistException.php
new file mode 100644
index 000000000..ad0e2d088
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/ComparisonMethodDoesNotExistException.php
@@ -0,0 +1,37 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use const PHP_EOL;
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ComparisonMethodDoesNotExistException extends Exception
+{
+ public function __construct(string $className, string $methodName)
+ {
+ parent::__construct(
+ sprintf(
+ 'Comparison method %s::%s() does not exist.',
+ $className,
+ $methodName
+ ),
+ 0,
+ null
+ );
+ }
+
+ public function __toString(): string
+ {
+ return $this->getMessage() . PHP_EOL;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/CoveredCodeNotExecutedException.php b/vendor/phpunit/phpunit/src/Framework/Exception/CoveredCodeNotExecutedException.php
new file mode 100644
index 000000000..78f89bc39
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/CoveredCodeNotExecutedException.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class CoveredCodeNotExecutedException extends RiskyTestError
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/Error.php b/vendor/phpunit/phpunit/src/Framework/Exception/Error.php
new file mode 100644
index 000000000..d43e42186
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/Error.php
@@ -0,0 +1,24 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class Error extends Exception implements SelfDescribing
+{
+ /**
+ * Wrapper for getMessage() which is declared as final.
+ */
+ public function toString(): string
+ {
+ return $this->getMessage();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/Exception.php b/vendor/phpunit/phpunit/src/Framework/Exception/Exception.php
new file mode 100644
index 000000000..0b21e6de3
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/Exception.php
@@ -0,0 +1,81 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use function array_keys;
+use function get_object_vars;
+use PHPUnit\Util\Filter;
+use RuntimeException;
+use Throwable;
+
+/**
+ * Base class for all PHPUnit Framework exceptions.
+ *
+ * Ensures that exceptions thrown during a test run do not leave stray
+ * references behind.
+ *
+ * Every Exception contains a stack trace. Each stack frame contains the 'args'
+ * of the called function. The function arguments can contain references to
+ * instantiated objects. The references prevent the objects from being
+ * destructed (until test results are eventually printed), so memory cannot be
+ * freed up.
+ *
+ * With enabled process isolation, test results are serialized in the child
+ * process and unserialized in the parent process. The stack trace of Exceptions
+ * may contain objects that cannot be serialized or unserialized (e.g., PDO
+ * connections). Unserializing user-space objects from the child process into
+ * the parent would break the intended encapsulation of process isolation.
+ *
+ * @see http://fabien.potencier.org/article/9/php-serialization-stack-traces-and-exceptions
+ *
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+class Exception extends RuntimeException implements \PHPUnit\Exception
+{
+ /**
+ * @var array
+ */
+ protected $serializableTrace;
+
+ public function __construct($message = '', $code = 0, Throwable $previous = null)
+ {
+ parent::__construct($message, $code, $previous);
+
+ $this->serializableTrace = $this->getTrace();
+
+ foreach (array_keys($this->serializableTrace) as $key) {
+ unset($this->serializableTrace[$key]['args']);
+ }
+ }
+
+ public function __toString(): string
+ {
+ $string = TestFailure::exceptionToString($this);
+
+ if ($trace = Filter::getFilteredStacktrace($this)) {
+ $string .= "\n" . $trace;
+ }
+
+ return $string;
+ }
+
+ public function __sleep(): array
+ {
+ return array_keys(get_object_vars($this));
+ }
+
+ /**
+ * Returns the serializable trace (without 'args').
+ */
+ public function getSerializableTrace(): array
+ {
+ return $this->serializableTrace;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/ExpectationFailedException.php b/vendor/phpunit/phpunit/src/Framework/Exception/ExpectationFailedException.php
new file mode 100644
index 000000000..b9a595a88
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/ExpectationFailedException.php
@@ -0,0 +1,42 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use Exception;
+use SebastianBergmann\Comparator\ComparisonFailure;
+
+/**
+ * Exception for expectations which failed their check.
+ *
+ * The exception contains the error message and optionally a
+ * SebastianBergmann\Comparator\ComparisonFailure which is used to
+ * generate diff output of the failed expectations.
+ *
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ExpectationFailedException extends AssertionFailedError
+{
+ /**
+ * @var ComparisonFailure
+ */
+ protected $comparisonFailure;
+
+ public function __construct(string $message, ComparisonFailure $comparisonFailure = null, Exception $previous = null)
+ {
+ $this->comparisonFailure = $comparisonFailure;
+
+ parent::__construct($message, 0, $previous);
+ }
+
+ public function getComparisonFailure(): ?ComparisonFailure
+ {
+ return $this->comparisonFailure;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/IncompleteTestError.php b/vendor/phpunit/phpunit/src/Framework/Exception/IncompleteTestError.php
new file mode 100644
index 000000000..65f9c8bc3
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/IncompleteTestError.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class IncompleteTestError extends AssertionFailedError implements IncompleteTest
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/InvalidArgumentException.php b/vendor/phpunit/phpunit/src/Framework/Exception/InvalidArgumentException.php
new file mode 100644
index 000000000..77f580799
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/InvalidArgumentException.php
@@ -0,0 +1,46 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use function debug_backtrace;
+use function in_array;
+use function lcfirst;
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class InvalidArgumentException extends Exception
+{
+ public static function create(int $argument, string $type): self
+ {
+ $stack = debug_backtrace();
+ $function = $stack[1]['function'];
+
+ if (isset($stack[1]['class'])) {
+ $function = sprintf('%s::%s', $stack[1]['class'], $stack[1]['function']);
+ }
+
+ return new self(
+ sprintf(
+ 'Argument #%d of %s() must be %s %s',
+ $argument,
+ $function,
+ in_array(lcfirst($type)[0], ['a', 'e', 'i', 'o', 'u'], true) ? 'an' : 'a',
+ $type
+ )
+ );
+ }
+
+ private function __construct(string $message = '', int $code = 0, \Exception $previous = null)
+ {
+ parent::__construct($message, $code, $previous);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/InvalidCoversTargetException.php b/vendor/phpunit/phpunit/src/Framework/Exception/InvalidCoversTargetException.php
new file mode 100644
index 000000000..ebf2994a9
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/InvalidCoversTargetException.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class InvalidCoversTargetException extends CodeCoverageException
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/InvalidDataProviderException.php b/vendor/phpunit/phpunit/src/Framework/Exception/InvalidDataProviderException.php
new file mode 100644
index 000000000..7e2ef24c6
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/InvalidDataProviderException.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class InvalidDataProviderException extends Exception
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/MissingCoversAnnotationException.php b/vendor/phpunit/phpunit/src/Framework/Exception/MissingCoversAnnotationException.php
new file mode 100644
index 000000000..567a6c4c5
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/MissingCoversAnnotationException.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class MissingCoversAnnotationException extends RiskyTestError
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/NoChildTestSuiteException.php b/vendor/phpunit/phpunit/src/Framework/Exception/NoChildTestSuiteException.php
new file mode 100644
index 000000000..7ef4153b0
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/NoChildTestSuiteException.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class NoChildTestSuiteException extends Exception
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/OutputError.php b/vendor/phpunit/phpunit/src/Framework/Exception/OutputError.php
new file mode 100644
index 000000000..1c8b37e56
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/OutputError.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class OutputError extends AssertionFailedError
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/PHPTAssertionFailedError.php b/vendor/phpunit/phpunit/src/Framework/Exception/PHPTAssertionFailedError.php
new file mode 100644
index 000000000..17126139f
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/PHPTAssertionFailedError.php
@@ -0,0 +1,32 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class PHPTAssertionFailedError extends SyntheticError
+{
+ /**
+ * @var string
+ */
+ private $diff;
+
+ public function __construct(string $message, int $code, string $file, int $line, array $trace, string $diff)
+ {
+ parent::__construct($message, $code, $file, $line, $trace);
+ $this->diff = $diff;
+ }
+
+ public function getDiff(): string
+ {
+ return $this->diff;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/RiskyTestError.php b/vendor/phpunit/phpunit/src/Framework/Exception/RiskyTestError.php
new file mode 100644
index 000000000..a66552c0d
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/RiskyTestError.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+class RiskyTestError extends AssertionFailedError
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/SkippedTestError.php b/vendor/phpunit/phpunit/src/Framework/Exception/SkippedTestError.php
new file mode 100644
index 000000000..7d553dcf3
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/SkippedTestError.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class SkippedTestError extends AssertionFailedError implements SkippedTest
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/SkippedTestSuiteError.php b/vendor/phpunit/phpunit/src/Framework/Exception/SkippedTestSuiteError.php
new file mode 100644
index 000000000..5448508a1
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/SkippedTestSuiteError.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class SkippedTestSuiteError extends AssertionFailedError implements SkippedTest
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/SyntheticError.php b/vendor/phpunit/phpunit/src/Framework/Exception/SyntheticError.php
new file mode 100644
index 000000000..c3124ba0c
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/SyntheticError.php
@@ -0,0 +1,61 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+class SyntheticError extends AssertionFailedError
+{
+ /**
+ * The synthetic file.
+ *
+ * @var string
+ */
+ protected $syntheticFile = '';
+
+ /**
+ * The synthetic line number.
+ *
+ * @var int
+ */
+ protected $syntheticLine = 0;
+
+ /**
+ * The synthetic trace.
+ *
+ * @var array
+ */
+ protected $syntheticTrace = [];
+
+ public function __construct(string $message, int $code, string $file, int $line, array $trace)
+ {
+ parent::__construct($message, $code);
+
+ $this->syntheticFile = $file;
+ $this->syntheticLine = $line;
+ $this->syntheticTrace = $trace;
+ }
+
+ public function getSyntheticFile(): string
+ {
+ return $this->syntheticFile;
+ }
+
+ public function getSyntheticLine(): int
+ {
+ return $this->syntheticLine;
+ }
+
+ public function getSyntheticTrace(): array
+ {
+ return $this->syntheticTrace;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/SyntheticSkippedError.php b/vendor/phpunit/phpunit/src/Framework/Exception/SyntheticSkippedError.php
new file mode 100644
index 000000000..f6e155d7b
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/SyntheticSkippedError.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class SyntheticSkippedError extends SyntheticError implements SkippedTest
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/UnintentionallyCoveredCodeError.php b/vendor/phpunit/phpunit/src/Framework/Exception/UnintentionallyCoveredCodeError.php
new file mode 100644
index 000000000..fcd1d8249
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/UnintentionallyCoveredCodeError.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class UnintentionallyCoveredCodeError extends RiskyTestError
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/Warning.php b/vendor/phpunit/phpunit/src/Framework/Exception/Warning.php
new file mode 100644
index 000000000..35e94493c
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception/Warning.php
@@ -0,0 +1,24 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class Warning extends Exception implements SelfDescribing
+{
+ /**
+ * Wrapper for getMessage() which is declared as final.
+ */
+ public function toString(): string
+ {
+ return $this->getMessage();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/ExceptionWrapper.php b/vendor/phpunit/phpunit/src/Framework/ExceptionWrapper.php
new file mode 100644
index 000000000..d1ff4abc6
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/ExceptionWrapper.php
@@ -0,0 +1,122 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use function array_keys;
+use function get_class;
+use function spl_object_hash;
+use PHPUnit\Util\Filter;
+use Throwable;
+
+/**
+ * Wraps Exceptions thrown by code under test.
+ *
+ * Re-instantiates Exceptions thrown by user-space code to retain their original
+ * class names, properties, and stack traces (but without arguments).
+ *
+ * Unlike PHPUnit\Framework\Exception, the complete stack of previous Exceptions
+ * is processed.
+ *
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ExceptionWrapper extends Exception
+{
+ /**
+ * @var string
+ */
+ protected $className;
+
+ /**
+ * @var null|ExceptionWrapper
+ */
+ protected $previous;
+
+ public function __construct(Throwable $t)
+ {
+ // PDOException::getCode() is a string.
+ // @see https://php.net/manual/en/class.pdoexception.php#95812
+ parent::__construct($t->getMessage(), (int) $t->getCode());
+
+ $this->setOriginalException($t);
+ }
+
+ public function __toString(): string
+ {
+ $string = TestFailure::exceptionToString($this);
+
+ if ($trace = Filter::getFilteredStacktrace($this)) {
+ $string .= "\n" . $trace;
+ }
+
+ if ($this->previous) {
+ $string .= "\nCaused by\n" . $this->previous;
+ }
+
+ return $string;
+ }
+
+ public function getClassName(): string
+ {
+ return $this->className;
+ }
+
+ public function getPreviousWrapped(): ?self
+ {
+ return $this->previous;
+ }
+
+ public function setClassName(string $className): void
+ {
+ $this->className = $className;
+ }
+
+ public function setOriginalException(Throwable $t): void
+ {
+ $this->originalException($t);
+
+ $this->className = get_class($t);
+ $this->file = $t->getFile();
+ $this->line = $t->getLine();
+
+ $this->serializableTrace = $t->getTrace();
+
+ foreach (array_keys($this->serializableTrace) as $key) {
+ unset($this->serializableTrace[$key]['args']);
+ }
+
+ if ($t->getPrevious()) {
+ $this->previous = new self($t->getPrevious());
+ }
+ }
+
+ public function getOriginalException(): ?Throwable
+ {
+ return $this->originalException();
+ }
+
+ /**
+ * Method to contain static originalException to exclude it from stacktrace to prevent the stacktrace contents,
+ * which can be quite big, from being garbage-collected, thus blocking memory until shutdown.
+ *
+ * Approach works both for var_dump() and var_export() and print_r().
+ */
+ private function originalException(Throwable $exceptionToStore = null): ?Throwable
+ {
+ static $originalExceptions;
+
+ $instanceId = spl_object_hash($this);
+
+ if ($exceptionToStore) {
+ $originalExceptions[$instanceId] = $exceptionToStore;
+ }
+
+ return $originalExceptions[$instanceId] ?? null;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/ExecutionOrderDependency.php b/vendor/phpunit/phpunit/src/Framework/ExecutionOrderDependency.php
new file mode 100644
index 000000000..09c343c16
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/ExecutionOrderDependency.php
@@ -0,0 +1,206 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use function array_filter;
+use function array_map;
+use function array_values;
+use function count;
+use function explode;
+use function in_array;
+use function strpos;
+use function trim;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ExecutionOrderDependency
+{
+ /**
+ * @var string
+ */
+ private $className = '';
+
+ /**
+ * @var string
+ */
+ private $methodName = '';
+
+ /**
+ * @var bool
+ */
+ private $useShallowClone = false;
+
+ /**
+ * @var bool
+ */
+ private $useDeepClone = false;
+
+ public static function createFromDependsAnnotation(string $className, string $annotation): self
+ {
+ // Split clone option and target
+ $parts = explode(' ', trim($annotation), 2);
+
+ if (count($parts) === 1) {
+ $cloneOption = '';
+ $target = $parts[0];
+ } else {
+ $cloneOption = $parts[0];
+ $target = $parts[1];
+ }
+
+ // Prefix provided class for targets assumed to be in scope
+ if ($target !== '' && strpos($target, '::') === false) {
+ $target = $className . '::' . $target;
+ }
+
+ return new self($target, null, $cloneOption);
+ }
+
+ /**
+ * @psalm-param list<ExecutionOrderDependency> $dependencies
+ *
+ * @psalm-return list<ExecutionOrderDependency>
+ */
+ public static function filterInvalid(array $dependencies): array
+ {
+ return array_values(
+ array_filter(
+ $dependencies,
+ static function (self $d)
+ {
+ return $d->isValid();
+ }
+ )
+ );
+ }
+
+ /**
+ * @psalm-param list<ExecutionOrderDependency> $existing
+ * @psalm-param list<ExecutionOrderDependency> $additional
+ *
+ * @psalm-return list<ExecutionOrderDependency>
+ */
+ public static function mergeUnique(array $existing, array $additional): array
+ {
+ $existingTargets = array_map(
+ static function ($dependency)
+ {
+ return $dependency->getTarget();
+ },
+ $existing
+ );
+
+ foreach ($additional as $dependency) {
+ if (in_array($dependency->getTarget(), $existingTargets, true)) {
+ continue;
+ }
+
+ $existingTargets[] = $dependency->getTarget();
+ $existing[] = $dependency;
+ }
+
+ return $existing;
+ }
+
+ /**
+ * @psalm-param list<ExecutionOrderDependency> $left
+ * @psalm-param list<ExecutionOrderDependency> $right
+ *
+ * @psalm-return list<ExecutionOrderDependency>
+ */
+ public static function diff(array $left, array $right): array
+ {
+ if ($right === []) {
+ return $left;
+ }
+
+ if ($left === []) {
+ return [];
+ }
+
+ $diff = [];
+ $rightTargets = array_map(
+ static function ($dependency)
+ {
+ return $dependency->getTarget();
+ },
+ $right
+ );
+
+ foreach ($left as $dependency) {
+ if (in_array($dependency->getTarget(), $rightTargets, true)) {
+ continue;
+ }
+
+ $diff[] = $dependency;
+ }
+
+ return $diff;
+ }
+
+ public function __construct(string $classOrCallableName, ?string $methodName = null, ?string $option = null)
+ {
+ if ($classOrCallableName === '') {
+ return;
+ }
+
+ if (strpos($classOrCallableName, '::') !== false) {
+ [$this->className, $this->methodName] = explode('::', $classOrCallableName);
+ } else {
+ $this->className = $classOrCallableName;
+ $this->methodName = !empty($methodName) ? $methodName : 'class';
+ }
+
+ if ($option === 'clone') {
+ $this->useDeepClone = true;
+ } elseif ($option === 'shallowClone') {
+ $this->useShallowClone = true;
+ }
+ }
+
+ public function __toString(): string
+ {
+ return $this->getTarget();
+ }
+
+ public function isValid(): bool
+ {
+ // Invalid dependencies can be declared and are skipped by the runner
+ return $this->className !== '' && $this->methodName !== '';
+ }
+
+ public function useShallowClone(): bool
+ {
+ return $this->useShallowClone;
+ }
+
+ public function useDeepClone(): bool
+ {
+ return $this->useDeepClone;
+ }
+
+ public function targetIsClass(): bool
+ {
+ return $this->methodName === 'class';
+ }
+
+ public function getTarget(): string
+ {
+ return $this->isValid()
+ ? $this->className . '::' . $this->methodName
+ : '';
+ }
+
+ public function getTargetClassName(): string
+ {
+ return $this->className;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/IncompleteTest.php b/vendor/phpunit/phpunit/src/Framework/IncompleteTest.php
new file mode 100644
index 000000000..b77b1afff
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/IncompleteTest.php
@@ -0,0 +1,19 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use Throwable;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+interface IncompleteTest extends Throwable
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/IncompleteTestCase.php b/vendor/phpunit/phpunit/src/Framework/IncompleteTestCase.php
new file mode 100644
index 000000000..ee1e3e9fe
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/IncompleteTestCase.php
@@ -0,0 +1,66 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class IncompleteTestCase extends TestCase
+{
+ /**
+ * @var bool
+ */
+ protected $backupGlobals = false;
+
+ /**
+ * @var bool
+ */
+ protected $backupStaticAttributes = false;
+
+ /**
+ * @var bool
+ */
+ protected $runTestInSeparateProcess = false;
+
+ /**
+ * @var string
+ */
+ private $message;
+
+ public function __construct(string $className, string $methodName, string $message = '')
+ {
+ parent::__construct($className . '::' . $methodName);
+
+ $this->message = $message;
+ }
+
+ public function getMessage(): string
+ {
+ return $this->message;
+ }
+
+ /**
+ * Returns a string representation of the test case.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ public function toString(): string
+ {
+ return $this->getName();
+ }
+
+ /**
+ * @throws Exception
+ */
+ protected function runTest(): void
+ {
+ $this->markTestIncomplete($this->message);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/InvalidParameterGroupException.php b/vendor/phpunit/phpunit/src/Framework/InvalidParameterGroupException.php
new file mode 100644
index 000000000..feb9cc989
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/InvalidParameterGroupException.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class InvalidParameterGroupException extends Exception
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Api/Api.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Api/Api.php
new file mode 100644
index 000000000..e2f0a2802
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Api/Api.php
@@ -0,0 +1,97 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use PHPUnit\Framework\MockObject\Builder\InvocationMocker as InvocationMockerBuilder;
+use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
+
+/**
+ * @internal This trait is not covered by the backward compatibility promise for PHPUnit
+ */
+trait Api
+{
+ /**
+ * @var ConfigurableMethod[]
+ */
+ private static $__phpunit_configurableMethods;
+
+ /**
+ * @var object
+ */
+ private $__phpunit_originalObject;
+
+ /**
+ * @var bool
+ */
+ private $__phpunit_returnValueGeneration = true;
+
+ /**
+ * @var InvocationHandler
+ */
+ private $__phpunit_invocationMocker;
+
+ /** @noinspection MagicMethodsValidityInspection */
+ public static function __phpunit_initConfigurableMethods(ConfigurableMethod ...$configurableMethods): void
+ {
+ if (isset(static::$__phpunit_configurableMethods)) {
+ throw new ConfigurableMethodsAlreadyInitializedException(
+ 'Configurable methods is already initialized and can not be reinitialized'
+ );
+ }
+
+ static::$__phpunit_configurableMethods = $configurableMethods;
+ }
+
+ /** @noinspection MagicMethodsValidityInspection */
+ public function __phpunit_setOriginalObject($originalObject): void
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ /** @noinspection MagicMethodsValidityInspection */
+ public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration): void
+ {
+ $this->__phpunit_returnValueGeneration = $returnValueGeneration;
+ }
+
+ /** @noinspection MagicMethodsValidityInspection */
+ public function __phpunit_getInvocationHandler(): InvocationHandler
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new InvocationHandler(
+ static::$__phpunit_configurableMethods,
+ $this->__phpunit_returnValueGeneration
+ );
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ /** @noinspection MagicMethodsValidityInspection */
+ public function __phpunit_hasMatchers(): bool
+ {
+ return $this->__phpunit_getInvocationHandler()->hasMatchers();
+ }
+
+ /** @noinspection MagicMethodsValidityInspection */
+ public function __phpunit_verify(bool $unsetInvocationMocker = true): void
+ {
+ $this->__phpunit_getInvocationHandler()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+
+ public function expects(InvocationOrder $matcher): InvocationMockerBuilder
+ {
+ return $this->__phpunit_getInvocationHandler()->expects($matcher);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Api/Method.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Api/Method.php
new file mode 100644
index 000000000..f6df7533c
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Api/Method.php
@@ -0,0 +1,30 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function call_user_func_array;
+use function func_get_args;
+use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount;
+
+/**
+ * @internal This trait is not covered by the backward compatibility promise for PHPUnit
+ */
+trait Method
+{
+ public function method()
+ {
+ $expects = $this->expects(new AnyInvokedCount);
+
+ return call_user_func_array(
+ [$expects, 'method'],
+ func_get_args()
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Api/MockedCloneMethod.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Api/MockedCloneMethod.php
new file mode 100644
index 000000000..91e35f937
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Api/MockedCloneMethod.php
@@ -0,0 +1,21 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+/**
+ * @internal This trait is not covered by the backward compatibility promise for PHPUnit
+ */
+trait MockedCloneMethod
+{
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationHandler();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Api/UnmockedCloneMethod.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Api/UnmockedCloneMethod.php
new file mode 100644
index 000000000..3f493d203
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Api/UnmockedCloneMethod.php
@@ -0,0 +1,23 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+/**
+ * @internal This trait is not covered by the backward compatibility promise for PHPUnit
+ */
+trait UnmockedCloneMethod
+{
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationHandler();
+
+ parent::__clone();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Identity.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Identity.php
new file mode 100644
index 000000000..a68bfadf9
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Identity.php
@@ -0,0 +1,25 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Builder;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+interface Identity
+{
+ /**
+ * Sets the identification of the expectation to $id.
+ *
+ * @note The identifier is unique per mock object.
+ *
+ * @param string $id unique identification of expectation
+ */
+ public function id($id);
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationMocker.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationMocker.php
new file mode 100644
index 000000000..89b1e31ab
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationMocker.php
@@ -0,0 +1,306 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Builder;
+
+use function array_map;
+use function array_merge;
+use function count;
+use function in_array;
+use function is_string;
+use function strtolower;
+use PHPUnit\Framework\Constraint\Constraint;
+use PHPUnit\Framework\MockObject\ConfigurableMethod;
+use PHPUnit\Framework\MockObject\IncompatibleReturnValueException;
+use PHPUnit\Framework\MockObject\InvocationHandler;
+use PHPUnit\Framework\MockObject\Matcher;
+use PHPUnit\Framework\MockObject\MatcherAlreadyRegisteredException;
+use PHPUnit\Framework\MockObject\MethodCannotBeConfiguredException;
+use PHPUnit\Framework\MockObject\MethodNameAlreadyConfiguredException;
+use PHPUnit\Framework\MockObject\MethodNameNotConfiguredException;
+use PHPUnit\Framework\MockObject\MethodParametersAlreadyConfiguredException;
+use PHPUnit\Framework\MockObject\Rule;
+use PHPUnit\Framework\MockObject\Stub\ConsecutiveCalls;
+use PHPUnit\Framework\MockObject\Stub\Exception;
+use PHPUnit\Framework\MockObject\Stub\ReturnArgument;
+use PHPUnit\Framework\MockObject\Stub\ReturnCallback;
+use PHPUnit\Framework\MockObject\Stub\ReturnReference;
+use PHPUnit\Framework\MockObject\Stub\ReturnSelf;
+use PHPUnit\Framework\MockObject\Stub\ReturnStub;
+use PHPUnit\Framework\MockObject\Stub\ReturnValueMap;
+use PHPUnit\Framework\MockObject\Stub\Stub;
+use Throwable;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class InvocationMocker implements InvocationStubber, MethodNameMatch
+{
+ /**
+ * @var InvocationHandler
+ */
+ private $invocationHandler;
+
+ /**
+ * @var Matcher
+ */
+ private $matcher;
+
+ /**
+ * @var ConfigurableMethod[]
+ */
+ private $configurableMethods;
+
+ public function __construct(InvocationHandler $handler, Matcher $matcher, ConfigurableMethod ...$configurableMethods)
+ {
+ $this->invocationHandler = $handler;
+ $this->matcher = $matcher;
+ $this->configurableMethods = $configurableMethods;
+ }
+
+ /**
+ * @throws MatcherAlreadyRegisteredException
+ *
+ * @return $this
+ */
+ public function id($id): self
+ {
+ $this->invocationHandler->registerMatcher($id, $this->matcher);
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function will(Stub $stub): Identity
+ {
+ $this->matcher->setStub($stub);
+
+ return $this;
+ }
+
+ /**
+ * @param mixed $value
+ * @param mixed[] $nextValues
+ *
+ * @throws IncompatibleReturnValueException
+ */
+ public function willReturn($value, ...$nextValues): self
+ {
+ if (count($nextValues) === 0) {
+ $this->ensureTypeOfReturnValues([$value]);
+
+ $stub = $value instanceof Stub ? $value : new ReturnStub($value);
+ } else {
+ $values = array_merge([$value], $nextValues);
+
+ $this->ensureTypeOfReturnValues($values);
+
+ $stub = new ConsecutiveCalls($values);
+ }
+
+ return $this->will($stub);
+ }
+
+ public function willReturnReference(&$reference): self
+ {
+ $stub = new ReturnReference($reference);
+
+ return $this->will($stub);
+ }
+
+ public function willReturnMap(array $valueMap): self
+ {
+ $stub = new ReturnValueMap($valueMap);
+
+ return $this->will($stub);
+ }
+
+ public function willReturnArgument($argumentIndex): self
+ {
+ $stub = new ReturnArgument($argumentIndex);
+
+ return $this->will($stub);
+ }
+
+ public function willReturnCallback($callback): self
+ {
+ $stub = new ReturnCallback($callback);
+
+ return $this->will($stub);
+ }
+
+ public function willReturnSelf(): self
+ {
+ $stub = new ReturnSelf;
+
+ return $this->will($stub);
+ }
+
+ public function willReturnOnConsecutiveCalls(...$values): self
+ {
+ $stub = new ConsecutiveCalls($values);
+
+ return $this->will($stub);
+ }
+
+ public function willThrowException(Throwable $exception): self
+ {
+ $stub = new Exception($exception);
+
+ return $this->will($stub);
+ }
+
+ /**
+ * @return $this
+ */
+ public function after($id): self
+ {
+ $this->matcher->setAfterMatchBuilderId($id);
+
+ return $this;
+ }
+
+ /**
+ * @param mixed[] $arguments
+ *
+ * @throws \PHPUnit\Framework\Exception
+ * @throws MethodNameNotConfiguredException
+ * @throws MethodParametersAlreadyConfiguredException
+ *
+ * @return $this
+ */
+ public function with(...$arguments): self
+ {
+ $this->ensureParametersCanBeConfigured();
+
+ $this->matcher->setParametersRule(new Rule\Parameters($arguments));
+
+ return $this;
+ }
+
+ /**
+ * @param array ...$arguments
+ *
+ * @throws \PHPUnit\Framework\Exception
+ * @throws MethodNameNotConfiguredException
+ * @throws MethodParametersAlreadyConfiguredException
+ *
+ * @return $this
+ */
+ public function withConsecutive(...$arguments): self
+ {
+ $this->ensureParametersCanBeConfigured();
+
+ $this->matcher->setParametersRule(new Rule\ConsecutiveParameters($arguments));
+
+ return $this;
+ }
+
+ /**
+ * @throws MethodNameNotConfiguredException
+ * @throws MethodParametersAlreadyConfiguredException
+ *
+ * @return $this
+ */
+ public function withAnyParameters(): self
+ {
+ $this->ensureParametersCanBeConfigured();
+
+ $this->matcher->setParametersRule(new Rule\AnyParameters);
+
+ return $this;
+ }
+
+ /**
+ * @param Constraint|string $constraint
+ *
+ * @throws \PHPUnit\Framework\InvalidArgumentException
+ * @throws MethodCannotBeConfiguredException
+ * @throws MethodNameAlreadyConfiguredException
+ *
+ * @return $this
+ */
+ public function method($constraint): self
+ {
+ if ($this->matcher->hasMethodNameRule()) {
+ throw new MethodNameAlreadyConfiguredException;
+ }
+
+ $configurableMethodNames = array_map(
+ static function (ConfigurableMethod $configurable)
+ {
+ return strtolower($configurable->getName());
+ },
+ $this->configurableMethods
+ );
+
+ if (is_string($constraint) && !in_array(strtolower($constraint), $configurableMethodNames, true)) {
+ throw new MethodCannotBeConfiguredException($constraint);
+ }
+
+ $this->matcher->setMethodNameRule(new Rule\MethodName($constraint));
+
+ return $this;
+ }
+
+ /**
+ * @throws MethodNameNotConfiguredException
+ * @throws MethodParametersAlreadyConfiguredException
+ */
+ private function ensureParametersCanBeConfigured(): void
+ {
+ if (!$this->matcher->hasMethodNameRule()) {
+ throw new MethodNameNotConfiguredException;
+ }
+
+ if ($this->matcher->hasParametersRule()) {
+ throw new MethodParametersAlreadyConfiguredException;
+ }
+ }
+
+ private function getConfiguredMethod(): ?ConfigurableMethod
+ {
+ $configuredMethod = null;
+
+ foreach ($this->configurableMethods as $configurableMethod) {
+ if ($this->matcher->getMethodNameRule()->matchesName($configurableMethod->getName())) {
+ if ($configuredMethod !== null) {
+ return null;
+ }
+
+ $configuredMethod = $configurableMethod;
+ }
+ }
+
+ return $configuredMethod;
+ }
+
+ /**
+ * @throws IncompatibleReturnValueException
+ */
+ private function ensureTypeOfReturnValues(array $values): void
+ {
+ $configuredMethod = $this->getConfiguredMethod();
+
+ if ($configuredMethod === null) {
+ return;
+ }
+
+ foreach ($values as $value) {
+ if (!$configuredMethod->mayReturn($value)) {
+ throw new IncompatibleReturnValueException(
+ $configuredMethod,
+ $value
+ );
+ }
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationStubber.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationStubber.php
new file mode 100644
index 000000000..f32ff0e7c
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationStubber.php
@@ -0,0 +1,65 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Builder;
+
+use PHPUnit\Framework\MockObject\Stub\Stub;
+use Throwable;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+interface InvocationStubber
+{
+ public function will(Stub $stub): Identity;
+
+ /** @return self */
+ public function willReturn($value, ...$nextValues)/*: self */;
+
+ /**
+ * @param mixed $reference
+ *
+ * @return self
+ */
+ public function willReturnReference(&$reference)/*: self */;
+
+ /**
+ * @param array<int, array<int, mixed>> $valueMap
+ *
+ * @return self
+ */
+ public function willReturnMap(array $valueMap)/*: self */;
+
+ /**
+ * @param int $argumentIndex
+ *
+ * @return self
+ */
+ public function willReturnArgument($argumentIndex)/*: self */;
+
+ /**
+ * @param callable $callback
+ *
+ * @return self
+ */
+ public function willReturnCallback($callback)/*: self */;
+
+ /** @return self */
+ public function willReturnSelf()/*: self */;
+
+ /**
+ * @param mixed $values
+ *
+ * @return self
+ */
+ public function willReturnOnConsecutiveCalls(...$values)/*: self */;
+
+ /** @return self */
+ public function willThrowException(Throwable $exception)/*: self */;
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/MethodNameMatch.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/MethodNameMatch.php
new file mode 100644
index 000000000..543d596cc
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/MethodNameMatch.php
@@ -0,0 +1,26 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Builder;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+interface MethodNameMatch extends ParametersMatch
+{
+ /**
+ * Adds a new method name match and returns the parameter match object for
+ * further matching possibilities.
+ *
+ * @param \PHPUnit\Framework\Constraint\Constraint $constraint Constraint for matching method, if a string is passed it will use the PHPUnit_Framework_Constraint_IsEqual
+ *
+ * @return ParametersMatch
+ */
+ public function method($constraint);
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php
new file mode 100644
index 000000000..707d82551
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php
@@ -0,0 +1,58 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Builder;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+interface ParametersMatch extends Stub
+{
+ /**
+ * Defines the expectation which must occur before the current is valid.
+ *
+ * @param string $id the identification of the expectation that should
+ * occur before this one
+ *
+ * @return Stub
+ */
+ public function after($id);
+
+ /**
+ * Sets the parameters to match for, each parameter to this function will
+ * be part of match. To perform specific matches or constraints create a
+ * new PHPUnit\Framework\Constraint\Constraint and use it for the parameter.
+ * If the parameter value is not a constraint it will use the
+ * PHPUnit\Framework\Constraint\IsEqual for the value.
+ *
+ * Some examples:
+ * <code>
+ * // match first parameter with value 2
+ * $b->with(2);
+ * // match first parameter with value 'smock' and second identical to 42
+ * $b->with('smock', new PHPUnit\Framework\Constraint\IsEqual(42));
+ * </code>
+ *
+ * @return ParametersMatch
+ */
+ public function with(...$arguments);
+
+ /**
+ * Sets a rule which allows any kind of parameters.
+ *
+ * Some examples:
+ * <code>
+ * // match any number of parameters
+ * $b->withAnyParameters();
+ * </code>
+ *
+ * @return ParametersMatch
+ */
+ public function withAnyParameters();
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Stub.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Stub.php
new file mode 100644
index 000000000..d7cb78fc4
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Stub.php
@@ -0,0 +1,24 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Builder;
+
+use PHPUnit\Framework\MockObject\Stub\Stub as BaseStub;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+interface Stub extends Identity
+{
+ /**
+ * Stubs the matching method with the stub object $stub. Any invocations of
+ * the matched method will now be handled by the stub instead.
+ */
+ public function will(BaseStub $stub): Identity;
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/ConfigurableMethod.php b/vendor/phpunit/phpunit/src/Framework/MockObject/ConfigurableMethod.php
new file mode 100644
index 000000000..4757dc637
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/ConfigurableMethod.php
@@ -0,0 +1,53 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use SebastianBergmann\Type\Type;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ConfigurableMethod
+{
+ /**
+ * @var string
+ */
+ private $name;
+
+ /**
+ * @var Type
+ */
+ private $returnType;
+
+ public function __construct(string $name, Type $returnType)
+ {
+ $this->name = $name;
+ $this->returnType = $returnType;
+ }
+
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ public function mayReturn($value): bool
+ {
+ if ($value === null && $this->returnType->allowsNull()) {
+ return true;
+ }
+
+ return $this->returnType->isAssignable(Type::fromValue($value, false));
+ }
+
+ public function getReturnTypeDeclaration(): string
+ {
+ return $this->returnType->asString();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/BadMethodCallException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/BadMethodCallException.php
new file mode 100644
index 000000000..7e655e235
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/BadMethodCallException.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class BadMethodCallException extends \BadMethodCallException implements Exception
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/CannotUseAddMethodsException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/CannotUseAddMethodsException.php
new file mode 100644
index 000000000..0698870bc
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/CannotUseAddMethodsException.php
@@ -0,0 +1,29 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class CannotUseAddMethodsException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct(string $type, string $methodName)
+ {
+ parent::__construct(
+ sprintf(
+ 'Trying to configure method "%s" with addMethods(), but it exists in class "%s". Use onlyMethods() for methods that exist in the class',
+ $methodName,
+ $type
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/CannotUseOnlyMethodsException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/CannotUseOnlyMethodsException.php
new file mode 100644
index 000000000..35a29b731
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/CannotUseOnlyMethodsException.php
@@ -0,0 +1,29 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class CannotUseOnlyMethodsException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct(string $type, string $methodName)
+ {
+ parent::__construct(
+ sprintf(
+ 'Trying to configure method "%s" with onlyMethods(), but it does not exist in class "%s". Use addMethods() for methods that do not exist in the class',
+ $methodName,
+ $type
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ClassAlreadyExistsException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ClassAlreadyExistsException.php
new file mode 100644
index 000000000..0ba9a187d
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ClassAlreadyExistsException.php
@@ -0,0 +1,28 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ClassAlreadyExistsException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct(string $className)
+ {
+ parent::__construct(
+ sprintf(
+ 'Class "%s" already exists',
+ $className
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ClassIsFinalException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ClassIsFinalException.php
new file mode 100644
index 000000000..e648f0263
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ClassIsFinalException.php
@@ -0,0 +1,28 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ClassIsFinalException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct(string $className)
+ {
+ parent::__construct(
+ sprintf(
+ 'Class "%s" is declared "final" and cannot be doubled',
+ $className
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ConfigurableMethodsAlreadyInitializedException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ConfigurableMethodsAlreadyInitializedException.php
new file mode 100644
index 000000000..d12ac9973
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ConfigurableMethodsAlreadyInitializedException.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ConfigurableMethodsAlreadyInitializedException extends \PHPUnit\Framework\Exception implements Exception
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/DuplicateMethodException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/DuplicateMethodException.php
new file mode 100644
index 000000000..864523acb
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/DuplicateMethodException.php
@@ -0,0 +1,32 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class DuplicateMethodException extends \PHPUnit\Framework\Exception implements Exception
+{
+ /**
+ * @psalm-param list<string> $methods
+ */
+ public function __construct(array $methods)
+ {
+ parent::__construct(
+ sprintf(
+ 'Cannot double using a method list that contains duplicates: "%s" (duplicate: "%s")',
+ implode(', ', $methods),
+ implode(', ', array_unique(array_diff_assoc($methods, array_unique($methods))))
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/Exception.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/Exception.php
new file mode 100644
index 000000000..5880bc033
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/Exception.php
@@ -0,0 +1,19 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use Throwable;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+interface Exception extends Throwable
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/IncompatibleReturnValueException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/IncompatibleReturnValueException.php
new file mode 100644
index 000000000..00febaf56
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/IncompatibleReturnValueException.php
@@ -0,0 +1,33 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class IncompatibleReturnValueException extends \PHPUnit\Framework\Exception implements Exception
+{
+ /**
+ * @param mixed $value
+ */
+ public function __construct(ConfigurableMethod $method, $value)
+ {
+ parent::__construct(
+ sprintf(
+ 'Method %s may not return value of type %s, its declared return type is "%s"',
+ $method->getName(),
+ is_object($value) ? get_class($value) : gettype($value),
+ $method->getReturnTypeDeclaration()
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/InvalidMethodNameException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/InvalidMethodNameException.php
new file mode 100644
index 000000000..d2444cf12
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/InvalidMethodNameException.php
@@ -0,0 +1,28 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class InvalidMethodNameException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct(string $method)
+ {
+ parent::__construct(
+ sprintf(
+ 'Cannot double method with invalid name "%s"',
+ $method
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MatchBuilderNotFoundException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MatchBuilderNotFoundException.php
new file mode 100644
index 000000000..c05b2bce6
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MatchBuilderNotFoundException.php
@@ -0,0 +1,28 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class MatchBuilderNotFoundException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct(string $id)
+ {
+ parent::__construct(
+ sprintf(
+ 'No builder found for match builder identification <%s>',
+ $id
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MatcherAlreadyRegisteredException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MatcherAlreadyRegisteredException.php
new file mode 100644
index 000000000..efcc13ed9
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MatcherAlreadyRegisteredException.php
@@ -0,0 +1,28 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class MatcherAlreadyRegisteredException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct(string $id)
+ {
+ parent::__construct(
+ sprintf(
+ 'Matcher with id <%s> is already registered',
+ $id
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MethodCannotBeConfiguredException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MethodCannotBeConfiguredException.php
new file mode 100644
index 000000000..707290439
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MethodCannotBeConfiguredException.php
@@ -0,0 +1,28 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class MethodCannotBeConfiguredException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct(string $method)
+ {
+ parent::__construct(
+ sprintf(
+ 'Trying to configure method "%s" which cannot be configured because it does not exist, has not been specified, is final, or is static',
+ $method
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MethodNameAlreadyConfiguredException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MethodNameAlreadyConfiguredException.php
new file mode 100644
index 000000000..1e9f2c04c
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MethodNameAlreadyConfiguredException.php
@@ -0,0 +1,21 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class MethodNameAlreadyConfiguredException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct()
+ {
+ parent::__construct('Method name is already configured');
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MethodNameNotConfiguredException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MethodNameNotConfiguredException.php
new file mode 100644
index 000000000..89565b77e
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MethodNameNotConfiguredException.php
@@ -0,0 +1,21 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class MethodNameNotConfiguredException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct()
+ {
+ parent::__construct('Method name is not configured');
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MethodParametersAlreadyConfiguredException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MethodParametersAlreadyConfiguredException.php
new file mode 100644
index 000000000..1609c6ffb
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/MethodParametersAlreadyConfiguredException.php
@@ -0,0 +1,21 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class MethodParametersAlreadyConfiguredException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct()
+ {
+ parent::__construct('Method parameters already configured');
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/OriginalConstructorInvocationRequiredException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/OriginalConstructorInvocationRequiredException.php
new file mode 100644
index 000000000..ecb9b63cf
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/OriginalConstructorInvocationRequiredException.php
@@ -0,0 +1,21 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class OriginalConstructorInvocationRequiredException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct()
+ {
+ parent::__construct('Proxying to original methods requires invoking the original constructor');
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ReflectionException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ReflectionException.php
new file mode 100644
index 000000000..d6319c694
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ReflectionException.php
@@ -0,0 +1,19 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use RuntimeException;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ReflectionException extends RuntimeException implements Exception
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ReturnValueNotConfiguredException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ReturnValueNotConfiguredException.php
new file mode 100644
index 000000000..8121e369b
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ReturnValueNotConfiguredException.php
@@ -0,0 +1,27 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ReturnValueNotConfiguredException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct(Invocation $invocation)
+ {
+ parent::__construct(
+ sprintf(
+ 'Return value inference disabled and no expectation set up for %s::%s()',
+ $invocation->getClassName(),
+ $invocation->getMethodName()
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/RuntimeException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/RuntimeException.php
new file mode 100644
index 000000000..33b6a5be3
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/RuntimeException.php
@@ -0,0 +1,17 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class RuntimeException extends \RuntimeException implements Exception
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/SoapExtensionNotAvailableException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/SoapExtensionNotAvailableException.php
new file mode 100644
index 000000000..98837c954
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/SoapExtensionNotAvailableException.php
@@ -0,0 +1,23 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class SoapExtensionNotAvailableException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct()
+ {
+ parent::__construct(
+ 'The SOAP extension is required to generate a test double from WSDL'
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/UnknownClassException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/UnknownClassException.php
new file mode 100644
index 000000000..e124f9b18
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/UnknownClassException.php
@@ -0,0 +1,28 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class UnknownClassException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct(string $className)
+ {
+ parent::__construct(
+ sprintf(
+ 'Class "%s" does not exist',
+ $className
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/UnknownTraitException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/UnknownTraitException.php
new file mode 100644
index 000000000..90fc8d848
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/UnknownTraitException.php
@@ -0,0 +1,28 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class UnknownTraitException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct(string $traitName)
+ {
+ parent::__construct(
+ sprintf(
+ 'Trait "%s" does not exist',
+ $traitName
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/UnknownTypeException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/UnknownTypeException.php
new file mode 100644
index 000000000..b1a70edd6
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/UnknownTypeException.php
@@ -0,0 +1,28 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function sprintf;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class UnknownTypeException extends \PHPUnit\Framework\Exception implements Exception
+{
+ public function __construct(string $type)
+ {
+ parent::__construct(
+ sprintf(
+ 'Class or interface "%s" does not exist',
+ $type
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator.php
new file mode 100644
index 000000000..cb8531cd3
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator.php
@@ -0,0 +1,1004 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use const DIRECTORY_SEPARATOR;
+use const PHP_EOL;
+use const PHP_MAJOR_VERSION;
+use const PREG_OFFSET_CAPTURE;
+use const WSDL_CACHE_NONE;
+use function array_merge;
+use function array_pop;
+use function array_unique;
+use function class_exists;
+use function count;
+use function explode;
+use function extension_loaded;
+use function implode;
+use function in_array;
+use function interface_exists;
+use function is_array;
+use function is_object;
+use function md5;
+use function mt_rand;
+use function preg_match;
+use function preg_match_all;
+use function range;
+use function serialize;
+use function sort;
+use function sprintf;
+use function str_replace;
+use function strlen;
+use function strpos;
+use function strtolower;
+use function substr;
+use function trait_exists;
+use Doctrine\Instantiator\Exception\ExceptionInterface as InstantiatorException;
+use Doctrine\Instantiator\Instantiator;
+use Exception;
+use Iterator;
+use IteratorAggregate;
+use PHPUnit\Framework\InvalidArgumentException;
+use ReflectionClass;
+use ReflectionMethod;
+use SebastianBergmann\Template\Exception as TemplateException;
+use SebastianBergmann\Template\Template;
+use SoapClient;
+use SoapFault;
+use Throwable;
+use Traversable;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class Generator
+{
+ /**
+ * @var array
+ */
+ private const EXCLUDED_METHOD_NAMES = [
+ '__CLASS__' => true,
+ '__DIR__' => true,
+ '__FILE__' => true,
+ '__FUNCTION__' => true,
+ '__LINE__' => true,
+ '__METHOD__' => true,
+ '__NAMESPACE__' => true,
+ '__TRAIT__' => true,
+ '__clone' => true,
+ '__halt_compiler' => true,
+ ];
+
+ /**
+ * @var array
+ */
+ private static $cache = [];
+
+ /**
+ * @var Template[]
+ */
+ private static $templates = [];
+
+ /**
+ * Returns a mock object for the specified class.
+ *
+ * @param null|array $methods
+ *
+ * @throws \PHPUnit\Framework\InvalidArgumentException
+ * @throws ClassAlreadyExistsException
+ * @throws ClassIsFinalException
+ * @throws DuplicateMethodException
+ * @throws InvalidMethodNameException
+ * @throws OriginalConstructorInvocationRequiredException
+ * @throws ReflectionException
+ * @throws RuntimeException
+ * @throws UnknownTypeException
+ */
+ public function getMock(string $type, $methods = [], array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = true, bool $callOriginalClone = true, bool $callAutoload = true, bool $cloneArguments = true, bool $callOriginalMethods = false, object $proxyTarget = null, bool $allowMockingUnknownTypes = true, bool $returnValueGeneration = true): MockObject
+ {
+ if (!is_array($methods) && null !== $methods) {
+ throw InvalidArgumentException::create(2, 'array');
+ }
+
+ if ($type === 'Traversable' || $type === '\\Traversable') {
+ $type = 'Iterator';
+ }
+
+ if (!$allowMockingUnknownTypes && !class_exists($type, $callAutoload) && !interface_exists($type, $callAutoload)) {
+ throw new UnknownTypeException($type);
+ }
+
+ if (null !== $methods) {
+ foreach ($methods as $method) {
+ if (!preg_match('~[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*~', (string) $method)) {
+ throw new InvalidMethodNameException((string) $method);
+ }
+ }
+
+ if ($methods !== array_unique($methods)) {
+ throw new DuplicateMethodException($methods);
+ }
+ }
+
+ if ($mockClassName !== '' && class_exists($mockClassName, false)) {
+ try {
+ $reflector = new ReflectionClass($mockClassName);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ if (!$reflector->implementsInterface(MockObject::class)) {
+ throw new ClassAlreadyExistsException($mockClassName);
+ }
+ }
+
+ if (!$callOriginalConstructor && $callOriginalMethods) {
+ throw new OriginalConstructorInvocationRequiredException;
+ }
+
+ $mock = $this->generate(
+ $type,
+ $methods,
+ $mockClassName,
+ $callOriginalClone,
+ $callAutoload,
+ $cloneArguments,
+ $callOriginalMethods
+ );
+
+ return $this->getObject(
+ $mock,
+ $type,
+ $callOriginalConstructor,
+ $callAutoload,
+ $arguments,
+ $callOriginalMethods,
+ $proxyTarget,
+ $returnValueGeneration
+ );
+ }
+
+ /**
+ * Returns a mock object for the specified abstract class with all abstract
+ * methods of the class mocked.
+ *
+ * Concrete methods to mock can be specified with the $mockedMethods parameter.
+ *
+ * @psalm-template RealInstanceType of object
+ * @psalm-param class-string<RealInstanceType> $originalClassName
+ * @psalm-return MockObject&RealInstanceType
+ *
+ * @throws \PHPUnit\Framework\InvalidArgumentException
+ * @throws ClassAlreadyExistsException
+ * @throws ClassIsFinalException
+ * @throws DuplicateMethodException
+ * @throws InvalidMethodNameException
+ * @throws OriginalConstructorInvocationRequiredException
+ * @throws ReflectionException
+ * @throws RuntimeException
+ * @throws UnknownClassException
+ * @throws UnknownTypeException
+ */
+ public function getMockForAbstractClass(string $originalClassName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = true, bool $callOriginalClone = true, bool $callAutoload = true, array $mockedMethods = null, bool $cloneArguments = true): MockObject
+ {
+ if (class_exists($originalClassName, $callAutoload) ||
+ interface_exists($originalClassName, $callAutoload)) {
+ try {
+ $reflector = new ReflectionClass($originalClassName);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ $methods = $mockedMethods;
+
+ foreach ($reflector->getMethods() as $method) {
+ if ($method->isAbstract() && !in_array($method->getName(), $methods ?? [], true)) {
+ $methods[] = $method->getName();
+ }
+ }
+
+ if (empty($methods)) {
+ $methods = null;
+ }
+
+ return $this->getMock(
+ $originalClassName,
+ $methods,
+ $arguments,
+ $mockClassName,
+ $callOriginalConstructor,
+ $callOriginalClone,
+ $callAutoload,
+ $cloneArguments
+ );
+ }
+
+ throw new UnknownClassException($originalClassName);
+ }
+
+ /**
+ * Returns a mock object for the specified trait with all abstract methods
+ * of the trait mocked. Concrete methods to mock can be specified with the
+ * `$mockedMethods` parameter.
+ *
+ * @psalm-param trait-string $traitName
+ *
+ * @throws \PHPUnit\Framework\InvalidArgumentException
+ * @throws ClassAlreadyExistsException
+ * @throws ClassIsFinalException
+ * @throws DuplicateMethodException
+ * @throws InvalidMethodNameException
+ * @throws OriginalConstructorInvocationRequiredException
+ * @throws ReflectionException
+ * @throws RuntimeException
+ * @throws UnknownClassException
+ * @throws UnknownTraitException
+ * @throws UnknownTypeException
+ */
+ public function getMockForTrait(string $traitName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = true, bool $callOriginalClone = true, bool $callAutoload = true, array $mockedMethods = null, bool $cloneArguments = true): MockObject
+ {
+ if (!trait_exists($traitName, $callAutoload)) {
+ throw new UnknownTraitException($traitName);
+ }
+
+ $className = $this->generateClassName(
+ $traitName,
+ '',
+ 'Trait_'
+ );
+
+ $classTemplate = $this->getTemplate('trait_class.tpl');
+
+ $classTemplate->setVar(
+ [
+ 'prologue' => 'abstract ',
+ 'class_name' => $className['className'],
+ 'trait_name' => $traitName,
+ ]
+ );
+
+ $mockTrait = new MockTrait($classTemplate->render(), $className['className']);
+ $mockTrait->generate();
+
+ return $this->getMockForAbstractClass($className['className'], $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments);
+ }
+
+ /**
+ * Returns an object for the specified trait.
+ *
+ * @psalm-param trait-string $traitName
+ *
+ * @throws ReflectionException
+ * @throws RuntimeException
+ * @throws UnknownTraitException
+ */
+ public function getObjectForTrait(string $traitName, string $traitClassName = '', bool $callAutoload = true, bool $callOriginalConstructor = false, array $arguments = []): object
+ {
+ if (!trait_exists($traitName, $callAutoload)) {
+ throw new UnknownTraitException($traitName);
+ }
+
+ $className = $this->generateClassName(
+ $traitName,
+ $traitClassName,
+ 'Trait_'
+ );
+
+ $classTemplate = $this->getTemplate('trait_class.tpl');
+
+ $classTemplate->setVar(
+ [
+ 'prologue' => '',
+ 'class_name' => $className['className'],
+ 'trait_name' => $traitName,
+ ]
+ );
+
+ return $this->getObject(
+ new MockTrait(
+ $classTemplate->render(),
+ $className['className']
+ ),
+ '',
+ $callOriginalConstructor,
+ $callAutoload,
+ $arguments
+ );
+ }
+
+ /**
+ * @throws ClassIsFinalException
+ * @throws ReflectionException
+ * @throws RuntimeException
+ */
+ public function generate(string $type, array $methods = null, string $mockClassName = '', bool $callOriginalClone = true, bool $callAutoload = true, bool $cloneArguments = true, bool $callOriginalMethods = false): MockClass
+ {
+ if ($mockClassName !== '') {
+ return $this->generateMock(
+ $type,
+ $methods,
+ $mockClassName,
+ $callOriginalClone,
+ $callAutoload,
+ $cloneArguments,
+ $callOriginalMethods
+ );
+ }
+
+ $key = md5(
+ $type .
+ serialize($methods) .
+ serialize($callOriginalClone) .
+ serialize($cloneArguments) .
+ serialize($callOriginalMethods)
+ );
+
+ if (!isset(self::$cache[$key])) {
+ self::$cache[$key] = $this->generateMock(
+ $type,
+ $methods,
+ $mockClassName,
+ $callOriginalClone,
+ $callAutoload,
+ $cloneArguments,
+ $callOriginalMethods
+ );
+ }
+
+ return self::$cache[$key];
+ }
+
+ /**
+ * @throws RuntimeException
+ * @throws SoapExtensionNotAvailableException
+ */
+ public function generateClassFromWsdl(string $wsdlFile, string $className, array $methods = [], array $options = []): string
+ {
+ if (!extension_loaded('soap')) {
+ throw new SoapExtensionNotAvailableException;
+ }
+
+ $options = array_merge($options, ['cache_wsdl' => WSDL_CACHE_NONE]);
+
+ try {
+ $client = new SoapClient($wsdlFile, $options);
+ $_methods = array_unique($client->__getFunctions());
+ unset($client);
+ } catch (SoapFault $e) {
+ throw new RuntimeException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+
+ sort($_methods);
+
+ $methodTemplate = $this->getTemplate('wsdl_method.tpl');
+ $methodsBuffer = '';
+
+ foreach ($_methods as $method) {
+ preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\(/', $method, $matches, PREG_OFFSET_CAPTURE);
+ $lastFunction = array_pop($matches[0]);
+ $nameStart = $lastFunction[1];
+ $nameEnd = $nameStart + strlen($lastFunction[0]) - 1;
+ $name = str_replace('(', '', $lastFunction[0]);
+
+ if (empty($methods) || in_array($name, $methods, true)) {
+ $args = explode(
+ ',',
+ str_replace(')', '', substr($method, $nameEnd + 1))
+ );
+
+ foreach (range(0, count($args) - 1) as $i) {
+ $parameterStart = strpos($args[$i], '$');
+
+ if (!$parameterStart) {
+ continue;
+ }
+
+ $args[$i] = substr($args[$i], $parameterStart);
+ }
+
+ $methodTemplate->setVar(
+ [
+ 'method_name' => $name,
+ 'arguments' => implode(', ', $args),
+ ]
+ );
+
+ $methodsBuffer .= $methodTemplate->render();
+ }
+ }
+
+ $optionsBuffer = '[';
+
+ foreach ($options as $key => $value) {
+ $optionsBuffer .= $key . ' => ' . $value;
+ }
+
+ $optionsBuffer .= ']';
+
+ $classTemplate = $this->getTemplate('wsdl_class.tpl');
+ $namespace = '';
+
+ if (strpos($className, '\\') !== false) {
+ $parts = explode('\\', $className);
+ $className = array_pop($parts);
+ $namespace = 'namespace ' . implode('\\', $parts) . ';' . "\n\n";
+ }
+
+ $classTemplate->setVar(
+ [
+ 'namespace' => $namespace,
+ 'class_name' => $className,
+ 'wsdl' => $wsdlFile,
+ 'options' => $optionsBuffer,
+ 'methods' => $methodsBuffer,
+ ]
+ );
+
+ return $classTemplate->render();
+ }
+
+ /**
+ * @throws ReflectionException
+ *
+ * @return string[]
+ */
+ public function getClassMethods(string $className): array
+ {
+ try {
+ $class = new ReflectionClass($className);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ $methods = [];
+
+ foreach ($class->getMethods() as $method) {
+ if ($method->isPublic() || $method->isAbstract()) {
+ $methods[] = $method->getName();
+ }
+ }
+
+ return $methods;
+ }
+
+ /**
+ * @throws ReflectionException
+ *
+ * @return MockMethod[]
+ */
+ public function mockClassMethods(string $className, bool $callOriginalMethods, bool $cloneArguments): array
+ {
+ try {
+ $class = new ReflectionClass($className);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ $methods = [];
+
+ foreach ($class->getMethods() as $method) {
+ if (($method->isPublic() || $method->isAbstract()) && $this->canMockMethod($method)) {
+ $methods[] = MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments);
+ }
+ }
+
+ return $methods;
+ }
+
+ /**
+ * @throws ReflectionException
+ *
+ * @return MockMethod[]
+ */
+ public function mockInterfaceMethods(string $interfaceName, bool $cloneArguments): array
+ {
+ try {
+ $class = new ReflectionClass($interfaceName);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ $methods = [];
+
+ foreach ($class->getMethods() as $method) {
+ $methods[] = MockMethod::fromReflection($method, false, $cloneArguments);
+ }
+
+ return $methods;
+ }
+
+ /**
+ * @psalm-param class-string $interfaceName
+ *
+ * @throws ReflectionException
+ *
+ * @return ReflectionMethod[]
+ */
+ private function userDefinedInterfaceMethods(string $interfaceName): array
+ {
+ try {
+ // @codeCoverageIgnoreStart
+ $interface = new ReflectionClass($interfaceName);
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ $methods = [];
+
+ foreach ($interface->getMethods() as $method) {
+ if (!$method->isUserDefined()) {
+ continue;
+ }
+
+ $methods[] = $method;
+ }
+
+ return $methods;
+ }
+
+ /**
+ * @throws ReflectionException
+ * @throws RuntimeException
+ */
+ private function getObject(MockType $mockClass, $type = '', bool $callOriginalConstructor = false, bool $callAutoload = false, array $arguments = [], bool $callOriginalMethods = false, object $proxyTarget = null, bool $returnValueGeneration = true)
+ {
+ $className = $mockClass->generate();
+
+ if ($callOriginalConstructor) {
+ if (count($arguments) === 0) {
+ $object = new $className;
+ } else {
+ try {
+ $class = new ReflectionClass($className);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ $object = $class->newInstanceArgs($arguments);
+ }
+ } else {
+ try {
+ $object = (new Instantiator)->instantiate($className);
+ } catch (InstantiatorException $e) {
+ throw new RuntimeException($e->getMessage());
+ }
+ }
+
+ if ($callOriginalMethods) {
+ if (!is_object($proxyTarget)) {
+ if (count($arguments) === 0) {
+ $proxyTarget = new $type;
+ } else {
+ try {
+ $class = new ReflectionClass($type);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ $proxyTarget = $class->newInstanceArgs($arguments);
+ }
+ }
+
+ $object->__phpunit_setOriginalObject($proxyTarget);
+ }
+
+ if ($object instanceof MockObject) {
+ $object->__phpunit_setReturnValueGeneration($returnValueGeneration);
+ }
+
+ return $object;
+ }
+
+ /**
+ * @throws ClassIsFinalException
+ * @throws ReflectionException
+ * @throws RuntimeException
+ */
+ private function generateMock(string $type, ?array $explicitMethods, string $mockClassName, bool $callOriginalClone, bool $callAutoload, bool $cloneArguments, bool $callOriginalMethods): MockClass
+ {
+ $classTemplate = $this->getTemplate('mocked_class.tpl');
+ $additionalInterfaces = [];
+ $mockedCloneMethod = false;
+ $unmockedCloneMethod = false;
+ $isClass = false;
+ $isInterface = false;
+ $class = null;
+ $mockMethods = new MockMethodSet;
+
+ $_mockClassName = $this->generateClassName(
+ $type,
+ $mockClassName,
+ 'Mock_'
+ );
+
+ if (class_exists($_mockClassName['fullClassName'], $callAutoload)) {
+ $isClass = true;
+ } elseif (interface_exists($_mockClassName['fullClassName'], $callAutoload)) {
+ $isInterface = true;
+ }
+
+ if (!$isClass && !$isInterface) {
+ $prologue = 'class ' . $_mockClassName['originalClassName'] . "\n{\n}\n\n";
+
+ if (!empty($_mockClassName['namespaceName'])) {
+ $prologue = 'namespace ' . $_mockClassName['namespaceName'] .
+ " {\n\n" . $prologue . "}\n\n" .
+ "namespace {\n\n";
+
+ $epilogue = "\n\n}";
+ }
+
+ $mockedCloneMethod = true;
+ } else {
+ try {
+ $class = new ReflectionClass($_mockClassName['fullClassName']);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ if ($class->isFinal()) {
+ throw new ClassIsFinalException($_mockClassName['fullClassName']);
+ }
+
+ // @see https://github.com/sebastianbergmann/phpunit/issues/2995
+ if ($isInterface && $class->implementsInterface(Throwable::class)) {
+ $actualClassName = Exception::class;
+ $additionalInterfaces[] = $class->getName();
+ $isInterface = false;
+
+ try {
+ $class = new ReflectionClass($actualClassName);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ foreach ($this->userDefinedInterfaceMethods($_mockClassName['fullClassName']) as $method) {
+ $methodName = $method->getName();
+
+ if ($class->hasMethod($methodName)) {
+ try {
+ $classMethod = $class->getMethod($methodName);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ if (!$this->canMockMethod($classMethod)) {
+ continue;
+ }
+ }
+
+ $mockMethods->addMethods(
+ MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments)
+ );
+ }
+
+ $_mockClassName = $this->generateClassName(
+ $actualClassName,
+ $_mockClassName['className'],
+ 'Mock_'
+ );
+ }
+
+ // @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/103
+ if ($isInterface && $class->implementsInterface(Traversable::class) &&
+ !$class->implementsInterface(Iterator::class) &&
+ !$class->implementsInterface(IteratorAggregate::class)) {
+ $additionalInterfaces[] = Iterator::class;
+
+ $mockMethods->addMethods(
+ ...$this->mockClassMethods(Iterator::class, $callOriginalMethods, $cloneArguments)
+ );
+ }
+
+ if ($class->hasMethod('__clone')) {
+ try {
+ $cloneMethod = $class->getMethod('__clone');
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ if (!$cloneMethod->isFinal()) {
+ if ($callOriginalClone && !$isInterface) {
+ $unmockedCloneMethod = true;
+ } else {
+ $mockedCloneMethod = true;
+ }
+ }
+ } else {
+ $mockedCloneMethod = true;
+ }
+ }
+
+ if ($isClass && $explicitMethods === []) {
+ $mockMethods->addMethods(
+ ...$this->mockClassMethods($_mockClassName['fullClassName'], $callOriginalMethods, $cloneArguments)
+ );
+ }
+
+ if ($isInterface && ($explicitMethods === [] || $explicitMethods === null)) {
+ $mockMethods->addMethods(
+ ...$this->mockInterfaceMethods($_mockClassName['fullClassName'], $cloneArguments)
+ );
+ }
+
+ if (is_array($explicitMethods)) {
+ foreach ($explicitMethods as $methodName) {
+ if ($class !== null && $class->hasMethod($methodName)) {
+ try {
+ $method = $class->getMethod($methodName);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ if ($this->canMockMethod($method)) {
+ $mockMethods->addMethods(
+ MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments)
+ );
+ }
+ } else {
+ $mockMethods->addMethods(
+ MockMethod::fromName(
+ $_mockClassName['fullClassName'],
+ $methodName,
+ $cloneArguments
+ )
+ );
+ }
+ }
+ }
+
+ $mockedMethods = '';
+ $configurable = [];
+
+ foreach ($mockMethods->asArray() as $mockMethod) {
+ $mockedMethods .= $mockMethod->generateCode();
+ $configurable[] = new ConfigurableMethod($mockMethod->getName(), $mockMethod->getReturnType());
+ }
+
+ $method = '';
+
+ if (!$mockMethods->hasMethod('method') && (!isset($class) || !$class->hasMethod('method'))) {
+ $method = PHP_EOL . ' use \PHPUnit\Framework\MockObject\Method;';
+ }
+
+ $cloneTrait = '';
+
+ if ($mockedCloneMethod) {
+ $cloneTrait = PHP_EOL . ' use \PHPUnit\Framework\MockObject\MockedCloneMethod;';
+ }
+
+ if ($unmockedCloneMethod) {
+ $cloneTrait = PHP_EOL . ' use \PHPUnit\Framework\MockObject\UnmockedCloneMethod;';
+ }
+
+ $classTemplate->setVar(
+ [
+ 'prologue' => $prologue ?? '',
+ 'epilogue' => $epilogue ?? '',
+ 'class_declaration' => $this->generateMockClassDeclaration(
+ $_mockClassName,
+ $isInterface,
+ $additionalInterfaces
+ ),
+ 'clone' => $cloneTrait,
+ 'mock_class_name' => $_mockClassName['className'],
+ 'mocked_methods' => $mockedMethods,
+ 'method' => $method,
+ ]
+ );
+
+ return new MockClass(
+ $classTemplate->render(),
+ $_mockClassName['className'],
+ $configurable
+ );
+ }
+
+ private function generateClassName(string $type, string $className, string $prefix): array
+ {
+ if ($type[0] === '\\') {
+ $type = substr($type, 1);
+ }
+
+ $classNameParts = explode('\\', $type);
+
+ if (count($classNameParts) > 1) {
+ $type = array_pop($classNameParts);
+ $namespaceName = implode('\\', $classNameParts);
+ $fullClassName = $namespaceName . '\\' . $type;
+ } else {
+ $namespaceName = '';
+ $fullClassName = $type;
+ }
+
+ if ($className === '') {
+ do {
+ $className = $prefix . $type . '_' .
+ substr(md5((string) mt_rand()), 0, 8);
+ } while (class_exists($className, false));
+ }
+
+ return [
+ 'className' => $className,
+ 'originalClassName' => $type,
+ 'fullClassName' => $fullClassName,
+ 'namespaceName' => $namespaceName,
+ ];
+ }
+
+ private function generateMockClassDeclaration(array $mockClassName, bool $isInterface, array $additionalInterfaces = []): string
+ {
+ $buffer = 'class ';
+
+ $additionalInterfaces[] = MockObject::class;
+ $interfaces = implode(', ', $additionalInterfaces);
+
+ if ($isInterface) {
+ $buffer .= sprintf(
+ '%s implements %s',
+ $mockClassName['className'],
+ $interfaces
+ );
+
+ if (!in_array($mockClassName['originalClassName'], $additionalInterfaces, true)) {
+ $buffer .= ', ';
+
+ if (!empty($mockClassName['namespaceName'])) {
+ $buffer .= $mockClassName['namespaceName'] . '\\';
+ }
+
+ $buffer .= $mockClassName['originalClassName'];
+ }
+ } else {
+ $buffer .= sprintf(
+ '%s extends %s%s implements %s',
+ $mockClassName['className'],
+ !empty($mockClassName['namespaceName']) ? $mockClassName['namespaceName'] . '\\' : '',
+ $mockClassName['originalClassName'],
+ $interfaces
+ );
+ }
+
+ return $buffer;
+ }
+
+ private function canMockMethod(ReflectionMethod $method): bool
+ {
+ return !($this->isConstructor($method) || $method->isFinal() || $method->isPrivate() || $this->isMethodNameExcluded($method->getName()));
+ }
+
+ private function isMethodNameExcluded(string $name): bool
+ {
+ return isset(self::EXCLUDED_METHOD_NAMES[$name]);
+ }
+
+ /**
+ * @throws RuntimeException
+ */
+ private function getTemplate(string $template): Template
+ {
+ $filename = __DIR__ . DIRECTORY_SEPARATOR . 'Generator' . DIRECTORY_SEPARATOR . $template;
+
+ if (!isset(self::$templates[$filename])) {
+ try {
+ self::$templates[$filename] = new Template($filename);
+ } catch (TemplateException $e) {
+ throw new RuntimeException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ }
+
+ return self::$templates[$filename];
+ }
+
+ /**
+ * @see https://github.com/sebastianbergmann/phpunit/issues/4139#issuecomment-605409765
+ */
+ private function isConstructor(ReflectionMethod $method): bool
+ {
+ $methodName = strtolower($method->getName());
+
+ if ($methodName === '__construct') {
+ return true;
+ }
+
+ if (PHP_MAJOR_VERSION >= 8) {
+ return false;
+ }
+
+ $className = strtolower($method->getDeclaringClass()->getName());
+
+ return $methodName === $className;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/deprecation.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/deprecation.tpl
new file mode 100644
index 000000000..5bf06f52d
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/deprecation.tpl
@@ -0,0 +1,2 @@
+
+ @trigger_error({deprecation}, E_USER_DEPRECATED);
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_class.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_class.tpl
new file mode 100644
index 000000000..593119fb2
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_class.tpl
@@ -0,0 +1,6 @@
+declare(strict_types=1);
+
+{prologue}{class_declaration}
+{
+ use \PHPUnit\Framework\MockObject\Api;{method}{clone}
+{mocked_methods}}{epilogue}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method.tpl
new file mode 100644
index 000000000..114ff8d0d
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method.tpl
@@ -0,0 +1,22 @@
+
+ {modifier} function {reference}{method_name}({arguments_decl}){return_declaration}
+ {{deprecation}
+ $__phpunit_arguments = [{arguments_call}];
+ $__phpunit_count = func_num_args();
+
+ if ($__phpunit_count > {arguments_count}) {
+ $__phpunit_arguments_tmp = func_get_args();
+
+ for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) {
+ $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i];
+ }
+ }
+
+ $__phpunit_result = $this->__phpunit_getInvocationHandler()->invoke(
+ new \PHPUnit\Framework\MockObject\Invocation(
+ '{class_name}', '{method_name}', $__phpunit_arguments, '{return_type}', $this, {clone_arguments}
+ )
+ );
+
+ return $__phpunit_result;
+ }
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method_void.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method_void.tpl
new file mode 100644
index 000000000..390202201
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method_void.tpl
@@ -0,0 +1,20 @@
+
+ {modifier} function {reference}{method_name}({arguments_decl}){return_declaration}
+ {{deprecation}
+ $__phpunit_arguments = [{arguments_call}];
+ $__phpunit_count = func_num_args();
+
+ if ($__phpunit_count > {arguments_count}) {
+ $__phpunit_arguments_tmp = func_get_args();
+
+ for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) {
+ $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i];
+ }
+ }
+
+ $this->__phpunit_getInvocationHandler()->invoke(
+ new \PHPUnit\Framework\MockObject\Invocation(
+ '{class_name}', '{method_name}', $__phpunit_arguments, '{return_type}', $this, {clone_arguments}
+ )
+ );
+ }
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_static_method.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_static_method.tpl
new file mode 100644
index 000000000..5e5cf23cd
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_static_method.tpl
@@ -0,0 +1,5 @@
+
+ {modifier} function {reference}{method_name}({arguments_decl}){return_declaration}
+ {
+ throw new \PHPUnit\Framework\MockObject\BadMethodCallException('Static method "{method_name}" cannot be invoked on mock object');
+ }
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method.tpl
new file mode 100644
index 000000000..91bef463d
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method.tpl
@@ -0,0 +1,22 @@
+
+ {modifier} function {reference}{method_name}({arguments_decl}){return_declaration}
+ {
+ $__phpunit_arguments = [{arguments_call}];
+ $__phpunit_count = func_num_args();
+
+ if ($__phpunit_count > {arguments_count}) {
+ $__phpunit_arguments_tmp = func_get_args();
+
+ for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) {
+ $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i];
+ }
+ }
+
+ $this->__phpunit_getInvocationHandler()->invoke(
+ new \PHPUnit\Framework\MockObject\Invocation(
+ '{class_name}', '{method_name}', $__phpunit_arguments, '{return_type}', $this, {clone_arguments}, true
+ )
+ );
+
+ return call_user_func_array(array($this->__phpunit_originalObject, "{method_name}"), $__phpunit_arguments);
+ }
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method_void.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method_void.tpl
new file mode 100644
index 000000000..cce198826
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method_void.tpl
@@ -0,0 +1,22 @@
+
+ {modifier} function {reference}{method_name}({arguments_decl}){return_declaration}
+ {
+ $__phpunit_arguments = [{arguments_call}];
+ $__phpunit_count = func_num_args();
+
+ if ($__phpunit_count > {arguments_count}) {
+ $__phpunit_arguments_tmp = func_get_args();
+
+ for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) {
+ $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i];
+ }
+ }
+
+ $this->__phpunit_getInvocationHandler()->invoke(
+ new \PHPUnit\Framework\MockObject\Invocation(
+ '{class_name}', '{method_name}', $__phpunit_arguments, '{return_type}', $this, {clone_arguments}, true
+ )
+ );
+
+ call_user_func_array(array($this->__phpunit_originalObject, "{method_name}"), $__phpunit_arguments);
+ }
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/trait_class.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/trait_class.tpl
new file mode 100644
index 000000000..a8fe470fd
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/trait_class.tpl
@@ -0,0 +1,6 @@
+declare(strict_types=1);
+
+{prologue}class {class_name}
+{
+ use {trait_name};
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_class.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_class.tpl
new file mode 100644
index 000000000..b3100b414
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_class.tpl
@@ -0,0 +1,9 @@
+declare(strict_types=1);
+
+{namespace}class {class_name} extends \SoapClient
+{
+ public function __construct($wsdl, array $options)
+ {
+ parent::__construct('{wsdl}', $options);
+ }
+{methods}}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_method.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_method.tpl
new file mode 100644
index 000000000..bb16e763e
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_method.tpl
@@ -0,0 +1,4 @@
+
+ public function {method_name}({arguments})
+ {
+ }
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Invocation.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Invocation.php
new file mode 100644
index 000000000..392938347
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Invocation.php
@@ -0,0 +1,254 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function array_map;
+use function explode;
+use function get_class;
+use function implode;
+use function is_object;
+use function sprintf;
+use function strpos;
+use function strtolower;
+use function substr;
+use Doctrine\Instantiator\Instantiator;
+use PHPUnit\Framework\SelfDescribing;
+use PHPUnit\Util\Type;
+use SebastianBergmann\Exporter\Exporter;
+use stdClass;
+use Throwable;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class Invocation implements SelfDescribing
+{
+ /**
+ * @var string
+ */
+ private $className;
+
+ /**
+ * @var string
+ */
+ private $methodName;
+
+ /**
+ * @var array
+ */
+ private $parameters;
+
+ /**
+ * @var string
+ */
+ private $returnType;
+
+ /**
+ * @var bool
+ */
+ private $isReturnTypeNullable = false;
+
+ /**
+ * @var bool
+ */
+ private $proxiedCall;
+
+ /**
+ * @var object
+ */
+ private $object;
+
+ public function __construct(string $className, string $methodName, array $parameters, string $returnType, object $object, bool $cloneObjects = false, bool $proxiedCall = false)
+ {
+ $this->className = $className;
+ $this->methodName = $methodName;
+ $this->parameters = $parameters;
+ $this->object = $object;
+ $this->proxiedCall = $proxiedCall;
+
+ if (strtolower($methodName) === '__tostring') {
+ $returnType = 'string';
+ }
+
+ if (strpos($returnType, '?') === 0) {
+ $returnType = substr($returnType, 1);
+ $this->isReturnTypeNullable = true;
+ }
+
+ $this->returnType = $returnType;
+
+ if (!$cloneObjects) {
+ return;
+ }
+
+ foreach ($this->parameters as $key => $value) {
+ if (is_object($value)) {
+ $this->parameters[$key] = $this->cloneObject($value);
+ }
+ }
+ }
+
+ public function getClassName(): string
+ {
+ return $this->className;
+ }
+
+ public function getMethodName(): string
+ {
+ return $this->methodName;
+ }
+
+ public function getParameters(): array
+ {
+ return $this->parameters;
+ }
+
+ /**
+ * @throws RuntimeException
+ *
+ * @return mixed Mocked return value
+ */
+ public function generateReturnValue()
+ {
+ if ($this->isReturnTypeNullable || $this->proxiedCall) {
+ return null;
+ }
+
+ $union = false;
+
+ if (strpos($this->returnType, '|') !== false) {
+ $types = explode('|', $this->returnType);
+ $union = true;
+ } else {
+ $types = [$this->returnType];
+ }
+
+ $types = array_map('strtolower', $types);
+
+ if (in_array('', $types, true) ||
+ in_array('null', $types, true) ||
+ in_array('mixed', $types, true) ||
+ in_array('void', $types, true)) {
+ return null;
+ }
+
+ if (in_array('false', $types, true) ||
+ in_array('bool', $types, true)) {
+ return false;
+ }
+
+ if (in_array('float', $types, true)) {
+ return 0.0;
+ }
+
+ if (in_array('int', $types, true)) {
+ return 0;
+ }
+
+ if (in_array('string', $types, true)) {
+ return '';
+ }
+
+ if (in_array('array', $types, true)) {
+ return [];
+ }
+
+ if (in_array('static', $types, true)) {
+ try {
+ return (new Instantiator)->instantiate(get_class($this->object));
+ } catch (Throwable $t) {
+ throw new RuntimeException(
+ $t->getMessage(),
+ (int) $t->getCode(),
+ $t
+ );
+ }
+ }
+
+ if (in_array('object', $types, true)) {
+ return new stdClass;
+ }
+
+ if (in_array('callable', $types, true) ||
+ in_array('closure', $types, true)) {
+ return static function (): void
+ {
+ };
+ }
+
+ if (in_array('traversable', $types, true) ||
+ in_array('generator', $types, true) ||
+ in_array('iterable', $types, true)) {
+ $generator = static function (): \Generator
+ {
+ yield from [];
+ };
+
+ return $generator();
+ }
+
+ if (!$union) {
+ try {
+ return (new Generator)->getMock($this->returnType, [], [], '', false);
+ } catch (Throwable $t) {
+ throw new RuntimeException(
+ sprintf(
+ 'Return value for %s::%s() cannot be generated: %s',
+ $this->className,
+ $this->methodName,
+ $t->getMessage(),
+ ),
+ (int) $t->getCode(),
+ );
+ }
+ }
+
+ throw new RuntimeException(
+ sprintf(
+ 'Return value for %s::%s() cannot be generated because the declared return type is a union, please configure a return value for this method',
+ $this->className,
+ $this->methodName
+ )
+ );
+ }
+
+ public function toString(): string
+ {
+ $exporter = new Exporter;
+
+ return sprintf(
+ '%s::%s(%s)%s',
+ $this->className,
+ $this->methodName,
+ implode(
+ ', ',
+ array_map(
+ [$exporter, 'shortenedExport'],
+ $this->parameters
+ )
+ ),
+ $this->returnType ? sprintf(': %s', $this->returnType) : ''
+ );
+ }
+
+ public function getObject(): object
+ {
+ return $this->object;
+ }
+
+ private function cloneObject(object $original): object
+ {
+ if (Type::isCloneable($original)) {
+ return clone $original;
+ }
+
+ return $original;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/InvocationHandler.php b/vendor/phpunit/phpunit/src/Framework/MockObject/InvocationHandler.php
new file mode 100644
index 000000000..b9d62610a
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/InvocationHandler.php
@@ -0,0 +1,186 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function strtolower;
+use Exception;
+use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
+use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
+use Throwable;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class InvocationHandler
+{
+ /**
+ * @var Matcher[]
+ */
+ private $matchers = [];
+
+ /**
+ * @var Matcher[]
+ */
+ private $matcherMap = [];
+
+ /**
+ * @var ConfigurableMethod[]
+ */
+ private $configurableMethods;
+
+ /**
+ * @var bool
+ */
+ private $returnValueGeneration;
+
+ /**
+ * @var Throwable
+ */
+ private $deferredError;
+
+ public function __construct(array $configurableMethods, bool $returnValueGeneration)
+ {
+ $this->configurableMethods = $configurableMethods;
+ $this->returnValueGeneration = $returnValueGeneration;
+ }
+
+ public function hasMatchers(): bool
+ {
+ foreach ($this->matchers as $matcher) {
+ if ($matcher->hasMatchers()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Looks up the match builder with identification $id and returns it.
+ *
+ * @param string $id The identification of the match builder
+ */
+ public function lookupMatcher(string $id): ?Matcher
+ {
+ if (isset($this->matcherMap[$id])) {
+ return $this->matcherMap[$id];
+ }
+
+ return null;
+ }
+
+ /**
+ * Registers a matcher with the identification $id. The matcher can later be
+ * looked up using lookupMatcher() to figure out if it has been invoked.
+ *
+ * @param string $id The identification of the matcher
+ * @param Matcher $matcher The builder which is being registered
+ *
+ * @throws MatcherAlreadyRegisteredException
+ */
+ public function registerMatcher(string $id, Matcher $matcher): void
+ {
+ if (isset($this->matcherMap[$id])) {
+ throw new MatcherAlreadyRegisteredException($id);
+ }
+
+ $this->matcherMap[$id] = $matcher;
+ }
+
+ public function expects(InvocationOrder $rule): InvocationMocker
+ {
+ $matcher = new Matcher($rule);
+ $this->addMatcher($matcher);
+
+ return new InvocationMocker(
+ $this,
+ $matcher,
+ ...$this->configurableMethods
+ );
+ }
+
+ /**
+ * @throws Exception
+ * @throws RuntimeException
+ */
+ public function invoke(Invocation $invocation)
+ {
+ $exception = null;
+ $hasReturnValue = false;
+ $returnValue = null;
+
+ foreach ($this->matchers as $match) {
+ try {
+ if ($match->matches($invocation)) {
+ $value = $match->invoked($invocation);
+
+ if (!$hasReturnValue) {
+ $returnValue = $value;
+ $hasReturnValue = true;
+ }
+ }
+ } catch (Exception $e) {
+ $exception = $e;
+ }
+ }
+
+ if ($exception !== null) {
+ throw $exception;
+ }
+
+ if ($hasReturnValue) {
+ return $returnValue;
+ }
+
+ if (!$this->returnValueGeneration) {
+ $exception = new ReturnValueNotConfiguredException($invocation);
+
+ if (strtolower($invocation->getMethodName()) === '__tostring') {
+ $this->deferredError = $exception;
+
+ return '';
+ }
+
+ throw $exception;
+ }
+
+ return $invocation->generateReturnValue();
+ }
+
+ public function matches(Invocation $invocation): bool
+ {
+ foreach ($this->matchers as $matcher) {
+ if (!$matcher->matches($invocation)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * @throws Throwable
+ */
+ public function verify(): void
+ {
+ foreach ($this->matchers as $matcher) {
+ $matcher->verify();
+ }
+
+ if ($this->deferredError) {
+ throw $this->deferredError;
+ }
+ }
+
+ private function addMatcher(Matcher $matcher): void
+ {
+ $this->matchers[] = $matcher;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Matcher.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Matcher.php
new file mode 100644
index 000000000..a0f8817bd
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Matcher.php
@@ -0,0 +1,272 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function assert;
+use function implode;
+use function sprintf;
+use PHPUnit\Framework\ExpectationFailedException;
+use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount;
+use PHPUnit\Framework\MockObject\Rule\AnyParameters;
+use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
+use PHPUnit\Framework\MockObject\Rule\InvokedCount;
+use PHPUnit\Framework\MockObject\Rule\MethodName;
+use PHPUnit\Framework\MockObject\Rule\ParametersRule;
+use PHPUnit\Framework\MockObject\Stub\Stub;
+use PHPUnit\Framework\TestFailure;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class Matcher
+{
+ /**
+ * @var InvocationOrder
+ */
+ private $invocationRule;
+
+ /**
+ * @var mixed
+ */
+ private $afterMatchBuilderId;
+
+ /**
+ * @var bool
+ */
+ private $afterMatchBuilderIsInvoked = false;
+
+ /**
+ * @var MethodName
+ */
+ private $methodNameRule;
+
+ /**
+ * @var ParametersRule
+ */
+ private $parametersRule;
+
+ /**
+ * @var Stub
+ */
+ private $stub;
+
+ public function __construct(InvocationOrder $rule)
+ {
+ $this->invocationRule = $rule;
+ }
+
+ public function hasMatchers(): bool
+ {
+ return !$this->invocationRule instanceof AnyInvokedCount;
+ }
+
+ public function hasMethodNameRule(): bool
+ {
+ return $this->methodNameRule !== null;
+ }
+
+ public function getMethodNameRule(): MethodName
+ {
+ return $this->methodNameRule;
+ }
+
+ public function setMethodNameRule(MethodName $rule): void
+ {
+ $this->methodNameRule = $rule;
+ }
+
+ public function hasParametersRule(): bool
+ {
+ return $this->parametersRule !== null;
+ }
+
+ public function setParametersRule(ParametersRule $rule): void
+ {
+ $this->parametersRule = $rule;
+ }
+
+ public function setStub(Stub $stub): void
+ {
+ $this->stub = $stub;
+ }
+
+ public function setAfterMatchBuilderId(string $id): void
+ {
+ $this->afterMatchBuilderId = $id;
+ }
+
+ /**
+ * @throws ExpectationFailedException
+ * @throws MatchBuilderNotFoundException
+ * @throws MethodNameNotConfiguredException
+ * @throws RuntimeException
+ */
+ public function invoked(Invocation $invocation)
+ {
+ if ($this->methodNameRule === null) {
+ throw new MethodNameNotConfiguredException;
+ }
+
+ if ($this->afterMatchBuilderId !== null) {
+ $matcher = $invocation->getObject()
+ ->__phpunit_getInvocationHandler()
+ ->lookupMatcher($this->afterMatchBuilderId);
+
+ if (!$matcher) {
+ throw new MatchBuilderNotFoundException($this->afterMatchBuilderId);
+ }
+
+ assert($matcher instanceof self);
+
+ if ($matcher->invocationRule->hasBeenInvoked()) {
+ $this->afterMatchBuilderIsInvoked = true;
+ }
+ }
+
+ $this->invocationRule->invoked($invocation);
+
+ try {
+ if ($this->parametersRule !== null) {
+ $this->parametersRule->apply($invocation);
+ }
+ } catch (ExpectationFailedException $e) {
+ throw new ExpectationFailedException(
+ sprintf(
+ "Expectation failed for %s when %s\n%s",
+ $this->methodNameRule->toString(),
+ $this->invocationRule->toString(),
+ $e->getMessage()
+ ),
+ $e->getComparisonFailure()
+ );
+ }
+
+ if ($this->stub) {
+ return $this->stub->invoke($invocation);
+ }
+
+ return $invocation->generateReturnValue();
+ }
+
+ /**
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ * @throws MatchBuilderNotFoundException
+ * @throws MethodNameNotConfiguredException
+ * @throws RuntimeException
+ */
+ public function matches(Invocation $invocation): bool
+ {
+ if ($this->afterMatchBuilderId !== null) {
+ $matcher = $invocation->getObject()
+ ->__phpunit_getInvocationHandler()
+ ->lookupMatcher($this->afterMatchBuilderId);
+
+ if (!$matcher) {
+ throw new MatchBuilderNotFoundException($this->afterMatchBuilderId);
+ }
+
+ assert($matcher instanceof self);
+
+ if (!$matcher->invocationRule->hasBeenInvoked()) {
+ return false;
+ }
+ }
+
+ if ($this->methodNameRule === null) {
+ throw new MethodNameNotConfiguredException;
+ }
+
+ if (!$this->invocationRule->matches($invocation)) {
+ return false;
+ }
+
+ try {
+ if (!$this->methodNameRule->matches($invocation)) {
+ return false;
+ }
+ } catch (ExpectationFailedException $e) {
+ throw new ExpectationFailedException(
+ sprintf(
+ "Expectation failed for %s when %s\n%s",
+ $this->methodNameRule->toString(),
+ $this->invocationRule->toString(),
+ $e->getMessage()
+ ),
+ $e->getComparisonFailure()
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ * @throws MethodNameNotConfiguredException
+ */
+ public function verify(): void
+ {
+ if ($this->methodNameRule === null) {
+ throw new MethodNameNotConfiguredException;
+ }
+
+ try {
+ $this->invocationRule->verify();
+
+ if ($this->parametersRule === null) {
+ $this->parametersRule = new AnyParameters;
+ }
+
+ $invocationIsAny = $this->invocationRule instanceof AnyInvokedCount;
+ $invocationIsNever = $this->invocationRule instanceof InvokedCount && $this->invocationRule->isNever();
+
+ if (!$invocationIsAny && !$invocationIsNever) {
+ $this->parametersRule->verify();
+ }
+ } catch (ExpectationFailedException $e) {
+ throw new ExpectationFailedException(
+ sprintf(
+ "Expectation failed for %s when %s.\n%s",
+ $this->methodNameRule->toString(),
+ $this->invocationRule->toString(),
+ TestFailure::exceptionToString($e)
+ )
+ );
+ }
+ }
+
+ public function toString(): string
+ {
+ $list = [];
+
+ if ($this->invocationRule !== null) {
+ $list[] = $this->invocationRule->toString();
+ }
+
+ if ($this->methodNameRule !== null) {
+ $list[] = 'where ' . $this->methodNameRule->toString();
+ }
+
+ if ($this->parametersRule !== null) {
+ $list[] = 'and ' . $this->parametersRule->toString();
+ }
+
+ if ($this->afterMatchBuilderId !== null) {
+ $list[] = 'after ' . $this->afterMatchBuilderId;
+ }
+
+ if ($this->stub !== null) {
+ $list[] = 'will ' . $this->stub->toString();
+ }
+
+ return implode(' ', $list);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MethodNameConstraint.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MethodNameConstraint.php
new file mode 100644
index 000000000..3082ab384
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MethodNameConstraint.php
@@ -0,0 +1,48 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function is_string;
+use function sprintf;
+use function strtolower;
+use PHPUnit\Framework\Constraint\Constraint;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class MethodNameConstraint extends Constraint
+{
+ /**
+ * @var string
+ */
+ private $methodName;
+
+ public function __construct(string $methodName)
+ {
+ $this->methodName = $methodName;
+ }
+
+ public function toString(): string
+ {
+ return sprintf(
+ 'is "%s"',
+ $this->methodName
+ );
+ }
+
+ protected function matches($other): bool
+ {
+ if (!is_string($other)) {
+ return false;
+ }
+
+ return strtolower($this->methodName) === strtolower($other);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php
new file mode 100644
index 000000000..aec32a2d4
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php
@@ -0,0 +1,516 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function array_diff;
+use function array_merge;
+use PHPUnit\Framework\TestCase;
+use ReflectionClass;
+
+/**
+ * @psalm-template MockedType
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+final class MockBuilder
+{
+ /**
+ * @var TestCase
+ */
+ private $testCase;
+
+ /**
+ * @var string
+ */
+ private $type;
+
+ /**
+ * @var null|string[]
+ */
+ private $methods = [];
+
+ /**
+ * @var bool
+ */
+ private $emptyMethodsArray = false;
+
+ /**
+ * @var string
+ */
+ private $mockClassName = '';
+
+ /**
+ * @var array
+ */
+ private $constructorArgs = [];
+
+ /**
+ * @var bool
+ */
+ private $originalConstructor = true;
+
+ /**
+ * @var bool
+ */
+ private $originalClone = true;
+
+ /**
+ * @var bool
+ */
+ private $autoload = true;
+
+ /**
+ * @var bool
+ */
+ private $cloneArguments = false;
+
+ /**
+ * @var bool
+ */
+ private $callOriginalMethods = false;
+
+ /**
+ * @var ?object
+ */
+ private $proxyTarget;
+
+ /**
+ * @var bool
+ */
+ private $allowMockingUnknownTypes = true;
+
+ /**
+ * @var bool
+ */
+ private $returnValueGeneration = true;
+
+ /**
+ * @var Generator
+ */
+ private $generator;
+
+ /**
+ * @param string|string[] $type
+ *
+ * @psalm-param class-string<MockedType>|string|string[] $type
+ */
+ public function __construct(TestCase $testCase, $type)
+ {
+ $this->testCase = $testCase;
+ $this->type = $type;
+ $this->generator = new Generator;
+ }
+
+ /**
+ * Creates a mock object using a fluent interface.
+ *
+ * @throws \PHPUnit\Framework\InvalidArgumentException
+ * @throws ClassAlreadyExistsException
+ * @throws ClassIsFinalException
+ * @throws DuplicateMethodException
+ * @throws InvalidMethodNameException
+ * @throws OriginalConstructorInvocationRequiredException
+ * @throws ReflectionException
+ * @throws RuntimeException
+ * @throws UnknownTypeException
+ *
+ * @psalm-return MockObject&MockedType
+ */
+ public function getMock(): MockObject
+ {
+ $object = $this->generator->getMock(
+ $this->type,
+ !$this->emptyMethodsArray ? $this->methods : null,
+ $this->constructorArgs,
+ $this->mockClassName,
+ $this->originalConstructor,
+ $this->originalClone,
+ $this->autoload,
+ $this->cloneArguments,
+ $this->callOriginalMethods,
+ $this->proxyTarget,
+ $this->allowMockingUnknownTypes,
+ $this->returnValueGeneration
+ );
+
+ $this->testCase->registerMockObject($object);
+
+ return $object;
+ }
+
+ /**
+ * Creates a mock object for an abstract class using a fluent interface.
+ *
+ * @psalm-return MockObject&MockedType
+ *
+ * @throws \PHPUnit\Framework\Exception
+ * @throws ReflectionException
+ * @throws RuntimeException
+ */
+ public function getMockForAbstractClass(): MockObject
+ {
+ $object = $this->generator->getMockForAbstractClass(
+ $this->type,
+ $this->constructorArgs,
+ $this->mockClassName,
+ $this->originalConstructor,
+ $this->originalClone,
+ $this->autoload,
+ $this->methods,
+ $this->cloneArguments
+ );
+
+ $this->testCase->registerMockObject($object);
+
+ return $object;
+ }
+
+ /**
+ * Creates a mock object for a trait using a fluent interface.
+ *
+ * @psalm-return MockObject&MockedType
+ *
+ * @throws \PHPUnit\Framework\Exception
+ * @throws ReflectionException
+ * @throws RuntimeException
+ */
+ public function getMockForTrait(): MockObject
+ {
+ $object = $this->generator->getMockForTrait(
+ $this->type,
+ $this->constructorArgs,
+ $this->mockClassName,
+ $this->originalConstructor,
+ $this->originalClone,
+ $this->autoload,
+ $this->methods,
+ $this->cloneArguments
+ );
+
+ $this->testCase->registerMockObject($object);
+
+ return $object;
+ }
+
+ /**
+ * Specifies the subset of methods to mock. Default is to mock none of them.
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/pull/3687
+ *
+ * @return $this
+ */
+ public function setMethods(?array $methods = null): self
+ {
+ if ($methods === null) {
+ $this->methods = $methods;
+ } else {
+ $this->methods = array_merge($this->methods ?? [], $methods);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Specifies the subset of methods to mock, requiring each to exist in the class.
+ *
+ * @param string[] $methods
+ *
+ * @throws CannotUseOnlyMethodsException
+ * @throws ReflectionException
+ *
+ * @return $this
+ */
+ public function onlyMethods(array $methods): self
+ {
+ if (empty($methods)) {
+ $this->emptyMethodsArray = true;
+
+ return $this;
+ }
+
+ try {
+ $reflector = new ReflectionClass($this->type);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ foreach ($methods as $method) {
+ if (!$reflector->hasMethod($method)) {
+ throw new CannotUseOnlyMethodsException($this->type, $method);
+ }
+ }
+
+ $this->methods = array_merge($this->methods ?? [], $methods);
+
+ return $this;
+ }
+
+ /**
+ * Specifies methods that don't exist in the class which you want to mock.
+ *
+ * @param string[] $methods
+ *
+ * @throws CannotUseAddMethodsException
+ * @throws ReflectionException
+ * @throws RuntimeException
+ *
+ * @return $this
+ */
+ public function addMethods(array $methods): self
+ {
+ if (empty($methods)) {
+ $this->emptyMethodsArray = true;
+
+ return $this;
+ }
+
+ try {
+ $reflector = new ReflectionClass($this->type);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ foreach ($methods as $method) {
+ if ($reflector->hasMethod($method)) {
+ throw new CannotUseAddMethodsException($this->type, $method);
+ }
+ }
+
+ $this->methods = array_merge($this->methods ?? [], $methods);
+
+ return $this;
+ }
+
+ /**
+ * Specifies the subset of methods to not mock. Default is to mock all of them.
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/pull/3687
+ *
+ * @throws ReflectionException
+ */
+ public function setMethodsExcept(array $methods = []): self
+ {
+ return $this->setMethods(
+ array_diff(
+ $this->generator->getClassMethods($this->type),
+ $methods
+ )
+ );
+ }
+
+ /**
+ * Specifies the arguments for the constructor.
+ *
+ * @return $this
+ */
+ public function setConstructorArgs(array $args): self
+ {
+ $this->constructorArgs = $args;
+
+ return $this;
+ }
+
+ /**
+ * Specifies the name for the mock class.
+ *
+ * @return $this
+ */
+ public function setMockClassName(string $name): self
+ {
+ $this->mockClassName = $name;
+
+ return $this;
+ }
+
+ /**
+ * Disables the invocation of the original constructor.
+ *
+ * @return $this
+ */
+ public function disableOriginalConstructor(): self
+ {
+ $this->originalConstructor = false;
+
+ return $this;
+ }
+
+ /**
+ * Enables the invocation of the original constructor.
+ *
+ * @return $this
+ */
+ public function enableOriginalConstructor(): self
+ {
+ $this->originalConstructor = true;
+
+ return $this;
+ }
+
+ /**
+ * Disables the invocation of the original clone constructor.
+ *
+ * @return $this
+ */
+ public function disableOriginalClone(): self
+ {
+ $this->originalClone = false;
+
+ return $this;
+ }
+
+ /**
+ * Enables the invocation of the original clone constructor.
+ *
+ * @return $this
+ */
+ public function enableOriginalClone(): self
+ {
+ $this->originalClone = true;
+
+ return $this;
+ }
+
+ /**
+ * Disables the use of class autoloading while creating the mock object.
+ *
+ * @return $this
+ */
+ public function disableAutoload(): self
+ {
+ $this->autoload = false;
+
+ return $this;
+ }
+
+ /**
+ * Enables the use of class autoloading while creating the mock object.
+ *
+ * @return $this
+ */
+ public function enableAutoload(): self
+ {
+ $this->autoload = true;
+
+ return $this;
+ }
+
+ /**
+ * Disables the cloning of arguments passed to mocked methods.
+ *
+ * @return $this
+ */
+ public function disableArgumentCloning(): self
+ {
+ $this->cloneArguments = false;
+
+ return $this;
+ }
+
+ /**
+ * Enables the cloning of arguments passed to mocked methods.
+ *
+ * @return $this
+ */
+ public function enableArgumentCloning(): self
+ {
+ $this->cloneArguments = true;
+
+ return $this;
+ }
+
+ /**
+ * Enables the invocation of the original methods.
+ *
+ * @return $this
+ */
+ public function enableProxyingToOriginalMethods(): self
+ {
+ $this->callOriginalMethods = true;
+
+ return $this;
+ }
+
+ /**
+ * Disables the invocation of the original methods.
+ *
+ * @return $this
+ */
+ public function disableProxyingToOriginalMethods(): self
+ {
+ $this->callOriginalMethods = false;
+ $this->proxyTarget = null;
+
+ return $this;
+ }
+
+ /**
+ * Sets the proxy target.
+ *
+ * @return $this
+ */
+ public function setProxyTarget(object $object): self
+ {
+ $this->proxyTarget = $object;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function allowMockingUnknownTypes(): self
+ {
+ $this->allowMockingUnknownTypes = true;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function disallowMockingUnknownTypes(): self
+ {
+ $this->allowMockingUnknownTypes = false;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function enableAutoReturnValueGeneration(): self
+ {
+ $this->returnValueGeneration = true;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function disableAutoReturnValueGeneration(): self
+ {
+ $this->returnValueGeneration = false;
+
+ return $this;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MockClass.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MockClass.php
new file mode 100644
index 000000000..253d78460
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MockClass.php
@@ -0,0 +1,69 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function call_user_func;
+use function class_exists;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class MockClass implements MockType
+{
+ /**
+ * @var string
+ */
+ private $classCode;
+
+ /**
+ * @var class-string
+ */
+ private $mockName;
+
+ /**
+ * @var ConfigurableMethod[]
+ */
+ private $configurableMethods;
+
+ /**
+ * @psalm-param class-string $mockName
+ */
+ public function __construct(string $classCode, string $mockName, array $configurableMethods)
+ {
+ $this->classCode = $classCode;
+ $this->mockName = $mockName;
+ $this->configurableMethods = $configurableMethods;
+ }
+
+ /**
+ * @psalm-return class-string
+ */
+ public function generate(): string
+ {
+ if (!class_exists($this->mockName, false)) {
+ eval($this->classCode);
+
+ call_user_func(
+ [
+ $this->mockName,
+ '__phpunit_initConfigurableMethods',
+ ],
+ ...$this->configurableMethods
+ );
+ }
+
+ return $this->mockName;
+ }
+
+ public function getClassCode(): string
+ {
+ return $this->classCode;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MockMethod.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MockMethod.php
new file mode 100644
index 000000000..5e02cae5f
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MockMethod.php
@@ -0,0 +1,398 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use const DIRECTORY_SEPARATOR;
+use function implode;
+use function is_string;
+use function preg_match;
+use function preg_replace;
+use function sprintf;
+use function substr_count;
+use function trim;
+use function var_export;
+use ReflectionMethod;
+use ReflectionNamedType;
+use ReflectionParameter;
+use ReflectionUnionType;
+use SebastianBergmann\Template\Exception as TemplateException;
+use SebastianBergmann\Template\Template;
+use SebastianBergmann\Type\ReflectionMapper;
+use SebastianBergmann\Type\Type;
+use SebastianBergmann\Type\UnknownType;
+use SebastianBergmann\Type\VoidType;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class MockMethod
+{
+ /**
+ * @var Template[]
+ */
+ private static $templates = [];
+
+ /**
+ * @var string
+ */
+ private $className;
+
+ /**
+ * @var string
+ */
+ private $methodName;
+
+ /**
+ * @var bool
+ */
+ private $cloneArguments;
+
+ /**
+ * @var string string
+ */
+ private $modifier;
+
+ /**
+ * @var string
+ */
+ private $argumentsForDeclaration;
+
+ /**
+ * @var string
+ */
+ private $argumentsForCall;
+
+ /**
+ * @var Type
+ */
+ private $returnType;
+
+ /**
+ * @var string
+ */
+ private $reference;
+
+ /**
+ * @var bool
+ */
+ private $callOriginalMethod;
+
+ /**
+ * @var bool
+ */
+ private $static;
+
+ /**
+ * @var ?string
+ */
+ private $deprecation;
+
+ /**
+ * @throws ReflectionException
+ * @throws RuntimeException
+ */
+ public static function fromReflection(ReflectionMethod $method, bool $callOriginalMethod, bool $cloneArguments): self
+ {
+ if ($method->isPrivate()) {
+ $modifier = 'private';
+ } elseif ($method->isProtected()) {
+ $modifier = 'protected';
+ } else {
+ $modifier = 'public';
+ }
+
+ if ($method->isStatic()) {
+ $modifier .= ' static';
+ }
+
+ if ($method->returnsReference()) {
+ $reference = '&';
+ } else {
+ $reference = '';
+ }
+
+ $docComment = $method->getDocComment();
+
+ if (is_string($docComment) &&
+ preg_match('#\*[ \t]*+@deprecated[ \t]*+(.*?)\r?+\n[ \t]*+\*(?:[ \t]*+@|/$)#s', $docComment, $deprecation)) {
+ $deprecation = trim(preg_replace('#[ \t]*\r?\n[ \t]*+\*[ \t]*+#', ' ', $deprecation[1]));
+ } else {
+ $deprecation = null;
+ }
+
+ return new self(
+ $method->getDeclaringClass()->getName(),
+ $method->getName(),
+ $cloneArguments,
+ $modifier,
+ self::getMethodParametersForDeclaration($method),
+ self::getMethodParametersForCall($method),
+ (new ReflectionMapper)->fromMethodReturnType($method),
+ $reference,
+ $callOriginalMethod,
+ $method->isStatic(),
+ $deprecation
+ );
+ }
+
+ public static function fromName(string $fullClassName, string $methodName, bool $cloneArguments): self
+ {
+ return new self(
+ $fullClassName,
+ $methodName,
+ $cloneArguments,
+ 'public',
+ '',
+ '',
+ new UnknownType,
+ '',
+ false,
+ false,
+ null
+ );
+ }
+
+ public function __construct(string $className, string $methodName, bool $cloneArguments, string $modifier, string $argumentsForDeclaration, string $argumentsForCall, Type $returnType, string $reference, bool $callOriginalMethod, bool $static, ?string $deprecation)
+ {
+ $this->className = $className;
+ $this->methodName = $methodName;
+ $this->cloneArguments = $cloneArguments;
+ $this->modifier = $modifier;
+ $this->argumentsForDeclaration = $argumentsForDeclaration;
+ $this->argumentsForCall = $argumentsForCall;
+ $this->returnType = $returnType;
+ $this->reference = $reference;
+ $this->callOriginalMethod = $callOriginalMethod;
+ $this->static = $static;
+ $this->deprecation = $deprecation;
+ }
+
+ public function getName(): string
+ {
+ return $this->methodName;
+ }
+
+ /**
+ * @throws RuntimeException
+ */
+ public function generateCode(): string
+ {
+ if ($this->static) {
+ $templateFile = 'mocked_static_method.tpl';
+ } elseif ($this->returnType instanceof VoidType) {
+ $templateFile = sprintf(
+ '%s_method_void.tpl',
+ $this->callOriginalMethod ? 'proxied' : 'mocked'
+ );
+ } else {
+ $templateFile = sprintf(
+ '%s_method.tpl',
+ $this->callOriginalMethod ? 'proxied' : 'mocked'
+ );
+ }
+
+ $deprecation = $this->deprecation;
+
+ if (null !== $this->deprecation) {
+ $deprecation = "The {$this->className}::{$this->methodName} method is deprecated ({$this->deprecation}).";
+ $deprecationTemplate = $this->getTemplate('deprecation.tpl');
+
+ $deprecationTemplate->setVar(
+ [
+ 'deprecation' => var_export($deprecation, true),
+ ]
+ );
+
+ $deprecation = $deprecationTemplate->render();
+ }
+
+ $template = $this->getTemplate($templateFile);
+
+ $template->setVar(
+ [
+ 'arguments_decl' => $this->argumentsForDeclaration,
+ 'arguments_call' => $this->argumentsForCall,
+ 'return_declaration' => !empty($this->returnType->asString()) ? (': ' . $this->returnType->asString()) : '',
+ 'return_type' => $this->returnType->asString(),
+ 'arguments_count' => !empty($this->argumentsForCall) ? substr_count($this->argumentsForCall, ',') + 1 : 0,
+ 'class_name' => $this->className,
+ 'method_name' => $this->methodName,
+ 'modifier' => $this->modifier,
+ 'reference' => $this->reference,
+ 'clone_arguments' => $this->cloneArguments ? 'true' : 'false',
+ 'deprecation' => $deprecation,
+ ]
+ );
+
+ return $template->render();
+ }
+
+ public function getReturnType(): Type
+ {
+ return $this->returnType;
+ }
+
+ /**
+ * @throws RuntimeException
+ */
+ private function getTemplate(string $template): Template
+ {
+ $filename = __DIR__ . DIRECTORY_SEPARATOR . 'Generator' . DIRECTORY_SEPARATOR . $template;
+
+ if (!isset(self::$templates[$filename])) {
+ try {
+ self::$templates[$filename] = new Template($filename);
+ } catch (TemplateException $e) {
+ throw new RuntimeException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ }
+
+ return self::$templates[$filename];
+ }
+
+ /**
+ * Returns the parameters of a function or method.
+ *
+ * @throws RuntimeException
+ */
+ private static function getMethodParametersForDeclaration(ReflectionMethod $method): string
+ {
+ $parameters = [];
+
+ foreach ($method->getParameters() as $i => $parameter) {
+ $name = '$' . $parameter->getName();
+
+ /* Note: PHP extensions may use empty names for reference arguments
+ * or "..." for methods taking a variable number of arguments.
+ */
+ if ($name === '$' || $name === '$...') {
+ $name = '$arg' . $i;
+ }
+
+ $nullable = '';
+ $default = '';
+ $reference = '';
+ $typeDeclaration = '';
+ $type = null;
+ $typeName = null;
+
+ if ($parameter->hasType()) {
+ $type = $parameter->getType();
+
+ if ($type instanceof ReflectionNamedType) {
+ $typeName = $type->getName();
+ }
+ }
+
+ if ($parameter->isVariadic()) {
+ $name = '...' . $name;
+ } elseif ($parameter->isDefaultValueAvailable()) {
+ $default = ' = ' . self::exportDefaultValue($parameter);
+ } elseif ($parameter->isOptional()) {
+ $default = ' = null';
+ }
+
+ if ($type !== null) {
+ if ($typeName !== 'mixed' && $parameter->allowsNull() && !$type instanceof ReflectionUnionType) {
+ $nullable = '?';
+ }
+
+ if ($typeName === 'self') {
+ $typeDeclaration = $method->getDeclaringClass()->getName() . ' ';
+ } elseif ($typeName !== null) {
+ $typeDeclaration = $typeName . ' ';
+ } elseif ($type instanceof ReflectionUnionType) {
+ $typeDeclaration = self::unionTypeAsString(
+ $type,
+ $method->getDeclaringClass()->getName()
+ );
+ }
+ }
+
+ if ($parameter->isPassedByReference()) {
+ $reference = '&';
+ }
+
+ $parameters[] = $nullable . $typeDeclaration . $reference . $name . $default;
+ }
+
+ return implode(', ', $parameters);
+ }
+
+ /**
+ * Returns the parameters of a function or method.
+ *
+ * @throws ReflectionException
+ */
+ private static function getMethodParametersForCall(ReflectionMethod $method): string
+ {
+ $parameters = [];
+
+ foreach ($method->getParameters() as $i => $parameter) {
+ $name = '$' . $parameter->getName();
+
+ /* Note: PHP extensions may use empty names for reference arguments
+ * or "..." for methods taking a variable number of arguments.
+ */
+ if ($name === '$' || $name === '$...') {
+ $name = '$arg' . $i;
+ }
+
+ if ($parameter->isVariadic()) {
+ continue;
+ }
+
+ if ($parameter->isPassedByReference()) {
+ $parameters[] = '&' . $name;
+ } else {
+ $parameters[] = $name;
+ }
+ }
+
+ return implode(', ', $parameters);
+ }
+
+ /**
+ * @throws ReflectionException
+ */
+ private static function exportDefaultValue(ReflectionParameter $parameter): string
+ {
+ try {
+ return (string) var_export($parameter->getDefaultValue(), true);
+ // @codeCoverageIgnoreStart
+ } catch (\ReflectionException $e) {
+ throw new ReflectionException(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ private static function unionTypeAsString(ReflectionUnionType $union, string $self): string
+ {
+ $types = [];
+
+ foreach ($union->getTypes() as $type) {
+ if ((string) $type === 'self') {
+ $types[] = $self;
+ } else {
+ $types[] = $type;
+ }
+ }
+
+ return implode('|', $types) . ' ';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MockMethodSet.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MockMethodSet.php
new file mode 100644
index 000000000..1c78963c0
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MockMethodSet.php
@@ -0,0 +1,45 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function array_key_exists;
+use function array_values;
+use function strtolower;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class MockMethodSet
+{
+ /**
+ * @var MockMethod[]
+ */
+ private $methods = [];
+
+ public function addMethods(MockMethod ...$methods): void
+ {
+ foreach ($methods as $method) {
+ $this->methods[strtolower($method->getName())] = $method;
+ }
+ }
+
+ /**
+ * @return MockMethod[]
+ */
+ public function asArray(): array
+ {
+ return array_values($this->methods);
+ }
+
+ public function hasMethod(string $methodName): bool
+ {
+ return array_key_exists(strtolower($methodName), $this->methods);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MockObject.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MockObject.php
new file mode 100644
index 000000000..094decf43
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MockObject.php
@@ -0,0 +1,27 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use PHPUnit\Framework\MockObject\Builder\InvocationMocker as BuilderInvocationMocker;
+use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
+
+/**
+ * @method BuilderInvocationMocker method($constraint)
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+interface MockObject extends Stub
+{
+ public function __phpunit_setOriginalObject($originalObject): void;
+
+ public function __phpunit_verify(bool $unsetInvocationMocker = true): void;
+
+ public function expects(InvocationOrder $invocationRule): BuilderInvocationMocker;
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MockTrait.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MockTrait.php
new file mode 100644
index 000000000..7c326988f
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MockTrait.php
@@ -0,0 +1,54 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use function class_exists;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class MockTrait implements MockType
+{
+ /**
+ * @var string
+ */
+ private $classCode;
+
+ /**
+ * @var class-string
+ */
+ private $mockName;
+
+ /**
+ * @psalm-param class-string $mockName
+ */
+ public function __construct(string $classCode, string $mockName)
+ {
+ $this->classCode = $classCode;
+ $this->mockName = $mockName;
+ }
+
+ /**
+ * @psalm-return class-string
+ */
+ public function generate(): string
+ {
+ if (!class_exists($this->mockName, false)) {
+ eval($this->classCode);
+ }
+
+ return $this->mockName;
+ }
+
+ public function getClassCode(): string
+ {
+ return $this->classCode;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MockType.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MockType.php
new file mode 100644
index 000000000..6a03fb51a
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MockType.php
@@ -0,0 +1,21 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+interface MockType
+{
+ /**
+ * @psalm-return class-string
+ */
+ public function generate(): string;
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/AnyInvokedCount.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/AnyInvokedCount.php
new file mode 100644
index 000000000..f93e5686b
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/AnyInvokedCount.php
@@ -0,0 +1,36 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Rule;
+
+use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class AnyInvokedCount extends InvocationOrder
+{
+ public function toString(): string
+ {
+ return 'invoked zero or more times';
+ }
+
+ public function verify(): void
+ {
+ }
+
+ public function matches(BaseInvocation $invocation): bool
+ {
+ return true;
+ }
+
+ protected function invokedDo(BaseInvocation $invocation): void
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/AnyParameters.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/AnyParameters.php
new file mode 100644
index 000000000..61de78878
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/AnyParameters.php
@@ -0,0 +1,31 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Rule;
+
+use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class AnyParameters implements ParametersRule
+{
+ public function toString(): string
+ {
+ return 'with any parameters';
+ }
+
+ public function apply(BaseInvocation $invocation): void
+ {
+ }
+
+ public function verify(): void
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/ConsecutiveParameters.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/ConsecutiveParameters.php
new file mode 100644
index 000000000..6025c0a16
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/ConsecutiveParameters.php
@@ -0,0 +1,130 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Rule;
+
+use function count;
+use function gettype;
+use function is_iterable;
+use function sprintf;
+use PHPUnit\Framework\Constraint\Constraint;
+use PHPUnit\Framework\Constraint\IsEqual;
+use PHPUnit\Framework\ExpectationFailedException;
+use PHPUnit\Framework\InvalidParameterGroupException;
+use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ConsecutiveParameters implements ParametersRule
+{
+ /**
+ * @var array
+ */
+ private $parameterGroups = [];
+
+ /**
+ * @var array
+ */
+ private $invocations = [];
+
+ /**
+ * @throws \PHPUnit\Framework\Exception
+ */
+ public function __construct(array $parameterGroups)
+ {
+ foreach ($parameterGroups as $index => $parameters) {
+ if (!is_iterable($parameters)) {
+ throw new InvalidParameterGroupException(
+ sprintf(
+ 'Parameter group #%d must be an array or Traversable, got %s',
+ $index,
+ gettype($parameters)
+ )
+ );
+ }
+
+ foreach ($parameters as $parameter) {
+ if (!$parameter instanceof Constraint) {
+ $parameter = new IsEqual($parameter);
+ }
+
+ $this->parameterGroups[$index][] = $parameter;
+ }
+ }
+ }
+
+ public function toString(): string
+ {
+ return 'with consecutive parameters';
+ }
+
+ /**
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public function apply(BaseInvocation $invocation): void
+ {
+ $this->invocations[] = $invocation;
+ $callIndex = count($this->invocations) - 1;
+
+ $this->verifyInvocation($invocation, $callIndex);
+ }
+
+ /**
+ * @throws \PHPUnit\Framework\ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ public function verify(): void
+ {
+ foreach ($this->invocations as $callIndex => $invocation) {
+ $this->verifyInvocation($invocation, $callIndex);
+ }
+ }
+
+ /**
+ * Verify a single invocation.
+ *
+ * @param int $callIndex
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ private function verifyInvocation(BaseInvocation $invocation, $callIndex): void
+ {
+ if (!isset($this->parameterGroups[$callIndex])) {
+ // no parameter assertion for this call index
+ return;
+ }
+
+ $parameters = $this->parameterGroups[$callIndex];
+
+ if (count($invocation->getParameters()) < count($parameters)) {
+ throw new ExpectationFailedException(
+ sprintf(
+ 'Parameter count for invocation %s is too low.',
+ $invocation->toString()
+ )
+ );
+ }
+
+ foreach ($parameters as $i => $parameter) {
+ $parameter->evaluate(
+ $invocation->getParameters()[$i],
+ sprintf(
+ 'Parameter %s for invocation #%d %s does not match expected ' .
+ 'value.',
+ $i,
+ $callIndex,
+ $invocation->toString()
+ )
+ );
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvocationOrder.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvocationOrder.php
new file mode 100644
index 000000000..90aa49350
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvocationOrder.php
@@ -0,0 +1,47 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Rule;
+
+use function count;
+use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
+use PHPUnit\Framework\MockObject\Verifiable;
+use PHPUnit\Framework\SelfDescribing;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+abstract class InvocationOrder implements SelfDescribing, Verifiable
+{
+ /**
+ * @var BaseInvocation[]
+ */
+ private $invocations = [];
+
+ public function getInvocationCount(): int
+ {
+ return count($this->invocations);
+ }
+
+ public function hasBeenInvoked(): bool
+ {
+ return count($this->invocations) > 0;
+ }
+
+ final public function invoked(BaseInvocation $invocation)
+ {
+ $this->invocations[] = $invocation;
+
+ return $this->invokedDo($invocation);
+ }
+
+ abstract public function matches(BaseInvocation $invocation): bool;
+
+ abstract protected function invokedDo(BaseInvocation $invocation);
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtIndex.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtIndex.php
new file mode 100644
index 000000000..2a6625e2f
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtIndex.php
@@ -0,0 +1,75 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Rule;
+
+use function sprintf;
+use PHPUnit\Framework\ExpectationFailedException;
+use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4297
+ * @codeCoverageIgnore
+ */
+final class InvokedAtIndex extends InvocationOrder
+{
+ /**
+ * @var int
+ */
+ private $sequenceIndex;
+
+ /**
+ * @var int
+ */
+ private $currentIndex = -1;
+
+ /**
+ * @param int $sequenceIndex
+ */
+ public function __construct($sequenceIndex)
+ {
+ $this->sequenceIndex = $sequenceIndex;
+ }
+
+ public function toString(): string
+ {
+ return 'invoked at sequence index ' . $this->sequenceIndex;
+ }
+
+ public function matches(BaseInvocation $invocation): bool
+ {
+ $this->currentIndex++;
+
+ return $this->currentIndex == $this->sequenceIndex;
+ }
+
+ /**
+ * Verifies that the current expectation is valid. If everything is OK the
+ * code should just return, if not it must throw an exception.
+ *
+ * @throws ExpectationFailedException
+ */
+ public function verify(): void
+ {
+ if ($this->currentIndex < $this->sequenceIndex) {
+ throw new ExpectationFailedException(
+ sprintf(
+ 'The expected invocation at index %s was never reached.',
+ $this->sequenceIndex
+ )
+ );
+ }
+ }
+
+ protected function invokedDo(BaseInvocation $invocation): void
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastCount.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastCount.php
new file mode 100644
index 000000000..a84aa6559
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastCount.php
@@ -0,0 +1,64 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Rule;
+
+use PHPUnit\Framework\ExpectationFailedException;
+use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class InvokedAtLeastCount extends InvocationOrder
+{
+ /**
+ * @var int
+ */
+ private $requiredInvocations;
+
+ /**
+ * @param int $requiredInvocations
+ */
+ public function __construct($requiredInvocations)
+ {
+ $this->requiredInvocations = $requiredInvocations;
+ }
+
+ public function toString(): string
+ {
+ return 'invoked at least ' . $this->requiredInvocations . ' times';
+ }
+
+ /**
+ * Verifies that the current expectation is valid. If everything is OK the
+ * code should just return, if not it must throw an exception.
+ *
+ * @throws ExpectationFailedException
+ */
+ public function verify(): void
+ {
+ $count = $this->getInvocationCount();
+
+ if ($count < $this->requiredInvocations) {
+ throw new ExpectationFailedException(
+ 'Expected invocation at least ' . $this->requiredInvocations .
+ ' times but it occurred ' . $count . ' time(s).'
+ );
+ }
+ }
+
+ public function matches(BaseInvocation $invocation): bool
+ {
+ return true;
+ }
+
+ protected function invokedDo(BaseInvocation $invocation): void
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastOnce.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastOnce.php
new file mode 100644
index 000000000..d0ad1f801
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastOnce.php
@@ -0,0 +1,50 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Rule;
+
+use PHPUnit\Framework\ExpectationFailedException;
+use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class InvokedAtLeastOnce extends InvocationOrder
+{
+ public function toString(): string
+ {
+ return 'invoked at least once';
+ }
+
+ /**
+ * Verifies that the current expectation is valid. If everything is OK the
+ * code should just return, if not it must throw an exception.
+ *
+ * @throws ExpectationFailedException
+ */
+ public function verify(): void
+ {
+ $count = $this->getInvocationCount();
+
+ if ($count < 1) {
+ throw new ExpectationFailedException(
+ 'Expected invocation at least once but it never occurred.'
+ );
+ }
+ }
+
+ public function matches(BaseInvocation $invocation): bool
+ {
+ return true;
+ }
+
+ protected function invokedDo(BaseInvocation $invocation): void
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtMostCount.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtMostCount.php
new file mode 100644
index 000000000..c3b815aa4
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtMostCount.php
@@ -0,0 +1,64 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Rule;
+
+use PHPUnit\Framework\ExpectationFailedException;
+use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class InvokedAtMostCount extends InvocationOrder
+{
+ /**
+ * @var int
+ */
+ private $allowedInvocations;
+
+ /**
+ * @param int $allowedInvocations
+ */
+ public function __construct($allowedInvocations)
+ {
+ $this->allowedInvocations = $allowedInvocations;
+ }
+
+ public function toString(): string
+ {
+ return 'invoked at most ' . $this->allowedInvocations . ' times';
+ }
+
+ /**
+ * Verifies that the current expectation is valid. If everything is OK the
+ * code should just return, if not it must throw an exception.
+ *
+ * @throws ExpectationFailedException
+ */
+ public function verify(): void
+ {
+ $count = $this->getInvocationCount();
+
+ if ($count > $this->allowedInvocations) {
+ throw new ExpectationFailedException(
+ 'Expected invocation at most ' . $this->allowedInvocations .
+ ' times but it occurred ' . $count . ' time(s).'
+ );
+ }
+ }
+
+ public function matches(BaseInvocation $invocation): bool
+ {
+ return true;
+ }
+
+ protected function invokedDo(BaseInvocation $invocation): void
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedCount.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedCount.php
new file mode 100644
index 000000000..188326c91
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedCount.php
@@ -0,0 +1,102 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Rule;
+
+use function sprintf;
+use PHPUnit\Framework\ExpectationFailedException;
+use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class InvokedCount extends InvocationOrder
+{
+ /**
+ * @var int
+ */
+ private $expectedCount;
+
+ /**
+ * @param int $expectedCount
+ */
+ public function __construct($expectedCount)
+ {
+ $this->expectedCount = $expectedCount;
+ }
+
+ public function isNever(): bool
+ {
+ return $this->expectedCount === 0;
+ }
+
+ public function toString(): string
+ {
+ return 'invoked ' . $this->expectedCount . ' time(s)';
+ }
+
+ public function matches(BaseInvocation $invocation): bool
+ {
+ return true;
+ }
+
+ /**
+ * Verifies that the current expectation is valid. If everything is OK the
+ * code should just return, if not it must throw an exception.
+ *
+ * @throws ExpectationFailedException
+ */
+ public function verify(): void
+ {
+ $count = $this->getInvocationCount();
+
+ if ($count !== $this->expectedCount) {
+ throw new ExpectationFailedException(
+ sprintf(
+ 'Method was expected to be called %d times, ' .
+ 'actually called %d times.',
+ $this->expectedCount,
+ $count
+ )
+ );
+ }
+ }
+
+ /**
+ * @throws ExpectationFailedException
+ */
+ protected function invokedDo(BaseInvocation $invocation): void
+ {
+ $count = $this->getInvocationCount();
+
+ if ($count > $this->expectedCount) {
+ $message = $invocation->toString() . ' ';
+
+ switch ($this->expectedCount) {
+ case 0:
+ $message .= 'was not expected to be called.';
+
+ break;
+
+ case 1:
+ $message .= 'was not expected to be called more than once.';
+
+ break;
+
+ default:
+ $message .= sprintf(
+ 'was not expected to be called more than %d times.',
+ $this->expectedCount
+ );
+ }
+
+ throw new ExpectationFailedException($message);
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/MethodName.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/MethodName.php
new file mode 100644
index 000000000..83ba3b8da
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/MethodName.php
@@ -0,0 +1,68 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Rule;
+
+use function is_string;
+use PHPUnit\Framework\Constraint\Constraint;
+use PHPUnit\Framework\InvalidArgumentException;
+use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
+use PHPUnit\Framework\MockObject\MethodNameConstraint;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class MethodName
+{
+ /**
+ * @var Constraint
+ */
+ private $constraint;
+
+ /**
+ * @param Constraint|string $constraint
+ *
+ * @throws InvalidArgumentException
+ */
+ public function __construct($constraint)
+ {
+ if (is_string($constraint)) {
+ $constraint = new MethodNameConstraint($constraint);
+ }
+
+ if (!$constraint instanceof Constraint) {
+ throw InvalidArgumentException::create(1, 'PHPUnit\Framework\Constraint\Constraint object or string');
+ }
+
+ $this->constraint = $constraint;
+ }
+
+ public function toString(): string
+ {
+ return 'method name ' . $this->constraint->toString();
+ }
+
+ /**
+ * @throws \PHPUnit\Framework\ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ public function matches(BaseInvocation $invocation): bool
+ {
+ return $this->matchesName($invocation->getMethodName());
+ }
+
+ /**
+ * @throws \PHPUnit\Framework\ExpectationFailedException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ public function matchesName(string $methodName): bool
+ {
+ return (bool) $this->constraint->evaluate($methodName, '', true);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/Parameters.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/Parameters.php
new file mode 100644
index 000000000..3f1cc53ae
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/Parameters.php
@@ -0,0 +1,160 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Rule;
+
+use function count;
+use function get_class;
+use function sprintf;
+use Exception;
+use PHPUnit\Framework\Constraint\Constraint;
+use PHPUnit\Framework\Constraint\IsAnything;
+use PHPUnit\Framework\Constraint\IsEqual;
+use PHPUnit\Framework\ExpectationFailedException;
+use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class Parameters implements ParametersRule
+{
+ /**
+ * @var Constraint[]
+ */
+ private $parameters = [];
+
+ /**
+ * @var BaseInvocation
+ */
+ private $invocation;
+
+ /**
+ * @var bool|ExpectationFailedException
+ */
+ private $parameterVerificationResult;
+
+ /**
+ * @throws \PHPUnit\Framework\Exception
+ */
+ public function __construct(array $parameters)
+ {
+ foreach ($parameters as $parameter) {
+ if (!($parameter instanceof Constraint)) {
+ $parameter = new IsEqual(
+ $parameter
+ );
+ }
+
+ $this->parameters[] = $parameter;
+ }
+ }
+
+ public function toString(): string
+ {
+ $text = 'with parameter';
+
+ foreach ($this->parameters as $index => $parameter) {
+ if ($index > 0) {
+ $text .= ' and';
+ }
+
+ $text .= ' ' . $index . ' ' . $parameter->toString();
+ }
+
+ return $text;
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function apply(BaseInvocation $invocation): void
+ {
+ $this->invocation = $invocation;
+ $this->parameterVerificationResult = null;
+
+ try {
+ $this->parameterVerificationResult = $this->doVerify();
+ } catch (ExpectationFailedException $e) {
+ $this->parameterVerificationResult = $e;
+
+ throw $this->parameterVerificationResult;
+ }
+ }
+
+ /**
+ * Checks if the invocation $invocation matches the current rules. If it
+ * does the rule will get the invoked() method called which should check
+ * if an expectation is met.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ public function verify(): void
+ {
+ $this->doVerify();
+ }
+
+ /**
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws ExpectationFailedException
+ */
+ private function doVerify(): bool
+ {
+ if (isset($this->parameterVerificationResult)) {
+ return $this->guardAgainstDuplicateEvaluationOfParameterConstraints();
+ }
+
+ if ($this->invocation === null) {
+ throw new ExpectationFailedException('Mocked method does not exist.');
+ }
+
+ if (count($this->invocation->getParameters()) < count($this->parameters)) {
+ $message = 'Parameter count for invocation %s is too low.';
+
+ // The user called `->with($this->anything())`, but may have meant
+ // `->withAnyParameters()`.
+ //
+ // @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/199
+ if (count($this->parameters) === 1 &&
+ get_class($this->parameters[0]) === IsAnything::class) {
+ $message .= "\nTo allow 0 or more parameters with any value, omit ->with() or use ->withAnyParameters() instead.";
+ }
+
+ throw new ExpectationFailedException(
+ sprintf($message, $this->invocation->toString())
+ );
+ }
+
+ foreach ($this->parameters as $i => $parameter) {
+ $parameter->evaluate(
+ $this->invocation->getParameters()[$i],
+ sprintf(
+ 'Parameter %s for invocation %s does not match expected ' .
+ 'value.',
+ $i,
+ $this->invocation->toString()
+ )
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * @throws ExpectationFailedException
+ */
+ private function guardAgainstDuplicateEvaluationOfParameterConstraints(): bool
+ {
+ if ($this->parameterVerificationResult instanceof ExpectationFailedException) {
+ throw $this->parameterVerificationResult;
+ }
+
+ return (bool) $this->parameterVerificationResult;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/ParametersRule.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/ParametersRule.php
new file mode 100644
index 000000000..70c47fe32
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/ParametersRule.php
@@ -0,0 +1,28 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Rule;
+
+use PHPUnit\Framework\ExpectationFailedException;
+use PHPUnit\Framework\MockObject\Invocation as BaseInvocation;
+use PHPUnit\Framework\MockObject\Verifiable;
+use PHPUnit\Framework\SelfDescribing;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+interface ParametersRule extends SelfDescribing, Verifiable
+{
+ /**
+ * @throws ExpectationFailedException if the invocation violates the rule
+ */
+ public function apply(BaseInvocation $invocation): void;
+
+ public function verify(): void;
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub.php
new file mode 100644
index 000000000..2b032e2dc
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub.php
@@ -0,0 +1,26 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use PHPUnit\Framework\MockObject\Builder\InvocationStubber;
+
+/**
+ * @method InvocationStubber method($constraint)
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+interface Stub
+{
+ public function __phpunit_getInvocationHandler(): InvocationHandler;
+
+ public function __phpunit_hasMatchers(): bool;
+
+ public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration): void;
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ConsecutiveCalls.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ConsecutiveCalls.php
new file mode 100644
index 000000000..0dcf386b3
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ConsecutiveCalls.php
@@ -0,0 +1,57 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Stub;
+
+use function array_shift;
+use function sprintf;
+use PHPUnit\Framework\MockObject\Invocation;
+use SebastianBergmann\Exporter\Exporter;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ConsecutiveCalls implements Stub
+{
+ /**
+ * @var array
+ */
+ private $stack;
+
+ /**
+ * @var mixed
+ */
+ private $value;
+
+ public function __construct(array $stack)
+ {
+ $this->stack = $stack;
+ }
+
+ public function invoke(Invocation $invocation)
+ {
+ $this->value = array_shift($this->stack);
+
+ if ($this->value instanceof Stub) {
+ $this->value = $this->value->invoke($invocation);
+ }
+
+ return $this->value;
+ }
+
+ public function toString(): string
+ {
+ $exporter = new Exporter;
+
+ return sprintf(
+ 'return user-specified value %s',
+ $exporter->export($this->value)
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/Exception.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/Exception.php
new file mode 100644
index 000000000..5d64c96a5
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/Exception.php
@@ -0,0 +1,46 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Stub;
+
+use function sprintf;
+use PHPUnit\Framework\MockObject\Invocation;
+use SebastianBergmann\Exporter\Exporter;
+use Throwable;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class Exception implements Stub
+{
+ private $exception;
+
+ public function __construct(Throwable $exception)
+ {
+ $this->exception = $exception;
+ }
+
+ /**
+ * @throws Throwable
+ */
+ public function invoke(Invocation $invocation): void
+ {
+ throw $this->exception;
+ }
+
+ public function toString(): string
+ {
+ $exporter = new Exporter;
+
+ return sprintf(
+ 'raise user-specified exception %s',
+ $exporter->export($this->exception)
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnArgument.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnArgument.php
new file mode 100644
index 000000000..c7b3f8f41
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnArgument.php
@@ -0,0 +1,41 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Stub;
+
+use function sprintf;
+use PHPUnit\Framework\MockObject\Invocation;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ReturnArgument implements Stub
+{
+ /**
+ * @var int
+ */
+ private $argumentIndex;
+
+ public function __construct($argumentIndex)
+ {
+ $this->argumentIndex = $argumentIndex;
+ }
+
+ public function invoke(Invocation $invocation)
+ {
+ if (isset($invocation->getParameters()[$this->argumentIndex])) {
+ return $invocation->getParameters()[$this->argumentIndex];
+ }
+ }
+
+ public function toString(): string
+ {
+ return sprintf('return argument #%d', $this->argumentIndex);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnCallback.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnCallback.php
new file mode 100644
index 000000000..e02181e90
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnCallback.php
@@ -0,0 +1,59 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Stub;
+
+use function call_user_func_array;
+use function get_class;
+use function is_array;
+use function is_object;
+use function sprintf;
+use PHPUnit\Framework\MockObject\Invocation;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ReturnCallback implements Stub
+{
+ private $callback;
+
+ public function __construct($callback)
+ {
+ $this->callback = $callback;
+ }
+
+ public function invoke(Invocation $invocation)
+ {
+ return call_user_func_array($this->callback, $invocation->getParameters());
+ }
+
+ public function toString(): string
+ {
+ if (is_array($this->callback)) {
+ if (is_object($this->callback[0])) {
+ $class = get_class($this->callback[0]);
+ $type = '->';
+ } else {
+ $class = $this->callback[0];
+ $type = '::';
+ }
+
+ return sprintf(
+ 'return result of user defined callback %s%s%s() with the ' .
+ 'passed arguments',
+ $class,
+ $type,
+ $this->callback[1]
+ );
+ }
+
+ return 'return result of user defined callback ' . $this->callback .
+ ' with the passed arguments';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnReference.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnReference.php
new file mode 100644
index 000000000..0d288cebe
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnReference.php
@@ -0,0 +1,45 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Stub;
+
+use function sprintf;
+use PHPUnit\Framework\MockObject\Invocation;
+use SebastianBergmann\Exporter\Exporter;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ReturnReference implements Stub
+{
+ /**
+ * @var mixed
+ */
+ private $reference;
+
+ public function __construct(&$reference)
+ {
+ $this->reference = &$reference;
+ }
+
+ public function invoke(Invocation $invocation)
+ {
+ return $this->reference;
+ }
+
+ public function toString(): string
+ {
+ $exporter = new Exporter;
+
+ return sprintf(
+ 'return user-specified reference %s',
+ $exporter->export($this->reference)
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnSelf.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnSelf.php
new file mode 100644
index 000000000..6d2137bfb
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnSelf.php
@@ -0,0 +1,32 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Stub;
+
+use PHPUnit\Framework\MockObject\Invocation;
+use PHPUnit\Framework\MockObject\RuntimeException;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ReturnSelf implements Stub
+{
+ /**
+ * @throws RuntimeException
+ */
+ public function invoke(Invocation $invocation)
+ {
+ return $invocation->getObject();
+ }
+
+ public function toString(): string
+ {
+ return 'return the current object';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnStub.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnStub.php
new file mode 100644
index 000000000..fbcd0a07a
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnStub.php
@@ -0,0 +1,45 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Stub;
+
+use function sprintf;
+use PHPUnit\Framework\MockObject\Invocation;
+use SebastianBergmann\Exporter\Exporter;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ReturnStub implements Stub
+{
+ /**
+ * @var mixed
+ */
+ private $value;
+
+ public function __construct($value)
+ {
+ $this->value = $value;
+ }
+
+ public function invoke(Invocation $invocation)
+ {
+ return $this->value;
+ }
+
+ public function toString(): string
+ {
+ $exporter = new Exporter;
+
+ return sprintf(
+ 'return user-specified value %s',
+ $exporter->export($this->value)
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnValueMap.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnValueMap.php
new file mode 100644
index 000000000..5fcd3a09a
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnValueMap.php
@@ -0,0 +1,53 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Stub;
+
+use function array_pop;
+use function count;
+use function is_array;
+use PHPUnit\Framework\MockObject\Invocation;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class ReturnValueMap implements Stub
+{
+ /**
+ * @var array
+ */
+ private $valueMap;
+
+ public function __construct(array $valueMap)
+ {
+ $this->valueMap = $valueMap;
+ }
+
+ public function invoke(Invocation $invocation)
+ {
+ $parameterCount = count($invocation->getParameters());
+
+ foreach ($this->valueMap as $map) {
+ if (!is_array($map) || $parameterCount !== (count($map) - 1)) {
+ continue;
+ }
+
+ $return = array_pop($map);
+
+ if ($invocation->getParameters() === $map) {
+ return $return;
+ }
+ }
+ }
+
+ public function toString(): string
+ {
+ return 'return value from a map';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/Stub.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/Stub.php
new file mode 100644
index 000000000..15cfce5c3
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/Stub.php
@@ -0,0 +1,27 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject\Stub;
+
+use PHPUnit\Framework\MockObject\Invocation;
+use PHPUnit\Framework\SelfDescribing;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+interface Stub extends SelfDescribing
+{
+ /**
+ * Fakes the processing of the invocation $invocation by returning a
+ * specific value.
+ *
+ * @param Invocation $invocation The invocation which was mocked and matched by the current method and argument matchers
+ */
+ public function invoke(Invocation $invocation);
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Verifiable.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Verifiable.php
new file mode 100644
index 000000000..8c9a82c5a
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Verifiable.php
@@ -0,0 +1,26 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework\MockObject;
+
+use PHPUnit\Framework\ExpectationFailedException;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+interface Verifiable
+{
+ /**
+ * Verifies that the current expectation is valid. If everything is OK the
+ * code should just return, if not it must throw an exception.
+ *
+ * @throws ExpectationFailedException
+ */
+ public function verify(): void;
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Reorderable.php b/vendor/phpunit/phpunit/src/Framework/Reorderable.php
new file mode 100644
index 000000000..34951f8dc
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Reorderable.php
@@ -0,0 +1,28 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+interface Reorderable
+{
+ public function sortId(): string;
+
+ /**
+ * @return list<ExecutionOrderDependency>
+ */
+ public function provides(): array;
+
+ /**
+ * @return list<ExecutionOrderDependency>
+ */
+ public function requires(): array;
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/SelfDescribing.php b/vendor/phpunit/phpunit/src/Framework/SelfDescribing.php
new file mode 100644
index 000000000..73034f650
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/SelfDescribing.php
@@ -0,0 +1,21 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+interface SelfDescribing
+{
+ /**
+ * Returns a string representation of the object.
+ */
+ public function toString(): string;
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/SkippedTest.php b/vendor/phpunit/phpunit/src/Framework/SkippedTest.php
new file mode 100644
index 000000000..a12aa402d
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/SkippedTest.php
@@ -0,0 +1,19 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use Throwable;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+interface SkippedTest extends Throwable
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/SkippedTestCase.php b/vendor/phpunit/phpunit/src/Framework/SkippedTestCase.php
new file mode 100644
index 000000000..51c00619c
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/SkippedTestCase.php
@@ -0,0 +1,66 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class SkippedTestCase extends TestCase
+{
+ /**
+ * @var bool
+ */
+ protected $backupGlobals = false;
+
+ /**
+ * @var bool
+ */
+ protected $backupStaticAttributes = false;
+
+ /**
+ * @var bool
+ */
+ protected $runTestInSeparateProcess = false;
+
+ /**
+ * @var string
+ */
+ private $message;
+
+ public function __construct(string $className, string $methodName, string $message = '')
+ {
+ parent::__construct($className . '::' . $methodName);
+
+ $this->message = $message;
+ }
+
+ public function getMessage(): string
+ {
+ return $this->message;
+ }
+
+ /**
+ * Returns a string representation of the test case.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ public function toString(): string
+ {
+ return $this->getName();
+ }
+
+ /**
+ * @throws Exception
+ */
+ protected function runTest(): void
+ {
+ $this->markTestSkipped($this->message);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Test.php b/vendor/phpunit/phpunit/src/Framework/Test.php
new file mode 100644
index 000000000..be0dcd0ef
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Test.php
@@ -0,0 +1,23 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use Countable;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+interface Test extends Countable
+{
+ /**
+ * Runs a test and collects its result in a TestResult instance.
+ */
+ public function run(TestResult $result = null): TestResult;
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestBuilder.php b/vendor/phpunit/phpunit/src/Framework/TestBuilder.php
new file mode 100644
index 000000000..5dd91e219
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/TestBuilder.php
@@ -0,0 +1,239 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use function assert;
+use function count;
+use function get_class;
+use function sprintf;
+use function trim;
+use PHPUnit\Util\Filter;
+use PHPUnit\Util\InvalidDataSetException;
+use PHPUnit\Util\Test as TestUtil;
+use ReflectionClass;
+use Throwable;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class TestBuilder
+{
+ public function build(ReflectionClass $theClass, string $methodName): Test
+ {
+ $className = $theClass->getName();
+
+ if (!$theClass->isInstantiable()) {
+ return new ErrorTestCase(
+ sprintf('Cannot instantiate class "%s".', $className)
+ );
+ }
+
+ $backupSettings = TestUtil::getBackupSettings(
+ $className,
+ $methodName
+ );
+
+ $preserveGlobalState = TestUtil::getPreserveGlobalStateSettings(
+ $className,
+ $methodName
+ );
+
+ $runTestInSeparateProcess = TestUtil::getProcessIsolationSettings(
+ $className,
+ $methodName
+ );
+
+ $runClassInSeparateProcess = TestUtil::getClassProcessIsolationSettings(
+ $className,
+ $methodName
+ );
+
+ $constructor = $theClass->getConstructor();
+
+ if ($constructor === null) {
+ throw new Exception('No valid test provided.');
+ }
+
+ $parameters = $constructor->getParameters();
+
+ // TestCase() or TestCase($name)
+ if (count($parameters) < 2) {
+ $test = $this->buildTestWithoutData($className);
+ } // TestCase($name, $data)
+ else {
+ try {
+ $data = TestUtil::getProvidedData(
+ $className,
+ $methodName
+ );
+ } catch (IncompleteTestError $e) {
+ $message = sprintf(
+ "Test for %s::%s marked incomplete by data provider\n%s",
+ $className,
+ $methodName,
+ $this->throwableToString($e)
+ );
+
+ $data = new IncompleteTestCase($className, $methodName, $message);
+ } catch (SkippedTestError $e) {
+ $message = sprintf(
+ "Test for %s::%s skipped by data provider\n%s",
+ $className,
+ $methodName,
+ $this->throwableToString($e)
+ );
+
+ $data = new SkippedTestCase($className, $methodName, $message);
+ } catch (Throwable $t) {
+ $message = sprintf(
+ "The data provider specified for %s::%s is invalid.\n%s",
+ $className,
+ $methodName,
+ $this->throwableToString($t)
+ );
+
+ $data = new ErrorTestCase($message);
+ }
+
+ // Test method with @dataProvider.
+ if (isset($data)) {
+ $test = $this->buildDataProviderTestSuite(
+ $methodName,
+ $className,
+ $data,
+ $runTestInSeparateProcess,
+ $preserveGlobalState,
+ $runClassInSeparateProcess,
+ $backupSettings
+ );
+ } else {
+ $test = $this->buildTestWithoutData($className);
+ }
+ }
+
+ if ($test instanceof TestCase) {
+ $test->setName($methodName);
+ $this->configureTestCase(
+ $test,
+ $runTestInSeparateProcess,
+ $preserveGlobalState,
+ $runClassInSeparateProcess,
+ $backupSettings
+ );
+ }
+
+ return $test;
+ }
+
+ /** @psalm-param class-string $className */
+ private function buildTestWithoutData(string $className)
+ {
+ return new $className;
+ }
+
+ /** @psalm-param class-string $className */
+ private function buildDataProviderTestSuite(
+ string $methodName,
+ string $className,
+ $data,
+ bool $runTestInSeparateProcess,
+ ?bool $preserveGlobalState,
+ bool $runClassInSeparateProcess,
+ array $backupSettings
+ ): DataProviderTestSuite {
+ $dataProviderTestSuite = new DataProviderTestSuite(
+ $className . '::' . $methodName
+ );
+
+ $groups = TestUtil::getGroups($className, $methodName);
+
+ if ($data instanceof ErrorTestCase ||
+ $data instanceof SkippedTestCase ||
+ $data instanceof IncompleteTestCase) {
+ $dataProviderTestSuite->addTest($data, $groups);
+ } else {
+ foreach ($data as $_dataName => $_data) {
+ $_test = new $className($methodName, $_data, $_dataName);
+
+ assert($_test instanceof TestCase);
+
+ $this->configureTestCase(
+ $_test,
+ $runTestInSeparateProcess,
+ $preserveGlobalState,
+ $runClassInSeparateProcess,
+ $backupSettings
+ );
+
+ $dataProviderTestSuite->addTest($_test, $groups);
+ }
+ }
+
+ return $dataProviderTestSuite;
+ }
+
+ private function configureTestCase(
+ TestCase $test,
+ bool $runTestInSeparateProcess,
+ ?bool $preserveGlobalState,
+ bool $runClassInSeparateProcess,
+ array $backupSettings
+ ): void {
+ if ($runTestInSeparateProcess) {
+ $test->setRunTestInSeparateProcess(true);
+
+ if ($preserveGlobalState !== null) {
+ $test->setPreserveGlobalState($preserveGlobalState);
+ }
+ }
+
+ if ($runClassInSeparateProcess) {
+ $test->setRunClassInSeparateProcess(true);
+
+ if ($preserveGlobalState !== null) {
+ $test->setPreserveGlobalState($preserveGlobalState);
+ }
+ }
+
+ if ($backupSettings['backupGlobals'] !== null) {
+ $test->setBackupGlobals($backupSettings['backupGlobals']);
+ }
+
+ if ($backupSettings['backupStaticAttributes'] !== null) {
+ $test->setBackupStaticAttributes(
+ $backupSettings['backupStaticAttributes']
+ );
+ }
+ }
+
+ private function throwableToString(Throwable $t): string
+ {
+ $message = $t->getMessage();
+
+ if (empty(trim($message))) {
+ $message = '<no message>';
+ }
+
+ if ($t instanceof InvalidDataSetException) {
+ return sprintf(
+ "%s\n%s",
+ $message,
+ Filter::getFilteredStacktrace($t)
+ );
+ }
+
+ return sprintf(
+ "%s: %s\n%s",
+ get_class($t),
+ $message,
+ Filter::getFilteredStacktrace($t)
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestCase.php b/vendor/phpunit/phpunit/src/Framework/TestCase.php
new file mode 100644
index 000000000..f90245bd1
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/TestCase.php
@@ -0,0 +1,2581 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use const LC_ALL;
+use const LC_COLLATE;
+use const LC_CTYPE;
+use const LC_MONETARY;
+use const LC_NUMERIC;
+use const LC_TIME;
+use const PATHINFO_FILENAME;
+use const PHP_EOL;
+use const PHP_URL_PATH;
+use function array_filter;
+use function array_flip;
+use function array_keys;
+use function array_merge;
+use function array_pop;
+use function array_search;
+use function array_unique;
+use function array_values;
+use function basename;
+use function call_user_func;
+use function chdir;
+use function class_exists;
+use function clearstatcache;
+use function count;
+use function debug_backtrace;
+use function defined;
+use function explode;
+use function get_class;
+use function get_include_path;
+use function getcwd;
+use function implode;
+use function in_array;
+use function ini_set;
+use function is_array;
+use function is_callable;
+use function is_int;
+use function is_object;
+use function is_string;
+use function libxml_clear_errors;
+use function method_exists;
+use function ob_end_clean;
+use function ob_get_contents;
+use function ob_get_level;
+use function ob_start;
+use function parse_url;
+use function pathinfo;
+use function preg_replace;
+use function serialize;
+use function setlocale;
+use function sprintf;
+use function strpos;
+use function substr;
+use function trim;
+use function var_export;
+use DeepCopy\DeepCopy;
+use PHPUnit\Framework\Constraint\Exception as ExceptionConstraint;
+use PHPUnit\Framework\Constraint\ExceptionCode;
+use PHPUnit\Framework\Constraint\ExceptionMessage;
+use PHPUnit\Framework\Constraint\ExceptionMessageRegularExpression;
+use PHPUnit\Framework\Constraint\LogicalOr;
+use PHPUnit\Framework\Error\Deprecated;
+use PHPUnit\Framework\Error\Error;
+use PHPUnit\Framework\Error\Notice;
+use PHPUnit\Framework\Error\Warning as WarningError;
+use PHPUnit\Framework\MockObject\Generator as MockGenerator;
+use PHPUnit\Framework\MockObject\MockBuilder;
+use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount as AnyInvokedCountMatcher;
+use PHPUnit\Framework\MockObject\Rule\InvokedAtIndex as InvokedAtIndexMatcher;
+use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastCount as InvokedAtLeastCountMatcher;
+use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastOnce as InvokedAtLeastOnceMatcher;
+use PHPUnit\Framework\MockObject\Rule\InvokedAtMostCount as InvokedAtMostCountMatcher;
+use PHPUnit\Framework\MockObject\Rule\InvokedCount as InvokedCountMatcher;
+use PHPUnit\Framework\MockObject\Stub;
+use PHPUnit\Framework\MockObject\Stub\ConsecutiveCalls as ConsecutiveCallsStub;
+use PHPUnit\Framework\MockObject\Stub\Exception as ExceptionStub;
+use PHPUnit\Framework\MockObject\Stub\ReturnArgument as ReturnArgumentStub;
+use PHPUnit\Framework\MockObject\Stub\ReturnCallback as ReturnCallbackStub;
+use PHPUnit\Framework\MockObject\Stub\ReturnSelf as ReturnSelfStub;
+use PHPUnit\Framework\MockObject\Stub\ReturnStub;
+use PHPUnit\Framework\MockObject\Stub\ReturnValueMap as ReturnValueMapStub;
+use PHPUnit\Runner\BaseTestRunner;
+use PHPUnit\Runner\PhptTestCase;
+use PHPUnit\Util\Exception as UtilException;
+use PHPUnit\Util\GlobalState;
+use PHPUnit\Util\PHP\AbstractPhpProcess;
+use PHPUnit\Util\Test as TestUtil;
+use PHPUnit\Util\Type;
+use Prophecy\Exception\Prediction\PredictionException;
+use Prophecy\Prophecy\MethodProphecy;
+use Prophecy\Prophecy\ObjectProphecy;
+use Prophecy\Prophet;
+use ReflectionClass;
+use ReflectionException;
+use SebastianBergmann\Comparator\Comparator;
+use SebastianBergmann\Comparator\Factory as ComparatorFactory;
+use SebastianBergmann\Diff\Differ;
+use SebastianBergmann\Exporter\Exporter;
+use SebastianBergmann\GlobalState\ExcludeList;
+use SebastianBergmann\GlobalState\Restorer;
+use SebastianBergmann\GlobalState\Snapshot;
+use SebastianBergmann\ObjectEnumerator\Enumerator;
+use SebastianBergmann\Template\Template;
+use SoapClient;
+use Throwable;
+
+/**
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+abstract class TestCase extends Assert implements Reorderable, SelfDescribing, Test
+{
+ private const LOCALE_CATEGORIES = [LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME];
+
+ /**
+ * @var ?bool
+ */
+ protected $backupGlobals;
+
+ /**
+ * @var string[]
+ */
+ protected $backupGlobalsExcludeList = [];
+
+ /**
+ * @var string[]
+ *
+ * @deprecated Use $backupGlobalsExcludeList instead
+ */
+ protected $backupGlobalsBlacklist = [];
+
+ /**
+ * @var bool
+ */
+ protected $backupStaticAttributes;
+
+ /**
+ * @var array<string,array<int,string>>
+ */
+ protected $backupStaticAttributesExcludeList = [];
+
+ /**
+ * @var array<string,array<int,string>>
+ *
+ * @deprecated Use $backupStaticAttributesExcludeList instead
+ */
+ protected $backupStaticAttributesBlacklist = [];
+
+ /**
+ * @var bool
+ */
+ protected $runTestInSeparateProcess;
+
+ /**
+ * @var bool
+ */
+ protected $preserveGlobalState = true;
+
+ /**
+ * @var list<ExecutionOrderDependency>
+ */
+ protected $providedTests = [];
+
+ /**
+ * @var bool
+ */
+ private $runClassInSeparateProcess;
+
+ /**
+ * @var bool
+ */
+ private $inIsolation = false;
+
+ /**
+ * @var array
+ */
+ private $data;
+
+ /**
+ * @var int|string
+ */
+ private $dataName;
+
+ /**
+ * @var null|string
+ */
+ private $expectedException;
+
+ /**
+ * @var null|string
+ */
+ private $expectedExceptionMessage;
+
+ /**
+ * @var null|string
+ */
+ private $expectedExceptionMessageRegExp;
+
+ /**
+ * @var null|int|string
+ */
+ private $expectedExceptionCode;
+
+ /**
+ * @var string
+ */
+ private $name = '';
+
+ /**
+ * @var list<ExecutionOrderDependency>
+ */
+ private $dependencies = [];
+
+ /**
+ * @var array
+ */
+ private $dependencyInput = [];
+
+ /**
+ * @var array<string,string>
+ */
+ private $iniSettings = [];
+
+ /**
+ * @var array
+ */
+ private $locale = [];
+
+ /**
+ * @var MockObject[]
+ */
+ private $mockObjects = [];
+
+ /**
+ * @var MockGenerator
+ */
+ private $mockObjectGenerator;
+
+ /**
+ * @var int
+ */
+ private $status = BaseTestRunner::STATUS_UNKNOWN;
+
+ /**
+ * @var string
+ */
+ private $statusMessage = '';
+
+ /**
+ * @var int
+ */
+ private $numAssertions = 0;
+
+ /**
+ * @var TestResult
+ */
+ private $result;
+
+ /**
+ * @var mixed
+ */
+ private $testResult;
+
+ /**
+ * @var string
+ */
+ private $output = '';
+
+ /**
+ * @var ?string
+ */
+ private $outputExpectedRegex;
+
+ /**
+ * @var ?string
+ */
+ private $outputExpectedString;
+
+ /**
+ * @var mixed
+ */
+ private $outputCallback = false;
+
+ /**
+ * @var bool
+ */
+ private $outputBufferingActive = false;
+
+ /**
+ * @var int
+ */
+ private $outputBufferingLevel;
+
+ /**
+ * @var bool
+ */
+ private $outputRetrievedForAssertion = false;
+
+ /**
+ * @var ?Snapshot
+ */
+ private $snapshot;
+
+ /**
+ * @var \Prophecy\Prophet
+ */
+ private $prophet;
+
+ /**
+ * @var bool
+ */
+ private $beStrictAboutChangesToGlobalState = false;
+
+ /**
+ * @var bool
+ */
+ private $registerMockObjectsFromTestArgumentsRecursively = false;
+
+ /**
+ * @var string[]
+ */
+ private $warnings = [];
+
+ /**
+ * @var string[]
+ */
+ private $groups = [];
+
+ /**
+ * @var bool
+ */
+ private $doesNotPerformAssertions = false;
+
+ /**
+ * @var Comparator[]
+ */
+ private $customComparators = [];
+
+ /**
+ * @var string[]
+ */
+ private $doubledTypes = [];
+
+ /**
+ * Returns a matcher that matches when the method is executed
+ * zero or more times.
+ */
+ public static function any(): AnyInvokedCountMatcher
+ {
+ return new AnyInvokedCountMatcher;
+ }
+
+ /**
+ * Returns a matcher that matches when the method is never executed.
+ */
+ public static function never(): InvokedCountMatcher
+ {
+ return new InvokedCountMatcher(0);
+ }
+
+ /**
+ * Returns a matcher that matches when the method is executed
+ * at least N times.
+ */
+ public static function atLeast(int $requiredInvocations): InvokedAtLeastCountMatcher
+ {
+ return new InvokedAtLeastCountMatcher(
+ $requiredInvocations
+ );
+ }
+
+ /**
+ * Returns a matcher that matches when the method is executed at least once.
+ */
+ public static function atLeastOnce(): InvokedAtLeastOnceMatcher
+ {
+ return new InvokedAtLeastOnceMatcher;
+ }
+
+ /**
+ * Returns a matcher that matches when the method is executed exactly once.
+ */
+ public static function once(): InvokedCountMatcher
+ {
+ return new InvokedCountMatcher(1);
+ }
+
+ /**
+ * Returns a matcher that matches when the method is executed
+ * exactly $count times.
+ */
+ public static function exactly(int $count): InvokedCountMatcher
+ {
+ return new InvokedCountMatcher($count);
+ }
+
+ /**
+ * Returns a matcher that matches when the method is executed
+ * at most N times.
+ */
+ public static function atMost(int $allowedInvocations): InvokedAtMostCountMatcher
+ {
+ return new InvokedAtMostCountMatcher($allowedInvocations);
+ }
+
+ /**
+ * Returns a matcher that matches when the method is executed
+ * at the given index.
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4297
+ * @codeCoverageIgnore
+ */
+ public static function at(int $index): InvokedAtIndexMatcher
+ {
+ $stack = debug_backtrace();
+
+ while (!empty($stack)) {
+ $frame = array_pop($stack);
+
+ if (isset($frame['object']) && $frame['object'] instanceof self) {
+ $frame['object']->addWarning(
+ 'The at() matcher has been deprecated. It will be removed in PHPUnit 10. Please refactor your test to not rely on the order in which methods are invoked.'
+ );
+
+ break;
+ }
+ }
+
+ return new InvokedAtIndexMatcher($index);
+ }
+
+ public static function returnValue($value): ReturnStub
+ {
+ return new ReturnStub($value);
+ }
+
+ public static function returnValueMap(array $valueMap): ReturnValueMapStub
+ {
+ return new ReturnValueMapStub($valueMap);
+ }
+
+ public static function returnArgument(int $argumentIndex): ReturnArgumentStub
+ {
+ return new ReturnArgumentStub($argumentIndex);
+ }
+
+ public static function returnCallback($callback): ReturnCallbackStub
+ {
+ return new ReturnCallbackStub($callback);
+ }
+
+ /**
+ * Returns the current object.
+ *
+ * This method is useful when mocking a fluent interface.
+ */
+ public static function returnSelf(): ReturnSelfStub
+ {
+ return new ReturnSelfStub;
+ }
+
+ public static function throwException(Throwable $exception): ExceptionStub
+ {
+ return new ExceptionStub($exception);
+ }
+
+ public static function onConsecutiveCalls(...$args): ConsecutiveCallsStub
+ {
+ return new ConsecutiveCallsStub($args);
+ }
+
+ /**
+ * @param int|string $dataName
+ *
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function __construct(?string $name = null, array $data = [], $dataName = '')
+ {
+ if ($name !== null) {
+ $this->setName($name);
+ }
+
+ $this->data = $data;
+ $this->dataName = $dataName;
+ }
+
+ /**
+ * This method is called before the first test of this test class is run.
+ */
+ public static function setUpBeforeClass(): void
+ {
+ }
+
+ /**
+ * This method is called after the last test of this test class is run.
+ */
+ public static function tearDownAfterClass(): void
+ {
+ }
+
+ /**
+ * This method is called before each test.
+ */
+ protected function setUp(): void
+ {
+ }
+
+ /**
+ * Performs assertions shared by all tests of a test case.
+ *
+ * This method is called between setUp() and test.
+ */
+ protected function assertPreConditions(): void
+ {
+ }
+
+ /**
+ * Performs assertions shared by all tests of a test case.
+ *
+ * This method is called between test and tearDown().
+ */
+ protected function assertPostConditions(): void
+ {
+ }
+
+ /**
+ * This method is called after each test.
+ */
+ protected function tearDown(): void
+ {
+ }
+
+ /**
+ * Returns a string representation of the test case.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Exception
+ */
+ public function toString(): string
+ {
+ try {
+ $class = new ReflectionClass($this);
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ $buffer = sprintf(
+ '%s::%s',
+ $class->name,
+ $this->getName(false)
+ );
+
+ return $buffer . $this->getDataSetAsString();
+ }
+
+ public function count(): int
+ {
+ return 1;
+ }
+
+ public function getActualOutputForAssertion(): string
+ {
+ $this->outputRetrievedForAssertion = true;
+
+ return $this->getActualOutput();
+ }
+
+ public function expectOutputRegex(string $expectedRegex): void
+ {
+ $this->outputExpectedRegex = $expectedRegex;
+ }
+
+ public function expectOutputString(string $expectedString): void
+ {
+ $this->outputExpectedString = $expectedString;
+ }
+
+ /**
+ * @psalm-param class-string<\Throwable> $exception
+ */
+ public function expectException(string $exception): void
+ {
+ // @codeCoverageIgnoreStart
+ switch ($exception) {
+ case Deprecated::class:
+ $this->addWarning('Support for using expectException() with PHPUnit\Framework\Error\Deprecated is deprecated and will be removed in PHPUnit 10. Use expectDeprecation() instead.');
+
+ break;
+
+ case Error::class:
+ $this->addWarning('Support for using expectException() with PHPUnit\Framework\Error\Error is deprecated and will be removed in PHPUnit 10. Use expectError() instead.');
+
+ break;
+
+ case Notice::class:
+ $this->addWarning('Support for using expectException() with PHPUnit\Framework\Error\Notice is deprecated and will be removed in PHPUnit 10. Use expectNotice() instead.');
+
+ break;
+
+ case WarningError::class:
+ $this->addWarning('Support for using expectException() with PHPUnit\Framework\Error\Warning is deprecated and will be removed in PHPUnit 10. Use expectWarning() instead.');
+
+ break;
+ }
+ // @codeCoverageIgnoreEnd
+
+ $this->expectedException = $exception;
+ }
+
+ /**
+ * @param int|string $code
+ */
+ public function expectExceptionCode($code): void
+ {
+ $this->expectedExceptionCode = $code;
+ }
+
+ public function expectExceptionMessage(string $message): void
+ {
+ $this->expectedExceptionMessage = $message;
+ }
+
+ public function expectExceptionMessageMatches(string $regularExpression): void
+ {
+ $this->expectedExceptionMessageRegExp = $regularExpression;
+ }
+
+ /**
+ * Sets up an expectation for an exception to be raised by the code under test.
+ * Information for expected exception class, expected exception message, and
+ * expected exception code are retrieved from a given Exception object.
+ */
+ public function expectExceptionObject(\Exception $exception): void
+ {
+ $this->expectException(get_class($exception));
+ $this->expectExceptionMessage($exception->getMessage());
+ $this->expectExceptionCode($exception->getCode());
+ }
+
+ public function expectNotToPerformAssertions(): void
+ {
+ $this->doesNotPerformAssertions = true;
+ }
+
+ public function expectDeprecation(): void
+ {
+ $this->expectedException = Deprecated::class;
+ }
+
+ public function expectDeprecationMessage(string $message): void
+ {
+ $this->expectExceptionMessage($message);
+ }
+
+ public function expectDeprecationMessageMatches(string $regularExpression): void
+ {
+ $this->expectExceptionMessageMatches($regularExpression);
+ }
+
+ public function expectNotice(): void
+ {
+ $this->expectedException = Notice::class;
+ }
+
+ public function expectNoticeMessage(string $message): void
+ {
+ $this->expectExceptionMessage($message);
+ }
+
+ public function expectNoticeMessageMatches(string $regularExpression): void
+ {
+ $this->expectExceptionMessageMatches($regularExpression);
+ }
+
+ public function expectWarning(): void
+ {
+ $this->expectedException = WarningError::class;
+ }
+
+ public function expectWarningMessage(string $message): void
+ {
+ $this->expectExceptionMessage($message);
+ }
+
+ public function expectWarningMessageMatches(string $regularExpression): void
+ {
+ $this->expectExceptionMessageMatches($regularExpression);
+ }
+
+ public function expectError(): void
+ {
+ $this->expectedException = Error::class;
+ }
+
+ public function expectErrorMessage(string $message): void
+ {
+ $this->expectExceptionMessage($message);
+ }
+
+ public function expectErrorMessageMatches(string $regularExpression): void
+ {
+ $this->expectExceptionMessageMatches($regularExpression);
+ }
+
+ public function getStatus(): int
+ {
+ return $this->status;
+ }
+
+ public function markAsRisky(): void
+ {
+ $this->status = BaseTestRunner::STATUS_RISKY;
+ }
+
+ public function getStatusMessage(): string
+ {
+ return $this->statusMessage;
+ }
+
+ public function hasFailed(): bool
+ {
+ $status = $this->getStatus();
+
+ return $status === BaseTestRunner::STATUS_FAILURE || $status === BaseTestRunner::STATUS_ERROR;
+ }
+
+ /**
+ * Runs the test case and collects the results in a TestResult object.
+ * If no TestResult object is passed a new one will be created.
+ *
+ * @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException
+ * @throws \SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws CodeCoverageException
+ * @throws UtilException
+ */
+ public function run(TestResult $result = null): TestResult
+ {
+ if ($result === null) {
+ $result = $this->createResult();
+ }
+
+ if (!$this instanceof ErrorTestCase && !$this instanceof WarningTestCase) {
+ $this->setTestResultObject($result);
+ }
+
+ if (!$this instanceof ErrorTestCase &&
+ !$this instanceof WarningTestCase &&
+ !$this instanceof SkippedTestCase &&
+ !$this->handleDependencies()) {
+ return $result;
+ }
+
+ if ($this->runInSeparateProcess()) {
+ $runEntireClass = $this->runClassInSeparateProcess && !$this->runTestInSeparateProcess;
+
+ try {
+ $class = new ReflectionClass($this);
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ if ($runEntireClass) {
+ $template = new Template(
+ __DIR__ . '/../Util/PHP/Template/TestCaseClass.tpl'
+ );
+ } else {
+ $template = new Template(
+ __DIR__ . '/../Util/PHP/Template/TestCaseMethod.tpl'
+ );
+ }
+
+ if ($this->preserveGlobalState) {
+ $constants = GlobalState::getConstantsAsString();
+ $globals = GlobalState::getGlobalsAsString();
+ $includedFiles = GlobalState::getIncludedFilesAsString();
+ $iniSettings = GlobalState::getIniSettingsAsString();
+ } else {
+ $constants = '';
+
+ if (!empty($GLOBALS['__PHPUNIT_BOOTSTRAP'])) {
+ $globals = '$GLOBALS[\'__PHPUNIT_BOOTSTRAP\'] = ' . var_export($GLOBALS['__PHPUNIT_BOOTSTRAP'], true) . ";\n";
+ } else {
+ $globals = '';
+ }
+
+ $includedFiles = '';
+ $iniSettings = '';
+ }
+
+ $coverage = $result->getCollectCodeCoverageInformation() ? 'true' : 'false';
+ $isStrictAboutTestsThatDoNotTestAnything = $result->isStrictAboutTestsThatDoNotTestAnything() ? 'true' : 'false';
+ $isStrictAboutOutputDuringTests = $result->isStrictAboutOutputDuringTests() ? 'true' : 'false';
+ $enforcesTimeLimit = $result->enforcesTimeLimit() ? 'true' : 'false';
+ $isStrictAboutTodoAnnotatedTests = $result->isStrictAboutTodoAnnotatedTests() ? 'true' : 'false';
+ $isStrictAboutResourceUsageDuringSmallTests = $result->isStrictAboutResourceUsageDuringSmallTests() ? 'true' : 'false';
+
+ if (defined('PHPUNIT_COMPOSER_INSTALL')) {
+ $composerAutoload = var_export(PHPUNIT_COMPOSER_INSTALL, true);
+ } else {
+ $composerAutoload = '\'\'';
+ }
+
+ if (defined('__PHPUNIT_PHAR__')) {
+ $phar = var_export(__PHPUNIT_PHAR__, true);
+ } else {
+ $phar = '\'\'';
+ }
+
+ $codeCoverage = $result->getCodeCoverage();
+ $codeCoverageFilter = null;
+ $cachesStaticAnalysis = 'false';
+ $codeCoverageCacheDirectory = null;
+ $driverMethod = 'forLineCoverage';
+
+ if ($codeCoverage) {
+ $codeCoverageFilter = $codeCoverage->filter();
+
+ if ($codeCoverage->collectsBranchAndPathCoverage()) {
+ $driverMethod = 'forLineAndPathCoverage';
+ }
+
+ if ($codeCoverage->cachesStaticAnalysis()) {
+ $cachesStaticAnalysis = 'true';
+ $codeCoverageCacheDirectory = $codeCoverage->cacheDirectory();
+ }
+ }
+
+ $data = var_export(serialize($this->data), true);
+ $dataName = var_export($this->dataName, true);
+ $dependencyInput = var_export(serialize($this->dependencyInput), true);
+ $includePath = var_export(get_include_path(), true);
+ $codeCoverageFilter = var_export(serialize($codeCoverageFilter), true);
+ $codeCoverageCacheDirectory = var_export(serialize($codeCoverageCacheDirectory), true);
+ // must do these fixes because TestCaseMethod.tpl has unserialize('{data}') in it, and we can't break BC
+ // the lines above used to use addcslashes() rather than var_export(), which breaks null byte escape sequences
+ $data = "'." . $data . ".'";
+ $dataName = "'.(" . $dataName . ").'";
+ $dependencyInput = "'." . $dependencyInput . ".'";
+ $includePath = "'." . $includePath . ".'";
+ $codeCoverageFilter = "'." . $codeCoverageFilter . ".'";
+ $codeCoverageCacheDirectory = "'." . $codeCoverageCacheDirectory . ".'";
+
+ $configurationFilePath = $GLOBALS['__PHPUNIT_CONFIGURATION_FILE'] ?? '';
+
+ $var = [
+ 'composerAutoload' => $composerAutoload,
+ 'phar' => $phar,
+ 'filename' => $class->getFileName(),
+ 'className' => $class->getName(),
+ 'collectCodeCoverageInformation' => $coverage,
+ 'cachesStaticAnalysis' => $cachesStaticAnalysis,
+ 'codeCoverageCacheDirectory' => $codeCoverageCacheDirectory,
+ 'driverMethod' => $driverMethod,
+ 'data' => $data,
+ 'dataName' => $dataName,
+ 'dependencyInput' => $dependencyInput,
+ 'constants' => $constants,
+ 'globals' => $globals,
+ 'include_path' => $includePath,
+ 'included_files' => $includedFiles,
+ 'iniSettings' => $iniSettings,
+ 'isStrictAboutTestsThatDoNotTestAnything' => $isStrictAboutTestsThatDoNotTestAnything,
+ 'isStrictAboutOutputDuringTests' => $isStrictAboutOutputDuringTests,
+ 'enforcesTimeLimit' => $enforcesTimeLimit,
+ 'isStrictAboutTodoAnnotatedTests' => $isStrictAboutTodoAnnotatedTests,
+ 'isStrictAboutResourceUsageDuringSmallTests' => $isStrictAboutResourceUsageDuringSmallTests,
+ 'codeCoverageFilter' => $codeCoverageFilter,
+ 'configurationFilePath' => $configurationFilePath,
+ 'name' => $this->getName(false),
+ ];
+
+ if (!$runEntireClass) {
+ $var['methodName'] = $this->name;
+ }
+
+ $template->setVar($var);
+
+ $php = AbstractPhpProcess::factory();
+ $php->runTestJob($template->render(), $this, $result);
+ } else {
+ $result->run($this);
+ }
+
+ $this->result = null;
+
+ return $result;
+ }
+
+ /**
+ * Returns a builder object to create mock objects using a fluent interface.
+ *
+ * @psalm-template RealInstanceType of object
+ * @psalm-param class-string<RealInstanceType> $className
+ * @psalm-return MockBuilder<RealInstanceType>
+ */
+ public function getMockBuilder(string $className): MockBuilder
+ {
+ $this->recordDoubledType($className);
+
+ return new MockBuilder($this, $className);
+ }
+
+ public function registerComparator(Comparator $comparator): void
+ {
+ ComparatorFactory::getInstance()->register($comparator);
+
+ $this->customComparators[] = $comparator;
+ }
+
+ /**
+ * @return string[]
+ *
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function doubledTypes(): array
+ {
+ return array_unique($this->doubledTypes);
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function getGroups(): array
+ {
+ return $this->groups;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function setGroups(array $groups): void
+ {
+ $this->groups = $groups;
+ }
+
+ /**
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function getName(bool $withDataSet = true): string
+ {
+ if ($withDataSet) {
+ return $this->name . $this->getDataSetAsString(false);
+ }
+
+ return $this->name;
+ }
+
+ /**
+ * Returns the size of the test.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function getSize(): int
+ {
+ return TestUtil::getSize(
+ static::class,
+ $this->getName(false)
+ );
+ }
+
+ /**
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function hasSize(): bool
+ {
+ return $this->getSize() !== TestUtil::UNKNOWN;
+ }
+
+ /**
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function isSmall(): bool
+ {
+ return $this->getSize() === TestUtil::SMALL;
+ }
+
+ /**
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function isMedium(): bool
+ {
+ return $this->getSize() === TestUtil::MEDIUM;
+ }
+
+ /**
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ *
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function isLarge(): bool
+ {
+ return $this->getSize() === TestUtil::LARGE;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function getActualOutput(): string
+ {
+ if (!$this->outputBufferingActive) {
+ return $this->output;
+ }
+
+ return (string) ob_get_contents();
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function hasOutput(): bool
+ {
+ if ($this->output === '') {
+ return false;
+ }
+
+ if ($this->hasExpectationOnOutput()) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function doesNotPerformAssertions(): bool
+ {
+ return $this->doesNotPerformAssertions;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function hasExpectationOnOutput(): bool
+ {
+ return is_string($this->outputExpectedString) || is_string($this->outputExpectedRegex) || $this->outputRetrievedForAssertion;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function getExpectedException(): ?string
+ {
+ return $this->expectedException;
+ }
+
+ /**
+ * @return null|int|string
+ *
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function getExpectedExceptionCode()
+ {
+ return $this->expectedExceptionCode;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function getExpectedExceptionMessage(): ?string
+ {
+ return $this->expectedExceptionMessage;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function getExpectedExceptionMessageRegExp(): ?string
+ {
+ return $this->expectedExceptionMessageRegExp;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function setRegisterMockObjectsFromTestArgumentsRecursively(bool $flag): void
+ {
+ $this->registerMockObjectsFromTestArgumentsRecursively = $flag;
+ }
+
+ /**
+ * @throws Throwable
+ *
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function runBare(): void
+ {
+ $this->numAssertions = 0;
+
+ $this->snapshotGlobalState();
+ $this->startOutputBuffering();
+ clearstatcache();
+ $currentWorkingDirectory = getcwd();
+
+ $hookMethods = TestUtil::getHookMethods(static::class);
+
+ $hasMetRequirements = false;
+
+ try {
+ $this->checkRequirements();
+ $hasMetRequirements = true;
+
+ if ($this->inIsolation) {
+ foreach ($hookMethods['beforeClass'] as $method) {
+ $this->{$method}();
+ }
+ }
+
+ $this->setDoesNotPerformAssertionsFromAnnotation();
+
+ foreach ($hookMethods['before'] as $method) {
+ $this->{$method}();
+ }
+
+ foreach ($hookMethods['preCondition'] as $method) {
+ $this->{$method}();
+ }
+
+ $this->testResult = $this->runTest();
+ $this->verifyMockObjects();
+
+ foreach ($hookMethods['postCondition'] as $method) {
+ $this->{$method}();
+ }
+
+ if (!empty($this->warnings)) {
+ throw new Warning(
+ implode(
+ "\n",
+ array_unique($this->warnings)
+ )
+ );
+ }
+
+ $this->status = BaseTestRunner::STATUS_PASSED;
+ } catch (IncompleteTest $e) {
+ $this->status = BaseTestRunner::STATUS_INCOMPLETE;
+ $this->statusMessage = $e->getMessage();
+ } catch (SkippedTest $e) {
+ $this->status = BaseTestRunner::STATUS_SKIPPED;
+ $this->statusMessage = $e->getMessage();
+ } catch (Warning $e) {
+ $this->status = BaseTestRunner::STATUS_WARNING;
+ $this->statusMessage = $e->getMessage();
+ } catch (AssertionFailedError $e) {
+ $this->status = BaseTestRunner::STATUS_FAILURE;
+ $this->statusMessage = $e->getMessage();
+ } catch (PredictionException $e) {
+ $this->status = BaseTestRunner::STATUS_FAILURE;
+ $this->statusMessage = $e->getMessage();
+ } catch (Throwable $_e) {
+ $e = $_e;
+ $this->status = BaseTestRunner::STATUS_ERROR;
+ $this->statusMessage = $_e->getMessage();
+ }
+
+ $this->mockObjects = [];
+ $this->prophet = null;
+
+ // Tear down the fixture. An exception raised in tearDown() will be
+ // caught and passed on when no exception was raised before.
+ try {
+ if ($hasMetRequirements) {
+ foreach ($hookMethods['after'] as $method) {
+ $this->{$method}();
+ }
+
+ if ($this->inIsolation) {
+ foreach ($hookMethods['afterClass'] as $method) {
+ $this->{$method}();
+ }
+ }
+ }
+ } catch (Throwable $_e) {
+ $e = $e ?? $_e;
+ }
+
+ try {
+ $this->stopOutputBuffering();
+ } catch (RiskyTestError $_e) {
+ $e = $e ?? $_e;
+ }
+
+ if (isset($_e)) {
+ $this->status = BaseTestRunner::STATUS_ERROR;
+ $this->statusMessage = $_e->getMessage();
+ }
+
+ clearstatcache();
+
+ if ($currentWorkingDirectory !== getcwd()) {
+ chdir($currentWorkingDirectory);
+ }
+
+ $this->restoreGlobalState();
+ $this->unregisterCustomComparators();
+ $this->cleanupIniSettings();
+ $this->cleanupLocaleSettings();
+ libxml_clear_errors();
+
+ // Perform assertion on output.
+ if (!isset($e)) {
+ try {
+ if ($this->outputExpectedRegex !== null) {
+ $this->assertMatchesRegularExpression($this->outputExpectedRegex, $this->output);
+ } elseif ($this->outputExpectedString !== null) {
+ $this->assertEquals($this->outputExpectedString, $this->output);
+ }
+ } catch (Throwable $_e) {
+ $e = $_e;
+ }
+ }
+
+ // Workaround for missing "finally".
+ if (isset($e)) {
+ if ($e instanceof PredictionException) {
+ $e = new AssertionFailedError($e->getMessage());
+ }
+
+ $this->onNotSuccessfulTest($e);
+ }
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function setName(string $name): void
+ {
+ $this->name = $name;
+
+ if (is_callable($this->sortId(), true)) {
+ $this->providedTests = [new ExecutionOrderDependency($this->sortId())];
+ }
+ }
+
+ /**
+ * @param list<ExecutionOrderDependency> $dependencies
+ *
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function setDependencies(array $dependencies): void
+ {
+ $this->dependencies = $dependencies;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function setDependencyInput(array $dependencyInput): void
+ {
+ $this->dependencyInput = $dependencyInput;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function setBeStrictAboutChangesToGlobalState(?bool $beStrictAboutChangesToGlobalState): void
+ {
+ $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function setBackupGlobals(?bool $backupGlobals): void
+ {
+ if ($this->backupGlobals === null && $backupGlobals !== null) {
+ $this->backupGlobals = $backupGlobals;
+ }
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function setBackupStaticAttributes(?bool $backupStaticAttributes): void
+ {
+ if ($this->backupStaticAttributes === null && $backupStaticAttributes !== null) {
+ $this->backupStaticAttributes = $backupStaticAttributes;
+ }
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function setRunTestInSeparateProcess(bool $runTestInSeparateProcess): void
+ {
+ if ($this->runTestInSeparateProcess === null) {
+ $this->runTestInSeparateProcess = $runTestInSeparateProcess;
+ }
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function setRunClassInSeparateProcess(bool $runClassInSeparateProcess): void
+ {
+ if ($this->runClassInSeparateProcess === null) {
+ $this->runClassInSeparateProcess = $runClassInSeparateProcess;
+ }
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function setPreserveGlobalState(bool $preserveGlobalState): void
+ {
+ $this->preserveGlobalState = $preserveGlobalState;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function setInIsolation(bool $inIsolation): void
+ {
+ $this->inIsolation = $inIsolation;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function isInIsolation(): bool
+ {
+ return $this->inIsolation;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function getResult()
+ {
+ return $this->testResult;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function setResult($result): void
+ {
+ $this->testResult = $result;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function setOutputCallback(callable $callback): void
+ {
+ $this->outputCallback = $callback;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function getTestResultObject(): ?TestResult
+ {
+ return $this->result;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function setTestResultObject(TestResult $result): void
+ {
+ $this->result = $result;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function registerMockObject(MockObject $mockObject): void
+ {
+ $this->mockObjects[] = $mockObject;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function addToAssertionCount(int $count): void
+ {
+ $this->numAssertions += $count;
+ }
+
+ /**
+ * Returns the number of assertions performed by this test.
+ *
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function getNumAssertions(): int
+ {
+ return $this->numAssertions;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function usesDataProvider(): bool
+ {
+ return !empty($this->data);
+ }
+
+ /**
+ * @return int|string
+ *
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function dataName()
+ {
+ return $this->dataName;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function getDataSetAsString(bool $includeData = true): string
+ {
+ $buffer = '';
+
+ if (!empty($this->data)) {
+ if (is_int($this->dataName)) {
+ $buffer .= sprintf(' with data set #%d', $this->dataName);
+ } else {
+ $buffer .= sprintf(' with data set "%s"', $this->dataName);
+ }
+
+ if ($includeData) {
+ $exporter = new Exporter;
+
+ $buffer .= sprintf(' (%s)', $exporter->shortenedRecursiveExport($this->data));
+ }
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * Gets the data set of a TestCase.
+ *
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function getProvidedData(): array
+ {
+ return $this->data;
+ }
+
+ /**
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ public function addWarning(string $warning): void
+ {
+ $this->warnings[] = $warning;
+ }
+
+ public function sortId(): string
+ {
+ $id = $this->name;
+
+ if (strpos($id, '::') === false) {
+ $id = static::class . '::' . $id;
+ }
+
+ if ($this->usesDataProvider()) {
+ $id .= $this->getDataSetAsString(false);
+ }
+
+ return $id;
+ }
+
+ /**
+ * Returns the normalized test name as class::method.
+ *
+ * @return list<ExecutionOrderDependency>
+ */
+ public function provides(): array
+ {
+ return $this->providedTests;
+ }
+
+ /**
+ * Returns a list of normalized dependency names, class::method.
+ *
+ * This list can differ from the raw dependencies as the resolver has
+ * no need for the [!][shallow]clone prefix that is filtered out
+ * during normalization.
+ *
+ * @return list<ExecutionOrderDependency>
+ */
+ public function requires(): array
+ {
+ return $this->dependencies;
+ }
+
+ /**
+ * Override to run the test and assert its state.
+ *
+ * @throws \SebastianBergmann\ObjectEnumerator\InvalidArgumentException
+ * @throws AssertionFailedError
+ * @throws Exception
+ * @throws ExpectationFailedException
+ * @throws Throwable
+ */
+ protected function runTest()
+ {
+ if (trim($this->name) === '') {
+ throw new Exception(
+ 'PHPUnit\Framework\TestCase::$name must be a non-blank string.'
+ );
+ }
+
+ $testArguments = array_merge($this->data, $this->dependencyInput);
+
+ $this->registerMockObjectsFromTestArguments($testArguments);
+
+ try {
+ $testResult = $this->{$this->name}(...array_values($testArguments));
+ } catch (Throwable $exception) {
+ if (!$this->checkExceptionExpectations($exception)) {
+ throw $exception;
+ }
+
+ if ($this->expectedException !== null) {
+ if ($this->expectedException === Error::class) {
+ $this->assertThat(
+ $exception,
+ LogicalOr::fromConstraints(
+ new ExceptionConstraint(Error::class),
+ new ExceptionConstraint(\Error::class)
+ )
+ );
+ } else {
+ $this->assertThat(
+ $exception,
+ new ExceptionConstraint(
+ $this->expectedException
+ )
+ );
+ }
+ }
+
+ if ($this->expectedExceptionMessage !== null) {
+ $this->assertThat(
+ $exception,
+ new ExceptionMessage(
+ $this->expectedExceptionMessage
+ )
+ );
+ }
+
+ if ($this->expectedExceptionMessageRegExp !== null) {
+ $this->assertThat(
+ $exception,
+ new ExceptionMessageRegularExpression(
+ $this->expectedExceptionMessageRegExp
+ )
+ );
+ }
+
+ if ($this->expectedExceptionCode !== null) {
+ $this->assertThat(
+ $exception,
+ new ExceptionCode(
+ $this->expectedExceptionCode
+ )
+ );
+ }
+
+ return;
+ }
+
+ if ($this->expectedException !== null) {
+ $this->assertThat(
+ null,
+ new ExceptionConstraint(
+ $this->expectedException
+ )
+ );
+ } elseif ($this->expectedExceptionMessage !== null) {
+ $this->numAssertions++;
+
+ throw new AssertionFailedError(
+ sprintf(
+ 'Failed asserting that exception with message "%s" is thrown',
+ $this->expectedExceptionMessage
+ )
+ );
+ } elseif ($this->expectedExceptionMessageRegExp !== null) {
+ $this->numAssertions++;
+
+ throw new AssertionFailedError(
+ sprintf(
+ 'Failed asserting that exception with message matching "%s" is thrown',
+ $this->expectedExceptionMessageRegExp
+ )
+ );
+ } elseif ($this->expectedExceptionCode !== null) {
+ $this->numAssertions++;
+
+ throw new AssertionFailedError(
+ sprintf(
+ 'Failed asserting that exception with code "%s" is thrown',
+ $this->expectedExceptionCode
+ )
+ );
+ }
+
+ return $testResult;
+ }
+
+ /**
+ * This method is a wrapper for the ini_set() function that automatically
+ * resets the modified php.ini setting to its original value after the
+ * test is run.
+ *
+ * @throws Exception
+ */
+ protected function iniSet(string $varName, string $newValue): void
+ {
+ $currentValue = ini_set($varName, $newValue);
+
+ if ($currentValue !== false) {
+ $this->iniSettings[$varName] = $currentValue;
+ } else {
+ throw new Exception(
+ sprintf(
+ 'INI setting "%s" could not be set to "%s".',
+ $varName,
+ $newValue
+ )
+ );
+ }
+ }
+
+ /**
+ * This method is a wrapper for the setlocale() function that automatically
+ * resets the locale to its original value after the test is run.
+ *
+ * @throws Exception
+ */
+ protected function setLocale(...$args): void
+ {
+ if (count($args) < 2) {
+ throw new Exception;
+ }
+
+ [$category, $locale] = $args;
+
+ if (!in_array($category, self::LOCALE_CATEGORIES, true)) {
+ throw new Exception;
+ }
+
+ if (!is_array($locale) && !is_string($locale)) {
+ throw new Exception;
+ }
+
+ $this->locale[$category] = setlocale($category, 0);
+
+ $result = setlocale(...$args);
+
+ if ($result === false) {
+ throw new Exception(
+ 'The locale functionality is not implemented on your platform, ' .
+ 'the specified locale does not exist or the category name is ' .
+ 'invalid.'
+ );
+ }
+ }
+
+ /**
+ * Makes configurable stub for the specified class.
+ *
+ * @psalm-template RealInstanceType of object
+ * @psalm-param class-string<RealInstanceType> $originalClassName
+ * @psalm-return Stub&RealInstanceType
+ */
+ protected function createStub(string $originalClassName): Stub
+ {
+ return $this->createMockObject($originalClassName);
+ }
+
+ /**
+ * Returns a mock object for the specified class.
+ *
+ * @psalm-template RealInstanceType of object
+ * @psalm-param class-string<RealInstanceType> $originalClassName
+ * @psalm-return MockObject&RealInstanceType
+ */
+ protected function createMock(string $originalClassName): MockObject
+ {
+ return $this->createMockObject($originalClassName);
+ }
+
+ /**
+ * Returns a configured mock object for the specified class.
+ *
+ * @psalm-template RealInstanceType of object
+ * @psalm-param class-string<RealInstanceType> $originalClassName
+ * @psalm-return MockObject&RealInstanceType
+ */
+ protected function createConfiguredMock(string $originalClassName, array $configuration): MockObject
+ {
+ $o = $this->createMockObject($originalClassName);
+
+ foreach ($configuration as $method => $return) {
+ $o->method($method)->willReturn($return);
+ }
+
+ return $o;
+ }
+
+ /**
+ * Returns a partial mock object for the specified class.
+ *
+ * @param string[] $methods
+ *
+ * @psalm-template RealInstanceType of object
+ * @psalm-param class-string<RealInstanceType> $originalClassName
+ * @psalm-return MockObject&RealInstanceType
+ */
+ protected function createPartialMock(string $originalClassName, array $methods): MockObject
+ {
+ try {
+ $reflector = new ReflectionClass($originalClassName);
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ $mockedMethodsThatDontExist = array_filter(
+ $methods,
+ static function (string $method) use ($reflector)
+ {
+ return !$reflector->hasMethod($method);
+ }
+ );
+
+ if ($mockedMethodsThatDontExist) {
+ $this->addWarning(
+ sprintf(
+ 'createPartialMock() called with method(s) %s that do not exist in %s. This will not be allowed in future versions of PHPUnit.',
+ implode(', ', $mockedMethodsThatDontExist),
+ $originalClassName
+ )
+ );
+ }
+
+ return $this->getMockBuilder($originalClassName)
+ ->disableOriginalConstructor()
+ ->disableOriginalClone()
+ ->disableArgumentCloning()
+ ->disallowMockingUnknownTypes()
+ ->setMethods(empty($methods) ? null : $methods)
+ ->getMock();
+ }
+
+ /**
+ * Returns a test proxy for the specified class.
+ *
+ * @psalm-template RealInstanceType of object
+ * @psalm-param class-string<RealInstanceType> $originalClassName
+ * @psalm-return MockObject&RealInstanceType
+ */
+ protected function createTestProxy(string $originalClassName, array $constructorArguments = []): MockObject
+ {
+ return $this->getMockBuilder($originalClassName)
+ ->setConstructorArgs($constructorArguments)
+ ->enableProxyingToOriginalMethods()
+ ->getMock();
+ }
+
+ /**
+ * Mocks the specified class and returns the name of the mocked class.
+ *
+ * @param null|array $methods $methods
+ *
+ * @psalm-template RealInstanceType of object
+ * @psalm-param class-string<RealInstanceType>|string $originalClassName
+ * @psalm-return class-string<MockObject&RealInstanceType>
+ */
+ protected function getMockClass(string $originalClassName, $methods = [], array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = false, bool $callOriginalClone = true, bool $callAutoload = true, bool $cloneArguments = false): string
+ {
+ $this->recordDoubledType($originalClassName);
+
+ $mock = $this->getMockObjectGenerator()->getMock(
+ $originalClassName,
+ $methods,
+ $arguments,
+ $mockClassName,
+ $callOriginalConstructor,
+ $callOriginalClone,
+ $callAutoload,
+ $cloneArguments
+ );
+
+ return get_class($mock);
+ }
+
+ /**
+ * Returns a mock object for the specified abstract class with all abstract
+ * methods of the class mocked. Concrete methods are not mocked by default.
+ * To mock concrete methods, use the 7th parameter ($mockedMethods).
+ *
+ * @psalm-template RealInstanceType of object
+ * @psalm-param class-string<RealInstanceType> $originalClassName
+ * @psalm-return MockObject&RealInstanceType
+ */
+ protected function getMockForAbstractClass(string $originalClassName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = true, bool $callOriginalClone = true, bool $callAutoload = true, array $mockedMethods = [], bool $cloneArguments = false): MockObject
+ {
+ $this->recordDoubledType($originalClassName);
+
+ $mockObject = $this->getMockObjectGenerator()->getMockForAbstractClass(
+ $originalClassName,
+ $arguments,
+ $mockClassName,
+ $callOriginalConstructor,
+ $callOriginalClone,
+ $callAutoload,
+ $mockedMethods,
+ $cloneArguments
+ );
+
+ $this->registerMockObject($mockObject);
+
+ return $mockObject;
+ }
+
+ /**
+ * Returns a mock object based on the given WSDL file.
+ *
+ * @psalm-template RealInstanceType of object
+ * @psalm-param class-string<RealInstanceType>|string $originalClassName
+ * @psalm-return MockObject&RealInstanceType
+ */
+ protected function getMockFromWsdl(string $wsdlFile, string $originalClassName = '', string $mockClassName = '', array $methods = [], bool $callOriginalConstructor = true, array $options = []): MockObject
+ {
+ $this->recordDoubledType(SoapClient::class);
+
+ if ($originalClassName === '') {
+ $fileName = pathinfo(basename(parse_url($wsdlFile, PHP_URL_PATH)), PATHINFO_FILENAME);
+ $originalClassName = preg_replace('/\W/', '', $fileName);
+ }
+
+ if (!class_exists($originalClassName)) {
+ eval(
+ $this->getMockObjectGenerator()->generateClassFromWsdl(
+ $wsdlFile,
+ $originalClassName,
+ $methods,
+ $options
+ )
+ );
+ }
+
+ $mockObject = $this->getMockObjectGenerator()->getMock(
+ $originalClassName,
+ $methods,
+ ['', $options],
+ $mockClassName,
+ $callOriginalConstructor,
+ false,
+ false
+ );
+
+ $this->registerMockObject($mockObject);
+
+ return $mockObject;
+ }
+
+ /**
+ * Returns a mock object for the specified trait with all abstract methods
+ * of the trait mocked. Concrete methods to mock can be specified with the
+ * `$mockedMethods` parameter.
+ *
+ * @psalm-param trait-string $traitName
+ */
+ protected function getMockForTrait(string $traitName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = true, bool $callOriginalClone = true, bool $callAutoload = true, array $mockedMethods = [], bool $cloneArguments = false): MockObject
+ {
+ $this->recordDoubledType($traitName);
+
+ $mockObject = $this->getMockObjectGenerator()->getMockForTrait(
+ $traitName,
+ $arguments,
+ $mockClassName,
+ $callOriginalConstructor,
+ $callOriginalClone,
+ $callAutoload,
+ $mockedMethods,
+ $cloneArguments
+ );
+
+ $this->registerMockObject($mockObject);
+
+ return $mockObject;
+ }
+
+ /**
+ * Returns an object for the specified trait.
+ *
+ * @psalm-param trait-string $traitName
+ */
+ protected function getObjectForTrait(string $traitName, array $arguments = [], string $traitClassName = '', bool $callOriginalConstructor = true, bool $callOriginalClone = true, bool $callAutoload = true): object
+ {
+ $this->recordDoubledType($traitName);
+
+ return $this->getMockObjectGenerator()->getObjectForTrait(
+ $traitName,
+ $traitClassName,
+ $callAutoload,
+ $callOriginalConstructor,
+ $arguments
+ );
+ }
+
+ /**
+ * @throws \Prophecy\Exception\Doubler\ClassNotFoundException
+ * @throws \Prophecy\Exception\Doubler\DoubleException
+ * @throws \Prophecy\Exception\Doubler\InterfaceNotFoundException
+ *
+ * @psalm-param class-string|null $classOrInterface
+ */
+ protected function prophesize(?string $classOrInterface = null): ObjectProphecy
+ {
+ $this->addWarning('PHPUnit\Framework\TestCase::prophesize() is deprecated and will be removed in PHPUnit 10. Please use the trait provided by phpspec/prophecy-phpunit.');
+
+ if (is_string($classOrInterface)) {
+ $this->recordDoubledType($classOrInterface);
+ }
+
+ return $this->getProphet()->prophesize($classOrInterface);
+ }
+
+ /**
+ * Creates a default TestResult object.
+ *
+ * @internal This method is not covered by the backward compatibility promise for PHPUnit
+ */
+ protected function createResult(): TestResult
+ {
+ return new TestResult;
+ }
+
+ /**
+ * This method is called when a test method did not execute successfully.
+ *
+ * @throws Throwable
+ */
+ protected function onNotSuccessfulTest(Throwable $t): void
+ {
+ throw $t;
+ }
+
+ protected function recordDoubledType(string $originalClassName): void
+ {
+ $this->doubledTypes[] = $originalClassName;
+ }
+
+ /**
+ * @throws Throwable
+ */
+ private function verifyMockObjects(): void
+ {
+ foreach ($this->mockObjects as $mockObject) {
+ if ($mockObject->__phpunit_hasMatchers()) {
+ $this->numAssertions++;
+ }
+
+ $mockObject->__phpunit_verify(
+ $this->shouldInvocationMockerBeReset($mockObject)
+ );
+ }
+
+ if ($this->prophet !== null) {
+ try {
+ $this->prophet->checkPredictions();
+ } finally {
+ foreach ($this->prophet->getProphecies() as $objectProphecy) {
+ foreach ($objectProphecy->getMethodProphecies() as $methodProphecies) {
+ foreach ($methodProphecies as $methodProphecy) {
+ /* @var MethodProphecy $methodProphecy */
+ $this->numAssertions += count($methodProphecy->getCheckedPredictions());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @throws SkippedTestError
+ * @throws SyntheticSkippedError
+ * @throws Warning
+ */
+ private function checkRequirements(): void
+ {
+ if (!$this->name || !method_exists($this, $this->name)) {
+ return;
+ }
+
+ $missingRequirements = TestUtil::getMissingRequirements(
+ static::class,
+ $this->name
+ );
+
+ if (!empty($missingRequirements)) {
+ $this->markTestSkipped(implode(PHP_EOL, $missingRequirements));
+ }
+ }
+
+ private function handleDependencies(): bool
+ {
+ if ([] === $this->dependencies || $this->inIsolation) {
+ return true;
+ }
+
+ $passed = $this->result->passed();
+ $passedKeys = array_keys($passed);
+ $numKeys = count($passedKeys);
+
+ for ($i = 0; $i < $numKeys; $i++) {
+ $pos = strpos($passedKeys[$i], ' with data set');
+
+ if ($pos !== false) {
+ $passedKeys[$i] = substr($passedKeys[$i], 0, $pos);
+ }
+ }
+
+ $passedKeys = array_flip(array_unique($passedKeys));
+
+ foreach ($this->dependencies as $dependency) {
+ if (!$dependency->isValid()) {
+ $this->markSkippedForNotSpecifyingDependency();
+
+ return false;
+ }
+
+ if ($dependency->targetIsClass()) {
+ $dependencyClassName = $dependency->getTargetClassName();
+
+ if (array_search($dependencyClassName, $this->result->passedClasses(), true) === false) {
+ $this->markSkippedForMissingDependency($dependency);
+
+ return false;
+ }
+
+ continue;
+ }
+
+ $dependencyTarget = $dependency->getTarget();
+
+ if (!isset($passedKeys[$dependencyTarget])) {
+ if (!$this->isCallableTestMethod($dependencyTarget)) {
+ $this->markWarningForUncallableDependency($dependency);
+ } else {
+ $this->markSkippedForMissingDependency($dependency);
+ }
+
+ return false;
+ }
+
+ if (isset($passed[$dependencyTarget])) {
+ if ($passed[$dependencyTarget]['size'] != \PHPUnit\Util\Test::UNKNOWN &&
+ $this->getSize() != \PHPUnit\Util\Test::UNKNOWN &&
+ $passed[$dependencyTarget]['size'] > $this->getSize()) {
+ $this->result->addError(
+ $this,
+ new SkippedTestError(
+ 'This test depends on a test that is larger than itself.'
+ ),
+ 0
+ );
+
+ return false;
+ }
+
+ if ($dependency->useDeepClone()) {
+ $deepCopy = new DeepCopy;
+ $deepCopy->skipUncloneable(false);
+
+ $this->dependencyInput[$dependencyTarget] = $deepCopy->copy($passed[$dependencyTarget]['result']);
+ } elseif ($dependency->useShallowClone()) {
+ $this->dependencyInput[$dependencyTarget] = clone $passed[$dependencyTarget]['result'];
+ } else {
+ $this->dependencyInput[$dependencyTarget] = $passed[$dependencyTarget]['result'];
+ }
+ } else {
+ $this->dependencyInput[$dependencyTarget] = null;
+ }
+ }
+
+ return true;
+ }
+
+ private function markSkippedForNotSpecifyingDependency(): void
+ {
+ $this->status = BaseTestRunner::STATUS_SKIPPED;
+
+ $this->result->startTest($this);
+
+ $this->result->addError(
+ $this,
+ new SkippedTestError(
+ 'This method has an invalid @depends annotation.'
+ ),
+ 0
+ );
+
+ $this->result->endTest($this, 0);
+ }
+
+ private function markSkippedForMissingDependency(ExecutionOrderDependency $dependency): void
+ {
+ $this->status = BaseTestRunner::STATUS_SKIPPED;
+
+ $this->result->startTest($this);
+
+ $this->result->addError(
+ $this,
+ new SkippedTestError(
+ sprintf(
+ 'This test depends on "%s" to pass.',
+ $dependency->getTarget()
+ )
+ ),
+ 0
+ );
+
+ $this->result->endTest($this, 0);
+ }
+
+ private function markWarningForUncallableDependency(ExecutionOrderDependency $dependency): void
+ {
+ $this->status = BaseTestRunner::STATUS_WARNING;
+
+ $this->result->startTest($this);
+
+ $this->result->addWarning(
+ $this,
+ new Warning(
+ sprintf(
+ 'This test depends on "%s" which does not exist.',
+ $dependency->getTarget()
+ )
+ ),
+ 0
+ );
+
+ $this->result->endTest($this, 0);
+ }
+
+ /**
+ * Get the mock object generator, creating it if it doesn't exist.
+ */
+ private function getMockObjectGenerator(): MockGenerator
+ {
+ if ($this->mockObjectGenerator === null) {
+ $this->mockObjectGenerator = new MockGenerator;
+ }
+
+ return $this->mockObjectGenerator;
+ }
+
+ private function startOutputBuffering(): void
+ {
+ ob_start();
+
+ $this->outputBufferingActive = true;
+ $this->outputBufferingLevel = ob_get_level();
+ }
+
+ /**
+ * @throws RiskyTestError
+ */
+ private function stopOutputBuffering(): void
+ {
+ if (ob_get_level() !== $this->outputBufferingLevel) {
+ while (ob_get_level() >= $this->outputBufferingLevel) {
+ ob_end_clean();
+ }
+
+ throw new RiskyTestError(
+ 'Test code or tested code did not (only) close its own output buffers'
+ );
+ }
+
+ $this->output = ob_get_contents();
+
+ if ($this->outputCallback !== false) {
+ $this->output = (string) call_user_func($this->outputCallback, $this->output);
+ }
+
+ ob_end_clean();
+
+ $this->outputBufferingActive = false;
+ $this->outputBufferingLevel = ob_get_level();
+ }
+
+ private function snapshotGlobalState(): void
+ {
+ if ($this->runTestInSeparateProcess || $this->inIsolation ||
+ (!$this->backupGlobals && !$this->backupStaticAttributes)) {
+ return;
+ }
+
+ $this->snapshot = $this->createGlobalStateSnapshot($this->backupGlobals === true);
+ }
+
+ /**
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws RiskyTestError
+ */
+ private function restoreGlobalState(): void
+ {
+ if (!$this->snapshot instanceof Snapshot) {
+ return;
+ }
+
+ if ($this->beStrictAboutChangesToGlobalState) {
+ try {
+ $this->compareGlobalStateSnapshots(
+ $this->snapshot,
+ $this->createGlobalStateSnapshot($this->backupGlobals === true)
+ );
+ } catch (RiskyTestError $rte) {
+ // Intentionally left empty
+ }
+ }
+
+ $restorer = new Restorer;
+
+ if ($this->backupGlobals) {
+ $restorer->restoreGlobalVariables($this->snapshot);
+ }
+
+ if ($this->backupStaticAttributes) {
+ $restorer->restoreStaticAttributes($this->snapshot);
+ }
+
+ $this->snapshot = null;
+
+ if (isset($rte)) {
+ throw $rte;
+ }
+ }
+
+ private function createGlobalStateSnapshot(bool $backupGlobals): Snapshot
+ {
+ $excludeList = new ExcludeList;
+
+ foreach ($this->backupGlobalsExcludeList as $globalVariable) {
+ $excludeList->addGlobalVariable($globalVariable);
+ }
+
+ if (!empty($this->backupGlobalsBlacklist)) {
+ $this->addWarning('PHPUnit\Framework\TestCase::$backupGlobalsBlacklist is deprecated and will be removed in PHPUnit 10. Please use PHPUnit\Framework\TestCase::$backupGlobalsExcludeList instead.');
+
+ foreach ($this->backupGlobalsBlacklist as $globalVariable) {
+ $excludeList->addGlobalVariable($globalVariable);
+ }
+ }
+
+ if (!defined('PHPUNIT_TESTSUITE')) {
+ $excludeList->addClassNamePrefix('PHPUnit');
+ $excludeList->addClassNamePrefix('SebastianBergmann\CodeCoverage');
+ $excludeList->addClassNamePrefix('SebastianBergmann\FileIterator');
+ $excludeList->addClassNamePrefix('SebastianBergmann\Invoker');
+ $excludeList->addClassNamePrefix('SebastianBergmann\Template');
+ $excludeList->addClassNamePrefix('SebastianBergmann\Timer');
+ $excludeList->addClassNamePrefix('Symfony');
+ $excludeList->addClassNamePrefix('Doctrine\Instantiator');
+ $excludeList->addClassNamePrefix('Prophecy');
+ $excludeList->addStaticAttribute(ComparatorFactory::class, 'instance');
+
+ foreach ($this->backupStaticAttributesExcludeList as $class => $attributes) {
+ foreach ($attributes as $attribute) {
+ $excludeList->addStaticAttribute($class, $attribute);
+ }
+ }
+
+ if (!empty($this->backupStaticAttributesBlacklist)) {
+ $this->addWarning('PHPUnit\Framework\TestCase::$backupStaticAttributesBlacklist is deprecated and will be removed in PHPUnit 10. Please use PHPUnit\Framework\TestCase::$backupStaticAttributesExcludeList instead.');
+
+ foreach ($this->backupStaticAttributesBlacklist as $class => $attributes) {
+ foreach ($attributes as $attribute) {
+ $excludeList->addStaticAttribute($class, $attribute);
+ }
+ }
+ }
+ }
+
+ return new Snapshot(
+ $excludeList,
+ $backupGlobals,
+ (bool) $this->backupStaticAttributes,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false
+ );
+ }
+
+ /**
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws RiskyTestError
+ */
+ private function compareGlobalStateSnapshots(Snapshot $before, Snapshot $after): void
+ {
+ $backupGlobals = $this->backupGlobals === null || $this->backupGlobals;
+
+ if ($backupGlobals) {
+ $this->compareGlobalStateSnapshotPart(
+ $before->globalVariables(),
+ $after->globalVariables(),
+ "--- Global variables before the test\n+++ Global variables after the test\n"
+ );
+
+ $this->compareGlobalStateSnapshotPart(
+ $before->superGlobalVariables(),
+ $after->superGlobalVariables(),
+ "--- Super-global variables before the test\n+++ Super-global variables after the test\n"
+ );
+ }
+
+ if ($this->backupStaticAttributes) {
+ $this->compareGlobalStateSnapshotPart(
+ $before->staticAttributes(),
+ $after->staticAttributes(),
+ "--- Static attributes before the test\n+++ Static attributes after the test\n"
+ );
+ }
+ }
+
+ /**
+ * @throws RiskyTestError
+ */
+ private function compareGlobalStateSnapshotPart(array $before, array $after, string $header): void
+ {
+ if ($before != $after) {
+ $differ = new Differ($header);
+ $exporter = new Exporter;
+
+ $diff = $differ->diff(
+ $exporter->export($before),
+ $exporter->export($after)
+ );
+
+ throw new RiskyTestError(
+ $diff
+ );
+ }
+ }
+
+ private function getProphet(): Prophet
+ {
+ if ($this->prophet === null) {
+ $this->prophet = new Prophet;
+ }
+
+ return $this->prophet;
+ }
+
+ /**
+ * @throws \SebastianBergmann\ObjectEnumerator\InvalidArgumentException
+ */
+ private function shouldInvocationMockerBeReset(MockObject $mock): bool
+ {
+ $enumerator = new Enumerator;
+
+ foreach ($enumerator->enumerate($this->dependencyInput) as $object) {
+ if ($mock === $object) {
+ return false;
+ }
+ }
+
+ if (!is_array($this->testResult) && !is_object($this->testResult)) {
+ return true;
+ }
+
+ return !in_array($mock, $enumerator->enumerate($this->testResult), true);
+ }
+
+ /**
+ * @throws \SebastianBergmann\ObjectEnumerator\InvalidArgumentException
+ * @throws \SebastianBergmann\ObjectReflector\InvalidArgumentException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ private function registerMockObjectsFromTestArguments(array $testArguments, array &$visited = []): void
+ {
+ if ($this->registerMockObjectsFromTestArgumentsRecursively) {
+ foreach ((new Enumerator)->enumerate($testArguments) as $object) {
+ if ($object instanceof MockObject) {
+ $this->registerMockObject($object);
+ }
+ }
+ } else {
+ foreach ($testArguments as $testArgument) {
+ if ($testArgument instanceof MockObject) {
+ if (Type::isCloneable($testArgument)) {
+ $testArgument = clone $testArgument;
+ }
+
+ $this->registerMockObject($testArgument);
+ } elseif (is_array($testArgument) && !in_array($testArgument, $visited, true)) {
+ $visited[] = $testArgument;
+
+ $this->registerMockObjectsFromTestArguments(
+ $testArgument,
+ $visited
+ );
+ }
+ }
+ }
+ }
+
+ private function setDoesNotPerformAssertionsFromAnnotation(): void
+ {
+ $annotations = TestUtil::parseTestMethodAnnotations(
+ static::class,
+ $this->name
+ );
+
+ if (isset($annotations['method']['doesNotPerformAssertions'])) {
+ $this->doesNotPerformAssertions = true;
+ }
+ }
+
+ private function unregisterCustomComparators(): void
+ {
+ $factory = ComparatorFactory::getInstance();
+
+ foreach ($this->customComparators as $comparator) {
+ $factory->unregister($comparator);
+ }
+
+ $this->customComparators = [];
+ }
+
+ private function cleanupIniSettings(): void
+ {
+ foreach ($this->iniSettings as $varName => $oldValue) {
+ ini_set($varName, $oldValue);
+ }
+
+ $this->iniSettings = [];
+ }
+
+ private function cleanupLocaleSettings(): void
+ {
+ foreach ($this->locale as $category => $locale) {
+ setlocale($category, $locale);
+ }
+
+ $this->locale = [];
+ }
+
+ /**
+ * @throws Exception
+ */
+ private function checkExceptionExpectations(Throwable $throwable): bool
+ {
+ $result = false;
+
+ if ($this->expectedException !== null || $this->expectedExceptionCode !== null || $this->expectedExceptionMessage !== null || $this->expectedExceptionMessageRegExp !== null) {
+ $result = true;
+ }
+
+ if ($throwable instanceof Exception) {
+ $result = false;
+ }
+
+ if (is_string($this->expectedException)) {
+ try {
+ $reflector = new ReflectionClass($this->expectedException);
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ if ($this->expectedException === 'PHPUnit\Framework\Exception' ||
+ $this->expectedException === '\PHPUnit\Framework\Exception' ||
+ $reflector->isSubclassOf(Exception::class)) {
+ $result = true;
+ }
+ }
+
+ return $result;
+ }
+
+ private function runInSeparateProcess(): bool
+ {
+ return ($this->runTestInSeparateProcess || $this->runClassInSeparateProcess) &&
+ !$this->inIsolation && !$this instanceof PhptTestCase;
+ }
+
+ private function isCallableTestMethod(string $dependency): bool
+ {
+ [$className, $methodName] = explode('::', $dependency);
+
+ if (!class_exists($className)) {
+ return false;
+ }
+
+ try {
+ $class = new ReflectionClass($className);
+ } catch (ReflectionException $e) {
+ return false;
+ }
+
+ if (!$class->isSubclassOf(__CLASS__)) {
+ return false;
+ }
+
+ if (!$class->hasMethod($methodName)) {
+ return false;
+ }
+
+ try {
+ $method = $class->getMethod($methodName);
+ } catch (ReflectionException $e) {
+ return false;
+ }
+
+ return TestUtil::isTestMethod($method);
+ }
+
+ /**
+ * @psalm-template RealInstanceType of object
+ * @psalm-param class-string<RealInstanceType> $originalClassName
+ * @psalm-return MockObject&RealInstanceType
+ */
+ private function createMockObject(string $originalClassName): MockObject
+ {
+ return $this->getMockBuilder($originalClassName)
+ ->disableOriginalConstructor()
+ ->disableOriginalClone()
+ ->disableArgumentCloning()
+ ->disallowMockingUnknownTypes()
+ ->getMock();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestFailure.php b/vendor/phpunit/phpunit/src/Framework/TestFailure.php
new file mode 100644
index 000000000..0764bc789
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/TestFailure.php
@@ -0,0 +1,155 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use function get_class;
+use function sprintf;
+use function trim;
+use PHPUnit\Framework\Error\Error;
+use Throwable;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class TestFailure
+{
+ /**
+ * @var null|Test
+ */
+ private $failedTest;
+
+ /**
+ * @var Throwable
+ */
+ private $thrownException;
+
+ /**
+ * @var string
+ */
+ private $testName;
+
+ /**
+ * Returns a description for an exception.
+ */
+ public static function exceptionToString(Throwable $e): string
+ {
+ if ($e instanceof SelfDescribing) {
+ $buffer = $e->toString();
+
+ if ($e instanceof ExpectationFailedException && $e->getComparisonFailure()) {
+ $buffer .= $e->getComparisonFailure()->getDiff();
+ }
+
+ if ($e instanceof PHPTAssertionFailedError) {
+ $buffer .= $e->getDiff();
+ }
+
+ if (!empty($buffer)) {
+ $buffer = trim($buffer) . "\n";
+ }
+
+ return $buffer;
+ }
+
+ if ($e instanceof Error) {
+ return $e->getMessage() . "\n";
+ }
+
+ if ($e instanceof ExceptionWrapper) {
+ return $e->getClassName() . ': ' . $e->getMessage() . "\n";
+ }
+
+ return get_class($e) . ': ' . $e->getMessage() . "\n";
+ }
+
+ /**
+ * Constructs a TestFailure with the given test and exception.
+ */
+ public function __construct(Test $failedTest, Throwable $t)
+ {
+ if ($failedTest instanceof SelfDescribing) {
+ $this->testName = $failedTest->toString();
+ } else {
+ $this->testName = get_class($failedTest);
+ }
+
+ if (!$failedTest instanceof TestCase || !$failedTest->isInIsolation()) {
+ $this->failedTest = $failedTest;
+ }
+
+ $this->thrownException = $t;
+ }
+
+ /**
+ * Returns a short description of the failure.
+ */
+ public function toString(): string
+ {
+ return sprintf(
+ '%s: %s',
+ $this->testName,
+ $this->thrownException->getMessage()
+ );
+ }
+
+ /**
+ * Returns a description for the thrown exception.
+ */
+ public function getExceptionAsString(): string
+ {
+ return self::exceptionToString($this->thrownException);
+ }
+
+ /**
+ * Returns the name of the failing test (including data set, if any).
+ */
+ public function getTestName(): string
+ {
+ return $this->testName;
+ }
+
+ /**
+ * Returns the failing test.
+ *
+ * Note: The test object is not set when the test is executed in process
+ * isolation.
+ *
+ * @see Exception
+ */
+ public function failedTest(): ?Test
+ {
+ return $this->failedTest;
+ }
+
+ /**
+ * Gets the thrown exception.
+ */
+ public function thrownException(): Throwable
+ {
+ return $this->thrownException;
+ }
+
+ /**
+ * Returns the exception's message.
+ */
+ public function exceptionMessage(): string
+ {
+ return $this->thrownException()->getMessage();
+ }
+
+ /**
+ * Returns true if the thrown exception
+ * is of type AssertionFailedError.
+ */
+ public function isFailure(): bool
+ {
+ return $this->thrownException() instanceof AssertionFailedError;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestListener.php b/vendor/phpunit/phpunit/src/Framework/TestListener.php
new file mode 100644
index 000000000..eade600f2
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/TestListener.php
@@ -0,0 +1,45 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use Throwable;
+
+/**
+ * This interface, as well as the associated mechanism for extending PHPUnit,
+ * will be removed in PHPUnit 10. There is no alternative available in this
+ * version of PHPUnit.
+ *
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ *
+ * @deprecated
+ * @see https://github.com/sebastianbergmann/phpunit/issues/4676
+ */
+interface TestListener
+{
+ public function addError(Test $test, Throwable $t, float $time): void;
+
+ public function addWarning(Test $test, Warning $e, float $time): void;
+
+ public function addFailure(Test $test, AssertionFailedError $e, float $time): void;
+
+ public function addIncompleteTest(Test $test, Throwable $t, float $time): void;
+
+ public function addRiskyTest(Test $test, Throwable $t, float $time): void;
+
+ public function addSkippedTest(Test $test, Throwable $t, float $time): void;
+
+ public function startTestSuite(TestSuite $suite): void;
+
+ public function endTestSuite(TestSuite $suite): void;
+
+ public function startTest(Test $test): void;
+
+ public function endTest(Test $test, float $time): void;
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php b/vendor/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php
new file mode 100644
index 000000000..3e56708b6
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php
@@ -0,0 +1,59 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use Throwable;
+
+/**
+ * @deprecated The `TestListener` interface is deprecated
+ * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
+ */
+trait TestListenerDefaultImplementation
+{
+ public function addError(Test $test, Throwable $t, float $time): void
+ {
+ }
+
+ public function addWarning(Test $test, Warning $e, float $time): void
+ {
+ }
+
+ public function addFailure(Test $test, AssertionFailedError $e, float $time): void
+ {
+ }
+
+ public function addIncompleteTest(Test $test, Throwable $t, float $time): void
+ {
+ }
+
+ public function addRiskyTest(Test $test, Throwable $t, float $time): void
+ {
+ }
+
+ public function addSkippedTest(Test $test, Throwable $t, float $time): void
+ {
+ }
+
+ public function startTestSuite(TestSuite $suite): void
+ {
+ }
+
+ public function endTestSuite(TestSuite $suite): void
+ {
+ }
+
+ public function startTest(Test $test): void
+ {
+ }
+
+ public function endTest(Test $test, float $time): void
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestResult.php b/vendor/phpunit/phpunit/src/Framework/TestResult.php
new file mode 100644
index 000000000..99b4246cb
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/TestResult.php
@@ -0,0 +1,1318 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use const PHP_EOL;
+use function count;
+use function function_exists;
+use function get_class;
+use function sprintf;
+use function xdebug_get_monitored_functions;
+use function xdebug_is_debugger_active;
+use function xdebug_start_function_monitor;
+use function xdebug_stop_function_monitor;
+use AssertionError;
+use Countable;
+use Error;
+use PHPUnit\Util\ErrorHandler;
+use PHPUnit\Util\ExcludeList;
+use PHPUnit\Util\Printer;
+use PHPUnit\Util\Test as TestUtil;
+use ReflectionClass;
+use ReflectionException;
+use SebastianBergmann\CodeCoverage\CodeCoverage;
+use SebastianBergmann\CodeCoverage\Exception as OriginalCodeCoverageException;
+use SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException;
+use SebastianBergmann\Invoker\Invoker;
+use SebastianBergmann\Invoker\TimeoutException;
+use SebastianBergmann\ResourceOperations\ResourceOperations;
+use SebastianBergmann\Timer\Timer;
+use Throwable;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class TestResult implements Countable
+{
+ /**
+ * @var array
+ */
+ private $passed = [];
+
+ /**
+ * @var array<string>
+ */
+ private $passedTestClasses = [];
+
+ /**
+ * @var bool
+ */
+ private $currentTestSuiteFailed = false;
+
+ /**
+ * @var TestFailure[]
+ */
+ private $errors = [];
+
+ /**
+ * @var TestFailure[]
+ */
+ private $failures = [];
+
+ /**
+ * @var TestFailure[]
+ */
+ private $warnings = [];
+
+ /**
+ * @var TestFailure[]
+ */
+ private $notImplemented = [];
+
+ /**
+ * @var TestFailure[]
+ */
+ private $risky = [];
+
+ /**
+ * @var TestFailure[]
+ */
+ private $skipped = [];
+
+ /**
+ * @deprecated Use the `TestHook` interfaces instead
+ *
+ * @var TestListener[]
+ */
+ private $listeners = [];
+
+ /**
+ * @var int
+ */
+ private $runTests = 0;
+
+ /**
+ * @var float
+ */
+ private $time = 0;
+
+ /**
+ * Code Coverage information.
+ *
+ * @var CodeCoverage
+ */
+ private $codeCoverage;
+
+ /**
+ * @var bool
+ */
+ private $convertDeprecationsToExceptions = false;
+
+ /**
+ * @var bool
+ */
+ private $convertErrorsToExceptions = true;
+
+ /**
+ * @var bool
+ */
+ private $convertNoticesToExceptions = true;
+
+ /**
+ * @var bool
+ */
+ private $convertWarningsToExceptions = true;
+
+ /**
+ * @var bool
+ */
+ private $stop = false;
+
+ /**
+ * @var bool
+ */
+ private $stopOnError = false;
+
+ /**
+ * @var bool
+ */
+ private $stopOnFailure = false;
+
+ /**
+ * @var bool
+ */
+ private $stopOnWarning = false;
+
+ /**
+ * @var bool
+ */
+ private $beStrictAboutTestsThatDoNotTestAnything = true;
+
+ /**
+ * @var bool
+ */
+ private $beStrictAboutOutputDuringTests = false;
+
+ /**
+ * @var bool
+ */
+ private $beStrictAboutTodoAnnotatedTests = false;
+
+ /**
+ * @var bool
+ */
+ private $beStrictAboutResourceUsageDuringSmallTests = false;
+
+ /**
+ * @var bool
+ */
+ private $enforceTimeLimit = false;
+
+ /**
+ * @var bool
+ */
+ private $forceCoversAnnotation = false;
+
+ /**
+ * @var int
+ */
+ private $timeoutForSmallTests = 1;
+
+ /**
+ * @var int
+ */
+ private $timeoutForMediumTests = 10;
+
+ /**
+ * @var int
+ */
+ private $timeoutForLargeTests = 60;
+
+ /**
+ * @var bool
+ */
+ private $stopOnRisky = false;
+
+ /**
+ * @var bool
+ */
+ private $stopOnIncomplete = false;
+
+ /**
+ * @var bool
+ */
+ private $stopOnSkipped = false;
+
+ /**
+ * @var bool
+ */
+ private $lastTestFailed = false;
+
+ /**
+ * @var int
+ */
+ private $defaultTimeLimit = 0;
+
+ /**
+ * @var bool
+ */
+ private $stopOnDefect = false;
+
+ /**
+ * @var bool
+ */
+ private $registerMockObjectsFromTestArgumentsRecursively = false;
+
+ /**
+ * @deprecated Use the `TestHook` interfaces instead
+ *
+ * @codeCoverageIgnore
+ *
+ * Registers a TestListener.
+ */
+ public function addListener(TestListener $listener): void
+ {
+ $this->listeners[] = $listener;
+ }
+
+ /**
+ * @deprecated Use the `TestHook` interfaces instead
+ *
+ * @codeCoverageIgnore
+ *
+ * Unregisters a TestListener.
+ */
+ public function removeListener(TestListener $listener): void
+ {
+ foreach ($this->listeners as $key => $_listener) {
+ if ($listener === $_listener) {
+ unset($this->listeners[$key]);
+ }
+ }
+ }
+
+ /**
+ * @deprecated Use the `TestHook` interfaces instead
+ *
+ * @codeCoverageIgnore
+ *
+ * Flushes all flushable TestListeners.
+ */
+ public function flushListeners(): void
+ {
+ foreach ($this->listeners as $listener) {
+ if ($listener instanceof Printer) {
+ $listener->flush();
+ }
+ }
+ }
+
+ /**
+ * Adds an error to the list of errors.
+ */
+ public function addError(Test $test, Throwable $t, float $time): void
+ {
+ if ($t instanceof RiskyTestError) {
+ $this->recordRisky($test, $t);
+
+ $notifyMethod = 'addRiskyTest';
+
+ if ($test instanceof TestCase) {
+ $test->markAsRisky();
+ }
+
+ if ($this->stopOnRisky || $this->stopOnDefect) {
+ $this->stop();
+ }
+ } elseif ($t instanceof IncompleteTest) {
+ $this->recordNotImplemented($test, $t);
+
+ $notifyMethod = 'addIncompleteTest';
+
+ if ($this->stopOnIncomplete) {
+ $this->stop();
+ }
+ } elseif ($t instanceof SkippedTest) {
+ $this->recordSkipped($test, $t);
+
+ $notifyMethod = 'addSkippedTest';
+
+ if ($this->stopOnSkipped) {
+ $this->stop();
+ }
+ } else {
+ $this->recordError($test, $t);
+
+ $notifyMethod = 'addError';
+
+ if ($this->stopOnError || $this->stopOnFailure) {
+ $this->stop();
+ }
+ }
+
+ // @see https://github.com/sebastianbergmann/phpunit/issues/1953
+ if ($t instanceof Error) {
+ $t = new ExceptionWrapper($t);
+ }
+
+ foreach ($this->listeners as $listener) {
+ $listener->{$notifyMethod}($test, $t, $time);
+ }
+
+ $this->lastTestFailed = true;
+ $this->time += $time;
+ }
+
+ /**
+ * Adds a warning to the list of warnings.
+ * The passed in exception caused the warning.
+ */
+ public function addWarning(Test $test, Warning $e, float $time): void
+ {
+ if ($this->stopOnWarning || $this->stopOnDefect) {
+ $this->stop();
+ }
+
+ $this->recordWarning($test, $e);
+
+ foreach ($this->listeners as $listener) {
+ $listener->addWarning($test, $e, $time);
+ }
+
+ $this->time += $time;
+ }
+
+ /**
+ * Adds a failure to the list of failures.
+ * The passed in exception caused the failure.
+ */
+ public function addFailure(Test $test, AssertionFailedError $e, float $time): void
+ {
+ if ($e instanceof RiskyTestError || $e instanceof OutputError) {
+ $this->recordRisky($test, $e);
+
+ $notifyMethod = 'addRiskyTest';
+
+ if ($test instanceof TestCase) {
+ $test->markAsRisky();
+ }
+
+ if ($this->stopOnRisky || $this->stopOnDefect) {
+ $this->stop();
+ }
+ } elseif ($e instanceof IncompleteTest) {
+ $this->recordNotImplemented($test, $e);
+
+ $notifyMethod = 'addIncompleteTest';
+
+ if ($this->stopOnIncomplete) {
+ $this->stop();
+ }
+ } elseif ($e instanceof SkippedTest) {
+ $this->recordSkipped($test, $e);
+
+ $notifyMethod = 'addSkippedTest';
+
+ if ($this->stopOnSkipped) {
+ $this->stop();
+ }
+ } else {
+ $this->failures[] = new TestFailure($test, $e);
+ $notifyMethod = 'addFailure';
+
+ if ($this->stopOnFailure || $this->stopOnDefect) {
+ $this->stop();
+ }
+ }
+
+ foreach ($this->listeners as $listener) {
+ $listener->{$notifyMethod}($test, $e, $time);
+ }
+
+ $this->lastTestFailed = true;
+ $this->time += $time;
+ }
+
+ /**
+ * Informs the result that a test suite will be started.
+ */
+ public function startTestSuite(TestSuite $suite): void
+ {
+ $this->currentTestSuiteFailed = false;
+
+ foreach ($this->listeners as $listener) {
+ $listener->startTestSuite($suite);
+ }
+ }
+
+ /**
+ * Informs the result that a test suite was completed.
+ */
+ public function endTestSuite(TestSuite $suite): void
+ {
+ if (!$this->currentTestSuiteFailed) {
+ $this->passedTestClasses[] = $suite->getName();
+ }
+
+ foreach ($this->listeners as $listener) {
+ $listener->endTestSuite($suite);
+ }
+ }
+
+ /**
+ * Informs the result that a test will be started.
+ */
+ public function startTest(Test $test): void
+ {
+ $this->lastTestFailed = false;
+ $this->runTests += count($test);
+
+ foreach ($this->listeners as $listener) {
+ $listener->startTest($test);
+ }
+ }
+
+ /**
+ * Informs the result that a test was completed.
+ *
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ */
+ public function endTest(Test $test, float $time): void
+ {
+ foreach ($this->listeners as $listener) {
+ $listener->endTest($test, $time);
+ }
+
+ if (!$this->lastTestFailed && $test instanceof TestCase) {
+ $class = get_class($test);
+ $key = $class . '::' . $test->getName();
+
+ $this->passed[$key] = [
+ 'result' => $test->getResult(),
+ 'size' => TestUtil::getSize(
+ $class,
+ $test->getName(false)
+ ),
+ ];
+
+ $this->time += $time;
+ }
+
+ if ($this->lastTestFailed && $test instanceof TestCase) {
+ $this->currentTestSuiteFailed = true;
+ }
+ }
+
+ /**
+ * Returns true if no risky test occurred.
+ */
+ public function allHarmless(): bool
+ {
+ return $this->riskyCount() === 0;
+ }
+
+ /**
+ * Gets the number of risky tests.
+ */
+ public function riskyCount(): int
+ {
+ return count($this->risky);
+ }
+
+ /**
+ * Returns true if no incomplete test occurred.
+ */
+ public function allCompletelyImplemented(): bool
+ {
+ return $this->notImplementedCount() === 0;
+ }
+
+ /**
+ * Gets the number of incomplete tests.
+ */
+ public function notImplementedCount(): int
+ {
+ return count($this->notImplemented);
+ }
+
+ /**
+ * Returns an array of TestFailure objects for the risky tests.
+ *
+ * @return TestFailure[]
+ */
+ public function risky(): array
+ {
+ return $this->risky;
+ }
+
+ /**
+ * Returns an array of TestFailure objects for the incomplete tests.
+ *
+ * @return TestFailure[]
+ */
+ public function notImplemented(): array
+ {
+ return $this->notImplemented;
+ }
+
+ /**
+ * Returns true if no test has been skipped.
+ */
+ public function noneSkipped(): bool
+ {
+ return $this->skippedCount() === 0;
+ }
+
+ /**
+ * Gets the number of skipped tests.
+ */
+ public function skippedCount(): int
+ {
+ return count($this->skipped);
+ }
+
+ /**
+ * Returns an array of TestFailure objects for the skipped tests.
+ *
+ * @return TestFailure[]
+ */
+ public function skipped(): array
+ {
+ return $this->skipped;
+ }
+
+ /**
+ * Gets the number of detected errors.
+ */
+ public function errorCount(): int
+ {
+ return count($this->errors);
+ }
+
+ /**
+ * Returns an array of TestFailure objects for the errors.
+ *
+ * @return TestFailure[]
+ */
+ public function errors(): array
+ {
+ return $this->errors;
+ }
+
+ /**
+ * Gets the number of detected failures.
+ */
+ public function failureCount(): int
+ {
+ return count($this->failures);
+ }
+
+ /**
+ * Returns an array of TestFailure objects for the failures.
+ *
+ * @return TestFailure[]
+ */
+ public function failures(): array
+ {
+ return $this->failures;
+ }
+
+ /**
+ * Gets the number of detected warnings.
+ */
+ public function warningCount(): int
+ {
+ return count($this->warnings);
+ }
+
+ /**
+ * Returns an array of TestFailure objects for the warnings.
+ *
+ * @return TestFailure[]
+ */
+ public function warnings(): array
+ {
+ return $this->warnings;
+ }
+
+ /**
+ * Returns the names of the tests that have passed.
+ */
+ public function passed(): array
+ {
+ return $this->passed;
+ }
+
+ /**
+ * Returns the names of the TestSuites that have passed.
+ *
+ * This enables @depends-annotations for TestClassName::class
+ */
+ public function passedClasses(): array
+ {
+ return $this->passedTestClasses;
+ }
+
+ /**
+ * Returns whether code coverage information should be collected.
+ */
+ public function getCollectCodeCoverageInformation(): bool
+ {
+ return $this->codeCoverage !== null;
+ }
+
+ /**
+ * Runs a TestCase.
+ *
+ * @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws CodeCoverageException
+ * @throws UnintentionallyCoveredCodeException
+ */
+ public function run(Test $test): void
+ {
+ Assert::resetCount();
+
+ $size = TestUtil::UNKNOWN;
+
+ if ($test instanceof TestCase) {
+ $test->setRegisterMockObjectsFromTestArgumentsRecursively(
+ $this->registerMockObjectsFromTestArgumentsRecursively
+ );
+
+ $isAnyCoverageRequired = TestUtil::requiresCodeCoverageDataCollection($test);
+ $size = $test->getSize();
+ }
+
+ $error = false;
+ $failure = false;
+ $warning = false;
+ $incomplete = false;
+ $risky = false;
+ $skipped = false;
+
+ $this->startTest($test);
+
+ if ($this->convertDeprecationsToExceptions || $this->convertErrorsToExceptions || $this->convertNoticesToExceptions || $this->convertWarningsToExceptions) {
+ $errorHandler = new ErrorHandler(
+ $this->convertDeprecationsToExceptions,
+ $this->convertErrorsToExceptions,
+ $this->convertNoticesToExceptions,
+ $this->convertWarningsToExceptions
+ );
+
+ $errorHandler->register();
+ }
+
+ $collectCodeCoverage = $this->codeCoverage !== null &&
+ !$test instanceof ErrorTestCase &&
+ !$test instanceof WarningTestCase &&
+ $isAnyCoverageRequired;
+
+ if ($collectCodeCoverage) {
+ $this->codeCoverage->start($test);
+ }
+
+ $monitorFunctions = $this->beStrictAboutResourceUsageDuringSmallTests &&
+ !$test instanceof ErrorTestCase &&
+ !$test instanceof WarningTestCase &&
+ $size === TestUtil::SMALL &&
+ function_exists('xdebug_start_function_monitor');
+
+ if ($monitorFunctions) {
+ /* @noinspection ForgottenDebugOutputInspection */
+ xdebug_start_function_monitor(ResourceOperations::getFunctions());
+ }
+
+ $timer = new Timer;
+ $timer->start();
+
+ try {
+ $invoker = new Invoker;
+
+ if (!$test instanceof ErrorTestCase &&
+ !$test instanceof WarningTestCase &&
+ $this->shouldTimeLimitBeEnforced($size) &&
+ $invoker->canInvokeWithTimeout()) {
+ switch ($size) {
+ case TestUtil::SMALL:
+ $_timeout = $this->timeoutForSmallTests;
+
+ break;
+
+ case TestUtil::MEDIUM:
+ $_timeout = $this->timeoutForMediumTests;
+
+ break;
+
+ case TestUtil::LARGE:
+ $_timeout = $this->timeoutForLargeTests;
+
+ break;
+
+ default:
+ $_timeout = $this->defaultTimeLimit;
+ }
+
+ $invoker->invoke([$test, 'runBare'], [], $_timeout);
+ } else {
+ $test->runBare();
+ }
+ } catch (TimeoutException $e) {
+ $this->addFailure(
+ $test,
+ new RiskyTestError(
+ $e->getMessage()
+ ),
+ $_timeout
+ );
+
+ $risky = true;
+ } catch (AssertionFailedError $e) {
+ $failure = true;
+
+ if ($e instanceof RiskyTestError) {
+ $risky = true;
+ } elseif ($e instanceof IncompleteTestError) {
+ $incomplete = true;
+ } elseif ($e instanceof SkippedTestError) {
+ $skipped = true;
+ }
+ } catch (AssertionError $e) {
+ $test->addToAssertionCount(1);
+
+ $failure = true;
+ $frame = $e->getTrace()[0];
+
+ $e = new AssertionFailedError(
+ sprintf(
+ '%s in %s:%s',
+ $e->getMessage(),
+ $frame['file'] ?? $e->getFile(),
+ $frame['line'] ?? $e->getLine()
+ )
+ );
+ } catch (Warning $e) {
+ $warning = true;
+ } catch (Exception $e) {
+ $error = true;
+ } catch (Throwable $e) {
+ $e = new ExceptionWrapper($e);
+ $error = true;
+ }
+
+ $time = $timer->stop()->asSeconds();
+
+ $test->addToAssertionCount(Assert::getCount());
+
+ if ($monitorFunctions) {
+ $excludeList = new ExcludeList;
+
+ /** @noinspection ForgottenDebugOutputInspection */
+ $functions = xdebug_get_monitored_functions();
+
+ /* @noinspection ForgottenDebugOutputInspection */
+ xdebug_stop_function_monitor();
+
+ foreach ($functions as $function) {
+ if (!$excludeList->isExcluded($function['filename'])) {
+ $this->addFailure(
+ $test,
+ new RiskyTestError(
+ sprintf(
+ '%s() used in %s:%s',
+ $function['function'],
+ $function['filename'],
+ $function['lineno']
+ )
+ ),
+ $time
+ );
+ }
+ }
+ }
+
+ if ($this->beStrictAboutTestsThatDoNotTestAnything &&
+ $test->getNumAssertions() === 0) {
+ $risky = true;
+ }
+
+ if ($this->forceCoversAnnotation && !$error && !$failure && !$warning && !$incomplete && !$skipped && !$risky) {
+ $annotations = TestUtil::parseTestMethodAnnotations(
+ get_class($test),
+ $test->getName(false)
+ );
+
+ if (!isset($annotations['class']['covers']) &&
+ !isset($annotations['method']['covers']) &&
+ !isset($annotations['class']['coversNothing']) &&
+ !isset($annotations['method']['coversNothing'])) {
+ $this->addFailure(
+ $test,
+ new MissingCoversAnnotationException(
+ 'This test does not have a @covers annotation but is expected to have one'
+ ),
+ $time
+ );
+
+ $risky = true;
+ }
+ }
+
+ if ($collectCodeCoverage) {
+ $append = !$risky && !$incomplete && !$skipped;
+ $linesToBeCovered = [];
+ $linesToBeUsed = [];
+
+ if ($append && $test instanceof TestCase) {
+ try {
+ $linesToBeCovered = TestUtil::getLinesToBeCovered(
+ get_class($test),
+ $test->getName(false)
+ );
+
+ $linesToBeUsed = TestUtil::getLinesToBeUsed(
+ get_class($test),
+ $test->getName(false)
+ );
+ } catch (InvalidCoversTargetException $cce) {
+ $this->addWarning(
+ $test,
+ new Warning(
+ $cce->getMessage()
+ ),
+ $time
+ );
+ }
+ }
+
+ try {
+ $this->codeCoverage->stop(
+ $append,
+ $linesToBeCovered,
+ $linesToBeUsed
+ );
+ } catch (UnintentionallyCoveredCodeException $cce) {
+ $unintentionallyCoveredCodeError = new UnintentionallyCoveredCodeError(
+ 'This test executed code that is not listed as code to be covered or used:' .
+ PHP_EOL . $cce->getMessage()
+ );
+ } catch (OriginalCodeCoverageException $cce) {
+ $error = true;
+
+ $e = $e ?? $cce;
+ }
+ }
+
+ if (isset($errorHandler)) {
+ $errorHandler->unregister();
+
+ unset($errorHandler);
+ }
+
+ if ($error) {
+ $this->addError($test, $e, $time);
+ } elseif ($failure) {
+ $this->addFailure($test, $e, $time);
+ } elseif ($warning) {
+ $this->addWarning($test, $e, $time);
+ } elseif (isset($unintentionallyCoveredCodeError)) {
+ $this->addFailure(
+ $test,
+ $unintentionallyCoveredCodeError,
+ $time
+ );
+ } elseif ($this->beStrictAboutTestsThatDoNotTestAnything &&
+ !$test->doesNotPerformAssertions() &&
+ $test->getNumAssertions() === 0) {
+ try {
+ $reflected = new ReflectionClass($test);
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ $name = $test->getName(false);
+
+ if ($name && $reflected->hasMethod($name)) {
+ try {
+ $reflected = $reflected->getMethod($name);
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ $this->addFailure(
+ $test,
+ new RiskyTestError(
+ sprintf(
+ "This test did not perform any assertions\n\n%s:%d",
+ $reflected->getFileName(),
+ $reflected->getStartLine()
+ )
+ ),
+ $time
+ );
+ } elseif ($this->beStrictAboutTestsThatDoNotTestAnything &&
+ $test->doesNotPerformAssertions() &&
+ $test->getNumAssertions() > 0) {
+ $this->addFailure(
+ $test,
+ new RiskyTestError(
+ sprintf(
+ 'This test is annotated with "@doesNotPerformAssertions" but performed %d assertions',
+ $test->getNumAssertions()
+ )
+ ),
+ $time
+ );
+ } elseif ($this->beStrictAboutOutputDuringTests && $test->hasOutput()) {
+ $this->addFailure(
+ $test,
+ new OutputError(
+ sprintf(
+ 'This test printed output: %s',
+ $test->getActualOutput()
+ )
+ ),
+ $time
+ );
+ } elseif ($this->beStrictAboutTodoAnnotatedTests && $test instanceof TestCase) {
+ $annotations = TestUtil::parseTestMethodAnnotations(
+ get_class($test),
+ $test->getName(false)
+ );
+
+ if (isset($annotations['method']['todo'])) {
+ $this->addFailure(
+ $test,
+ new RiskyTestError(
+ 'Test method is annotated with @todo'
+ ),
+ $time
+ );
+ }
+ }
+
+ $this->endTest($test, $time);
+ }
+
+ /**
+ * Gets the number of run tests.
+ */
+ public function count(): int
+ {
+ return $this->runTests;
+ }
+
+ /**
+ * Checks whether the test run should stop.
+ */
+ public function shouldStop(): bool
+ {
+ return $this->stop;
+ }
+
+ /**
+ * Marks that the test run should stop.
+ */
+ public function stop(): void
+ {
+ $this->stop = true;
+ }
+
+ /**
+ * Returns the code coverage object.
+ */
+ public function getCodeCoverage(): ?CodeCoverage
+ {
+ return $this->codeCoverage;
+ }
+
+ /**
+ * Sets the code coverage object.
+ */
+ public function setCodeCoverage(CodeCoverage $codeCoverage): void
+ {
+ $this->codeCoverage = $codeCoverage;
+ }
+
+ /**
+ * Enables or disables the deprecation-to-exception conversion.
+ */
+ public function convertDeprecationsToExceptions(bool $flag): void
+ {
+ $this->convertDeprecationsToExceptions = $flag;
+ }
+
+ /**
+ * Returns the deprecation-to-exception conversion setting.
+ */
+ public function getConvertDeprecationsToExceptions(): bool
+ {
+ return $this->convertDeprecationsToExceptions;
+ }
+
+ /**
+ * Enables or disables the error-to-exception conversion.
+ */
+ public function convertErrorsToExceptions(bool $flag): void
+ {
+ $this->convertErrorsToExceptions = $flag;
+ }
+
+ /**
+ * Returns the error-to-exception conversion setting.
+ */
+ public function getConvertErrorsToExceptions(): bool
+ {
+ return $this->convertErrorsToExceptions;
+ }
+
+ /**
+ * Enables or disables the notice-to-exception conversion.
+ */
+ public function convertNoticesToExceptions(bool $flag): void
+ {
+ $this->convertNoticesToExceptions = $flag;
+ }
+
+ /**
+ * Returns the notice-to-exception conversion setting.
+ */
+ public function getConvertNoticesToExceptions(): bool
+ {
+ return $this->convertNoticesToExceptions;
+ }
+
+ /**
+ * Enables or disables the warning-to-exception conversion.
+ */
+ public function convertWarningsToExceptions(bool $flag): void
+ {
+ $this->convertWarningsToExceptions = $flag;
+ }
+
+ /**
+ * Returns the warning-to-exception conversion setting.
+ */
+ public function getConvertWarningsToExceptions(): bool
+ {
+ return $this->convertWarningsToExceptions;
+ }
+
+ /**
+ * Enables or disables the stopping when an error occurs.
+ */
+ public function stopOnError(bool $flag): void
+ {
+ $this->stopOnError = $flag;
+ }
+
+ /**
+ * Enables or disables the stopping when a failure occurs.
+ */
+ public function stopOnFailure(bool $flag): void
+ {
+ $this->stopOnFailure = $flag;
+ }
+
+ /**
+ * Enables or disables the stopping when a warning occurs.
+ */
+ public function stopOnWarning(bool $flag): void
+ {
+ $this->stopOnWarning = $flag;
+ }
+
+ public function beStrictAboutTestsThatDoNotTestAnything(bool $flag): void
+ {
+ $this->beStrictAboutTestsThatDoNotTestAnything = $flag;
+ }
+
+ public function isStrictAboutTestsThatDoNotTestAnything(): bool
+ {
+ return $this->beStrictAboutTestsThatDoNotTestAnything;
+ }
+
+ public function beStrictAboutOutputDuringTests(bool $flag): void
+ {
+ $this->beStrictAboutOutputDuringTests = $flag;
+ }
+
+ public function isStrictAboutOutputDuringTests(): bool
+ {
+ return $this->beStrictAboutOutputDuringTests;
+ }
+
+ public function beStrictAboutResourceUsageDuringSmallTests(bool $flag): void
+ {
+ $this->beStrictAboutResourceUsageDuringSmallTests = $flag;
+ }
+
+ public function isStrictAboutResourceUsageDuringSmallTests(): bool
+ {
+ return $this->beStrictAboutResourceUsageDuringSmallTests;
+ }
+
+ public function enforceTimeLimit(bool $flag): void
+ {
+ $this->enforceTimeLimit = $flag;
+ }
+
+ public function enforcesTimeLimit(): bool
+ {
+ return $this->enforceTimeLimit;
+ }
+
+ public function beStrictAboutTodoAnnotatedTests(bool $flag): void
+ {
+ $this->beStrictAboutTodoAnnotatedTests = $flag;
+ }
+
+ public function isStrictAboutTodoAnnotatedTests(): bool
+ {
+ return $this->beStrictAboutTodoAnnotatedTests;
+ }
+
+ public function forceCoversAnnotation(): void
+ {
+ $this->forceCoversAnnotation = true;
+ }
+
+ public function forcesCoversAnnotation(): bool
+ {
+ return $this->forceCoversAnnotation;
+ }
+
+ /**
+ * Enables or disables the stopping for risky tests.
+ */
+ public function stopOnRisky(bool $flag): void
+ {
+ $this->stopOnRisky = $flag;
+ }
+
+ /**
+ * Enables or disables the stopping for incomplete tests.
+ */
+ public function stopOnIncomplete(bool $flag): void
+ {
+ $this->stopOnIncomplete = $flag;
+ }
+
+ /**
+ * Enables or disables the stopping for skipped tests.
+ */
+ public function stopOnSkipped(bool $flag): void
+ {
+ $this->stopOnSkipped = $flag;
+ }
+
+ /**
+ * Enables or disables the stopping for defects: error, failure, warning.
+ */
+ public function stopOnDefect(bool $flag): void
+ {
+ $this->stopOnDefect = $flag;
+ }
+
+ /**
+ * Returns the time spent running the tests.
+ */
+ public function time(): float
+ {
+ return $this->time;
+ }
+
+ /**
+ * Returns whether the entire test was successful or not.
+ */
+ public function wasSuccessful(): bool
+ {
+ return $this->wasSuccessfulIgnoringWarnings() && empty($this->warnings);
+ }
+
+ public function wasSuccessfulIgnoringWarnings(): bool
+ {
+ return empty($this->errors) && empty($this->failures);
+ }
+
+ public function wasSuccessfulAndNoTestIsRiskyOrSkippedOrIncomplete(): bool
+ {
+ return $this->wasSuccessful() && $this->allHarmless() && $this->allCompletelyImplemented() && $this->noneSkipped();
+ }
+
+ /**
+ * Sets the default timeout for tests.
+ */
+ public function setDefaultTimeLimit(int $timeout): void
+ {
+ $this->defaultTimeLimit = $timeout;
+ }
+
+ /**
+ * Sets the timeout for small tests.
+ */
+ public function setTimeoutForSmallTests(int $timeout): void
+ {
+ $this->timeoutForSmallTests = $timeout;
+ }
+
+ /**
+ * Sets the timeout for medium tests.
+ */
+ public function setTimeoutForMediumTests(int $timeout): void
+ {
+ $this->timeoutForMediumTests = $timeout;
+ }
+
+ /**
+ * Sets the timeout for large tests.
+ */
+ public function setTimeoutForLargeTests(int $timeout): void
+ {
+ $this->timeoutForLargeTests = $timeout;
+ }
+
+ /**
+ * Returns the set timeout for large tests.
+ */
+ public function getTimeoutForLargeTests(): int
+ {
+ return $this->timeoutForLargeTests;
+ }
+
+ public function setRegisterMockObjectsFromTestArgumentsRecursively(bool $flag): void
+ {
+ $this->registerMockObjectsFromTestArgumentsRecursively = $flag;
+ }
+
+ private function recordError(Test $test, Throwable $t): void
+ {
+ $this->errors[] = new TestFailure($test, $t);
+ }
+
+ private function recordNotImplemented(Test $test, Throwable $t): void
+ {
+ $this->notImplemented[] = new TestFailure($test, $t);
+ }
+
+ private function recordRisky(Test $test, Throwable $t): void
+ {
+ $this->risky[] = new TestFailure($test, $t);
+ }
+
+ private function recordSkipped(Test $test, Throwable $t): void
+ {
+ $this->skipped[] = new TestFailure($test, $t);
+ }
+
+ private function recordWarning(Test $test, Throwable $t): void
+ {
+ $this->warnings[] = new TestFailure($test, $t);
+ }
+
+ private function shouldTimeLimitBeEnforced(int $size): bool
+ {
+ if (!$this->enforceTimeLimit) {
+ return false;
+ }
+
+ if (!(($this->defaultTimeLimit || $size !== TestUtil::UNKNOWN))) {
+ return false;
+ }
+
+ if (!extension_loaded('pcntl')) {
+ return false;
+ }
+
+ if (!class_exists(Invoker::class)) {
+ return false;
+ }
+
+ if (extension_loaded('xdebug') && xdebug_is_debugger_active()) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestSuite.php b/vendor/phpunit/phpunit/src/Framework/TestSuite.php
new file mode 100644
index 000000000..0bb81844b
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/TestSuite.php
@@ -0,0 +1,914 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use const PHP_EOL;
+use function array_keys;
+use function array_map;
+use function array_merge;
+use function array_unique;
+use function basename;
+use function call_user_func;
+use function class_exists;
+use function count;
+use function dirname;
+use function get_declared_classes;
+use function implode;
+use function is_bool;
+use function is_callable;
+use function is_file;
+use function is_object;
+use function is_string;
+use function method_exists;
+use function preg_match;
+use function preg_quote;
+use function sprintf;
+use function strpos;
+use function substr;
+use Iterator;
+use IteratorAggregate;
+use PHPUnit\Runner\BaseTestRunner;
+use PHPUnit\Runner\Filter\Factory;
+use PHPUnit\Runner\PhptTestCase;
+use PHPUnit\Util\FileLoader;
+use PHPUnit\Util\Test as TestUtil;
+use ReflectionClass;
+use ReflectionException;
+use ReflectionMethod;
+use Throwable;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+class TestSuite implements IteratorAggregate, Reorderable, SelfDescribing, Test
+{
+ /**
+ * Enable or disable the backup and restoration of the $GLOBALS array.
+ *
+ * @var bool
+ */
+ protected $backupGlobals;
+
+ /**
+ * Enable or disable the backup and restoration of static attributes.
+ *
+ * @var bool
+ */
+ protected $backupStaticAttributes;
+
+ /**
+ * @var bool
+ */
+ protected $runTestInSeparateProcess = false;
+
+ /**
+ * The name of the test suite.
+ *
+ * @var string
+ */
+ protected $name = '';
+
+ /**
+ * The test groups of the test suite.
+ *
+ * @psalm-var array<string,list<Test>>
+ */
+ protected $groups = [];
+
+ /**
+ * The tests in the test suite.
+ *
+ * @var Test[]
+ */
+ protected $tests = [];
+
+ /**
+ * The number of tests in the test suite.
+ *
+ * @var int
+ */
+ protected $numTests = -1;
+
+ /**
+ * @var bool
+ */
+ protected $testCase = false;
+
+ /**
+ * @var string[]
+ */
+ protected $foundClasses = [];
+
+ /**
+ * @var null|list<ExecutionOrderDependency>
+ */
+ protected $providedTests;
+
+ /**
+ * @var null|list<ExecutionOrderDependency>
+ */
+ protected $requiredTests;
+
+ /**
+ * @var bool
+ */
+ private $beStrictAboutChangesToGlobalState;
+
+ /**
+ * @var Factory
+ */
+ private $iteratorFilter;
+
+ /**
+ * @var int
+ */
+ private $declaredClassesPointer;
+
+ /**
+ * @psalm-var array<int,string>
+ */
+ private $warnings = [];
+
+ /**
+ * Constructs a new TestSuite.
+ *
+ * - PHPUnit\Framework\TestSuite() constructs an empty TestSuite.
+ *
+ * - PHPUnit\Framework\TestSuite(ReflectionClass) constructs a
+ * TestSuite from the given class.
+ *
+ * - PHPUnit\Framework\TestSuite(ReflectionClass, String)
+ * constructs a TestSuite from the given class with the given
+ * name.
+ *
+ * - PHPUnit\Framework\TestSuite(String) either constructs a
+ * TestSuite from the given class (if the passed string is the
+ * name of an existing class) or constructs an empty TestSuite
+ * with the given name.
+ *
+ * @param ReflectionClass|string $theClass
+ *
+ * @throws Exception
+ */
+ public function __construct($theClass = '', string $name = '')
+ {
+ if (!is_string($theClass) && !$theClass instanceof ReflectionClass) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'ReflectionClass object or string'
+ );
+ }
+
+ $this->declaredClassesPointer = count(get_declared_classes());
+
+ if (!$theClass instanceof ReflectionClass) {
+ if (class_exists($theClass, true)) {
+ if ($name === '') {
+ $name = $theClass;
+ }
+
+ try {
+ $theClass = new ReflectionClass($theClass);
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ } else {
+ $this->setName($theClass);
+
+ return;
+ }
+ }
+
+ if (!$theClass->isSubclassOf(TestCase::class)) {
+ $this->setName((string) $theClass);
+
+ return;
+ }
+
+ if ($name !== '') {
+ $this->setName($name);
+ } else {
+ $this->setName($theClass->getName());
+ }
+
+ $constructor = $theClass->getConstructor();
+
+ if ($constructor !== null &&
+ !$constructor->isPublic()) {
+ $this->addTest(
+ new WarningTestCase(
+ sprintf(
+ 'Class "%s" has no public constructor.',
+ $theClass->getName()
+ )
+ )
+ );
+
+ return;
+ }
+
+ foreach ($theClass->getMethods() as $method) {
+ if ($method->getDeclaringClass()->getName() === Assert::class) {
+ continue;
+ }
+
+ if ($method->getDeclaringClass()->getName() === TestCase::class) {
+ continue;
+ }
+
+ if (!TestUtil::isTestMethod($method)) {
+ continue;
+ }
+
+ $this->addTestMethod($theClass, $method);
+ }
+
+ if (empty($this->tests)) {
+ $this->addTest(
+ new WarningTestCase(
+ sprintf(
+ 'No tests found in class "%s".',
+ $theClass->getName()
+ )
+ )
+ );
+ }
+
+ $this->testCase = true;
+ }
+
+ /**
+ * Returns a string representation of the test suite.
+ */
+ public function toString(): string
+ {
+ return $this->getName();
+ }
+
+ /**
+ * Adds a test to the suite.
+ *
+ * @param array $groups
+ */
+ public function addTest(Test $test, $groups = []): void
+ {
+ try {
+ $class = new ReflectionClass($test);
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ if (!$class->isAbstract()) {
+ $this->tests[] = $test;
+ $this->clearCaches();
+
+ if ($test instanceof self && empty($groups)) {
+ $groups = $test->getGroups();
+ }
+
+ if ($this->containsOnlyVirtualGroups($groups)) {
+ $groups[] = 'default';
+ }
+
+ foreach ($groups as $group) {
+ if (!isset($this->groups[$group])) {
+ $this->groups[$group] = [$test];
+ } else {
+ $this->groups[$group][] = $test;
+ }
+ }
+
+ if ($test instanceof TestCase) {
+ $test->setGroups($groups);
+ }
+ }
+ }
+
+ /**
+ * Adds the tests from the given class to the suite.
+ *
+ * @psalm-param object|class-string $testClass
+ *
+ * @throws Exception
+ */
+ public function addTestSuite($testClass): void
+ {
+ if (!(is_object($testClass) || (is_string($testClass) && class_exists($testClass)))) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'class name or object'
+ );
+ }
+
+ if (!is_object($testClass)) {
+ try {
+ $testClass = new ReflectionClass($testClass);
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ if ($testClass instanceof self) {
+ $this->addTest($testClass);
+ } elseif ($testClass instanceof ReflectionClass) {
+ $suiteMethod = false;
+
+ if (!$testClass->isAbstract() && $testClass->hasMethod(BaseTestRunner::SUITE_METHODNAME)) {
+ try {
+ $method = $testClass->getMethod(
+ BaseTestRunner::SUITE_METHODNAME
+ );
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ if ($method->isStatic()) {
+ $this->addTest(
+ $method->invoke(null, $testClass->getName())
+ );
+
+ $suiteMethod = true;
+ }
+ }
+
+ if (!$suiteMethod && !$testClass->isAbstract() && $testClass->isSubclassOf(TestCase::class)) {
+ $this->addTest(new self($testClass));
+ }
+ } else {
+ throw new Exception;
+ }
+ }
+
+ public function addWarning(string $warning): void
+ {
+ $this->warnings[] = $warning;
+ }
+
+ /**
+ * Wraps both <code>addTest()</code> and <code>addTestSuite</code>
+ * as well as the separate import statements for the user's convenience.
+ *
+ * If the named file cannot be read or there are no new tests that can be
+ * added, a <code>PHPUnit\Framework\WarningTestCase</code> will be created instead,
+ * leaving the current test run untouched.
+ *
+ * @throws Exception
+ */
+ public function addTestFile(string $filename): void
+ {
+ if (is_file($filename) && substr($filename, -5) === '.phpt') {
+ $this->addTest(new PhptTestCase($filename));
+
+ $this->declaredClassesPointer = count(get_declared_classes());
+
+ return;
+ }
+
+ $numTests = count($this->tests);
+
+ // The given file may contain further stub classes in addition to the
+ // test class itself. Figure out the actual test class.
+ $filename = FileLoader::checkAndLoad($filename);
+ $newClasses = array_slice(get_declared_classes(), $this->declaredClassesPointer);
+
+ // The diff is empty in case a parent class (with test methods) is added
+ // AFTER a child class that inherited from it. To account for that case,
+ // accumulate all discovered classes, so the parent class may be found in
+ // a later invocation.
+ if (!empty($newClasses)) {
+ // On the assumption that test classes are defined first in files,
+ // process discovered classes in approximate LIFO order, so as to
+ // avoid unnecessary reflection.
+ $this->foundClasses = array_merge($newClasses, $this->foundClasses);
+ $this->declaredClassesPointer = count(get_declared_classes());
+ }
+
+ // The test class's name must match the filename, either in full, or as
+ // a PEAR/PSR-0 prefixed short name ('NameSpace_ShortName'), or as a
+ // PSR-1 local short name ('NameSpace\ShortName'). The comparison must be
+ // anchored to prevent false-positive matches (e.g., 'OtherShortName').
+ $shortName = basename($filename, '.php');
+ $shortNameRegEx = '/(?:^|_|\\\\)' . preg_quote($shortName, '/') . '$/';
+
+ foreach ($this->foundClasses as $i => $className) {
+ if (preg_match($shortNameRegEx, $className)) {
+ try {
+ $class = new ReflectionClass($className);
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ if ($class->getFileName() == $filename) {
+ $newClasses = [$className];
+ unset($this->foundClasses[$i]);
+
+ break;
+ }
+ }
+ }
+
+ foreach ($newClasses as $className) {
+ try {
+ $class = new ReflectionClass($className);
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ if (dirname($class->getFileName()) === __DIR__) {
+ continue;
+ }
+
+ if (!$class->isAbstract()) {
+ if ($class->hasMethod(BaseTestRunner::SUITE_METHODNAME)) {
+ try {
+ $method = $class->getMethod(
+ BaseTestRunner::SUITE_METHODNAME
+ );
+ // @codeCoverageIgnoreStart
+ } catch (ReflectionException $e) {
+ throw new Exception(
+ $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ // @codeCoverageIgnoreEnd
+
+ if ($method->isStatic()) {
+ $this->addTest($method->invoke(null, $className));
+ }
+ } elseif ($class->implementsInterface(Test::class)) {
+ $expectedClassName = $shortName;
+
+ if (($pos = strpos($expectedClassName, '.')) !== false) {
+ $expectedClassName = substr(
+ $expectedClassName,
+ 0,
+ $pos
+ );
+ }
+
+ if ($class->getShortName() !== $expectedClassName) {
+ $this->addWarning(
+ sprintf(
+ "Test case class not matching filename is deprecated\n in %s\n Class name was '%s', expected '%s'",
+ $filename,
+ $class->getShortName(),
+ $expectedClassName
+ )
+ );
+ }
+
+ $this->addTestSuite($class);
+ }
+ }
+ }
+
+ if (count($this->tests) > ++$numTests) {
+ $this->addWarning(
+ sprintf(
+ "Multiple test case classes per file is deprecated\n in %s",
+ $filename
+ )
+ );
+ }
+
+ $this->numTests = -1;
+ }
+
+ /**
+ * Wrapper for addTestFile() that adds multiple test files.
+ *
+ * @throws Exception
+ */
+ public function addTestFiles(iterable $fileNames): void
+ {
+ foreach ($fileNames as $filename) {
+ $this->addTestFile((string) $filename);
+ }
+ }
+
+ /**
+ * Counts the number of test cases that will be run by this test.
+ *
+ * @todo refactor usage of numTests in DefaultResultPrinter
+ */
+ public function count(): int
+ {
+ $this->numTests = 0;
+
+ foreach ($this as $test) {
+ $this->numTests += count($test);
+ }
+
+ return $this->numTests;
+ }
+
+ /**
+ * Returns the name of the suite.
+ */
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ /**
+ * Returns the test groups of the suite.
+ *
+ * @psalm-return list<string>
+ */
+ public function getGroups(): array
+ {
+ return array_map(
+ static function ($key): string
+ {
+ return (string) $key;
+ },
+ array_keys($this->groups)
+ );
+ }
+
+ public function getGroupDetails(): array
+ {
+ return $this->groups;
+ }
+
+ /**
+ * Set tests groups of the test case.
+ */
+ public function setGroupDetails(array $groups): void
+ {
+ $this->groups = $groups;
+ }
+
+ /**
+ * Runs the tests and collects their result in a TestResult.
+ *
+ * @throws \PHPUnit\Framework\CodeCoverageException
+ * @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException
+ * @throws \SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException
+ * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @throws Warning
+ */
+ public function run(TestResult $result = null): TestResult
+ {
+ if ($result === null) {
+ $result = $this->createResult();
+ }
+
+ if (count($this) === 0) {
+ return $result;
+ }
+
+ /** @psalm-var class-string $className */
+ $className = $this->name;
+ $hookMethods = TestUtil::getHookMethods($className);
+
+ $result->startTestSuite($this);
+
+ $test = null;
+
+ if ($this->testCase && class_exists($this->name, false)) {
+ try {
+ foreach ($hookMethods['beforeClass'] as $beforeClassMethod) {
+ if (method_exists($this->name, $beforeClassMethod)) {
+ if ($missingRequirements = TestUtil::getMissingRequirements($this->name, $beforeClassMethod)) {
+ $this->markTestSuiteSkipped(implode(PHP_EOL, $missingRequirements));
+ }
+
+ call_user_func([$this->name, $beforeClassMethod]);
+ }
+ }
+ } catch (SkippedTestSuiteError $error) {
+ foreach ($this->tests() as $test) {
+ $result->startTest($test);
+ $result->addFailure($test, $error, 0);
+ $result->endTest($test, 0);
+ }
+
+ $result->endTestSuite($this);
+
+ return $result;
+ } catch (Throwable $t) {
+ $errorAdded = false;
+
+ foreach ($this->tests() as $test) {
+ if ($result->shouldStop()) {
+ break;
+ }
+
+ $result->startTest($test);
+
+ if (!$errorAdded) {
+ $result->addError($test, $t, 0);
+
+ $errorAdded = true;
+ } else {
+ $result->addFailure(
+ $test,
+ new SkippedTestError('Test skipped because of an error in hook method'),
+ 0
+ );
+ }
+
+ $result->endTest($test, 0);
+ }
+
+ $result->endTestSuite($this);
+
+ return $result;
+ }
+ }
+
+ foreach ($this as $test) {
+ if ($result->shouldStop()) {
+ break;
+ }
+
+ if ($test instanceof TestCase || $test instanceof self) {
+ $test->setBeStrictAboutChangesToGlobalState($this->beStrictAboutChangesToGlobalState);
+ $test->setBackupGlobals($this->backupGlobals);
+ $test->setBackupStaticAttributes($this->backupStaticAttributes);
+ $test->setRunTestInSeparateProcess($this->runTestInSeparateProcess);
+ }
+
+ $test->run($result);
+ }
+
+ if ($this->testCase && class_exists($this->name, false)) {
+ foreach ($hookMethods['afterClass'] as $afterClassMethod) {
+ if (method_exists($this->name, $afterClassMethod)) {
+ try {
+ call_user_func([$this->name, $afterClassMethod]);
+ } catch (Throwable $t) {
+ $message = "Exception in {$this->name}::{$afterClassMethod}" . PHP_EOL . $t->getMessage();
+ $error = new SyntheticError($message, 0, $t->getFile(), $t->getLine(), $t->getTrace());
+
+ $placeholderTest = clone $test;
+ $placeholderTest->setName($afterClassMethod);
+
+ $result->startTest($placeholderTest);
+ $result->addFailure($placeholderTest, $error, 0);
+ $result->endTest($placeholderTest, 0);
+ }
+ }
+ }
+ }
+
+ $result->endTestSuite($this);
+
+ return $result;
+ }
+
+ public function setRunTestInSeparateProcess(bool $runTestInSeparateProcess): void
+ {
+ $this->runTestInSeparateProcess = $runTestInSeparateProcess;
+ }
+
+ public function setName(string $name): void
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * Returns the tests as an enumeration.
+ *
+ * @return Test[]
+ */
+ public function tests(): array
+ {
+ return $this->tests;
+ }
+
+ /**
+ * Set tests of the test suite.
+ *
+ * @param Test[] $tests
+ */
+ public function setTests(array $tests): void
+ {
+ $this->tests = $tests;
+ }
+
+ /**
+ * Mark the test suite as skipped.
+ *
+ * @param string $message
+ *
+ * @throws SkippedTestSuiteError
+ *
+ * @psalm-return never-return
+ */
+ public function markTestSuiteSkipped($message = ''): void
+ {
+ throw new SkippedTestSuiteError($message);
+ }
+
+ /**
+ * @param bool $beStrictAboutChangesToGlobalState
+ */
+ public function setBeStrictAboutChangesToGlobalState($beStrictAboutChangesToGlobalState): void
+ {
+ if (null === $this->beStrictAboutChangesToGlobalState && is_bool($beStrictAboutChangesToGlobalState)) {
+ $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState;
+ }
+ }
+
+ /**
+ * @param bool $backupGlobals
+ */
+ public function setBackupGlobals($backupGlobals): void
+ {
+ if (null === $this->backupGlobals && is_bool($backupGlobals)) {
+ $this->backupGlobals = $backupGlobals;
+ }
+ }
+
+ /**
+ * @param bool $backupStaticAttributes
+ */
+ public function setBackupStaticAttributes($backupStaticAttributes): void
+ {
+ if (null === $this->backupStaticAttributes && is_bool($backupStaticAttributes)) {
+ $this->backupStaticAttributes = $backupStaticAttributes;
+ }
+ }
+
+ /**
+ * Returns an iterator for this test suite.
+ */
+ public function getIterator(): Iterator
+ {
+ $iterator = new TestSuiteIterator($this);
+
+ if ($this->iteratorFilter !== null) {
+ $iterator = $this->iteratorFilter->factory($iterator, $this);
+ }
+
+ return $iterator;
+ }
+
+ public function injectFilter(Factory $filter): void
+ {
+ $this->iteratorFilter = $filter;
+
+ foreach ($this as $test) {
+ if ($test instanceof self) {
+ $test->injectFilter($filter);
+ }
+ }
+ }
+
+ /**
+ * @psalm-return array<int,string>
+ */
+ public function warnings(): array
+ {
+ return array_unique($this->warnings);
+ }
+
+ /**
+ * @return list<ExecutionOrderDependency>
+ */
+ public function provides(): array
+ {
+ if ($this->providedTests === null) {
+ $this->providedTests = [];
+
+ if (is_callable($this->sortId(), true)) {
+ $this->providedTests[] = new ExecutionOrderDependency($this->sortId());
+ }
+
+ foreach ($this->tests as $test) {
+ if (!($test instanceof Reorderable)) {
+ // @codeCoverageIgnoreStart
+ continue;
+ // @codeCoverageIgnoreEnd
+ }
+ $this->providedTests = ExecutionOrderDependency::mergeUnique($this->providedTests, $test->provides());
+ }
+ }
+
+ return $this->providedTests;
+ }
+
+ /**
+ * @return list<ExecutionOrderDependency>
+ */
+ public function requires(): array
+ {
+ if ($this->requiredTests === null) {
+ $this->requiredTests = [];
+
+ foreach ($this->tests as $test) {
+ if (!($test instanceof Reorderable)) {
+ // @codeCoverageIgnoreStart
+ continue;
+ // @codeCoverageIgnoreEnd
+ }
+ $this->requiredTests = ExecutionOrderDependency::mergeUnique(
+ ExecutionOrderDependency::filterInvalid($this->requiredTests),
+ $test->requires()
+ );
+ }
+
+ $this->requiredTests = ExecutionOrderDependency::diff($this->requiredTests, $this->provides());
+ }
+
+ return $this->requiredTests;
+ }
+
+ public function sortId(): string
+ {
+ return $this->getName() . '::class';
+ }
+
+ /**
+ * Creates a default TestResult object.
+ */
+ protected function createResult(): TestResult
+ {
+ return new TestResult;
+ }
+
+ /**
+ * @throws Exception
+ */
+ protected function addTestMethod(ReflectionClass $class, ReflectionMethod $method): void
+ {
+ $methodName = $method->getName();
+
+ $test = (new TestBuilder)->build($class, $methodName);
+
+ if ($test instanceof TestCase || $test instanceof DataProviderTestSuite) {
+ $test->setDependencies(
+ TestUtil::getDependencies($class->getName(), $methodName)
+ );
+ }
+
+ $this->addTest(
+ $test,
+ TestUtil::getGroups($class->getName(), $methodName)
+ );
+ }
+
+ private function clearCaches(): void
+ {
+ $this->numTests = -1;
+ $this->providedTests = null;
+ $this->requiredTests = null;
+ }
+
+ private function containsOnlyVirtualGroups(array $groups): bool
+ {
+ foreach ($groups as $group) {
+ if (strpos($group, '__phpunit_') !== 0) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestSuiteIterator.php b/vendor/phpunit/phpunit/src/Framework/TestSuiteIterator.php
new file mode 100644
index 000000000..e351622f3
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/TestSuiteIterator.php
@@ -0,0 +1,83 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use function assert;
+use function count;
+use RecursiveIterator;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class TestSuiteIterator implements RecursiveIterator
+{
+ /**
+ * @var int
+ */
+ private $position = 0;
+
+ /**
+ * @var Test[]
+ */
+ private $tests;
+
+ public function __construct(TestSuite $testSuite)
+ {
+ $this->tests = $testSuite->tests();
+ }
+
+ public function rewind(): void
+ {
+ $this->position = 0;
+ }
+
+ public function valid(): bool
+ {
+ return $this->position < count($this->tests);
+ }
+
+ public function key(): int
+ {
+ return $this->position;
+ }
+
+ public function current(): Test
+ {
+ return $this->tests[$this->position];
+ }
+
+ public function next(): void
+ {
+ $this->position++;
+ }
+
+ /**
+ * @throws NoChildTestSuiteException
+ */
+ public function getChildren(): self
+ {
+ if (!$this->hasChildren()) {
+ throw new NoChildTestSuiteException(
+ 'The current item is not a TestSuite instance and therefore does not have any children.'
+ );
+ }
+
+ $current = $this->current();
+
+ assert($current instanceof TestSuite);
+
+ return new self($current);
+ }
+
+ public function hasChildren(): bool
+ {
+ return $this->valid() && $this->current() instanceof TestSuite;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/WarningTestCase.php b/vendor/phpunit/phpunit/src/Framework/WarningTestCase.php
new file mode 100644
index 000000000..e1e41bc44
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/WarningTestCase.php
@@ -0,0 +1,66 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <[email protected]>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+/**
+ * @internal This class is not covered by the backward compatibility promise for PHPUnit
+ */
+final class WarningTestCase extends TestCase
+{
+ /**
+ * @var bool
+ */
+ protected $backupGlobals = false;
+
+ /**
+ * @var bool
+ */
+ protected $backupStaticAttributes = false;
+
+ /**
+ * @var bool
+ */
+ protected $runTestInSeparateProcess = false;
+
+ /**
+ * @var string
+ */
+ private $message;
+
+ public function __construct(string $message = '')
+ {
+ $this->message = $message;
+
+ parent::__construct('Warning');
+ }
+
+ public function getMessage(): string
+ {
+ return $this->message;
+ }
+
+ /**
+ * Returns a string representation of the test case.
+ */
+ public function toString(): string
+ {
+ return 'Warning';
+ }
+
+ /**
+ * @throws Exception
+ *
+ * @psalm-return never-return
+ */
+ protected function runTest(): void
+ {
+ throw new Warning($this->message);
+ }
+}