Repository: webmozarts/assert Branch: master Commit: ff31ad6efc62 Files: 124 Total size: 356.6 KB Directory structure: gitextract_vsvow73w/ ├── .editorconfig ├── .gitattributes ├── .github/ │ └── workflows/ │ └── ci.yaml ├── .gitignore ├── .php-cs-fixer.php ├── CHANGELOG.md ├── LICENSE ├── README.md ├── bin/ │ ├── generate.php │ └── src/ │ └── MixinGenerator.php ├── composer.json ├── phpunit.xml.dist ├── psalm.xml ├── src/ │ ├── Assert.php │ ├── InvalidArgumentException.php │ └── Mixin.php ├── tests/ │ ├── AssertTest.php │ ├── DummyEnum.php │ ├── ProjectCodeTest.php │ └── static-analysis/ │ ├── assert-alnum.php │ ├── assert-alpha.php │ ├── assert-boolean.php │ ├── assert-classExists.php │ ├── assert-contains.php │ ├── assert-count.php │ ├── assert-countBetween.php │ ├── assert-digits.php │ ├── assert-directory.php │ ├── assert-email.php │ ├── assert-endsWith.php │ ├── assert-eq.php │ ├── assert-false.php │ ├── assert-file.php │ ├── assert-fileExists.php │ ├── assert-float.php │ ├── assert-greaterThan.php │ ├── assert-greaterThanEq.php │ ├── assert-implementsInterface.php │ ├── assert-inArray.php │ ├── assert-integer.php │ ├── assert-integerish.php │ ├── assert-interfaceExists.php │ ├── assert-ip.php │ ├── assert-ipv4.php │ ├── assert-ipv6.php │ ├── assert-isAOf.php │ ├── assert-isAnyOf.php │ ├── assert-isArray.php │ ├── assert-isArrayAccessible.php │ ├── assert-isCallable.php │ ├── assert-isCountable.php │ ├── assert-isEmpty.php │ ├── assert-isInitialized.php │ ├── assert-isInstanceOf.php │ ├── assert-isInstanceOfAny.php │ ├── assert-isIterable.php │ ├── assert-isList.php │ ├── assert-isMap.php │ ├── assert-isNonEmptyList.php │ ├── assert-isNonEmptyMap.php │ ├── assert-isNotA.php │ ├── assert-isStatic.php │ ├── assert-keyExists.php │ ├── assert-keyNotExists.php │ ├── assert-length.php │ ├── assert-lengthBetween.php │ ├── assert-lessThan.php │ ├── assert-lessThanEq.php │ ├── assert-lower.php │ ├── assert-maxCount.php │ ├── assert-maxLength.php │ ├── assert-methodExists.php │ ├── assert-methodNotExists.php │ ├── assert-minCount.php │ ├── assert-minLength.php │ ├── assert-natural.php │ ├── assert-negativeInteger.php │ ├── assert-notContains.php │ ├── assert-notEmpty.php │ ├── assert-notEq.php │ ├── assert-notFalse.php │ ├── assert-notInArray.php │ ├── assert-notInstanceOf.php │ ├── assert-notNegativeInteger.php │ ├── assert-notNull.php │ ├── assert-notOneOf.php │ ├── assert-notRegex.php │ ├── assert-notSame.php │ ├── assert-notStatic.php │ ├── assert-notWhitespaceOnly.php │ ├── assert-null.php │ ├── assert-numeric.php │ ├── assert-object.php │ ├── assert-objectish.php │ ├── assert-oneOf.php │ ├── assert-positiveInteger.php │ ├── assert-propertyExists.php │ ├── assert-propertyNotExists.php │ ├── assert-psalm-notRedundant.php │ ├── assert-psalm-preserveContainerType.php │ ├── assert-psalm-preserveStringType.php │ ├── assert-range.php │ ├── assert-readable.php │ ├── assert-regex.php │ ├── assert-resource.php │ ├── assert-same.php │ ├── assert-scalar.php │ ├── assert-startsWith.php │ ├── assert-startsWithLetter.php │ ├── assert-string.php │ ├── assert-stringNotEmpty.php │ ├── assert-subclassOf.php │ ├── assert-throws.php │ ├── assert-true.php │ ├── assert-unicodeLetters.php │ ├── assert-uniqueValues.php │ ├── assert-upper.php │ ├── assert-uuid.php │ ├── assert-validArrayKey.php │ └── assert-writable.php └── tools/ ├── php-cs-fixer/ │ └── composer.json ├── phpunit/ │ └── composer.json ├── psalm/ │ └── composer.json └── roave-bc-check/ └── composer.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] charset=utf-8 end_of_line=lf trim_trailing_whitespace=true insert_final_newline=true indent_style=space indent_size=4 [*.{yaml,yml}] indent_size=2 ================================================ FILE: .gitattributes ================================================ /.gitattributes export-ignore /.gitignore export-ignore /.github export-ignore /.php-cs-fixer.php export-ignore /.editorconfig export-ignore /psalm.xml export-ignore /bin export-ignore /ci export-ignore /phpunit.xml.dist export-ignore /tests export-ignore /tools export-ignore ================================================ FILE: .github/workflows/ci.yaml ================================================ # https://docs.github.com/en/actions name: CI on: pull_request: ~ push: branches: - master jobs: static-code-analysis: name: Static Code Analysis runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install PHP uses: shivammathur/setup-php@v2 with: php-version: '8.4' coverage: none extensions: mbstring - name: Install dependencies run: >- composer install - name: Install tools run: >- composer run install-tools - name: Run code style check run: >- composer run cs-check - name: Run static analysis run: >- composer run static-analysis # Disabled for version 2.0, since there is no BC promise at this time. # - name: Run backwards compatibility check # run: >- # composer run bc-check tests: name: Tests runs-on: ubuntu-latest strategy: matrix: php-version: - "8.2" - "8.3" - "8.4" - "8.5" steps: - name: Checkout uses: actions/checkout@v4 - name: Install PHP uses: shivammathur/setup-php@v2 with: php-version: "${{ matrix.php-version }}" coverage: none extensions: mbstring - name: Install dependencies run: >- composer install - name: Install phpunit run: >- composer --working-dir=tools/phpunit install - name: Run tests run: >- composer run test windows-tests: name: Windows tests runs-on: windows-latest strategy: matrix: php-version: - "8.2" - "8.3" - "8.4" - "8.5" steps: - name: Checkout uses: actions/checkout@v4 - name: Install PHP uses: shivammathur/setup-php@v2 with: php-version: "${{ matrix.php-version }}" coverage: none extensions: mbstring - name: Install dependencies run: >- composer install - name: Install phpunit run: >- composer --working-dir=tools/phpunit install - name: Run tests run: >- composer run test ================================================ FILE: .gitignore ================================================ vendor/ /composer.lock .php-cs-fixer.cache .phpunit.result.cache ================================================ FILE: .php-cs-fixer.php ================================================ in(__DIR__.'/src') ->in(__DIR__.'/tests') ; return (new PhpCsFixer\Config()) ->setRiskyAllowed(true) ->setRules([ '@PSR2' => true, '@Symfony' => true, 'ordered_imports' => true, 'array_syntax' => ['syntax' => 'short'], 'fully_qualified_strict_types' => false, 'global_namespace_import' => true, 'no_superfluous_phpdoc_tags' => false, 'phpdoc_annotation_without_dot' => false, 'phpdoc_types_order' => false, 'phpdoc_separation' => ['skip_unlisted_annotations' => true], 'phpdoc_summary' => false, 'phpdoc_to_comment' => false, 'phpdoc_align' => false, 'yoda_style' => false, ]) ->setFinder($finder) ; ================================================ FILE: CHANGELOG.md ================================================ Changelog ========= ## 2.1.6 ### Fixed - Corrected docblocks for `list*` methods. ## 2.1.5 ### Fixed - Fixed regression of `instanceOf` messages ## 2.1.4 ### Fixed - Use custom message for more internal calls. ## 2.1.3 ### Fixed - Corrected `isList` type documentation. - Corrected `isAOf`, `isInstanceOf`, etc type documentation. ## 2.1.2 ### Fixed - Changed `all*` assertion values back to `mixed`. ## 2.1.1 ### Fixed - Optimized `stringNotEmpty` by internally using `notSame`. ## 2.1.0 ### Fixed - Corrected `@param` declaration for `isMap`. - Pass custom message to internal assertion calls. ## 2.0.0 ### Changed - **BREAKING** Minimum PHP version is now 8.2 (was 7.2). - **BREAKING** Remove deprecated `isTraversable`, use `isIterable` or `isInstanceOf` instead. - **BREAKING** Added `declare(strict_types=1)` to all classes. - Updated CI/CD test matrix to test PHP 8.2, 8.3, 8.4, and 8.5. - Updated development tools (PHPUnit, Psalm, PHP-CS-Fixer) to supported versions. - Added explicit return types and parameter types to all methods in both source code and tests. ### Added - All assertion methods now return the checked value. - Added `notInArray` and `notOneOf`. - Added `isInitialized`, to check if a class property is initialized. - Added `negativeInteger` and `notNegativeInteger` - Added `isStatic` and `notStatic` ### Fixed - Corrected validation of emails with unicode characters. ## 1.12.1 ### Fixed - Exclude tools from export. ## 1.12.0 ### Fixed - Corrected messages and typos in various assertions. - Document `void` return type. - Prevent UUIDs with trailing newlines from validating. - Assert values are strings before ctype checks. ## 1.11.0 ### Added * Added explicit (non-magic) `allNullOr*` methods, with `@psalm-assert` annotations, for better Psalm support. ### Changed * Trait methods will now check the assertion themselves, instead of using `__callStatic` * `isList` will now deal correctly with (modified) lists that contain `NaN` * `reportInvalidArgument` now has a return type of `never`. ### Removed * Removed `symfony/polyfill-ctype` as a dependency, and require `ext-ctype` instead. * You can still require the `symfony/polyfill-ctype` in your project if you need it, as it provides `ext-ctype` ## 1.10.0 ### Added * On invalid assertion, we throw a `Webmozart\Assert\InvalidArgumentException` * Added `Assert::positiveInteger()` ### Changed * Using a trait with real implementations of `all*()` and `nullOr*()` methods to improve psalm compatibility. ### Removed * Support for PHP <7.2 ## 1.9.1 ## Fixed * provisional support for PHP 8.0 ## 1.9.0 * added better Psalm support for `all*` & `nullOr*` methods * These methods are now understood by Psalm through a mixin. You may need a newer version of Psalm in order to use this * added `@psalm-pure` annotation to `Assert::notFalse()` * added more `@psalm-assert` annotations where appropriate ## Changed * the `all*` & `nullOr*` methods are now declared on an interface, instead of `@method` annotations. This interface is linked to the `Assert` class with a `@mixin` annotation. Most IDEs have supported this for a long time, and you should not lose any autocompletion capabilities. PHPStan has supported this since version `0.12.20`. This package is marked incompatible (with a composer conflict) with phpstan version prior to that. If you do not use PHPStan than this does not matter. ## 1.8.0 ### Added * added `Assert::notStartsWith()` * added `Assert::notEndsWith()` * added `Assert::inArray()` * added `@psalm-pure` annotations to pure assertions ### Fixed * Exception messages of comparisons between `DateTime(Immutable)` objects now display their date & time. * Custom Exception messages for `Assert::count()` now use the values to render the exception message. ## 1.7.0 (2020-02-14) ### Added * added `Assert::notFalse()` * added `Assert::isAOf()` * added `Assert::isAnyOf()` * added `Assert::isNotA()` ## 1.6.0 (2019-11-24) ### Added * added `Assert::validArrayKey()` * added `Assert::isNonEmptyList()` * added `Assert::isNonEmptyMap()` * added `@throws InvalidArgumentException` annotations to all methods that throw. * added `@psalm-assert` for the list type to the `isList` assertion. ### Fixed * `ResourceBundle` & `SimpleXMLElement` now pass the `isCountable` assertions. They are countable, without implementing the `Countable` interface. * The doc block of `range` now has the proper variables. * An empty array will now pass `isList` and `isMap`. As it is a valid form of both. If a non-empty variant is needed, use `isNonEmptyList` or `isNonEmptyMap`. ### Changed * Removed some `@psalm-assert` annotations, that were 'side effect' assertions See: * [#144](https://github.com/webmozart/assert/pull/144) * [#145](https://github.com/webmozart/assert/issues/145) * [#146](https://github.com/webmozart/assert/pull/146) * [#150](https://github.com/webmozart/assert/pull/150) * If you use Psalm, the minimum version needed is `3.6.0`. Which is enforced through a composer conflict. If you don't use Psalm, then this has no impact. ## 1.5.0 (2019-08-24) ### Added * added `Assert::uniqueValues()` * added `Assert::unicodeLetters()` * added: `Assert::email()` * added support for [Psalm](https://github.com/vimeo/psalm), by adding `@psalm-assert` annotations where appropriate. ### Fixed * `Assert::endsWith()` would not give the correct result when dealing with a multibyte suffix. * `Assert::length(), minLength, maxLength, lengthBetween` would not give the correct result when dealing with multibyte characters. **NOTE**: These 2 changes may break your assertions if you relied on the fact that multibyte characters didn't behave correctly. ### Changed * The names of some variables have been updated to better reflect what they are. * All function calls are now in their FQN form, slightly increasing performance. * Tests are now properly ran against HHVM-3.30 and PHP nightly. ### Deprecation * deprecated `Assert::isTraversable()` in favor of `Assert::isIterable()` * This was already done in 1.3.0, but it was only done through a silenced `trigger_error`. It is now annotated as well. ## 1.4.0 (2018-12-25) ### Added * added `Assert::ip()` * added `Assert::ipv4()` * added `Assert::ipv6()` * added `Assert::notRegex()` * added `Assert::interfaceExists()` * added `Assert::isList()` * added `Assert::isMap()` * added polyfill for ctype ### Fixed * Special case when comparing objects implementing `__toString()` ## 1.3.0 (2018-01-29) ### Added * added `Assert::minCount()` * added `Assert::maxCount()` * added `Assert::countBetween()` * added `Assert::isCountable()` * added `Assert::notWhitespaceOnly()` * added `Assert::natural()` * added `Assert::notContains()` * added `Assert::isArrayAccessible()` * added `Assert::isInstanceOfAny()` * added `Assert::isIterable()` ### Fixed * `stringNotEmpty` will no longer report "0" is an empty string ### Deprecation * deprecated `Assert::isTraversable()` in favor of `Assert::isIterable()` ## 1.2.0 (2016-11-23) * added `Assert::throws()` * added `Assert::count()` * added extension point `Assert::reportInvalidArgument()` for custom subclasses ## 1.1.0 (2016-08-09) * added `Assert::object()` * added `Assert::propertyExists()` * added `Assert::propertyNotExists()` * added `Assert::methodExists()` * added `Assert::methodNotExists()` * added `Assert::uuid()` ## 1.0.2 (2015-08-24) * integrated Style CI * add tests for minimum package dependencies on Travis CI ## 1.0.1 (2015-05-12) * added support for PHP 5.3.3 ## 1.0.0 (2015-05-12) * first stable release ## 1.0.0-beta (2015-03-19) * first beta release ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2014 Bernhard Schussek Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ Webmozart Assert ================ [![Latest Stable Version](https://poser.pugx.org/webmozart/assert/v/stable.svg)](https://packagist.org/packages/webmozart/assert) [![Total Downloads](https://poser.pugx.org/webmozart/assert/downloads.svg)](https://packagist.org/packages/webmozart/assert) This library contains efficient assertions to test the input and output of your methods. With these assertions, you can greatly reduce the amount of coding needed to write a safe implementation. All assertions in the [`Assert`] class throw an `Webmozart\Assert\InvalidArgumentException` if they fail. FAQ --- **What's the difference to [beberlei/assert]?** This library is heavily inspired by Benjamin Eberlei's wonderful [assert package], but fixes a usability issue with error messages that can't be fixed there without breaking backwards compatibility. This package features usable error messages by default. However, you can also easily write custom error messages: ``` Assert::string($path, 'The path is expected to be a string. Got: %s'); ``` In [beberlei/assert], the ordering of the `%s` placeholders is different for every assertion. This package, on the contrary, provides consistent placeholder ordering for all assertions: * `%s`: The tested value as string, e.g. `"/foo/bar"`. * `%2$s`, `%3$s`, ...: Additional assertion-specific values, e.g. the minimum/maximum length, allowed values, etc. Check the source code of the assertions to find out details about the additional available placeholders. Installation ------------ Use [Composer] to install the package: ```bash composer require webmozart/assert ``` Example ------- ```php use Webmozart\Assert\Assert; class Employee { public function __construct($id) { Assert::integer($id, 'The employee ID must be an integer. Got: %s'); Assert::greaterThan($id, 0, 'The employee ID must be a positive integer. Got: %s'); } } ``` If you create an employee with an invalid ID, an exception is thrown: ```php new Employee('foobar'); // => Webmozart\Assert\InvalidArgumentException: // The employee ID must be an integer. Got: string new Employee(-10); // => Webmozart\Assert\InvalidArgumentException: // The employee ID must be a positive integer. Got: -10 ``` Assertions ---------- The [`Assert`] class provides the following assertions: ### Type Assertions Method | Description -------------------------------------------------------- | -------------------------------------------------- `string($value, $message = '')` | Check that a value is a string `stringNotEmpty($value, $message = '')` | Check that a value is a non-empty string `integer($value, $message = '')` | Check that a value is an integer `integerish($value, $message = '')` | Check that a value casts to an integer `positiveInteger($value, $message = '')` | Check that a value is a positive (non-zero) integer `negativeInteger($value, $message = '')` | Check that a value is a negative integer `notNegativeInteger($value, $message = '')` | Check that a value is a non-negative integer `float($value, $message = '')` | Check that a value is a float `numeric($value, $message = '')` | Check that a value is numeric `natural($value, $message = '')` | Check that a value is a non-negative integer `boolean($value, $message = '')` | Check that a value is a boolean `scalar($value, $message = '')` | Check that a value is a scalar `object($value, $message = '')` | Check that a value is an object `objectish($value, $message = '')` | Check that a value is an object or a string of a class that exists `resource($value, $type = null, $message = '')` | Check that a value is a resource `isInitialized($value, $property, $message = '')` | Check that a value has an initialized property `isCallable($value, $message = '')` | Check that a value is a callable `isArray($value, $message = '')` | Check that a value is an array `isIterable($value, $message = '')` | Check that a value is an array or a `\Traversable` `isCountable($value, $message = '')` | Check that a value is an array or a `\Countable` `isInstanceOf($value, $class, $message = '')` | Check that a value is an `instanceof` a class `isInstanceOfAny($value, array $classes, $message = '')` | Check that a value is an `instanceof` at least one class on the array of classes `notInstanceOf($value, $class, $message = '')` | Check that a value is not an `instanceof` a class `isAOf($value, $class, $message = '')` | Check that a value is of the class or has one of its parents `isAnyOf($value, array $classes, $message = '')` | Check that a value is of at least one of the classes or has one of its parents `isNotA($value, $class, $message = '')` | Check that a value is not of the class or has not one of its parents `isArrayAccessible($value, $message = '')` | Check that a value can be accessed as an array `uniqueValues($values, $message = '')` | Check that the given array contains unique values ### Comparison Assertions Method | Description ----------------------------------------------------- | ------------------------------------------------------------------ `true($value, $message = '')` | Check that a value is `true` `false($value, $message = '')` | Check that a value is `false` `notFalse($value, $message = '')` | Check that a value is not `false` `null($value, $message = '')` | Check that a value is `null` `notNull($value, $message = '')` | Check that a value is not `null` `isEmpty($value, $message = '')` | Check that a value is `empty()` `notEmpty($value, $message = '')` | Check that a value is not `empty()` `eq($value, $value2, $message = '')` | Check that a value equals another (`==`) `notEq($value, $value2, $message = '')` | Check that a value does not equal another (`!=`) `same($value, $value2, $message = '')` | Check that a value is identical to another (`===`) `notSame($value, $value2, $message = '')` | Check that a value is not identical to another (`!==`) `greaterThan($value, $value2, $message = '')` | Check that a value is greater than another `greaterThanEq($value, $value2, $message = '')` | Check that a value is greater than or equal to another `lessThan($value, $value2, $message = '')` | Check that a value is less than another `lessThanEq($value, $value2, $message = '')` | Check that a value is less than or equal to another `range($value, $min, $max, $message = '')` | Check that a value is within a range `inArray($value, array $values, $message = '')` | Check that a value is one of a list of values `notInArray($value, array $values, $message = '')` | Check that a value is not one of a list of values `oneOf($value, array $values, $message = '')` | Check that a value is one of a list of values (alias of `inArray`) `notOneOf($value, array $values, $message = '')` | Check that a value is not one of a list of values (alias of `notInArray`) ### String Assertions You should check that a value is a string with `Assert::string()` before making any of the following assertions. Method | Description --------------------------------------------------- | ----------------------------------------------------------------- `contains($value, $subString, $message = '')` | Check that a string contains a substring `notContains($value, $subString, $message = '')` | Check that a string does not contain a substring `startsWith($value, $prefix, $message = '')` | Check that a string has a prefix `notStartsWith($value, $prefix, $message = '')` | Check that a string does not have a prefix `startsWithLetter($value, $message = '')` | Check that a string starts with a letter `endsWith($value, $suffix, $message = '')` | Check that a string has a suffix `notEndsWith($value, $suffix, $message = '')` | Check that a string does not have a suffix `regex($value, $pattern, $message = '')` | Check that a string matches a regular expression `notRegex($value, $pattern, $message = '')` | Check that a string does not match a regular expression `unicodeLetters($value, $message = '')` | Check that a string contains Unicode letters only `alpha($value, $message = '')` | Check that a string contains letters only `digits($value, $message = '')` | Check that a string contains digits only `alnum($value, $message = '')` | Check that a string contains letters and digits only `lower($value, $message = '')` | Check that a string contains lowercase characters only `upper($value, $message = '')` | Check that a string contains uppercase characters only `length($value, $length, $message = '')` | Check that a string has a certain number of characters `minLength($value, $min, $message = '')` | Check that a string has at least a certain number of characters `maxLength($value, $max, $message = '')` | Check that a string has at most a certain number of characters `lengthBetween($value, $min, $max, $message = '')` | Check that a string has a length in the given range `uuid($value, $message = '')` | Check that a string is a valid UUID `ip($value, $message = '')` | Check that a string is a valid IP (either IPv4 or IPv6) `ipv4($value, $message = '')` | Check that a string is a valid IPv4 `ipv6($value, $message = '')` | Check that a string is a valid IPv6 `email($value, $message = '')` | Check that a string is a valid e-mail address `notWhitespaceOnly($value, $message = '')` | Check that a string contains at least one non-whitespace character ### File Assertions Method | Description ----------------------------------- | -------------------------------------------------- `fileExists($value, $message = '')` | Check that a value is an existing path `file($value, $message = '')` | Check that a value is an existing file `directory($value, $message = '')` | Check that a value is an existing directory `readable($value, $message = '')` | Check that a value is a readable path `writable($value, $message = '')` | Check that a value is a writable path ### Object Assertions Method | Description ----------------------------------------------------- | -------------------------------------------------- `classExists($value, $message = '')` | Check that a value is an existing class name `subclassOf($value, $class, $message = '')` | Check that a class is a subclass of another `interfaceExists($value, $message = '')` | Check that a value is an existing interface name `implementsInterface($value, $class, $message = '')` | Check that a class implements an interface `propertyExists($value, $property, $message = '')` | Check that a property exists in a class/object `propertyNotExists($value, $property, $message = '')` | Check that a property does not exist in a class/object `methodExists($value, $method, $message = '')` | Check that a method exists in a class/object `methodNotExists($value, $method, $message = '')` | Check that a method does not exist in a class/object ### Array Assertions Method | Description -------------------------------------------------- | ------------------------------------------------------------------ `keyExists($array, $key, $message = '')` | Check that a key exists in an array `keyNotExists($array, $key, $message = '')` | Check that a key does not exist in an array `validArrayKey($key, $message = '')` | Check that a value is a valid array key (int or string) `count($array, $number, $message = '')` | Check that an array contains a specific number of elements `minCount($array, $min, $message = '')` | Check that an array contains at least a certain number of elements `maxCount($array, $max, $message = '')` | Check that an array contains at most a certain number of elements `countBetween($array, $min, $max, $message = '')` | Check that an array has a count in the given range `isList($array, $message = '')` | Check that an array is a non-associative list `isNonEmptyList($array, $message = '')` | Check that an array is a non-associative list, and not empty `isMap($array, $message = '')` | Check that an array is associative and has strings as keys `isNonEmptyMap($array, $message = '')` | Check that an array is associative and has strings as keys, and is not empty ### Function Assertions Method | Description ------------------------------------------| ----------------------------------------------------------------------------------------------------- `throws($closure, $class, $message = '')` | Check that a function throws a certain exception. Subclasses of the exception class will be accepted. `isStatic($closure, $message = '')` | Check that a function is static. `notStatic($closure, $message = '')` | Check that a function is not static. ### Collection Assertions All of the above assertions can be prefixed with `all*()` to test the contents of an array or a `\Traversable`: ```php Assert::allIsInstanceOf($employees, 'Acme\Employee'); ``` ### Nullable Assertions All of the above assertions can be prefixed with `nullOr*()` to run the assertion only if the value is not `null`: ```php Assert::nullOrString($middleName, 'The middle name must be a string or null. Got: %s'); ``` ### Extending Assert The `Assert` class comes with a few methods, which can be overridden to change the class behaviour. You can also extend it to add your own assertions. #### Overriding methods Overriding the following methods in your assertion class allows you to change the behaviour of the assertions: * `public static function __callStatic($name, $arguments)` * This method is used to 'create' the `nullOr` and `all` versions of the assertions. * `protected static function valueToString($value)` * This method is used for error messages, to convert the value to a string value for displaying. You could use this for representing a value object with a `__toString` method for example. * `protected static function typeToString($value)` * This method is used for error messages, to convert a value to a string representing its type. * `protected static function strlen($value)` * This method is used to calculate string length for relevant methods, using the `mb_strlen` if available and useful. * `protected static function reportInvalidArgument($message)` * This method is called when an assertion fails, with the specified error message. Here you can throw your own exception, or log something. ## Static analysis support Where applicable, assertion functions are annotated to support Psalm's [Assertion syntax](https://psalm.dev/docs/annotating_code/assertion_syntax/). A dedicated [PHPStan Plugin](https://github.com/phpstan/phpstan-webmozart-assert) is required for proper type support. Authors ------- * [Bernhard Schussek] a.k.a. [@webmozart] * [The Community Contributors] Contribute ---------- Contributions to the package are always welcome! * Report any bugs or issues you find on the [issue tracker]. * You can grab the source code at the package's [Git repository]. License ------- All contents of this package are licensed under the [MIT license]. [beberlei/assert]: https://github.com/beberlei/assert [assert package]: https://github.com/beberlei/assert [Composer]: https://getcomposer.org [Bernhard Schussek]: https://webmozarts.com [The Community Contributors]: https://github.com/webmozart/assert/graphs/contributors [issue tracker]: https://github.com/webmozart/assert/issues [Git repository]: https://github.com/webmozart/assert [@webmozart]: https://twitter.com/webmozart [MIT license]: LICENSE [`Assert`]: src/Assert.php ================================================ FILE: bin/generate.php ================================================ generate()); echo "Done."; ================================================ FILE: bin/src/MixinGenerator.php ================================================ * * @var string[] */ private array $unsupportedMethods = [ 'nullOrNotInstanceOf', // not supported by psalm (https://github.com/vimeo/psalm/issues/3443) 'allNotInstanceOf', // not supported by psalm (https://github.com/vimeo/psalm/issues/3443) 'nullOrNotEmpty', // not supported by psalm (https://github.com/vimeo/psalm/issues/3443) 'allNotEmpty', // not supported by psalm (https://github.com/vimeo/psalm/issues/3443) 'allNotNull', // not supported by psalm (https://github.com/vimeo/psalm/issues/3443) 'nullOrIsNotA', // not supported by psalm (https://github.com/vimeo/psalm/issues/3444) 'allIsNotA', // not supported by psalm (https://github.com/vimeo/psalm/issues/3444) 'nullOrNotFalse', // not supported by psalm (https://github.com/vimeo/psalm/issues/3443) 'allNotFalse', // not supported by psalm (https://github.com/vimeo/psalm/issues/3443) 'nullOrUpper', // not supported by psalm (https://github.com/vimeo/psalm/issues/3443) 'allUpper', // not supported by psalm (https://github.com/vimeo/psalm/issues/3443) 'nullOrIsNonEmptyMap', // not supported by psalm (https://github.com/vimeo/psalm/issues/3444) 'allIsNonEmptyMap', // not supported by psalm (https://github.com/vimeo/psalm/issues/3444) ]; private array $skipGenerateForMethods = [ 'isInitialized', ]; /** * @psalm-var list * * @var string[] */ private array $skipMethods = [ 'nullOrNull', // meaningless 'nullOrNotNull', // meaningless 'allNullOrNull', // meaningless 'allNullOrNotNull', // meaningless ]; public function generate(): string { return \sprintf( <<<'PHP' namespace() ); } private function namespace(): string { $assert = new ReflectionClass(Assert::class); $namespace = sprintf("namespace %s;\n\n", $assert->getNamespaceName()); $namespace .= sprintf("use %s;\n", ArrayAccess::class); $namespace .= sprintf("use %s;\n", Countable::class); $namespace .= sprintf("use %s;\n", Throwable::class); $namespace .= "\n"; $namespace .= $this->trait($assert); return $namespace; } private function trait(ReflectionClass $assert): string { $staticMethods = $this->getMethods($assert); $declaredMethods = []; foreach ($staticMethods as $method) { $nullOr = $this->nullOr($method, 4); if (null !== $nullOr) { $declaredMethods[] = $nullOr; } $all = $this->all($method, 4); if (null !== $all) { $declaredMethods[] = $all; } $allNullOr = $this->allNullOr($method, 4); if (null !== $allNullOr) { $declaredMethods[] = $allNullOr; } } return \sprintf( <<<'PHP' /** * This trait provides nullOr*, all* and allNullOr* variants of assertion base methods. * Do not use this trait directly: it will change, and is not designed for reuse. */ trait Mixin { %s } PHP , \implode("\n\n", $declaredMethods) ); } /** * @param ReflectionMethod $method * @param int $indent * * @return string|null * * @throws ReflectionException */ private function nullOr(ReflectionMethod $method, int $indent): ?string { return $this->assertion($method, 'nullOr%s', '%s|null', $indent, function (string $firstParameter, string $parameters) use ($method) { return <<name}({$firstParameter}, {$parameters}); return {$firstParameter}; BODY; }); } /** * @param ReflectionMethod $method * @param int $indent * * @return string|null * * @throws ReflectionException */ private function all(ReflectionMethod $method, int $indent): ?string { return $this->assertion($method, 'all%s', 'iterable<%s>', $indent, function (string $firstParameter, string $parameters) use ($method) { return <<name}(\$entry, {$parameters}); } return {$firstParameter}; BODY; }); } /** * @param ReflectionMethod $method * @param int $indent * * @return string|null * * @throws ReflectionException */ private function allNullOr(ReflectionMethod $method, int $indent): ?string { return $this->assertion($method, 'allNullOr%s', 'iterable<%s|null>', $indent, function (string $firstParameter, string $parameters) use ($method) { return <<name}(\$entry, {$parameters}); } return {$firstParameter}; BODY; }); } /** * @psalm-param callable(string,string):string $body * * @param ReflectionMethod $method * @param string $methodNameTemplate * @param string $typeTemplate * @param int $indent * @param callable $body * * @return string|null * * @throws ReflectionException */ private function assertion(ReflectionMethod $method, string $methodNameTemplate, string $typeTemplate, int $indent, callable $body): ?string { $newMethodName = sprintf($methodNameTemplate, ucfirst($method->name)); $comment = $method->getDocComment(); $parsedComment = $this->parseDocComment($comment); $parameters = []; /** @psalm-var array $parametersDefaults */ $parametersDefaults = []; /** @var array $parameterTypes */ $parameterTypes = []; $parametersReflection = $method->getParameters(); $nativeReturnType = 'mixed'; foreach ($parametersReflection as $parameterReflection) { $parameters[] = $parameterReflection->name; if ($parameterReflection->isDefaultValueAvailable()) { $defaultValue = $parameterReflection->getDefaultValue(); $defaultValue = Assert::nullOrScalar($defaultValue); $parametersDefaults[$parameterReflection->name] = $defaultValue; } if ($parameterReflection->hasType()) { if ($parameterReflection->name === 'value') { $parameterTypes[$parameterReflection->name] = 'mixed'; $nativeReturnType = match ($typeTemplate) { '%s|null' => $this->reduceParameterType($parameterReflection->getType()), 'iterable<%s>' => 'iterable', 'iterable<%s|null>' => 'iterable', }; } else { $parameterTypes[$parameterReflection->name] = $this->reduceParameterType($parameterReflection->getType()); } } } if (in_array($newMethodName, $this->skipMethods, true)) { return null; } $paramsAdded = false; $phpdocReturnType = 'mixed'; $phpdocLines = []; foreach ($parsedComment as $key => $values) { if ($this->shouldSkipAnnotation($newMethodName, $key)) { continue; } if ($paramsAdded || 'param' === $key) { $paramsAdded = true; if (count($phpdocLines) > 0) { $phpdocLines[] = ''; } } if ('deprecated' === $key) { $phpdocLines[] = ''; } $longestType = 0; $longestName = 0; foreach ($values as $i => $value) { $parts = $this->splitDocLine($value); if (('param' === $key || 'psalm-param' === $key) && isset($parts[1]) && isset($parameters[0]) && $parts[1] === '$'.$parameters[0] && 'mixed' !== $parts[0]) { $parts[0] = $this->applyTypeTemplate($parts[0], $typeTemplate); $values[$i] = \implode(' ', $parts); } } if ('psalm-return' === $key || 'return' === $key) { continue; } if ('param' === $key) { [$longestType, $longestName] = $this->findLongestTypeAndName($values); } foreach ($values as $value) { $parts = $this->splitDocLine($value); $type = $parts[0]; if ('psalm-assert' === $key) { $type = $this->applyTypeTemplate($type, $typeTemplate); $phpdocReturnType = $type; } if ('param' === $key) { if (!isset($parts[1])) { throw new RuntimeException(sprintf('param key must come with type and variable name in method: %s', $method->name)); } $type = str_pad($type, $longestType, ' '); $parts[1] = str_pad($parts[1], $longestName, ' '); } $comment = sprintf('@%s %s', $key, $type); if (count($parts) >= 2) { $comment .= sprintf(' %s', \implode(' ', array_slice($parts, 1))); } $phpdocLines[] = trim($comment); } if ('deprecated' === $key || 'psalm-pure' === $key || 'psalm-assert' === $key || 'see' === $key) { $phpdocLines[] = ''; } } $phpdocLines[] = '@return '.$phpdocReturnType; $phpdocLines[] = ''; $phpdocLinesDeduplicatedEmptyLines = []; foreach ($phpdocLines as $line) { $currentLine = trim($line); if ('' === $currentLine && count($phpdocLinesDeduplicatedEmptyLines) > 0) { $previousLine = trim($phpdocLinesDeduplicatedEmptyLines[count($phpdocLinesDeduplicatedEmptyLines) - 1]); if ('' === $previousLine) { continue; } } $phpdocLinesDeduplicatedEmptyLines[] = $line; } return $this->staticMethod($newMethodName, $parameters, $parameterTypes, $parametersDefaults, $phpdocLinesDeduplicatedEmptyLines, $indent, $body, $nativeReturnType); } private function reduceParameterType(ReflectionType $type): string { if ($type instanceof ReflectionIntersectionType) { return \implode('&', \array_map([$this, 'reduceParameterType'], $type->getTypes())); } if ($type instanceof ReflectionUnionType) { return \implode('|', \array_map([$this, 'reduceParameterType'], $type->getTypes())); } $type = Assert::isInstanceOf($type, ReflectionNamedType::class); if ($type->getName() === 'mixed') { return $type->getName(); } return ($type->allowsNull() ? '?' : '') . $type->getName(); } private function applyTypeTemplate(string $type, string $typeTemplate): string { $combinedType = sprintf($typeTemplate, $type); if ('empty|null' === $combinedType) { $combinedType = 'empty'; // @see https://github.com/vimeo/psalm/issues/3492 } return $combinedType; } private function shouldSkipAnnotation(string $newMethodName, string $key): bool { if (!in_array($newMethodName, $this->unsupportedMethods, true)) { return false; } return 'psalm-assert' === $key || 'psalm-return' === $key; } /** * @psalm-param array $values * @psalm-return array{int, int} * * @param string[] $values * * @return int[] */ private function findLongestTypeAndName(array $values): array { $longestType = 0; $longestName = 0; foreach ($values as $value) { $parts = $this->splitDocLine($value); $type = $parts[0]; if (strlen($type) > $longestType) { $longestType = strlen($type); } if (!isset($parts[1])) { continue; } $name = $parts[1]; if (strlen($name) > $longestName) { $longestName = strlen($name); } } return [$longestType, $longestName]; } /** * @psalm-param list $parameters * @psalm-param array $defaults * @psalm-param list $phpdocLines * * @param string $name * @param string[] $parameters * @param array $types * @param string[] $defaults * @param array $phpdocLines * @param int $indent * @param callable(string,string): string $body * @param string $returnType * * @return string */ private function staticMethod(string $name, array $parameters, array $types, array $defaults, array $phpdocLines, int $indent, callable $body, string $returnType): string { Assert::notEmpty($parameters); $indentation = str_repeat(' ', $indent); $parameterList = \array_map(static fn (string $parameter): string => '$'.$parameter, $parameters); $firstParameter = \array_shift($parameterList); $parameterList = \implode(', ', $parameterList); $methodBody = \preg_replace('/(?<=^|\n)(?!\n)/', $indentation.$indentation, $body($firstParameter, $parameterList)); Assert::stringNotEmpty($methodBody); $staticFunction = $this->phpdoc($phpdocLines, $indent)."\n"; $staticFunction .= $indentation.'public static function '.$name.$this->functionParameters($parameters, $types, $defaults).": {$returnType}\n" .$indentation."{\n"; $staticFunction .= $methodBody."\n".$indentation."}"; return $staticFunction; } /** * @psalm-param list $parameters * @psalm-param array $defaults * * @param string[] $parameters * @param array $types * @param string[] $defaults * * @return string */ private function functionParameters(array $parameters, array $types, array $defaults): string { $result = ''; foreach ($parameters as $i => $parameter) { if ($i > 0) { $result .= ', '; } Assert::keyExists($types, $parameter); $result .= $types[$parameter].' $'.$parameter; if (array_key_exists($parameter, $defaults)) { $defaultValue = null === $defaults[$parameter] ? 'null' : var_export($defaults[$parameter], true); $result .= ' = '.$defaultValue; } } return '('.$result.')'; } /** * @psalm-param list $lines * * @param string[] $lines * @param int $indent * * @return string */ private function phpdoc(array $lines, int $indent): string { $indentation = str_repeat(' ', $indent); $phpdoc = $indentation.'/**'; $throws = ''; foreach ($lines as $line) { if (\str_starts_with($line, '@throws')) { $throws .= "\n".$indentation.\rtrim(' * '.$line); } else { $phpdoc .= "\n".$indentation.\rtrim(' * '.$line); } } if (strlen($throws) > 0) { $phpdoc .= $throws; } $phpdoc .= "\n".$indentation.' */'; return $phpdoc; } /** * @psalm-return array> * * @param string $comment * * @return string[][] */ private function parseDocComment(string $comment): array { $lines = explode("\n", $comment); $result = []; foreach ($lines as $line) { if (preg_match('~^\*\s+@(\S+)(\s+.*)?$~', trim($line), $matches)) { if (2 === count($matches)) { $matches[2] = ''; } $result[$matches[1]][] = trim($matches[2]); } } return $result; } /** * @psalm-return list{string, string|null, string|null} * * @param string $line * * @return string[] */ private function splitDocLine(string $line): array { if (!preg_match('~^(.*)\s+(\$\S+)(?:\s+(.*))?$~', $line, $matches)) { return [$line, null, null]; } return [trim($matches[1]), $matches[2], $matches[3] ?? null]; } /** * @psalm-return list * * @param ReflectionClass $assert * * @return ReflectionMethod[] */ private function getMethods(ReflectionClass $assert): array { $methods = []; $staticMethods = $assert->getMethods(ReflectionMethod::IS_STATIC); foreach ($staticMethods as $staticMethod) { if (in_array($staticMethod->name, $this->skipGenerateForMethods)) { continue; } $modifiers = $staticMethod->getModifiers(); if (0 === ($modifiers & ReflectionMethod::IS_PUBLIC)) { continue; } if ($staticMethod->getFileName() !== $assert->getFileName()) { // Skip this method - was imported by generated mixin continue; } if ('__callStatic' === $staticMethod->name) { continue; } $methods[] = $staticMethod; } return $methods; } } ================================================ FILE: composer.json ================================================ { "name": "webmozart/assert", "description": "Assertions to validate method input/output with nice error messages.", "license": "MIT", "keywords": [ "assert", "check", "validate" ], "authors": [ { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" }, { "name": "Woody Gilk", "email": "woody.gilk@gmail.com" } ], "require": { "php": "^8.2", "ext-ctype": "*", "ext-date": "*", "ext-filter": "*" }, "suggest": { "ext-intl": "", "ext-simplexml": "", "ext-spl": "" }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" } }, "autoload-dev": { "psr-4": { "Webmozart\\Assert\\Bin\\": "bin/src", "Webmozart\\Assert\\Tests\\": "tests/" } }, "extra": { "branch-alias": { "dev-feature/2-0": "2.0-dev" } }, "scripts": { "install-tools": [ "composer --working-dir=tools/php-cs-fixer install", "composer --working-dir=tools/phpunit install", "composer --working-dir=tools/psalm install", "composer --working-dir=tools/roave-bc-check install" ], "update-tools": [ "composer --working-dir=tools/php-cs-fixer update", "composer --working-dir=tools/phpunit update", "composer --working-dir=tools/psalm update", "composer --working-dir=tools/roave-bc-check update" ], "generate-mixin": "php bin/generate.php", "bc-check": "./tools/roave-bc-check/vendor/bin/roave-backward-compatibility-check", "cs-check" : "./tools/php-cs-fixer/vendor/bin/php-cs-fixer check", "cs-fix": "./tools/php-cs-fixer/vendor/bin/php-cs-fixer fix", "static-analysis": "./tools/psalm/vendor/bin/psalm --threads=4 --root=$(pwd)", "test": "./tools/phpunit/vendor/bin/phpunit" } } ================================================ FILE: phpunit.xml.dist ================================================ ./tests/ ./tests/static-analysis ./src/ ================================================ FILE: psalm.xml ================================================ ================================================ FILE: src/Assert.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Webmozart\Assert; use ArrayAccess; use Closure; use Countable; use DateTime; use DateTimeImmutable; use ReflectionFunction; use ReflectionProperty; use Throwable; use Traversable; /** * Efficient assertions to validate the input/output of your methods. * * @since 1.0 * * @author Bernhard Schussek */ class Assert { use Mixin; /** * @psalm-pure * * @psalm-assert string $value * * @throws InvalidArgumentException */ public static function string(mixed $value, string $message = ''): string { if (!\is_string($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a string. Got: %s', static::typeToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert non-empty-string $value * * @psalm-return non-empty-string * * @throws InvalidArgumentException */ public static function stringNotEmpty(mixed $value, string $message = ''): string { static::string($value, $message); static::notSame($value, '', $message); return $value; } /** * @psalm-pure * * @psalm-assert int $value * * @throws InvalidArgumentException */ public static function integer(mixed $value, string $message = ''): int { if (!\is_int($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an integer. Got: %s', static::typeToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert numeric $value * * @throws InvalidArgumentException */ public static function integerish(mixed $value, string $message = ''): int|float|string { if (!\is_numeric($value) || $value != (int) $value) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an integerish value. Got: %s', static::typeToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert positive-int $value * * @psalm-return positive-int * * @throws InvalidArgumentException */ public static function positiveInteger(mixed $value, string $message = ''): int { static::integer($value, $message); if ($value < 1) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a positive integer. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * @psalm-assert non-negative-int $value * * @psalm-return non-negative-int * * @throws InvalidArgumentException */ public static function notNegativeInteger(mixed $value, string $message = ''): int { static::integer($value, $message); if ($value < 0) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a non negative integer. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * @psalm-assert negative-int $value * * @psalm-return negative-int * * @throws InvalidArgumentException */ public static function negativeInteger(mixed $value, string $message = ''): int { static::integer($value, $message); if ($value >= 0) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a negative integer. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert float $value * * @throws InvalidArgumentException */ public static function float(mixed $value, string $message = ''): float { if (!\is_float($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a float. Got: %s', static::typeToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert numeric $value * * @throws InvalidArgumentException */ public static function numeric(mixed $value, string $message = ''): int|float|string { if (!\is_numeric($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a numeric. Got: %s', static::typeToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert positive-int|0 $value * * @psalm-return positive-int|0 * * @throws InvalidArgumentException */ public static function natural(mixed $value, string $message = ''): int { if (!\is_int($value) || $value < 0) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a non-negative integer. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert bool $value * * @throws InvalidArgumentException */ public static function boolean(mixed $value, string $message = ''): bool { if (!\is_bool($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a boolean. Got: %s', static::typeToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert scalar $value * * @throws InvalidArgumentException */ public static function scalar(mixed $value, string $message = ''): int|bool|float|string { if (!\is_scalar($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a scalar. Got: %s', static::typeToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert object $value * * @throws InvalidArgumentException */ public static function object(mixed $value, string $message = ''): object { if (!\is_object($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an object. Got: %s', static::typeToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert object|string $value * * @psalm-return object|string * * @throws InvalidArgumentException */ public static function objectish(mixed $value, string $message = ''): object|string { if (!\is_object($value) && !\is_string($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an objectish value. Got: %s', static::typeToString($value) )); } if (\is_string($value) && !\class_exists($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected class to be defined. Got: %s', $value )); } return $value; } /** * @psalm-pure * * @psalm-assert resource $value * * @see https://www.php.net/manual/en/function.get-resource-type.php * * @psalm-return resource * * @throws InvalidArgumentException */ public static function resource(mixed $value, ?string $type = null, string $message = ''): mixed { if (!\is_resource($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a resource. Got: %s', static::typeToString($value), $type // User supplied message might include the second placeholder. )); } if ($type && $type !== \get_resource_type($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a resource of type %2$s. Got: %s', static::typeToString($value), $type )); } return $value; } /** * @psalm-pure * * @psalm-assert object $value * * @throws InvalidArgumentException */ public static function isInitialized(mixed $value, string $property, string $message = ''): object { Assert::object($value); $reflectionProperty = new ReflectionProperty($value, $property); if (!$reflectionProperty->isInitialized($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected property %s to be initialized.', $property, )); } return $value; } /** * @psalm-pure * * @psalm-assert callable $value * * @throws InvalidArgumentException */ public static function isCallable(mixed $value, string $message = ''): callable { if (!\is_callable($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a callable. Got: %s', static::typeToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert array $value * * @throws InvalidArgumentException */ public static function isArray(mixed $value, string $message = ''): array { if (!\is_array($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an array. Got: %s', static::typeToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert array|ArrayAccess $value * * @throws InvalidArgumentException */ public static function isArrayAccessible(mixed $value, string $message = ''): array|ArrayAccess { if (!\is_array($value) && !($value instanceof ArrayAccess)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an array accessible. Got: %s', static::typeToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert countable $value * * @throws InvalidArgumentException */ public static function isCountable(mixed $value, string $message = ''): array|Countable { if (!\is_array($value) && !($value instanceof Countable)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a countable. Got: %s', static::typeToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @throws InvalidArgumentException */ public static function isIterable(mixed $value, string $message = ''): iterable { if (!\is_array($value) && !($value instanceof Traversable)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an iterable. Got: %s', static::typeToString($value) )); } return $value; } /** * @psalm-pure * * @template T of object * * @psalm-assert T $value * * @psalm-param class-string $class * * @return T * * @throws InvalidArgumentException */ public static function isInstanceOf(mixed $value, mixed $class, string $message = ''): object { static::string($class, 'Expected class as a string. Got: %s'); if (!($value instanceof $class)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an instance of %2$s. Got: %s', static::typeToString($value), $class )); } return $value; } /** * @template T of object * * @psalm-assert object $value * @psalm-param class-string $class * * @return !T * * @throws InvalidArgumentException */ public static function notInstanceOf(mixed $value, mixed $class, string $message = ''): object { static::string($class, 'Expected class as a string. Got: %s'); if (!\is_object($value) || $value instanceof $class) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an instance other than %2$s. Got: %s', static::typeToString($value), $class )); } return $value; } /** * @template T of object * * @psalm-assert T $value * * @param T $value * * @return T * * @throws InvalidArgumentException */ public static function isInstanceOfAny(mixed $value, mixed $classes, string $message = ''): object { static::isIterable($classes); foreach ($classes as $class) { static::string($class, 'Expected class as a string. Got: %s'); if ($value instanceof $class) { return $value; } } static::reportInvalidArgument(\sprintf( $message ?: 'Expected an instance of any of %2$s. Got: %s', static::typeToString($value), \implode(', ', \array_map(static::valueToString(...), \iterator_to_array($classes))) )); } /** * @psalm-pure * * @template T of object * * @psalm-assert T|class-string $value * * @return T * * @throws InvalidArgumentException */ public static function isAOf(mixed $value, mixed $class, string $message = ''): object|string { static::string($class, 'Expected class as a string. Got: %s'); if (!\is_a($value, $class, \is_string($value))) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an instance of this class or to this class among its parents "%2$s". Got: %s', static::valueToString($value), $class )); } return $value; } /** * @psalm-pure * * @template T * * @psalm-assert object|class-string $value * * @param T $value * * @return T * * @throws InvalidArgumentException */ public static function isNotA(mixed $value, mixed $class, string $message = ''): object|string { static::objectish($value, $message); static::string($class, 'Expected class as a string. Got: %s'); if (\is_a($value, $class, \is_string($value))) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an instance of this class or to this class among its parents other than "%2$s". Got: %s', static::valueToString($value), $class )); } return $value; } /** * @psalm-pure * * @param object|string $value * @param string[] $classes * @psalm-param array $classes * * @throws InvalidArgumentException */ public static function isAnyOf(mixed $value, mixed $classes, string $message = ''): object|string { static::objectish($value, $message); static::isIterable($classes); foreach ($classes as $class) { static::string($class, 'Expected class as a string. Got: %s'); if (\is_a($value, $class, \is_string($value))) { return $value; } } static::reportInvalidArgument(\sprintf( $message ?: 'Expected an instance of any of this classes or any of those classes among their parents "%2$s". Got: %s', static::valueToString($value), \implode(', ', \iterator_to_array($classes)) )); } /** * @psalm-pure * * @psalm-assert empty $value * * @psalm-return empty * * @throws InvalidArgumentException */ public static function isEmpty(mixed $value, string $message = ''): mixed { if (!empty($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an empty value. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert !empty $value * * @psalm-return !empty * * @throws InvalidArgumentException */ public static function notEmpty(mixed $value, string $message = ''): mixed { if (empty($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a non-empty value. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert null $value * * @throws InvalidArgumentException */ public static function null(mixed $value, string $message = ''): null { if (null !== $value) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected null. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert !null $value * * @psalm-return !null * * @throws InvalidArgumentException */ public static function notNull(mixed $value, string $message = ''): mixed { if (null === $value) { static::reportInvalidArgument( $message ?: 'Expected a value other than null.' ); } return $value; } /** * @psalm-pure * * @psalm-assert true $value * * @throws InvalidArgumentException */ public static function true(mixed $value, string $message = ''): true { if (true !== $value) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to be true. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert false $value * * @throws InvalidArgumentException */ public static function false(mixed $value, string $message = ''): false { if (false !== $value) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to be false. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert !false $value * * @throws InvalidArgumentException */ public static function notFalse(mixed $value, string $message = ''): mixed { if (false === $value) { static::reportInvalidArgument( $message ?: 'Expected a value other than false.' ); } return $value; } /** * @psalm-pure * * @psalm-param string $value * * @throws InvalidArgumentException */ public static function ip(mixed $value, string $message = ''): string { static::string($value, $message); if (false === \filter_var($value, \FILTER_VALIDATE_IP)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to be an IP. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-param string $value * * @throws InvalidArgumentException */ public static function ipv4(mixed $value, string $message = ''): string { static::string($value, $message); if (false === \filter_var($value, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to be an IPv4. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-param string $value * * @throws InvalidArgumentException */ public static function ipv6(mixed $value, string $message = ''): string { static::string($value, $message); if (false === \filter_var($value, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to be an IPv6. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-param string $value * * @throws InvalidArgumentException */ public static function email(mixed $value, string $message = ''): string { static::string($value, $message); if (false === \filter_var($value, FILTER_VALIDATE_EMAIL, FILTER_FLAG_EMAIL_UNICODE)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to be a valid e-mail address. Got: %s', static::valueToString($value) )); } return $value; } /** * Does non-strict comparisons on the items, so ['3', 3] will not pass the assertion. * * @throws InvalidArgumentException */ public static function uniqueValues(mixed $values, string $message = ''): array { static::isArray($values); $allValues = \count($values); $uniqueValues = \count(\array_unique($values)); if ($allValues !== $uniqueValues) { $difference = $allValues - $uniqueValues; static::reportInvalidArgument(\sprintf( $message ?: 'Expected an array of unique values, but %s of them %s duplicated', $difference, 1 === $difference ? 'is' : 'are' )); } return $values; } /** * @throws InvalidArgumentException */ public static function eq(mixed $value, mixed $expect, string $message = ''): mixed { if ($expect != $value) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value equal to %2$s. Got: %s', static::valueToString($value), static::valueToString($expect) )); } return $value; } /** * @throws InvalidArgumentException */ public static function notEq(mixed $value, mixed $expect, string $message = ''): mixed { if ($expect == $value) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a different value than %s.', static::valueToString($expect) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function same(mixed $value, mixed $expect, string $message = ''): mixed { if ($expect !== $value) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value identical to %2$s. Got: %s', static::valueToString($value), static::valueToString($expect) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function notSame(mixed $value, mixed $expect, string $message = ''): mixed { if ($expect === $value) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value not identical to %s.', static::valueToString($expect) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function greaterThan(mixed $value, mixed $limit, string $message = ''): mixed { if ($value <= $limit) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value greater than %2$s. Got: %s', static::valueToString($value), static::valueToString($limit) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function greaterThanEq(mixed $value, mixed $limit, string $message = ''): mixed { if ($value < $limit) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value greater than or equal to %2$s. Got: %s', static::valueToString($value), static::valueToString($limit) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function lessThan(mixed $value, mixed $limit, string $message = ''): mixed { if ($value >= $limit) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value less than %2$s. Got: %s', static::valueToString($value), static::valueToString($limit) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function lessThanEq(mixed $value, mixed $limit, string $message = ''): mixed { if ($value > $limit) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value less than or equal to %2$s. Got: %s', static::valueToString($value), static::valueToString($limit) )); } return $value; } /** * Inclusive range, so Assert::(3, 3, 5) passes. * * @psalm-pure * * @throws InvalidArgumentException */ public static function range(mixed $value, mixed $min, mixed $max, string $message = ''): mixed { if ($value < $min || $value > $max) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value between %2$s and %3$s. Got: %s', static::valueToString($value), static::valueToString($min), static::valueToString($max) )); } return $value; } /** * A more human-readable alias of Assert::inArray(). * * @psalm-pure * * @throws InvalidArgumentException */ public static function oneOf(mixed $value, mixed $values, string $message = ''): mixed { static::inArray($value, $values, $message); return $value; } /** * Does strict comparison, so Assert::inArray(3, ['3']) does not pass the assertion. * * @psalm-pure * * @throws InvalidArgumentException */ public static function inArray(mixed $value, mixed $values, string $message = ''): mixed { static::isArray($values); if (!\in_array($value, $values, true)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected one of: %2$s. Got: %s', static::valueToString($value), \implode(', ', \array_map(static::valueToString(...), $values)) )); } return $value; } /** * A more human-readable alias of Assert::notInArray(). * * @psalm-pure * * @throws InvalidArgumentException */ public static function notOneOf(mixed $value, mixed $values, string $message = ''): mixed { static::notInArray($value, $values, $message); return $value; } /** * Check that a value is not present * * Does strict comparison, so Assert::notInArray(3, [1, 2, 3]) will not pass * the assertion, but Assert::notInArray(3, ['3']) will. * * @psalm-pure * * @throws InvalidArgumentException */ public static function notInArray(mixed $value, mixed $values, string $message = ''): mixed { static::isArray($values); if (\in_array($value, $values, true)) { static::reportInvalidArgument(\sprintf( $message ?: '%2$s was not expected to contain a value. Got: %s', static::valueToString($value), \implode(', ', \array_map(static::valueToString(...), $values)) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function contains(mixed $value, mixed $subString, string $message = ''): string { static::string($value); static::string($subString); if (!\str_contains($value, $subString)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to contain %2$s. Got: %s', static::valueToString($value), static::valueToString($subString) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function notContains(mixed $value, mixed $subString, string $message = ''): string { static::string($value); static::string($subString); if (\str_contains($value, $subString)) { static::reportInvalidArgument(\sprintf( $message ?: '%2$s was not expected to be contained in a value. Got: %s', static::valueToString($value), static::valueToString($subString) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function notWhitespaceOnly(mixed $value, string $message = ''): string { static::string($value); if (\preg_match('/^\s*$/', $value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a non-whitespace string. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function startsWith(mixed $value, mixed $prefix, string $message = ''): string { static::string($value); static::string($prefix); if (!\str_starts_with($value, $prefix)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to start with %2$s. Got: %s', static::valueToString($value), static::valueToString($prefix) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function notStartsWith(mixed $value, mixed $prefix, string $message = ''): string { static::string($value); static::string($prefix); if (\str_starts_with($value, $prefix)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value not to start with %2$s. Got: %s', static::valueToString($value), static::valueToString($prefix) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function startsWithLetter(mixed $value, string $message = ''): string { static::string($value); $valid = isset($value[0]); if ($valid) { $locale = \setlocale(LC_CTYPE, '0'); \setlocale(LC_CTYPE, 'C'); $valid = \ctype_alpha($value[0]); \setlocale(LC_CTYPE, $locale); } if (!$valid) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to start with a letter. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function endsWith(mixed $value, mixed $suffix, string $message = ''): string { static::string($value); static::string($suffix); if (!\str_ends_with($value, $suffix)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to end with %2$s. Got: %s', static::valueToString($value), static::valueToString($suffix) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function notEndsWith(mixed $value, mixed $suffix, string $message = ''): string { static::string($value); static::string($suffix); if (\str_ends_with($value, $suffix)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value not to end with %2$s. Got: %s', static::valueToString($value), static::valueToString($suffix) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function regex(mixed $value, mixed $pattern, string $message = ''): string { static::string($value); static::string($pattern); if (!\preg_match($pattern, $value)) { static::reportInvalidArgument(\sprintf( $message ?: 'The value %s does not match the expected pattern.', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function notRegex(mixed $value, mixed $pattern, string $message = ''): string { static::string($value); static::string($pattern); if (\preg_match($pattern, $value, $matches, PREG_OFFSET_CAPTURE)) { static::reportInvalidArgument(\sprintf( $message ?: 'The value %s matches the pattern %s (at offset %d).', static::valueToString($value), static::valueToString($pattern), $matches[0][1] )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function unicodeLetters(mixed $value, string $message = ''): string { static::string($value, $message); if (!\preg_match('/^\p{L}+$/u', $value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to contain only Unicode letters. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function alpha(mixed $value, string $message = ''): string { static::string($value, $message); $locale = \setlocale(LC_CTYPE, '0'); \setlocale(LC_CTYPE, 'C'); $valid = !\ctype_alpha($value); \setlocale(LC_CTYPE, $locale); if ($valid) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to contain only letters. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function digits(mixed $value, string $message = ''): string { static::string($value, $message); $locale = \setlocale(LC_CTYPE, '0'); \setlocale(LC_CTYPE, 'C'); $valid = !\ctype_digit($value); \setlocale(LC_CTYPE, $locale); if ($valid) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to contain digits only. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function alnum(mixed $value, string $message = ''): string { static::string($value, $message); $locale = \setlocale(LC_CTYPE, '0'); \setlocale(LC_CTYPE, 'C'); $valid = !\ctype_alnum($value); \setlocale(LC_CTYPE, $locale); if ($valid) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to contain letters and digits only. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert lowercase-string $value * * @throws InvalidArgumentException */ public static function lower(mixed $value, string $message = ''): string { static::string($value, $message); $locale = \setlocale(LC_CTYPE, '0'); \setlocale(LC_CTYPE, 'C'); $valid = !\ctype_lower($value); \setlocale(LC_CTYPE, $locale); if ($valid) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to contain lowercase characters only. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @psalm-assert !lowercase-string $value * * @throws InvalidArgumentException */ public static function upper(mixed $value, string $message = ''): string { static::string($value, $message); $locale = \setlocale(LC_CTYPE, '0'); \setlocale(LC_CTYPE, 'C'); $valid = !\ctype_upper($value); \setlocale(LC_CTYPE, $locale); if ($valid) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to contain uppercase characters only. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function length(mixed $value, mixed $length, string $message = ''): string { static::string($value); static::integerish($length); if ($length !== static::strlen($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to contain %2$s characters. Got: %s', static::valueToString($value), $length )); } return $value; } /** * Inclusive min. * * @psalm-pure * * @throws InvalidArgumentException */ public static function minLength(mixed $value, mixed $min, string $message = ''): string { static::string($value); static::integerish($min); if (static::strlen($value) < $min) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to contain at least %2$s characters. Got: %s', static::valueToString($value), $min )); } return $value; } /** * Inclusive max. * * @psalm-pure * * @throws InvalidArgumentException */ public static function maxLength(mixed $value, mixed $max, string $message = ''): string { static::string($value); static::integerish($max); if (static::strlen($value) > $max) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to contain at most %2$s characters. Got: %s', static::valueToString($value), $max )); } return $value; } /** * Inclusive, so Assert::lengthBetween('asd', 3, 5); passes the assertion. * * @psalm-pure * * @throws InvalidArgumentException */ public static function lengthBetween(mixed $value, mixed $min, mixed $max, string $message = ''): string { static::string($value); static::integerish($min); static::integerish($max); $length = static::strlen($value); if ($length < $min || $length > $max) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a value to contain between %2$s and %3$s characters. Got: %s', static::valueToString($value), $min, $max )); } return $value; } /** * Will also pass if $value is a directory, use Assert::file() instead if you need to be sure it is a file. * * @throws InvalidArgumentException */ public static function fileExists(mixed $value, string $message = ''): string { static::string($value); if (!\file_exists($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'The path %s does not exist.', static::valueToString($value) )); } return $value; } /** * @throws InvalidArgumentException */ public static function file(mixed $value, string $message = ''): string { static::string($value); if (!\is_file($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'The path %s is not a file.', static::valueToString($value) )); } return $value; } /** * @throws InvalidArgumentException */ public static function directory(mixed $value, string $message = ''): string { static::string($value); if (!\is_dir($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'The path %s is not a directory.', static::valueToString($value) )); } return $value; } /** * @throws InvalidArgumentException */ public static function readable(mixed $value, string $message = ''): string { static::string($value); if (!\is_readable($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'The path %s is not readable.', static::valueToString($value) )); } return $value; } /** * @throws InvalidArgumentException */ public static function writable(mixed $value, string $message = ''): string { static::string($value); if (!\is_writable($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'The path %s is not writable.', static::valueToString($value) )); } return $value; } /** * @psalm-assert class-string $value * * @throws InvalidArgumentException */ public static function classExists(mixed $value, string $message = ''): string { static::string($value); if (!\class_exists($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an existing class name. Got: %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @template ExpectedType of object * * @psalm-assert class-string $value * * @param class-string $class * * @return class-string * * @throws InvalidArgumentException */ public static function subclassOf(mixed $value, mixed $class, string $message = ''): string { static::string($value); static::string($class); if (!\is_subclass_of($value, $class)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected a sub-class of %2$s. Got: %s', static::valueToString($value), static::valueToString($class) )); } return $value; } /** * @psalm-assert class-string $value * * @throws InvalidArgumentException */ public static function interfaceExists(mixed $value, string $message = ''): string { static::string($value); if (!\interface_exists($value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an existing interface name. got %s', static::valueToString($value) )); } return $value; } /** * @psalm-pure * * @template ExpectedType of object * * @psalm-assert class-string|ExpectedType $value * * @param class-string|ExpectedType $value * @param class-string $interface * * @throws InvalidArgumentException */ public static function implementsInterface(mixed $value, mixed $interface, string $message = ''): object|string { static::objectish($value); $implements = \class_implements($value); static::isArray($implements); if (!\in_array($interface, $implements, true)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an implementation of %2$s. Got: %s', static::valueToString($value), static::valueToString($interface) )); } return $value; } /** * @psalm-pure * * @param string|object $classOrObject * * @throws InvalidArgumentException */ public static function propertyExists(mixed $classOrObject, mixed $property, string $message = ''): object|string { static::objectish($classOrObject); if (!\property_exists($classOrObject, $property)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected the property %s to exist.', static::valueToString($property) )); } return $classOrObject; } /** * @psalm-pure * * @param string|object $classOrObject * @psalm-param class-string|object $classOrObject * * @throws InvalidArgumentException */ public static function propertyNotExists(mixed $classOrObject, mixed $property, string $message = ''): mixed { if (!(\is_string($classOrObject) || \is_object($classOrObject)) || \property_exists($classOrObject, $property)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected the property %s to not exist.', static::valueToString($property) )); } return $classOrObject; } /** * @psalm-pure * * @param string|object $classOrObject * @psalm-param class-string|object $classOrObject * * @throws InvalidArgumentException */ public static function methodExists(mixed $classOrObject, mixed $method, string $message = ''): object|string { static::objectish($classOrObject); if (!\method_exists($classOrObject, $method)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected the method %s to exist.', static::valueToString($method) )); } return $classOrObject; } /** * @psalm-pure * * @param string|object $classOrObject * @psalm-param class-string|object $classOrObject * * @throws InvalidArgumentException */ public static function methodNotExists(mixed $classOrObject, mixed $method, string $message = ''): mixed { static::objectish($classOrObject); if (\method_exists($classOrObject, $method)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected the method %s to not exist.', static::valueToString($method) )); } return $classOrObject; } /** * @psalm-pure * * @param string|int $key * * @throws InvalidArgumentException */ public static function keyExists(mixed $array, string|int $key, string $message = ''): array { static::isArray($array, $message); if (!(isset($array[$key]) || \array_key_exists($key, $array))) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected the key %s to exist.', static::valueToString($key) )); } return $array; } /** * @psalm-pure * * @param string|int $key * * @throws InvalidArgumentException */ public static function keyNotExists(mixed $array, string|int $key, string $message = ''): array { static::isArray($array, $message); if (isset($array[$key]) || \array_key_exists($key, $array)) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected the key %s to not exist.', static::valueToString($key) )); } return $array; } /** * Checks if a value is a valid array key (int or string). * * @psalm-pure * * @psalm-assert array-key $value * * @throws InvalidArgumentException */ public static function validArrayKey(mixed $value, string $message = ''): string|int { if (!(\is_int($value) || \is_string($value))) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected string or integer. Got: %s', static::typeToString($value) )); } return $value; } /** * @throws InvalidArgumentException */ public static function count(mixed $array, mixed $number, string $message = ''): array|Countable { static::isCountable($array); static::integerish($number); static::eq( \count($array), $number, \sprintf( $message ?: 'Expected an array to contain %d elements. Got: %d.', $number, \count($array) ) ); return $array; } /** * @throws InvalidArgumentException */ public static function minCount(mixed $array, mixed $min, string $message = ''): array|Countable { static::isCountable($array); static::integerish($min); if (\count($array) < $min) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an array to contain at least %2$d elements. Got: %d', \count($array), $min )); } return $array; } /** * @throws InvalidArgumentException */ public static function maxCount(mixed $array, mixed $max, string $message = ''): array|Countable { static::isCountable($array); static::integerish($max); if (\count($array) > $max) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an array to contain at most %2$d elements. Got: %d', \count($array), $max )); } return $array; } /** * @throws InvalidArgumentException */ public static function countBetween(mixed $array, mixed $min, mixed $max, string $message = ''): array|Countable { static::isCountable($array); static::integerish($min); static::integerish($max); $count = \count($array); if ($count < $min || $count > $max) { static::reportInvalidArgument(\sprintf( $message ?: 'Expected an array to contain between %2$d and %3$d elements. Got: %d', $count, $min, $max )); } return $array; } /** * @psalm-pure * * @psalm-assert list $array * * @psalm-return list * * @throws InvalidArgumentException */ public static function isList(mixed $array, string $message = ''): array { if (!\is_array($array) || !\array_is_list($array)) { static::reportInvalidArgument( $message ?: 'Expected list - non-associative array.' ); } return $array; } /** * @psalm-pure * * @psalm-assert non-empty-list $array * * @psalm-return non-empty-list * * @throws InvalidArgumentException */ public static function isNonEmptyList(mixed $array, string $message = ''): array { static::isList($array, $message); static::notEmpty($array, $message); return $array; } /** * @psalm-pure * * @template T * * @psalm-assert array $array * * @param mixed|array $array * * @return array * * @throws InvalidArgumentException */ public static function isMap(mixed $array, string $message = ''): array { static::isArray($array, $message); if (\count($array) > 0 && \array_is_list($array)) { static::reportInvalidArgument( $message ?: 'Expected map - associative array with string keys.' ); } return $array; } /** * @psalm-assert callable $callable * * @param Closure|callable $callable * * @return Closure|callable-string * * @throws InvalidArgumentException */ public static function isStatic(mixed $callable, string $message = ''): Closure|string { static::isCallable($callable, $message); $callable = static::callableToClosure($callable); $reflection = new ReflectionFunction($callable); if (!$reflection->isStatic()) { static::reportInvalidArgument( $message ?: 'Closure is not static.' ); } return $callable; } /** * @psalm-assert callable $callable * * @param Closure|callable $callable * * @return Closure|callable-string * * @throws InvalidArgumentException */ public static function notStatic(mixed $callable, string $message = ''): Closure|string { static::isCallable($callable, $message); $callable = static::callableToClosure($callable); $reflection = new ReflectionFunction($callable); if ($reflection->isStatic()) { static::reportInvalidArgument( $message ?: 'Closure is not static.' ); } return $callable; } /** * @psalm-pure * * @template T * * @psalm-assert array $array * @psalm-assert !empty $array * * @param array $array * * @return array * * @throws InvalidArgumentException */ public static function isNonEmptyMap(mixed $array, string $message = ''): array { static::isMap($array, $message); static::notEmpty($array, $message); return $array; } /** * @psalm-pure * * @throws InvalidArgumentException */ public static function uuid(mixed $value, string $message = ''): string { static::string($value, $message); $originalValue = $value; $value = \str_replace(['urn:', 'uuid:', '{', '}'], '', $value); // The nil UUID is special form of UUID that is specified to have all // 128 bits set to zero. if ('00000000-0000-0000-0000-000000000000' === $value) { return $originalValue; } if (!\preg_match('/^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/D', $value)) { static::reportInvalidArgument(\sprintf( $message ?: 'Value %s is not a valid UUID.', static::valueToString($value) )); } return $originalValue; } /** * @psalm-param class-string $class * * @throws InvalidArgumentException */ public static function throws(mixed $expression, string $class = Throwable::class, string $message = ''): callable { static::string($class); static::isCallable($expression); $actual = 'none'; try { $expression(); } catch (Throwable $e) { $actual = \get_class($e); if ($e instanceof $class) { return $expression; } } static::reportInvalidArgument($message ?: \sprintf( 'Expected to throw "%s", got "%s"', $class, $actual )); } /** * @psalm-pure * * @return Closure|callable-string */ protected static function callableToClosure(callable $callable): Closure|string { if (\is_string($callable) && \function_exists($callable)) { return $callable; } if ($callable instanceof Closure) { return $callable; } return $callable(...); } /** * @psalm-pure */ protected static function valueToString(mixed $value): string { if (null === $value) { return 'null'; } if (true === $value) { return 'true'; } if (false === $value) { return 'false'; } if (\is_array($value)) { return 'array'; } if (\is_object($value)) { if (\method_exists($value, '__toString')) { return \get_class($value).': '.self::valueToString($value->__toString()); } if ($value instanceof DateTime || $value instanceof DateTimeImmutable) { return \get_class($value).': '.self::valueToString($value->format('c')); } if (\enum_exists(\get_class($value))) { return \get_class($value).'::'.$value->name; } return \get_class($value); } if (\is_resource($value)) { return 'resource'; } if (\is_string($value)) { return '"'.$value.'"'; } return (string) $value; } /** * @psalm-pure */ protected static function typeToString(mixed $value): string { return \is_object($value) ? \get_class($value) : \gettype($value); } protected static function strlen(string $value): int { if (!\function_exists('mb_detect_encoding')) { return \strlen($value); } if (false === $encoding = \mb_detect_encoding($value)) { return \strlen($value); } return \mb_strlen($value, $encoding); } /** * @psalm-pure this method is not supposed to perform side effects * * @throws InvalidArgumentException */ protected static function reportInvalidArgument(string $message): never { throw new InvalidArgumentException($message); } private function __construct() { } } ================================================ FILE: src/InvalidArgumentException.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Webmozart\Assert; class InvalidArgumentException extends \InvalidArgumentException { } ================================================ FILE: src/Mixin.php ================================================ $value * * @return iterable * * @throws InvalidArgumentException */ public static function allString(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::string($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrString(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::string($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert non-empty-string|null $value * * @return non-empty-string|null * * @throws InvalidArgumentException */ public static function nullOrStringNotEmpty(mixed $value, string $message = ''): mixed { null === $value || static::stringNotEmpty($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allStringNotEmpty(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::stringNotEmpty($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrStringNotEmpty(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::stringNotEmpty($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert int|null $value * * @return int|null * * @throws InvalidArgumentException */ public static function nullOrInteger(mixed $value, string $message = ''): mixed { null === $value || static::integer($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allInteger(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::integer($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrInteger(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::integer($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert numeric|null $value * * @return numeric|null * * @throws InvalidArgumentException */ public static function nullOrIntegerish(mixed $value, string $message = ''): mixed { null === $value || static::integerish($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allIntegerish(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::integerish($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrIntegerish(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::integerish($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert positive-int|null $value * * @return positive-int|null * * @throws InvalidArgumentException */ public static function nullOrPositiveInteger(mixed $value, string $message = ''): mixed { null === $value || static::positiveInteger($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allPositiveInteger(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::positiveInteger($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrPositiveInteger(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::positiveInteger($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert non-negative-int|null $value * * @return non-negative-int|null * * @throws InvalidArgumentException */ public static function nullOrNotNegativeInteger(mixed $value, string $message = ''): mixed { null === $value || static::notNegativeInteger($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNotNegativeInteger(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::notNegativeInteger($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrNotNegativeInteger(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::notNegativeInteger($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert negative-int|null $value * * @return negative-int|null * * @throws InvalidArgumentException */ public static function nullOrNegativeInteger(mixed $value, string $message = ''): mixed { null === $value || static::negativeInteger($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNegativeInteger(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::negativeInteger($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrNegativeInteger(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::negativeInteger($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert float|null $value * * @return float|null * * @throws InvalidArgumentException */ public static function nullOrFloat(mixed $value, string $message = ''): mixed { null === $value || static::float($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allFloat(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::float($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrFloat(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::float($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert numeric|null $value * * @return numeric|null * * @throws InvalidArgumentException */ public static function nullOrNumeric(mixed $value, string $message = ''): mixed { null === $value || static::numeric($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNumeric(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::numeric($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrNumeric(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::numeric($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert positive-int|0|null $value * * @return positive-int|0|null * * @throws InvalidArgumentException */ public static function nullOrNatural(mixed $value, string $message = ''): mixed { null === $value || static::natural($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNatural(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::natural($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrNatural(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::natural($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert bool|null $value * * @return bool|null * * @throws InvalidArgumentException */ public static function nullOrBoolean(mixed $value, string $message = ''): mixed { null === $value || static::boolean($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allBoolean(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::boolean($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrBoolean(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::boolean($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert scalar|null $value * * @return scalar|null * * @throws InvalidArgumentException */ public static function nullOrScalar(mixed $value, string $message = ''): mixed { null === $value || static::scalar($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allScalar(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::scalar($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrScalar(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::scalar($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert object|null $value * * @return object|null * * @throws InvalidArgumentException */ public static function nullOrObject(mixed $value, string $message = ''): mixed { null === $value || static::object($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allObject(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::object($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrObject(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::object($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert object|string|null $value * * @return object|string|null * * @throws InvalidArgumentException */ public static function nullOrObjectish(mixed $value, string $message = ''): mixed { null === $value || static::objectish($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allObjectish(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::objectish($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrObjectish(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::objectish($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert resource|null $value * * @see https://www.php.net/manual/en/function.get-resource-type.php * * @return resource|null * * @throws InvalidArgumentException */ public static function nullOrResource(mixed $value, ?string $type = null, string $message = ''): mixed { null === $value || static::resource($value, $type, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @see https://www.php.net/manual/en/function.get-resource-type.php * * @return iterable * * @throws InvalidArgumentException */ public static function allResource(mixed $value, ?string $type = null, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::resource($entry, $type, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @see https://www.php.net/manual/en/function.get-resource-type.php * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrResource(mixed $value, ?string $type = null, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::resource($entry, $type, $message); } return $value; } /** * @psalm-pure * * @psalm-assert callable|null $value * * @return callable|null * * @throws InvalidArgumentException */ public static function nullOrIsCallable(mixed $value, string $message = ''): mixed { null === $value || static::isCallable($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allIsCallable(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::isCallable($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrIsCallable(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::isCallable($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert array|null $value * * @return array|null * * @throws InvalidArgumentException */ public static function nullOrIsArray(mixed $value, string $message = ''): mixed { null === $value || static::isArray($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allIsArray(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::isArray($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrIsArray(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::isArray($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert array|ArrayAccess|null $value * * @return array|ArrayAccess|null * * @throws InvalidArgumentException */ public static function nullOrIsArrayAccessible(mixed $value, string $message = ''): mixed { null === $value || static::isArrayAccessible($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allIsArrayAccessible(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::isArrayAccessible($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrIsArrayAccessible(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::isArrayAccessible($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert countable|null $value * * @return countable|null * * @throws InvalidArgumentException */ public static function nullOrIsCountable(mixed $value, string $message = ''): mixed { null === $value || static::isCountable($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allIsCountable(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::isCountable($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrIsCountable(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::isCountable($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable|null $value * * @return iterable|null * * @throws InvalidArgumentException */ public static function nullOrIsIterable(mixed $value, string $message = ''): mixed { null === $value || static::isIterable($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allIsIterable(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::isIterable($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrIsIterable(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::isIterable($entry, $message); } return $value; } /** * @psalm-pure * * @template T of object * @psalm-assert T|null $value * * @psalm-param class-string $class * @return T|null * * @throws InvalidArgumentException */ public static function nullOrIsInstanceOf(mixed $value, mixed $class, string $message = ''): mixed { null === $value || static::isInstanceOf($value, $class, $message); return $value; } /** * @psalm-pure * * @template T of object * @psalm-assert iterable $value * * @psalm-param class-string $class * @return iterable * * @throws InvalidArgumentException */ public static function allIsInstanceOf(mixed $value, mixed $class, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::isInstanceOf($entry, $class, $message); } return $value; } /** * @psalm-pure * * @template T of object * @psalm-assert iterable $value * * @psalm-param class-string $class * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrIsInstanceOf(mixed $value, mixed $class, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::isInstanceOf($entry, $class, $message); } return $value; } /** * @template T of object * @psalm-param class-string $class * @return mixed * * @throws InvalidArgumentException */ public static function nullOrNotInstanceOf(mixed $value, mixed $class, string $message = ''): mixed { null === $value || static::notInstanceOf($value, $class, $message); return $value; } /** * @template T of object * @psalm-param class-string $class * @return mixed * * @throws InvalidArgumentException */ public static function allNotInstanceOf(mixed $value, mixed $class, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::notInstanceOf($entry, $class, $message); } return $value; } /** * @template T of object * @psalm-assert iterable $value * * @psalm-param class-string $class * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrNotInstanceOf(mixed $value, mixed $class, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::notInstanceOf($entry, $class, $message); } return $value; } /** * @template T of object * @psalm-assert T|null $value * * @param T|null $value * * @return T|null * * @throws InvalidArgumentException */ public static function nullOrIsInstanceOfAny(mixed $value, mixed $classes, string $message = ''): mixed { null === $value || static::isInstanceOfAny($value, $classes, $message); return $value; } /** * @template T of object * @psalm-assert iterable $value * * @param iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allIsInstanceOfAny(mixed $value, mixed $classes, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::isInstanceOfAny($entry, $classes, $message); } return $value; } /** * @template T of object * @psalm-assert iterable $value * * @param iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrIsInstanceOfAny(mixed $value, mixed $classes, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::isInstanceOfAny($entry, $classes, $message); } return $value; } /** * @psalm-pure * * @template T of object * @psalm-assert T|class-string|null $value * * @return T|class-string|null * * @throws InvalidArgumentException */ public static function nullOrIsAOf(mixed $value, mixed $class, string $message = ''): mixed { null === $value || static::isAOf($value, $class, $message); return $value; } /** * @psalm-pure * * @template T of object * @psalm-assert iterable> $value * * @return iterable> * * @throws InvalidArgumentException */ public static function allIsAOf(mixed $value, mixed $class, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::isAOf($entry, $class, $message); } return $value; } /** * @psalm-pure * * @template T of object * @psalm-assert iterable|null> $value * * @return iterable|null> * * @throws InvalidArgumentException */ public static function allNullOrIsAOf(mixed $value, mixed $class, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::isAOf($entry, $class, $message); } return $value; } /** * @psalm-pure * * @template T * * @param T|null $value * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrIsNotA(mixed $value, mixed $class, string $message = ''): mixed { null === $value || static::isNotA($value, $class, $message); return $value; } /** * @psalm-pure * * @template T * * @param iterable $value * * @return mixed * * @throws InvalidArgumentException */ public static function allIsNotA(mixed $value, mixed $class, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::isNotA($entry, $class, $message); } return $value; } /** * @psalm-pure * * @template T * @psalm-assert iterable $value * * @param iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrIsNotA(mixed $value, mixed $class, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::isNotA($entry, $class, $message); } return $value; } /** * @psalm-pure * * @param object|string|null $value * @param string[] $classes * * @psalm-param array $classes * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrIsAnyOf(mixed $value, mixed $classes, string $message = ''): mixed { null === $value || static::isAnyOf($value, $classes, $message); return $value; } /** * @psalm-pure * * @param iterable $value * @param string[] $classes * * @psalm-param array $classes * * @return mixed * * @throws InvalidArgumentException */ public static function allIsAnyOf(mixed $value, mixed $classes, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::isAnyOf($entry, $classes, $message); } return $value; } /** * @psalm-pure * * @param iterable $value * @param string[] $classes * * @psalm-param array $classes * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrIsAnyOf(mixed $value, mixed $classes, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::isAnyOf($entry, $classes, $message); } return $value; } /** * @psalm-pure * * @psalm-assert empty $value * * @return empty * * @throws InvalidArgumentException */ public static function nullOrIsEmpty(mixed $value, string $message = ''): mixed { null === $value || static::isEmpty($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allIsEmpty(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::isEmpty($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrIsEmpty(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::isEmpty($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrNotEmpty(mixed $value, string $message = ''): mixed { null === $value || static::notEmpty($value, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNotEmpty(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::notEmpty($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrNotEmpty(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::notEmpty($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNull(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::null($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNotNull(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::notNull($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert true|null $value * * @return true|null * * @throws InvalidArgumentException */ public static function nullOrTrue(mixed $value, string $message = ''): mixed { null === $value || static::true($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allTrue(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::true($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrTrue(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::true($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert false|null $value * * @return false|null * * @throws InvalidArgumentException */ public static function nullOrFalse(mixed $value, string $message = ''): mixed { null === $value || static::false($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allFalse(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::false($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrFalse(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::false($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrNotFalse(mixed $value, string $message = ''): mixed { null === $value || static::notFalse($value, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNotFalse(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::notFalse($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrNotFalse(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::notFalse($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-param string|null $value * @return mixed * * @throws InvalidArgumentException */ public static function nullOrIp(mixed $value, string $message = ''): mixed { null === $value || static::ip($value, $message); return $value; } /** * @psalm-pure * * @psalm-param iterable $value * @return mixed * * @throws InvalidArgumentException */ public static function allIp(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::ip($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-param iterable $value * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrIp(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::ip($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-param string|null $value * @return mixed * * @throws InvalidArgumentException */ public static function nullOrIpv4(mixed $value, string $message = ''): mixed { null === $value || static::ipv4($value, $message); return $value; } /** * @psalm-pure * * @psalm-param iterable $value * @return mixed * * @throws InvalidArgumentException */ public static function allIpv4(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::ipv4($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-param iterable $value * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrIpv4(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::ipv4($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-param string|null $value * @return mixed * * @throws InvalidArgumentException */ public static function nullOrIpv6(mixed $value, string $message = ''): mixed { null === $value || static::ipv6($value, $message); return $value; } /** * @psalm-pure * * @psalm-param iterable $value * @return mixed * * @throws InvalidArgumentException */ public static function allIpv6(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::ipv6($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-param iterable $value * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrIpv6(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::ipv6($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-param string|null $value * @return mixed * * @throws InvalidArgumentException */ public static function nullOrEmail(mixed $value, string $message = ''): mixed { null === $value || static::email($value, $message); return $value; } /** * @psalm-pure * * @psalm-param iterable $value * @return mixed * * @throws InvalidArgumentException */ public static function allEmail(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::email($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-param iterable $value * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrEmail(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::email($entry, $message); } return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function nullOrUniqueValues(mixed $values, string $message = ''): mixed { null === $values || static::uniqueValues($values, $message); return $values; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allUniqueValues(mixed $values, string $message = ''): mixed { static::isIterable($values); foreach ($values as $entry) { static::uniqueValues($entry, $message); } return $values; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrUniqueValues(mixed $values, string $message = ''): mixed { static::isIterable($values); foreach ($values as $entry) { null === $entry || static::uniqueValues($entry, $message); } return $values; } /** * @return mixed * * @throws InvalidArgumentException */ public static function nullOrEq(mixed $value, mixed $expect, string $message = ''): mixed { null === $value || static::eq($value, $expect, $message); return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allEq(mixed $value, mixed $expect, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::eq($entry, $expect, $message); } return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrEq(mixed $value, mixed $expect, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::eq($entry, $expect, $message); } return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function nullOrNotEq(mixed $value, mixed $expect, string $message = ''): mixed { null === $value || static::notEq($value, $expect, $message); return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allNotEq(mixed $value, mixed $expect, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::notEq($entry, $expect, $message); } return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrNotEq(mixed $value, mixed $expect, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::notEq($entry, $expect, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrSame(mixed $value, mixed $expect, string $message = ''): mixed { null === $value || static::same($value, $expect, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allSame(mixed $value, mixed $expect, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::same($entry, $expect, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrSame(mixed $value, mixed $expect, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::same($entry, $expect, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrNotSame(mixed $value, mixed $expect, string $message = ''): mixed { null === $value || static::notSame($value, $expect, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNotSame(mixed $value, mixed $expect, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::notSame($entry, $expect, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrNotSame(mixed $value, mixed $expect, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::notSame($entry, $expect, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrGreaterThan(mixed $value, mixed $limit, string $message = ''): mixed { null === $value || static::greaterThan($value, $limit, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allGreaterThan(mixed $value, mixed $limit, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::greaterThan($entry, $limit, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrGreaterThan(mixed $value, mixed $limit, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::greaterThan($entry, $limit, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrGreaterThanEq(mixed $value, mixed $limit, string $message = ''): mixed { null === $value || static::greaterThanEq($value, $limit, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allGreaterThanEq(mixed $value, mixed $limit, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::greaterThanEq($entry, $limit, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrGreaterThanEq(mixed $value, mixed $limit, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::greaterThanEq($entry, $limit, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrLessThan(mixed $value, mixed $limit, string $message = ''): mixed { null === $value || static::lessThan($value, $limit, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allLessThan(mixed $value, mixed $limit, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::lessThan($entry, $limit, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrLessThan(mixed $value, mixed $limit, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::lessThan($entry, $limit, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrLessThanEq(mixed $value, mixed $limit, string $message = ''): mixed { null === $value || static::lessThanEq($value, $limit, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allLessThanEq(mixed $value, mixed $limit, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::lessThanEq($entry, $limit, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrLessThanEq(mixed $value, mixed $limit, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::lessThanEq($entry, $limit, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrRange(mixed $value, mixed $min, mixed $max, string $message = ''): mixed { null === $value || static::range($value, $min, $max, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allRange(mixed $value, mixed $min, mixed $max, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::range($entry, $min, $max, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrRange(mixed $value, mixed $min, mixed $max, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::range($entry, $min, $max, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrOneOf(mixed $value, mixed $values, string $message = ''): mixed { null === $value || static::oneOf($value, $values, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allOneOf(mixed $value, mixed $values, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::oneOf($entry, $values, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrOneOf(mixed $value, mixed $values, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::oneOf($entry, $values, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrInArray(mixed $value, mixed $values, string $message = ''): mixed { null === $value || static::inArray($value, $values, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allInArray(mixed $value, mixed $values, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::inArray($entry, $values, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrInArray(mixed $value, mixed $values, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::inArray($entry, $values, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrNotOneOf(mixed $value, mixed $values, string $message = ''): mixed { null === $value || static::notOneOf($value, $values, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNotOneOf(mixed $value, mixed $values, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::notOneOf($entry, $values, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrNotOneOf(mixed $value, mixed $values, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::notOneOf($entry, $values, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrNotInArray(mixed $value, mixed $values, string $message = ''): mixed { null === $value || static::notInArray($value, $values, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNotInArray(mixed $value, mixed $values, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::notInArray($entry, $values, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrNotInArray(mixed $value, mixed $values, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::notInArray($entry, $values, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrContains(mixed $value, mixed $subString, string $message = ''): mixed { null === $value || static::contains($value, $subString, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allContains(mixed $value, mixed $subString, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::contains($entry, $subString, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrContains(mixed $value, mixed $subString, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::contains($entry, $subString, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrNotContains(mixed $value, mixed $subString, string $message = ''): mixed { null === $value || static::notContains($value, $subString, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNotContains(mixed $value, mixed $subString, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::notContains($entry, $subString, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrNotContains(mixed $value, mixed $subString, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::notContains($entry, $subString, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrNotWhitespaceOnly(mixed $value, string $message = ''): mixed { null === $value || static::notWhitespaceOnly($value, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNotWhitespaceOnly(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::notWhitespaceOnly($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrNotWhitespaceOnly(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::notWhitespaceOnly($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrStartsWith(mixed $value, mixed $prefix, string $message = ''): mixed { null === $value || static::startsWith($value, $prefix, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allStartsWith(mixed $value, mixed $prefix, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::startsWith($entry, $prefix, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrStartsWith(mixed $value, mixed $prefix, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::startsWith($entry, $prefix, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrNotStartsWith(mixed $value, mixed $prefix, string $message = ''): mixed { null === $value || static::notStartsWith($value, $prefix, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNotStartsWith(mixed $value, mixed $prefix, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::notStartsWith($entry, $prefix, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrNotStartsWith(mixed $value, mixed $prefix, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::notStartsWith($entry, $prefix, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrStartsWithLetter(mixed $value, string $message = ''): mixed { null === $value || static::startsWithLetter($value, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allStartsWithLetter(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::startsWithLetter($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrStartsWithLetter(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::startsWithLetter($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrEndsWith(mixed $value, mixed $suffix, string $message = ''): mixed { null === $value || static::endsWith($value, $suffix, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allEndsWith(mixed $value, mixed $suffix, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::endsWith($entry, $suffix, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrEndsWith(mixed $value, mixed $suffix, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::endsWith($entry, $suffix, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrNotEndsWith(mixed $value, mixed $suffix, string $message = ''): mixed { null === $value || static::notEndsWith($value, $suffix, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNotEndsWith(mixed $value, mixed $suffix, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::notEndsWith($entry, $suffix, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrNotEndsWith(mixed $value, mixed $suffix, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::notEndsWith($entry, $suffix, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrRegex(mixed $value, mixed $pattern, string $message = ''): mixed { null === $value || static::regex($value, $pattern, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allRegex(mixed $value, mixed $pattern, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::regex($entry, $pattern, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrRegex(mixed $value, mixed $pattern, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::regex($entry, $pattern, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrNotRegex(mixed $value, mixed $pattern, string $message = ''): mixed { null === $value || static::notRegex($value, $pattern, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNotRegex(mixed $value, mixed $pattern, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::notRegex($entry, $pattern, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrNotRegex(mixed $value, mixed $pattern, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::notRegex($entry, $pattern, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrUnicodeLetters(mixed $value, string $message = ''): mixed { null === $value || static::unicodeLetters($value, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allUnicodeLetters(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::unicodeLetters($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrUnicodeLetters(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::unicodeLetters($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrAlpha(mixed $value, string $message = ''): mixed { null === $value || static::alpha($value, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allAlpha(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::alpha($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrAlpha(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::alpha($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrDigits(mixed $value, string $message = ''): mixed { null === $value || static::digits($value, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allDigits(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::digits($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrDigits(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::digits($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrAlnum(mixed $value, string $message = ''): mixed { null === $value || static::alnum($value, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allAlnum(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::alnum($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrAlnum(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::alnum($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert lowercase-string|null $value * * @return lowercase-string|null * * @throws InvalidArgumentException */ public static function nullOrLower(mixed $value, string $message = ''): mixed { null === $value || static::lower($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allLower(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::lower($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrLower(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::lower($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrUpper(mixed $value, string $message = ''): mixed { null === $value || static::upper($value, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allUpper(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::upper($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrUpper(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::upper($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrLength(mixed $value, mixed $length, string $message = ''): mixed { null === $value || static::length($value, $length, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allLength(mixed $value, mixed $length, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::length($entry, $length, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrLength(mixed $value, mixed $length, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::length($entry, $length, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrMinLength(mixed $value, mixed $min, string $message = ''): mixed { null === $value || static::minLength($value, $min, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allMinLength(mixed $value, mixed $min, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::minLength($entry, $min, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrMinLength(mixed $value, mixed $min, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::minLength($entry, $min, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrMaxLength(mixed $value, mixed $max, string $message = ''): mixed { null === $value || static::maxLength($value, $max, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allMaxLength(mixed $value, mixed $max, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::maxLength($entry, $max, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrMaxLength(mixed $value, mixed $max, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::maxLength($entry, $max, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrLengthBetween(mixed $value, mixed $min, mixed $max, string $message = ''): mixed { null === $value || static::lengthBetween($value, $min, $max, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allLengthBetween(mixed $value, mixed $min, mixed $max, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::lengthBetween($entry, $min, $max, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrLengthBetween(mixed $value, mixed $min, mixed $max, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::lengthBetween($entry, $min, $max, $message); } return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function nullOrFileExists(mixed $value, string $message = ''): mixed { null === $value || static::fileExists($value, $message); return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allFileExists(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::fileExists($entry, $message); } return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrFileExists(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::fileExists($entry, $message); } return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function nullOrFile(mixed $value, string $message = ''): mixed { null === $value || static::file($value, $message); return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allFile(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::file($entry, $message); } return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrFile(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::file($entry, $message); } return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function nullOrDirectory(mixed $value, string $message = ''): mixed { null === $value || static::directory($value, $message); return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allDirectory(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::directory($entry, $message); } return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrDirectory(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::directory($entry, $message); } return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function nullOrReadable(mixed $value, string $message = ''): mixed { null === $value || static::readable($value, $message); return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allReadable(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::readable($entry, $message); } return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrReadable(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::readable($entry, $message); } return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function nullOrWritable(mixed $value, string $message = ''): mixed { null === $value || static::writable($value, $message); return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allWritable(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::writable($entry, $message); } return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrWritable(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::writable($entry, $message); } return $value; } /** * @psalm-assert class-string|null $value * * @return class-string|null * * @throws InvalidArgumentException */ public static function nullOrClassExists(mixed $value, string $message = ''): mixed { null === $value || static::classExists($value, $message); return $value; } /** * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allClassExists(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::classExists($entry, $message); } return $value; } /** * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrClassExists(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::classExists($entry, $message); } return $value; } /** * @psalm-pure * * @template ExpectedType of object * @psalm-assert class-string|null $value * * @param class-string $class * * @return class-string|null * * @throws InvalidArgumentException */ public static function nullOrSubclassOf(mixed $value, mixed $class, string $message = ''): mixed { null === $value || static::subclassOf($value, $class, $message); return $value; } /** * @psalm-pure * * @template ExpectedType of object * @psalm-assert iterable> $value * * @param class-string $class * * @return iterable> * * @throws InvalidArgumentException */ public static function allSubclassOf(mixed $value, mixed $class, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::subclassOf($entry, $class, $message); } return $value; } /** * @psalm-pure * * @template ExpectedType of object * @psalm-assert iterable|null> $value * * @param class-string $class * * @return iterable|null> * * @throws InvalidArgumentException */ public static function allNullOrSubclassOf(mixed $value, mixed $class, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::subclassOf($entry, $class, $message); } return $value; } /** * @psalm-assert class-string|null $value * * @return class-string|null * * @throws InvalidArgumentException */ public static function nullOrInterfaceExists(mixed $value, string $message = ''): mixed { null === $value || static::interfaceExists($value, $message); return $value; } /** * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allInterfaceExists(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::interfaceExists($entry, $message); } return $value; } /** * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrInterfaceExists(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::interfaceExists($entry, $message); } return $value; } /** * @psalm-pure * * @template ExpectedType of object * @psalm-assert class-string|ExpectedType|null $value * * @param class-string|ExpectedType|null $value * @param class-string $interface * * @return class-string|ExpectedType|null * * @throws InvalidArgumentException */ public static function nullOrImplementsInterface(mixed $value, mixed $interface, string $message = ''): mixed { null === $value || static::implementsInterface($value, $interface, $message); return $value; } /** * @psalm-pure * * @template ExpectedType of object * @psalm-assert iterable|ExpectedType> $value * * @param iterable|ExpectedType> $value * @param class-string $interface * * @return iterable|ExpectedType> * * @throws InvalidArgumentException */ public static function allImplementsInterface(mixed $value, mixed $interface, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::implementsInterface($entry, $interface, $message); } return $value; } /** * @psalm-pure * * @template ExpectedType of object * @psalm-assert iterable|ExpectedType|null> $value * * @param iterable|ExpectedType|null> $value * @param class-string $interface * * @return iterable|ExpectedType|null> * * @throws InvalidArgumentException */ public static function allNullOrImplementsInterface(mixed $value, mixed $interface, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::implementsInterface($entry, $interface, $message); } return $value; } /** * @psalm-pure * * @param string|object|null $classOrObject * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrPropertyExists(mixed $classOrObject, mixed $property, string $message = ''): mixed { null === $classOrObject || static::propertyExists($classOrObject, $property, $message); return $classOrObject; } /** * @psalm-pure * * @param iterable $classOrObject * * @return mixed * * @throws InvalidArgumentException */ public static function allPropertyExists(mixed $classOrObject, mixed $property, string $message = ''): mixed { static::isIterable($classOrObject); foreach ($classOrObject as $entry) { static::propertyExists($entry, $property, $message); } return $classOrObject; } /** * @psalm-pure * * @param iterable $classOrObject * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrPropertyExists(mixed $classOrObject, mixed $property, string $message = ''): mixed { static::isIterable($classOrObject); foreach ($classOrObject as $entry) { null === $entry || static::propertyExists($entry, $property, $message); } return $classOrObject; } /** * @psalm-pure * * @param string|object|null $classOrObject * * @psalm-param class-string|object|null $classOrObject * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrPropertyNotExists(mixed $classOrObject, mixed $property, string $message = ''): mixed { null === $classOrObject || static::propertyNotExists($classOrObject, $property, $message); return $classOrObject; } /** * @psalm-pure * * @param iterable $classOrObject * * @psalm-param iterable $classOrObject * * @return mixed * * @throws InvalidArgumentException */ public static function allPropertyNotExists(mixed $classOrObject, mixed $property, string $message = ''): mixed { static::isIterable($classOrObject); foreach ($classOrObject as $entry) { static::propertyNotExists($entry, $property, $message); } return $classOrObject; } /** * @psalm-pure * * @param iterable $classOrObject * * @psalm-param iterable $classOrObject * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrPropertyNotExists(mixed $classOrObject, mixed $property, string $message = ''): mixed { static::isIterable($classOrObject); foreach ($classOrObject as $entry) { null === $entry || static::propertyNotExists($entry, $property, $message); } return $classOrObject; } /** * @psalm-pure * * @param string|object|null $classOrObject * * @psalm-param class-string|object|null $classOrObject * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrMethodExists(mixed $classOrObject, mixed $method, string $message = ''): mixed { null === $classOrObject || static::methodExists($classOrObject, $method, $message); return $classOrObject; } /** * @psalm-pure * * @param iterable $classOrObject * * @psalm-param iterable $classOrObject * * @return mixed * * @throws InvalidArgumentException */ public static function allMethodExists(mixed $classOrObject, mixed $method, string $message = ''): mixed { static::isIterable($classOrObject); foreach ($classOrObject as $entry) { static::methodExists($entry, $method, $message); } return $classOrObject; } /** * @psalm-pure * * @param iterable $classOrObject * * @psalm-param iterable $classOrObject * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrMethodExists(mixed $classOrObject, mixed $method, string $message = ''): mixed { static::isIterable($classOrObject); foreach ($classOrObject as $entry) { null === $entry || static::methodExists($entry, $method, $message); } return $classOrObject; } /** * @psalm-pure * * @param string|object|null $classOrObject * * @psalm-param class-string|object|null $classOrObject * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrMethodNotExists(mixed $classOrObject, mixed $method, string $message = ''): mixed { null === $classOrObject || static::methodNotExists($classOrObject, $method, $message); return $classOrObject; } /** * @psalm-pure * * @param iterable $classOrObject * * @psalm-param iterable $classOrObject * * @return mixed * * @throws InvalidArgumentException */ public static function allMethodNotExists(mixed $classOrObject, mixed $method, string $message = ''): mixed { static::isIterable($classOrObject); foreach ($classOrObject as $entry) { static::methodNotExists($entry, $method, $message); } return $classOrObject; } /** * @psalm-pure * * @param iterable $classOrObject * * @psalm-param iterable $classOrObject * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrMethodNotExists(mixed $classOrObject, mixed $method, string $message = ''): mixed { static::isIterable($classOrObject); foreach ($classOrObject as $entry) { null === $entry || static::methodNotExists($entry, $method, $message); } return $classOrObject; } /** * @psalm-pure * * @param string|int $key * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrKeyExists(mixed $array, string|int $key, string $message = ''): mixed { null === $array || static::keyExists($array, $key, $message); return $array; } /** * @psalm-pure * * @param string|int $key * * @return mixed * * @throws InvalidArgumentException */ public static function allKeyExists(mixed $array, string|int $key, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { static::keyExists($entry, $key, $message); } return $array; } /** * @psalm-pure * * @param string|int $key * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrKeyExists(mixed $array, string|int $key, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { null === $entry || static::keyExists($entry, $key, $message); } return $array; } /** * @psalm-pure * * @param string|int $key * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrKeyNotExists(mixed $array, string|int $key, string $message = ''): mixed { null === $array || static::keyNotExists($array, $key, $message); return $array; } /** * @psalm-pure * * @param string|int $key * * @return mixed * * @throws InvalidArgumentException */ public static function allKeyNotExists(mixed $array, string|int $key, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { static::keyNotExists($entry, $key, $message); } return $array; } /** * @psalm-pure * * @param string|int $key * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrKeyNotExists(mixed $array, string|int $key, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { null === $entry || static::keyNotExists($entry, $key, $message); } return $array; } /** * @psalm-pure * * @psalm-assert array-key|null $value * * @return array-key|null * * @throws InvalidArgumentException */ public static function nullOrValidArrayKey(mixed $value, string $message = ''): mixed { null === $value || static::validArrayKey($value, $message); return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allValidArrayKey(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::validArrayKey($entry, $message); } return $value; } /** * @psalm-pure * * @psalm-assert iterable $value * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrValidArrayKey(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::validArrayKey($entry, $message); } return $value; } /** * @return mixed * * @throws InvalidArgumentException */ public static function nullOrCount(mixed $array, mixed $number, string $message = ''): mixed { null === $array || static::count($array, $number, $message); return $array; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allCount(mixed $array, mixed $number, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { static::count($entry, $number, $message); } return $array; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrCount(mixed $array, mixed $number, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { null === $entry || static::count($entry, $number, $message); } return $array; } /** * @return mixed * * @throws InvalidArgumentException */ public static function nullOrMinCount(mixed $array, mixed $min, string $message = ''): mixed { null === $array || static::minCount($array, $min, $message); return $array; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allMinCount(mixed $array, mixed $min, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { static::minCount($entry, $min, $message); } return $array; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrMinCount(mixed $array, mixed $min, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { null === $entry || static::minCount($entry, $min, $message); } return $array; } /** * @return mixed * * @throws InvalidArgumentException */ public static function nullOrMaxCount(mixed $array, mixed $max, string $message = ''): mixed { null === $array || static::maxCount($array, $max, $message); return $array; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allMaxCount(mixed $array, mixed $max, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { static::maxCount($entry, $max, $message); } return $array; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrMaxCount(mixed $array, mixed $max, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { null === $entry || static::maxCount($entry, $max, $message); } return $array; } /** * @return mixed * * @throws InvalidArgumentException */ public static function nullOrCountBetween(mixed $array, mixed $min, mixed $max, string $message = ''): mixed { null === $array || static::countBetween($array, $min, $max, $message); return $array; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allCountBetween(mixed $array, mixed $min, mixed $max, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { static::countBetween($entry, $min, $max, $message); } return $array; } /** * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrCountBetween(mixed $array, mixed $min, mixed $max, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { null === $entry || static::countBetween($entry, $min, $max, $message); } return $array; } /** * @psalm-pure * * @psalm-assert list|null $array * * @return list|null * * @throws InvalidArgumentException */ public static function nullOrIsList(mixed $array, string $message = ''): mixed { null === $array || static::isList($array, $message); return $array; } /** * @psalm-pure * * @psalm-assert iterable> $array * * @return iterable> * * @throws InvalidArgumentException */ public static function allIsList(mixed $array, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { static::isList($entry, $message); } return $array; } /** * @psalm-pure * * @psalm-assert iterable|null> $array * * @return iterable|null> * * @throws InvalidArgumentException */ public static function allNullOrIsList(mixed $array, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { null === $entry || static::isList($entry, $message); } return $array; } /** * @psalm-pure * * @psalm-assert non-empty-list|null $array * * @return non-empty-list|null * * @throws InvalidArgumentException */ public static function nullOrIsNonEmptyList(mixed $array, string $message = ''): mixed { null === $array || static::isNonEmptyList($array, $message); return $array; } /** * @psalm-pure * * @psalm-assert iterable> $array * * @return iterable> * * @throws InvalidArgumentException */ public static function allIsNonEmptyList(mixed $array, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { static::isNonEmptyList($entry, $message); } return $array; } /** * @psalm-pure * * @psalm-assert iterable|null> $array * * @return iterable|null> * * @throws InvalidArgumentException */ public static function allNullOrIsNonEmptyList(mixed $array, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { null === $entry || static::isNonEmptyList($entry, $message); } return $array; } /** * @psalm-pure * * @template T * @psalm-assert array|null $array * * @param mixed|array|null $array * * @return array|null * * @throws InvalidArgumentException */ public static function nullOrIsMap(mixed $array, string $message = ''): mixed { null === $array || static::isMap($array, $message); return $array; } /** * @psalm-pure * * @template T * @psalm-assert iterable> $array * * @param iterable> $array * * @return iterable> * * @throws InvalidArgumentException */ public static function allIsMap(mixed $array, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { static::isMap($entry, $message); } return $array; } /** * @psalm-pure * * @template T * @psalm-assert iterable|null> $array * * @param iterable|null> $array * * @return iterable|null> * * @throws InvalidArgumentException */ public static function allNullOrIsMap(mixed $array, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { null === $entry || static::isMap($entry, $message); } return $array; } /** * @psalm-assert callable|null $callable * * @param Closure|callable|null $callable * * @return callable|null * * @throws InvalidArgumentException */ public static function nullOrIsStatic(mixed $callable, string $message = ''): mixed { null === $callable || static::isStatic($callable, $message); return $callable; } /** * @psalm-assert iterable $callable * * @param iterable $callable * * @return iterable * * @throws InvalidArgumentException */ public static function allIsStatic(mixed $callable, string $message = ''): mixed { static::isIterable($callable); foreach ($callable as $entry) { static::isStatic($entry, $message); } return $callable; } /** * @psalm-assert iterable $callable * * @param iterable $callable * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrIsStatic(mixed $callable, string $message = ''): mixed { static::isIterable($callable); foreach ($callable as $entry) { null === $entry || static::isStatic($entry, $message); } return $callable; } /** * @psalm-assert callable|null $callable * * @param Closure|callable|null $callable * * @return callable|null * * @throws InvalidArgumentException */ public static function nullOrNotStatic(mixed $callable, string $message = ''): mixed { null === $callable || static::notStatic($callable, $message); return $callable; } /** * @psalm-assert iterable $callable * * @param iterable $callable * * @return iterable * * @throws InvalidArgumentException */ public static function allNotStatic(mixed $callable, string $message = ''): mixed { static::isIterable($callable); foreach ($callable as $entry) { static::notStatic($entry, $message); } return $callable; } /** * @psalm-assert iterable $callable * * @param iterable $callable * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrNotStatic(mixed $callable, string $message = ''): mixed { static::isIterable($callable); foreach ($callable as $entry) { null === $entry || static::notStatic($entry, $message); } return $callable; } /** * @psalm-pure * * @template T * * @param array|null $array * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrIsNonEmptyMap(mixed $array, string $message = ''): mixed { null === $array || static::isNonEmptyMap($array, $message); return $array; } /** * @psalm-pure * * @template T * * @param iterable> $array * * @return mixed * * @throws InvalidArgumentException */ public static function allIsNonEmptyMap(mixed $array, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { static::isNonEmptyMap($entry, $message); } return $array; } /** * @psalm-pure * * @template T * @psalm-assert iterable|null> $array * @psalm-assert iterable $array * * @param iterable|null> $array * * @return iterable * * @throws InvalidArgumentException */ public static function allNullOrIsNonEmptyMap(mixed $array, string $message = ''): mixed { static::isIterable($array); foreach ($array as $entry) { null === $entry || static::isNonEmptyMap($entry, $message); } return $array; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function nullOrUuid(mixed $value, string $message = ''): mixed { null === $value || static::uuid($value, $message); return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allUuid(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { static::uuid($entry, $message); } return $value; } /** * @psalm-pure * * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrUuid(mixed $value, string $message = ''): iterable { static::isIterable($value); foreach ($value as $entry) { null === $entry || static::uuid($entry, $message); } return $value; } /** * @psalm-param class-string $class * @return mixed * * @throws InvalidArgumentException */ public static function nullOrThrows(mixed $expression, string $class = 'Throwable', string $message = ''): mixed { null === $expression || static::throws($expression, $class, $message); return $expression; } /** * @psalm-param class-string $class * @return mixed * * @throws InvalidArgumentException */ public static function allThrows(mixed $expression, string $class = 'Throwable', string $message = ''): mixed { static::isIterable($expression); foreach ($expression as $entry) { static::throws($entry, $class, $message); } return $expression; } /** * @psalm-param class-string $class * @return mixed * * @throws InvalidArgumentException */ public static function allNullOrThrows(mixed $expression, string $class = 'Throwable', string $message = ''): mixed { static::isIterable($expression); foreach ($expression as $entry) { null === $entry || static::throws($entry, $class, $message); } return $expression; } } ================================================ FILE: tests/AssertTest.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Webmozart\Assert\Tests; use ArrayIterator; use ArrayObject; use DateTime; use DateTimeImmutable; use Error; use Exception; use LogicException; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use RuntimeException; use SimpleXMLElement; use stdClass; use Webmozart\Assert\Assert; /** * @since 1.0 * * @author Bernhard Schussek */ class AssertTest extends TestCase { private const SKIP_MIXIN_ASSERTION_TESTS = [ 'isInitialized', ]; public static function getResource() { static $resource; return $resource ??= tmpfile(); } public static function getTests(): array { $nanList = ['key' => 2, NAN]; unset($nanList['key']); $normalList = ['foo' => 'b', 3]; unset($normalList['foo']); return [ ['string', ['value'], true], ['string', [''], true], ['string', [1234], false], ['stringNotEmpty', ['value'], true], ['stringNotEmpty', ['0'], true], ['stringNotEmpty', [''], false], ['stringNotEmpty', [1234], false], ['integer', [123], true], ['integer', ['123'], false], ['integer', [1.0], false], ['integer', [1.23], false], ['integerish', [1.0], true], ['integerish', [1.23], false], ['integerish', [123], true], ['integerish', ['123'], true], ['positiveInteger', [123], true], ['positiveInteger', [1], true], ['positiveInteger', [-123], false], ['positiveInteger', [0], false], ['positiveInteger', [0.0], false], ['positiveInteger', ['123'], false], ['positiveInteger', ['-123'], false], ['positiveInteger', ['0'], false], ['positiveInteger', [1.0], false], ['positiveInteger', [1.23], false], ['notNegativeInteger', [123], true], ['notNegativeInteger', [1], true], ['notNegativeInteger', [-123], false], ['notNegativeInteger', [0], true], ['notNegativeInteger', [0.0], false], ['notNegativeInteger', ['123'], false], ['notNegativeInteger', ['-123'], false], ['notNegativeInteger', ['0'], false], ['notNegativeInteger', [1.0], false], ['notNegativeInteger', [1.23], false], ['negativeInteger', [123], false], ['negativeInteger', [1], false], ['negativeInteger', [-123], true], ['negativeInteger', [0], false], ['negativeInteger', [0.0], false], ['negativeInteger', ['123'], false], ['negativeInteger', ['-123'], false], ['negativeInteger', ['0'], false], ['negativeInteger', [1.0], false], ['negativeInteger', [1.23], false], ['float', [1.0], true], ['float', [1.23], true], ['float', [123], false], ['float', ['123'], false], ['numeric', [1.0], true], ['numeric', [1.23], true], ['numeric', [123], true], ['numeric', ['123'], true], ['numeric', ['foo'], false], ['natural', [0], true], ['natural', [1], true], ['natural', [-1], false], ['natural', ['1'], false], ['natural', [1.0], false], ['natural', [1.23], false], ['boolean', [true], true], ['boolean', [false], true], ['boolean', [1], false], ['boolean', ['1'], false], ['scalar', ['1'], true], ['scalar', [123], true], ['scalar', [true], true], ['scalar', [null], false], ['scalar', [[]], false], ['scalar', [new stdClass()], false], ['object', [new stdClass()], true], ['object', [new RuntimeException()], true], ['object', [null], false], ['object', [true], false], ['object', [1], false], ['object', [[]], false], ['objectish', [new stdClass()], true], ['objectish', [new RuntimeException()], true], ['objectish', [null], false], ['objectish', [true], false], ['objectish', [1], false], ['objectish', [[]], false], ['resource', [self::getResource()], true], ['resource', [self::getResource(), 'stream'], true], ['resource', [self::getResource(), 'other'], false], ['resource', [1], false], ['isInitialized', [new class { public mixed $a = null; }, 'a'], true], ['isInitialized', [new class { public mixed $a; }, 'a'], false], ['isInitialized', [new class { public mixed $a; public mixed $b = true; }, 'a'], false], ['isInitialized', [new class { public mixed $a; public mixed $b = true; }, 'b'], true], ['isCallable', ['strlen'], true], ['isCallable', [[self::class, 'getTests']], true], ['isCallable', [function () {}], true], ['isCallable', [1234], false], ['isCallable', ['foobar'], false], ['isArray', [[]], true], ['isArray', [[1, 2, 3]], true], ['isArray', [new ArrayIterator([])], false], ['isArray', [123], false], ['isArray', [new stdClass()], false], ['isArrayAccessible', [[]], true], ['isArrayAccessible', [[1, 2, 3]], true], ['isArrayAccessible', [new ArrayObject([])], true], ['isArrayAccessible', [123], false], ['isArrayAccessible', [new stdClass()], false], ['isCountable', [[]], true], ['isCountable', [[1, 2]], true], ['isCountable', [new ArrayIterator([])], true], ['isCountable', [new stdClass()], false], ['isCountable', [new SimpleXMLElement('bar')], true], ['isCountable', ['abcd'], false], ['isCountable', [123], false], ['isIterable', [[]], true], ['isIterable', [[1, 2, 3]], true], ['isIterable', [new ArrayIterator([])], true], ['isIterable', [123], false], ['isIterable', [new stdClass()], false], ['isInstanceOf', [new stdClass(), 'stdClass'], true], ['isInstanceOf', [new Exception(), 'stdClass'], false], ['isInstanceOf', [123, 'stdClass'], false], ['isInstanceOf', [[], 'stdClass'], false], ['isInstanceOf', [null, 'stdClass'], false], ['notInstanceOf', [new stdClass(), 'stdClass'], false], ['notInstanceOf', [new Exception(), 'stdClass'], true], ['notInstanceOf', [123, 'stdClass'], false], ['notInstanceOf', [[], 'stdClass'], false], ['notInstanceOf', [null, 'stdClass'], false], ['isInstanceOfAny', [new ArrayIterator(), ['Iterator', 'ArrayAccess']], true], ['isInstanceOfAny', [new Exception(), ['Exception', 'Countable']], true], ['isInstanceOfAny', [new Exception(), ['ArrayAccess', 'Countable']], false], ['isInstanceOfAny', [123, ['stdClass']], false], ['isInstanceOfAny', [[], ['stdClass']], false], ['isAOf', ['stdClass', 'stdClass'], true], ['isAOf', ['stdClass', 123], false], ['isAOf', ['Iterator', 'ArrayIterator'], false], ['isAOf', [123, 'Iterator'], false], ['isAOf', [[], 'Iterator'], false], ['isAnyOf', ['ArrayIterator', ['Iterator', 'ArrayAccess']], true], ['isAnyOf', ['ArrayIterator', [123]], false], ['isAnyOf', ['Exception', ['Exception', 'Countable']], true], ['isAnyOf', ['Exception', ['ArrayAccess', 'Countable']], false], ['isAnyOf', [123, ['stdClass']], false], ['isAnyOf', [[], ['stdClass']], false], ['isNotA', ['stdClass', 'stdClass'], false], ['isNotA', ['stdClass', 123], false], ['isNotA', [[], 'Iterator'], false], ['true', [true], true], ['true', [false], false], ['true', [1], false], ['true', [null], false], ['false', [false], true], ['false', [true], false], ['false', [1], false], ['false', [0], false], ['false', [null], false], ['notFalse', [false], false], ['notFalse', [true], true], ['notFalse', [1], true], ['notFalse', [0], true], ['notFalse', [null], true], ['null', [null], true], ['null', [false], false], ['null', [0], false], ['notNull', [false], true], ['notNull', [0], true], ['notNull', [null], false], ['isEmpty', [null], true], ['isEmpty', [false], true], ['isEmpty', [0], true], ['isEmpty', [''], true], ['isEmpty', [1], false], ['isEmpty', ['a'], false], ['notEmpty', [1], true], ['notEmpty', ['a'], true], ['notEmpty', [null], false], ['notEmpty', [false], false], ['notEmpty', [0], false], ['notEmpty', [''], false], ['eq', [1, 1], true], ['eq', [1, '1'], true], ['eq', [1, true], true], ['eq', [1, 0], false], ['notEq', [1, 0], true], ['notEq', [1, 1], false], ['notEq', [1, '1'], false], ['notEq', [1, true], false], ['same', [1, 1], true], ['same', [1, '1'], false], ['same', [1, true], false], ['same', [1, 0], false], ['notSame', [1, 0], true], ['notSame', [1, 1], false], ['notSame', [1, '1'], true], ['notSame', [1, true], true], ['greaterThan', [1, 0], true], ['greaterThan', [0, 0], false], ['greaterThanEq', [2, 1], true], ['greaterThanEq', [1, 1], true], ['greaterThanEq', [0, 1], false], ['lessThan', [0, 1], true], ['lessThan', [1, 1], false], ['lessThanEq', [0, 1], true], ['lessThanEq', [1, 1], true], ['lessThanEq', [2, 1], false], ['range', [1, 1, 2], true], ['range', [2, 1, 2], true], ['range', [0, 1, 2], false], ['range', [3, 1, 2], false], ['oneOf', [1, [1, 2, 3]], true], ['oneOf', [1, ['1', '2', '3']], false], ['notOneOf', [1, [1, 2, 3]], false], ['notOneOf', [1, ['1', '2', '3']], true], ['inArray', [1, [1, 2, 3]], true], ['inArray', [1, ['1', '2', '3']], false], ['notInArray', [1, [1, 2, 3]], false], ['notInArray', [1, ['1', '2', '3']], true], ['contains', ['abcd', 'ab'], true], ['contains', ['abcd', 'bc'], true], ['contains', ['abcd', 'cd'], true], ['contains', ['abcd', 'de'], false], ['contains', ['', 'de'], false], ['contains', ['äþçð', 'äþ'], true], ['contains', ['äþçð', 'þç'], true], ['contains', ['äþçð', 'çð'], true], ['contains', ['äþçð', 'ðé'], false], ['contains', ['', 'ðé'], false], ['contains', ['あいうえ', 'あい'], true], ['contains', ['あいうえ', 'いう'], true], ['contains', ['あいうえ', 'うえ'], true], ['contains', ['あいうえ', 'えお'], false], ['contains', ['', 'えお'], false], ['contains', ['😄😑☹️', '😄'], true], ['contains', ['😄😑☹️', '😑'], true], ['contains', ['😄😑☹️', '☹️'], true], ['contains', ['😄😑☹️', '😄☹️'], false], ['contains', ['', '😑'], false], ['notContains', ['abcd', 'ab'], false], ['notContains', ['abcd', 'bc'], false], ['notContains', ['abcd', 'cd'], false], ['notContains', ['abcd', 'de'], true], ['notContains', ['', 'de'], true], ['notContains', ['äþçð', 'äþ'], false], ['notContains', ['äþçð', 'þç'], false], ['notContains', ['äþçð', 'çð'], false], ['notContains', ['äþçð', 'ðé'], true], ['notContains', ['', 'ðé'], true], ['notContains', ['あいうえ', 'あい'], false], ['notContains', ['あいうえ', 'いう'], false], ['notContains', ['あいうえ', 'うえ'], false], ['notContains', ['あいうえ', 'えお'], true], ['notContains', ['', 'えお'], true], ['notContains', ['😄😑☹️', '😄'], false], ['notContains', ['😄😑☹️', '😑'], false], ['notContains', ['😄😑☹️', '☹️'], false], ['notContains', ['😄😑☹️', '😄☹️'], true], ['notContains', ['', '😑'], true], ['notWhitespaceOnly', ['abc'], true], ['notWhitespaceOnly', ['123'], true], ['notWhitespaceOnly', [' abc '], true], ['notWhitespaceOnly', ['a b c'], true], ['notWhitespaceOnly', [''], false], ['notWhitespaceOnly', [' '], false], ['notWhitespaceOnly', ["\t"], false], ['notWhitespaceOnly', ["\n"], false], ['notWhitespaceOnly', ["\r"], false], ['notWhitespaceOnly', ["\r\n\t "], false], ['startsWith', ['abcd', 'ab'], true], ['startsWith', ['abcd', 'bc'], false], ['startsWith', ['', 'bc'], false], ['startsWith', ['äþçð', 'äþ'], true], ['startsWith', ['äþçð', 'þç'], false], ['startsWith', ['', 'þç'], false], ['startsWith', ['あいうえ', 'あい'], true], ['startsWith', ['あいうえ', 'いう'], false], ['startsWith', ['', 'いう'], false], ['startsWith', ['😄😑☹️', '😄'], true], ['startsWith', ['😄😑☹️', '😑'], false], ['startsWith', ['', '😑'], false], ['startsWithLetter', ['abcd'], true], ['startsWithLetter', [[66]], false], ['startsWithLetter', ['a'], true], ['startsWithLetter', ['a1'], true], ['startsWithLetter', ['1abcd'], false], ['startsWithLetter', ['1'], false], ['startsWithLetter', [''], false], ['startsWithLetter', [null], false], ['startsWithLetter', [66], false], ['notStartsWith', ['abcd', 'ab'], false], ['notStartsWith', ['abcd', 'bc'], true], ['notStartsWith', ['', 'bc'], true], ['notStartsWith', ['äþçð', 'äþ'], false], ['notStartsWith', ['äþçð', 'þç'], true], ['notStartsWith', ['', 'þç'], true], ['notStartsWith', ['あいうえ', 'あい'], false], ['notStartsWith', ['あいうえ', 'いう'], true], ['notStartsWith', ['', 'いう'], true], ['notStartsWith', ['😄😑☹️', '😄'], false], ['notStartsWith', ['😄😑☹️', '😑'], true], ['notStartsWith', ['', '😑'], true], ['endsWith', ['abcd', 'cd'], true], ['endsWith', ['abcd', 'bc'], false], ['endsWith', ['', 'bc'], false], ['endsWith', ['äþçð', 'çð'], true], ['endsWith', ['äþçð', 'þç'], false], ['endsWith', ['', 'þç'], false], ['endsWith', ['あいうえ', 'うえ'], true], ['endsWith', ['あいうえ', 'いう'], false], ['endsWith', ['', 'いう'], false], ['endsWith', ['😄😑☹️', '☹️'], true], ['endsWith', ['😄😑☹️', '😑'], false], ['endsWith', ['', '😑'], false], ['notEndsWith', ['abcd', 'cd'], false], ['notEndsWith', ['abcd', 'bc'], true], ['notEndsWith', ['', 'bc'], true], ['notEndsWith', ['äþçð', 'çð'], false], ['notEndsWith', ['äþçð', 'þç'], true], ['notEndsWith', ['', 'þç'], true], ['notEndsWith', ['あいうえ', 'うえ'], false], ['notEndsWith', ['あいうえ', 'いう'], true], ['notEndsWith', ['', 'いう'], true], ['notEndsWith', ['😄😑☹️', '☹️'], false], ['notEndsWith', ['😄😑☹️', '😑'], true], ['notEndsWith', ['', '😑'], true], ['regex', ['abcd', '~^ab~'], true], ['regex', ['abcd', '~^bc~'], false], ['regex', ['', '~^bc~'], false], ['notRegex', ['abcd', '{^ab}'], false], ['notRegex', ['abcd', '{^bc}'], true], ['notRegex', ['', '{^bc}'], true], ['unicodeLetters', ['abcd'], true], ['unicodeLetters', ['ᴁڅਘธブ乶'], true], ['unicodeLetters', ['ȁȄ'], true], ['unicodeLetters', ['ȁ1Ȅ'], false], ['unicodeLetters', ['©'], false], ['unicodeLetters', ['🙁'], false], ['unicodeLetters', [''], false], ['alpha', ['abcd'], true], ['alpha', ['ab1cd'], false], ['alpha', [''], false], ['alpha', [66], false], ['alpha', [[]], false], ['digits', ['1234'], true], ['digits', ['12a34'], false], ['digits', [''], false], ['digits', [1234], false], ['alnum', ['ab12'], true], ['alnum', ['ab12$'], false], ['alnum', [''], false], ['alnum', [1234], false], ['lower', ['abcd'], true], ['lower', ['abCd'], false], ['lower', ['ab_d'], false], ['lower', [''], false], ['lower', [1234], false], ['upper', ['ABCD'], true], ['upper', ['ABcD'], false], ['upper', ['AB_D'], false], ['upper', [''], false], ['upper', [1234], false], ['length', ['abcd', 4], true], ['length', ['abc', 4], false], ['length', ['abcde', 4], false], ['length', ['äbcd', 4], true, true], ['length', ['äbc', 4], false, true], ['length', ['äbcde', 4], false, true], ['length', ['あbcd', 4], true, true], // 'HIRAGANA LETTER A' (U+3042) ['length', ['あbc', 4], false, true], ['length', ['あbcde', 4], false, true], ['minLength', ['abcd', 4], true], ['minLength', ['abcde', 4], true], ['minLength', ['abc', 4], false], ['minLength', ['äbcd', 4], true, true], ['minLength', ['äbcde', 4], true, true], ['minLength', ['äbc', 4], false, true], ['minLength', ['あbcd', 4], true, true], ['minLength', ['あbcde', 4], true, true], ['minLength', ['あbc', 4], false, true], ['maxLength', ['abcd', 4], true], ['maxLength', ['abc', 4], true], ['maxLength', ['abcde', 4], false], ['maxLength', ['äbcd', 4], true, true], ['maxLength', ['äbc', 4], true, true], ['maxLength', ['äbcde', 4], false, true], ['maxLength', ['あbcd', 4], true, true], ['maxLength', ['あbc', 4], true, true], ['maxLength', ['あbcde', 4], false, true], ['lengthBetween', ['abcd', 3, 5], true], ['lengthBetween', ['abc', 3, 5], true], ['lengthBetween', ['abcde', 3, 5], true], ['lengthBetween', ['ab', 3, 5], false], ['lengthBetween', ['abcdef', 3, 5], false], ['lengthBetween', ['äbcd', 3, 5], true, true], ['lengthBetween', ['äbc', 3, 5], true, true], ['lengthBetween', ['äbcde', 3, 5], true, true], ['lengthBetween', ['äb', 3, 5], false, true], ['lengthBetween', ['äbcdef', 3, 5], false, true], ['lengthBetween', ['あbcd', 3, 5], true, true], ['lengthBetween', ['あbc', 3, 5], true, true], ['lengthBetween', ['あbcde', 3, 5], true, true], ['lengthBetween', ['あb', 3, 5], false, true], ['lengthBetween', ['あbcdef', 3, 5], false, true], ['fileExists', [__FILE__], true], ['fileExists', [__DIR__], true], ['fileExists', [__DIR__.'/foobar'], false], ['file', [__FILE__], true], ['file', [__DIR__], false], ['file', [__DIR__.'/foobar'], false], ['directory', [__DIR__], true], ['directory', [__FILE__], false], ['directory', [__DIR__.'/foobar'], false], // no tests for readable()/writable() for now ['classExists', [__CLASS__], true], ['classExists', [__NAMESPACE__.'\Foobar'], false], ['subclassOf', [__CLASS__, 'PHPUnit\Framework\TestCase'], true], ['subclassOf', [__CLASS__, 'stdClass'], false], ['interfaceExists', ['\Countable'], true], ['interfaceExists', [__CLASS__], false], ['implementsInterface', ['ArrayIterator', 'Traversable'], true], ['implementsInterface', [__CLASS__, 'Traversable'], false], ['implementsInterface', [new DateTimeImmutable(), 'DateTimeInterface'], true], ['implementsInterface', [new DateTimeImmutable(), 'Traversable'], false], ['implementsInterface', [new ArrayIterator([]), 'DateTimeInterface'], false], ['implementsInterface', [new ArrayIterator([]), 'Traversable'], true], ['propertyExists', [(object) ['property' => 0], 'property'], true], ['propertyExists', [(object) ['property' => null], 'property'], true], ['propertyExists', [(object) ['property' => null], 'foo'], false], ['propertyNotExists', [(object) ['property' => 0], 'property'], false], ['propertyNotExists', [(object) ['property' => null], 'property'], false], ['methodExists', ['RuntimeException', 'getMessage'], true], ['methodExists', [new RuntimeException(), 'getMessage'], true], ['methodExists', ['stdClass', 'getMessage'], false], ['methodExists', [new stdClass(), 'getMessage'], false], ['methodNotExists', ['RuntimeException', 'getMessage'], false], ['methodNotExists', [new RuntimeException(), 'getMessage'], false], ['methodNotExists', ['stdClass', 'getMessage'], true], ['methodNotExists', [new stdClass(), 'getMessage'], true], ['keyExists', [['key' => 0], 'key'], true], ['keyExists', [['key' => null], 'key'], true], ['keyExists', [['key' => null], 'foo'], false], ['keyNotExists', [['key' => 0], 'key'], false], ['keyNotExists', [['key' => null], 'key'], false], ['keyNotExists', [['key' => null], 'foo'], true], ['validArrayKey', ['abcd'], true], ['validArrayKey', [1], true], ['validArrayKey', [false], false], ['validArrayKey', [true], false], ['validArrayKey', [new stdClass()], false], ['validArrayKey', [new ToStringClass('testString')], false], ['validArrayKey', [self::getResource()], false], ['count', [[0, 1, 2], 3], true], ['count', [[0, 1, 2], 2], false], ['minCount', [[0], 2], false], ['minCount', [[0, 1], 2], true], ['minCount', [[0, 1, 2], 2], true], ['maxCount', [[0, 1, 2], 2], false], ['maxCount', [[0, 1], 2], true], ['maxCount', [[0], 2], true], ['countBetween', [[0, 1, 2], 4, 5], false], ['countBetween', [[0, 1, 2], 3, 5], true], ['countBetween', [[0, 1, 2], 1, 2], false], ['countBetween', [[0, 1, 2], 2, 5], true], ['countBetween', [[0, 1, 2], 2, 3], true], ['isList', [[1, 2, 3]], true], ['isList', [[]], true], ['isList', [[0 => 1, 2 => 3]], false], ['isList', [['key' => 1, 'foo' => 2]], false], ['isList', [true], false], ['isList', [false], false], ['isList', [[true]], true], ['isList', [[false]], true], ['isList', [[[1], [2]]], true], ['isList', [[['foo' => 'bar'], ['baz' => 'tab']]], true], ['isList', [$nanList], true], ['isList', [$normalList], true], ['isNonEmptyList', [[1, 2, 3]], true], ['isNonEmptyList', [[]], false], ['isNonEmptyList', [[0 => 1, 2 => 3]], false], ['isNonEmptyList', [['key' => 1, 'foo' => 2]], false], ['isNonEmptyList', [true], false], ['isNonEmptyList', [false], false], ['isNonEmptyList', [[true]], true], ['isNonEmptyList', [[false]], true], ['isNonEmptyList', [[[1], [2]]], true], ['isNonEmptyList', [[['foo' => 'bar'], ['baz' => 'tab']]], true], ['isMap', [['key' => 1, 'foo' => 2]], true], ['isMap', [[0 => 1, 2 => 3]], true], ['isMap', [[]], true], ['isMap', [[1, 2, 3]], false], ['isNonEmptyMap', [['key' => 1, 'foo' => 2]], true], ['isNonEmptyMap', [[0 => 1, 2 => 3]], true], ['isNonEmptyMap', [[]], false], ['isNonEmptyMap', [[1, 2, 3]], false], ['uuid', ['00000000-0000-0000-0000-000000000000'], true], ['uuid', ['urn:ff6f8cb0-c57d-21e1-9b21-0800200c9a66'], true], ['uuid', ['uuid:{ff6f8cb0-c57d-21e1-9b21-0800200c9a66}'], true], ['uuid', ['ff6f8cb0-c57d-21e1-9b21-0800200c9a66'], true], ['uuid', ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66'], true], ['uuid', ['ff6f8cb0-c57d-31e1-9b21-0800200c9a66'], true], ['uuid', ['ff6f8cb0-c57d-41e1-9b21-0800200c9a66'], true], ['uuid', ['ff6f8cb0-c57d-51e1-9b21-0800200c9a66'], true], ['uuid', ['FF6F8CB0-C57D-11E1-9B21-0800200C9A66'], true], ['uuid', ["urn:ff6f8cb0-c57d-21e1-9b21-0800200c9a66\n"], false], ['uuid', ["ff6f8cb0-c57d-21e1-9b21-0800200c9a66\n"], false], ['uuid', ["FF6F8CB0-C57D-11E1-9B21-0800200C9A66\n"], false], ['uuid', ['zf6f8cb0-c57d-11e1-9b21-0800200c9a66'], false], ['uuid', ['af6f8cb0c57d11e19b210800200c9a66'], false], ['uuid', ['ff6f8cb0-c57da-51e1-9b21-0800200c9a66'], false], ['uuid', ['af6f8cb-c57d-11e1-9b21-0800200c9a66'], false], ['uuid', ['3f6f8cb0-c57d-11e1-9b21-0800200c9a6'], false], ['throws', [function () { throw new LogicException('test'); }, 'LogicException'], true], ['throws', [function () { throw new LogicException('test'); }, 'IllogicException'], false], ['throws', [function () { throw new Exception('test'); }], true], ['throws', [function () { trigger_error('test'); }, 'Throwable'], false, false], ['throws', [function () { trigger_error('test'); }, 'Unthrowable'], false, false], ['throws', [function () { throw new Error(); }, 'Throwable'], true, true], ['ip', ['192.168.0.1'], true], ['ip', ['255.255.255.255'], true], ['ip', ['0.0.0.0'], true], ['ip', ['2001:0db8:0000:0042:0000:8a2e:0370:7334'], true], ['ip', ['::ffff:192.0.2.1'], true], ['ip', ['::1'], true], ['ip', ['::'], true], ['ip', ['foo'], false], ['ip', [123], false], ['ip', [[]], false], ['ip', [null], false], ['ip', [false], false], ['ipv4', ['192.168.0.1'], true], ['ipv4', ['255.255.255.255'], true], ['ipv4', ['0.0.0.0'], true], ['ipv4', ['2001:0db8:0000:0042:0000:8a2e:0370:7334'], false], ['ipv4', ['::ffff:192.0.2.1'], false], ['ipv4', ['::1'], false], ['ipv4', ['::'], false], ['ipv4', ['foo'], false], ['ipv4', [123], false], ['ipv4', [[]], false], ['ipv4', [null], false], ['ipv4', [false], false], ['ipv6', ['192.168.0.1'], false], ['ipv6', ['255.255.255.255'], false], ['ipv6', ['0.0.0.0'], false], ['ipv6', ['2001:0db8:0000:0042:0000:8a2e:0370:7334'], true], ['ipv6', ['::ffff:192.0.2.1'], true], ['ipv6', ['::1'], true], ['ipv6', ['::'], true], ['ipv6', ['foo'], false], ['ipv6', [123], false], ['ipv6', [[]], false], ['ipv6', [null], false], ['ipv6', [false], false], ['email', ['foo'], false], ['email', [123], false], ['email', ['foo.com'], false], ['email', ['foo@bar.com'], true], ['email', ['föö@bar.com'], true], ['uniqueValues', [['qwerty', 'qwerty']], false], ['uniqueValues', [['asdfg', 'qwerty']], true], ['uniqueValues', [[123, '123']], false], ['isStatic', [static function () {}], true], ['isStatic', [function () {}], false], ['notStatic', [static function () {}], false], ['notStatic', [function () {}], true], ]; } public static function getMethods(): array { $methods = []; foreach (self::getTests() as $params) { $methods[$params[0]] = [$params[0]]; } return array_values($methods); } #[DataProvider('getTests')] public function testAssert(string $method, array $args, bool $success, bool $multibyte = false): void { if ($multibyte && !function_exists('mb_strlen')) { $this->markTestSkipped('The function mb_strlen() is not available'); } if (!$success) { $this->expectException('\InvalidArgumentException'); } $result = call_user_func_array(['Webmozart\Assert\Assert', $method], $args); $this->assertSame($args[array_key_first($args)], $result); } #[DataProvider('getTests')] public function testNullOr(string $method, array $args, bool $success, bool $multibyte = false): void { if (in_array($method, self::SKIP_MIXIN_ASSERTION_TESTS)) { $this->markTestSkipped("The method $method does not have nullOr Mixin."); } if (in_array($method, ['null', 'notNull'])) { $this->markTestSkipped('Meaningless test of '.$method); } if ($multibyte && !function_exists('mb_strlen')) { $this->markTestSkipped('The function mb_strlen() is not available'); } if (!$success && null !== reset($args)) { $this->expectException('\InvalidArgumentException'); } $result = call_user_func_array(['Webmozart\Assert\Assert', 'nullOr'.ucfirst($method)], $args); $this->assertSame($args[array_key_first($args)], $result); } #[DataProvider('getMethods')] public function testNullOrAcceptsNull(string $method): void { if (in_array($method, self::SKIP_MIXIN_ASSERTION_TESTS)) { $this->markTestSkipped("The method $method does not have nullOr Mixin."); } if (in_array($method, ['null', 'notNull'])) { $this->markTestSkipped('Meaningless test of '.$method); } $result = call_user_func(['Webmozart\Assert\Assert', 'nullOr'.ucfirst($method)], null, '', ''); $this->assertNull($result); } #[DataProvider('getTests')] public function testAllArray(string $method, array $args, bool $success, bool $multibyte = false): void { if (in_array($method, self::SKIP_MIXIN_ASSERTION_TESTS)) { $this->markTestSkipped("The method $method does not have all Mixin."); } if ($multibyte && !function_exists('mb_strlen')) { $this->markTestSkipped('The function mb_strlen() is not available'); } if (!$success) { $this->expectException('\InvalidArgumentException'); } $arg = array_shift($args); array_unshift($args, [$arg]); $result = call_user_func_array(['Webmozart\Assert\Assert', 'all'.ucfirst($method)], $args); $this->assertSame($args[array_key_first($args)], $result); } #[DataProvider('getTests')] public function testAllNullOrArray(string $method, array $args, bool $success, bool $multibyte = false): void { if (in_array($method, self::SKIP_MIXIN_ASSERTION_TESTS)) { $this->markTestSkipped("The method $method does not have allNullOr Mixin."); } if (in_array($method, ['null', 'notNull'])) { $this->markTestSkipped('Meaningless test of '.$method); } if ($multibyte && !function_exists('mb_strlen')) { $this->markTestSkipped('The function mb_strlen() is not available'); } $arg = array_shift($args); if ($arg === null) { $this->addToAssertionCount(1); return; } if (!$success) { $this->expectException('\InvalidArgumentException'); } array_unshift($args, [$arg, null]); $result = call_user_func_array(['Webmozart\Assert\Assert', 'allNullOr'.ucfirst($method)], $args); $this->assertSame($args[array_key_first($args)], $result); } #[DataProvider('getTests')] public function testAllTraversable(string $method, array $args, bool $success, bool $multibyte = false): void { if (in_array($method, self::SKIP_MIXIN_ASSERTION_TESTS)) { $this->markTestSkipped("The method $method does not have all Mixin."); } if ($multibyte && !function_exists('mb_strlen')) { $this->markTestSkipped('The function mb_strlen() is not available'); } if (!$success) { $this->expectException('\InvalidArgumentException'); } $arg = array_shift($args); array_unshift($args, new ArrayIterator([$arg])); $result = call_user_func_array(['Webmozart\Assert\Assert', 'all'.ucfirst($method)], $args); $this->assertSame($args[array_key_first($args)], $result); } public static function getStringConversions(): array { return [ ['integer', ['foobar'], 'Expected an integer. Got: string'], ['string', [1], 'Expected a string. Got: integer'], ['string', [true], 'Expected a string. Got: boolean'], ['string', [null], 'Expected a string. Got: NULL'], ['string', [[]], 'Expected a string. Got: array'], ['string', [new stdClass()], 'Expected a string. Got: stdClass'], ['string', [self::getResource()], 'Expected a string. Got: resource'], ['eq', ['1', '2'], 'Expected a value equal to "2". Got: "1"'], ['eq', [new ToStringClass('XXX'), new ToStringClass('YYY')], 'Expected a value equal to Webmozart\Assert\Tests\ToStringClass: "YYY". Got: Webmozart\Assert\Tests\ToStringClass: "XXX"'], ['eq', [1, 2], 'Expected a value equal to 2. Got: 1'], ['eq', [true, false], 'Expected a value equal to false. Got: true'], ['eq', [true, null], 'Expected a value equal to null. Got: true'], ['eq', [null, true], 'Expected a value equal to true. Got: null'], ['eq', [[1], [2]], 'Expected a value equal to array. Got: array'], ['eq', [new ArrayIterator([]), new stdClass()], 'Expected a value equal to stdClass. Got: ArrayIterator'], ['eq', [1, self::getResource()], 'Expected a value equal to resource. Got: 1'], ['lessThan', [new DateTime('2020-01-01 00:00:00+00:00'), new DateTime('1999-01-01 00:00:00+00:00')], 'Expected a value less than DateTime: "1999-01-01T00:00:00+00:00". Got: DateTime: "2020-01-01T00:00:00+00:00"'], ]; } #[DataProvider('getStringConversions')] public function testConvertValuesToStrings(string $method, array $args, string $exceptionMessage): void { $this->expectException('\InvalidArgumentException'); $this->expectExceptionMessage($exceptionMessage); call_user_func_array(['Webmozart\Assert\Assert', $method], $args); } public static function getInvalidInstanceOfCases(): iterable { yield [ [null, 'stdClass'], 'Expected an instance of stdClass. Got: NULL', ]; yield [ [123, 'stdClass'], 'Expected an instance of stdClass. Got: integer', ]; yield [ [[], 'Iterator'], 'Expected an instance of Iterator. Got: array', ]; yield [ [new stdClass(), 'Iterator'], 'Expected an instance of Iterator. Got: stdClass', ]; } #[DataProvider('getInvalidInstanceOfCases')] public function testInstanceOfExceptionMessages(array $args, string $exceptionMessage): void { $this->expectException('\InvalidArgumentException'); $this->expectExceptionMessage($exceptionMessage); call_user_func_array(['Webmozart\Assert\Assert', 'isInstanceOf'], $args); } public static function getInvalidIsAOfCases(): iterable { yield [ ['stdClass', 123], 'Expected class as a string. Got: integer', ]; yield [ ['Iterator', 'ArrayIterator'], 'Expected an instance of this class or to this class among its parents "ArrayIterator". Got: "Iterator"', ]; yield [ [123, 'Iterator'], 'Expected an instance of this class or to this class among its parents "Iterator". Got: 123', ]; yield [ [[], 'Iterator'], 'Expected an instance of this class or to this class among its parents "Iterator". Got: array', ]; yield [ [new stdClass(), 'Iterator'], 'Expected an instance of this class or to this class among its parents "Iterator". Got: stdClass', ]; } #[DataProvider('getInvalidIsAOfCases')] public function testIsAOfExceptionMessages(array $args, string $exceptionMessage): void { $this->expectException('\InvalidArgumentException'); $this->expectExceptionMessage($exceptionMessage); call_user_func_array(['Webmozart\Assert\Assert', 'isAOf'], $args); } public function testResourceOfTypeCustomMessage(): void { $this->expectException('\InvalidArgumentException'); $this->expectExceptionMessage('I want a resource of type curl. Got: NULL'); Assert::resource(null, 'curl', 'I want a resource of type %2$s. Got: %s'); } public function testEnumAssertionErrorMessage(): void { $this->expectException('\InvalidArgumentException'); $this->expectExceptionMessage('Expected null. Got: Webmozart\Assert\Tests\DummyEnum::CaseName'); Assert::null(DummyEnum::CaseName, 'Expected null. Got: %s'); } #[DataProvider('getMethodsThatUseOtherMethods')] public function testMessageIsPassedToInternalCalls(string $method, array $args, string $exceptionMessage): void { $this->expectException('\InvalidArgumentException'); $this->expectExceptionMessage($exceptionMessage); call_user_func_array(['Webmozart\Assert\Assert', $method], $args); } public static function getMethodsThatUseOtherMethods(): array { return [ [ 'method' => 'positiveInteger', 'args' => ['not-integer', 'Value must be a positive integer. Got: %s'], 'exceptionMessage' => 'Value must be a positive integer. Got: string', ], [ 'method' => 'notNegativeInteger', 'args' => ['not-integer', 'Value must be a non-negative integer. Got: %s'], 'exceptionMessage' => 'Value must be a non-negative integer. Got: string', ], [ 'method' => 'negativeInteger', 'args' => ['not-integer', 'Value must be a negative integer. Got: %s'], 'exceptionMessage' => 'Value must be a negative integer. Got: string', ], [ 'method' => 'ip', 'args' => [127001, 'Value must be a valid IP. Got: %s'], 'exceptionMessage' => 'Value must be a valid IP. Got: integer', ], [ 'method' => 'ipv4', 'args' => [127001, 'Value must be a valid IPv4. Got: %s'], 'exceptionMessage' => 'Value must be a valid IPv4. Got: integer', ], [ 'method' => 'ipv6', 'args' => [127001, 'Value must be a valid IPv6. Got: %s'], 'exceptionMessage' => 'Value must be a valid IPv6. Got: integer', ], [ 'method' => 'email', 'args' => [111111, 'Value must be a valid email. Got: %s'], 'exceptionMessage' => 'Value must be a valid email. Got: integer', ], [ 'method' => 'unicodeLetters', 'args' => [111, 'Value must be a string with valid unicode characters. Got: %s'], 'exceptionMessage' => 'Value must be a string with valid unicode characters. Got: integer', ], [ 'method' => 'alpha', 'args' => [111, 'Value must be a string with only alphabetic characters. Got: %s'], 'exceptionMessage' => 'Value must be a string with only alphabetic characters. Got: integer', ], [ 'method' => 'digits', 'args' => [111, 'Value must be a string with only digits. Got: %s'], 'exceptionMessage' => 'Value must be a string with only digits. Got: integer', ], [ 'method' => 'alnum', 'args' => [111, 'Value must be a string with only alphanumeric characters. Got: %s'], 'exceptionMessage' => 'Value must be a string with only alphanumeric characters. Got: integer', ], [ 'method' => 'lower', 'args' => [111, 'Value must be a string with only lowercase characters. Got: %s'], 'exceptionMessage' => 'Value must be a string with only lowercase characters. Got: integer', ], [ 'method' => 'upper', 'args' => [111, 'Value must be a string with only uppercase characters. Got: %s'], 'exceptionMessage' => 'Value must be a string with only uppercase characters. Got: integer', ], [ 'method' => 'keyExists', 'args' => [111, 'test', 'Value must be an array with key test. Got: %s'], 'exceptionMessage' => 'Value must be an array with key test. Got: integer', ], [ 'method' => 'keyNotExists', 'args' => [111, 'test', 'Value must be an array without key test. Got: %s'], 'exceptionMessage' => 'Value must be an array without key test. Got: integer', ], [ 'method' => 'isInstanceOf', 'args' => [111, 'stdClass', 'Value must be an instance of stdClass. Got: %s'], 'exceptionMessage' => 'Value must be an instance of stdClass. Got: integer', ], [ 'method' => 'notInstanceOf', 'args' => [111, 'stdClass', 'Value must be an instance of stdClass. Got: %s'], 'exceptionMessage' => 'Value must be an instance of stdClass. Got: integer', ], [ 'method' => 'isInstanceOfAny', 'args' => [111, ['stdClass'], 'Value must be an instance of stdClass. Got: %s'], 'exceptionMessage' => 'Value must be an instance of stdClass. Got: integer', ], [ 'method' => 'isNotA', 'args' => [111, 'stdClass', 'Value must be an instance of stdClass. Got: %s'], 'exceptionMessage' => 'Value must be an instance of stdClass. Got: integer', ], [ 'method' => 'isAnyOf', 'args' => [111, ['stdClass'], 'Value must be an instance of stdClass. Got: %s'], 'exceptionMessage' => 'Value must be an instance of stdClass. Got: integer', ], ]; } } /** * @ignore */ class ToStringClass { /** * @var string */ private $value; public function __construct(string $value) { $this->value = $value; } public function __toString(): string { return $this->value; } } ================================================ FILE: tests/DummyEnum.php ================================================ getDocComment(); self::$mixinMethodNames = []; foreach ($rc->getMethods() as $method) { self::$mixinMethodNames[] = $method->name; } } #[DataProvider('providesMethodNames')] public function testHasNullOr(string $method): void { if (in_array($method, $this->methodDoesNotHaveNullOrMixin)) { $this->markTestSkipped("The method $method does not have nullOr Mixin."); } $fullMethodName = 'nullOr'.ucfirst($method); if ($method === 'notNull' || $method === 'null') { $this->addToAssertionCount(1); return; } $correct = strpos((string) self::$assertDocComment, '@method static void '.$fullMethodName); if (!$correct) { $correct = in_array($fullMethodName, self::$mixinMethodNames, true); } if ($correct === false) { $this->fail(sprintf( 'All methods have a corresponding "nullOr" method, please add the "%s" method to the class level doc comment.', $fullMethodName )); } $this->addToAssertionCount(1); } #[DataProvider('providesMethodNames')] public function testHasAll(string $method): void { if (in_array($method, $this->methodDoesNotHaveAllMixin)) { $this->markTestSkipped("The method $method does not have all Mixin."); } $fullMethodName = 'all'.ucfirst($method); $correct = strpos((string) self::$assertDocComment, '@method static void '.$fullMethodName); if (!$correct) { $correct = in_array($fullMethodName, self::$mixinMethodNames, true); } if ($correct === false) { $this->fail(sprintf( 'All methods have a corresponding "all" method, please add the "%s" method to the class level doc comment.', $fullMethodName )); } $this->addToAssertionCount(1); } #[DataProvider('providesMethodNames')] public function testIsInReadme(string $method): void { $correct = strpos((string) self::$readmeContent, $method); if ($correct === false) { $this->fail(sprintf( 'All methods must be documented in the README.md, please add the "%s" method.', $method )); } $this->addToAssertionCount(1); } #[DataProvider('provideMethods')] public function testHasThrowsAnnotation(ReflectionMethod $method): void { $doc = $method->getDocComment(); $this->assertNotFalse( $doc, sprintf( 'Expected a doc comment on the "%s" method, but none found', $method->getName() ) ); $this->assertStringContainsString( '@throws InvalidArgumentException', $doc, sprintf( 'Expected method "%s" to have an @throws InvalidArgumentException annotation, but none found', $method->getName() ) ); } #[DataProvider('provideMethods')] public function testHasCorrespondingStaticAnalysisFile(ReflectionMethod $method): void { $doc = $method->getDocComment(); if ($doc === false || strpos($doc, '@psalm-assert') === false) { $this->addToAssertionCount(1); return; } $this->assertFileExists( __DIR__.'/static-analysis/assert-'.$method->getName().'.php' ); } public function testMixinIsUpToDateVersion(): void { if (PHP_OS_FAMILY === 'Windows') { $this->markTestSkipped('mixin generator is not expected to run on Windows'); return; } require_once __DIR__.'/../bin/src/MixinGenerator.php'; $generator = new MixinGenerator(); $actual = file_get_contents(__DIR__.'/../src/Mixin.php'); $this->assertEquals($generator->generate(), $actual, 'please regenerate Mixin with `php bin/generate.php` command in the project root'); } /** * @return array */ public static function providesMethodNames(): array { return array_map(function (ReflectionMethod $value) { return [$value->getName()]; }, self::getMethods()); } /** * @return array */ public static function provideMethods(): array { return array_map(function (ReflectionMethod $value) { return [$value]; }, self::getMethods()); } /** * @return array */ private static function getMethods(): array { static $methods; if ($methods !== null) { return $methods; } $rc = new ReflectionClass('\Webmozart\Assert\Assert'); $methods = []; $rcMethods = $rc->getMethods(ReflectionMethod::IS_PUBLIC); foreach ($rcMethods as $rcMethod) { if ($rcMethod->getFileName() !== $rc->getFileName()) { continue; } $methodName = $rcMethod->getName(); if (strpos($methodName, '__') === 0) { continue; } $methods[] = $rcMethod; } return $methods; } } ================================================ FILE: tests/static-analysis/assert-alnum.php ================================================ $value */ function allAlnum(iterable $value): iterable { Assert::allAlnum($value); return $value; } /** * @psalm-pure * * @param iterable $value */ function allNullOrAlnum(iterable $value): iterable { Assert::allNullOrAlnum($value); return $value; } ================================================ FILE: tests/static-analysis/assert-alpha.php ================================================ $value */ function allContains(iterable $value, string $subString): iterable { Assert::allContains($value, $subString); return $value; } /** * @psalm-pure * * @param iterable $value */ function allNullOrContains(iterable $value, string $subString): iterable { Assert::allNullOrContains($value, $subString); return $value; } ================================================ FILE: tests/static-analysis/assert-count.php ================================================ $value */ function allCount(iterable $value, int $number): iterable { Assert::allCount($value, $number); return $value; } /** * @param iterable $value */ function allNullOrCount(iterable $value, int $number): iterable { Assert::allCount($value, $number); return $value; } ================================================ FILE: tests/static-analysis/assert-countBetween.php ================================================ $value * @param int|float $min * @param int|float $max */ function allCountBetween(iterable $value, $min, $max): iterable { Assert::allCountBetween($value, $min, $max); return $value; } /** * @param iterable $value * @param int|float $min * @param int|float $max */ function allNullOrCountBetween(iterable $value, $min, $max): iterable { Assert::allNullOrCountBetween($value, $min, $max); return $value; } ================================================ FILE: tests/static-analysis/assert-digits.php ================================================ $value */ function allDigits(iterable $value): iterable { Assert::allDigits($value); return $value; } /** * @psalm-pure * * @param iterable $value */ function allNullOrDigits(iterable $value): iterable { Assert::allNullOrDigits($value); return $value; } ================================================ FILE: tests/static-analysis/assert-directory.php ================================================ $value */ function allEndsWith(iterable $value, string $suffix): iterable { Assert::allEndsWith($value, $suffix); return $value; } /** * @psalm-pure * * @param iterable $value */ function allNullOrEndsWith(iterable $value, string $suffix): iterable { Assert::allNullOrEndsWith($value, $suffix); return $value; } ================================================ FILE: tests/static-analysis/assert-eq.php ================================================ */ function implementsInterface(mixed $value) { Assert::implementsInterface($value, Serializable::class); return $value; } /** * @psalm-pure * * @param mixed $value * * @return Serializable|class-string|null */ function nullOrImplementsInterface(mixed $value) { Assert::nullOrImplementsInterface($value, Serializable::class); return $value; } /** * @psalm-pure * * @param mixed $value */ function allImplementsInterface(mixed $value): iterable { Assert::allImplementsInterface($value, Serializable::class); return $value; } /** * @psalm-pure * * @param mixed $value */ function allNullOrImplementsInterface(mixed $value): iterable { Assert::allNullOrImplementsInterface($value, Serializable::class); return $value; } ================================================ FILE: tests/static-analysis/assert-inArray.php ================================================ |Serializable */ function isAOf(mixed $value): mixed { Assert::isAOf($value, Serializable::class); return $value; } /** * @psalm-pure * * @param null|object|string $value * * @psalm-return null|class-string|Serializable */ function nullOrIsAOf(mixed $value): mixed { Assert::nullOrIsAOf($value, Serializable::class); return $value; } /** * @psalm-pure * * @param iterable $value * * @return iterable|Serializable> */ function allIsAOf(mixed $value): iterable { Assert::allIsAOf($value, Serializable::class); return $value; } /** * @psalm-pure * * @param iterable $value * * @return iterable|Serializable|null> */ function allNullOrIsAOf(mixed $value): iterable { Assert::allNullOrIsAOf($value, Serializable::class); return $value; } ================================================ FILE: tests/static-analysis/assert-isAnyOf.php ================================================ $classes */ function isAnyOf($value, array $classes): object|string { Assert::isAnyOf($value, $classes); return $value; } /** * @psalm-pure * * @param null|object|string $value * @param array $classes */ function nullOrIsAnyOf($value, array $classes): object|string|null { Assert::nullOrIsAnyOf($value, $classes); return $value; } /** * @psalm-pure * * @param iterable $value * @param array $classes */ function allIsAnyOf($value, array $classes): iterable { Assert::allIsAnyOf($value, $classes); return $value; } /** * @psalm-pure * * @param iterable $value * @param array $classes */ function allNullOrIsAnyOf($value, array $classes): iterable { Assert::allNullOrIsAnyOf($value, $classes); return $value; } ================================================ FILE: tests/static-analysis/assert-isArray.php ================================================ */ function allIsCountable(mixed $value) { Assert::allIsCountable($value); return $value; } /** * @psalm-pure * * @param mixed $value * * @return iterable */ function allNullOrIsCountable(mixed $value) { Assert::allNullOrIsCountable($value); return $value; } ================================================ FILE: tests/static-analysis/assert-isEmpty.php ================================================ */ function isEmptyArray(array $value) { Assert::isEmpty($value); return $value; } /** * @psalm-pure * * @return null|empty */ function nullOrIsEmpty(?object $value) { Assert::nullOrIsEmpty($value); return $value; } /** * @psalm-pure * * @param mixed $value */ function allIsEmpty(mixed $value): iterable { Assert::allIsEmpty($value); return $value; } /** * @psalm-pure * * @param mixed $value */ function allNullOrIsEmpty(mixed $value): iterable { Assert::allNullOrIsEmpty($value); return $value; } ================================================ FILE: tests/static-analysis/assert-isInitialized.php ================================================ $classes */ function isInstanceOfAny($value, array $classes): mixed { Assert::isInstanceOfAny($value, $classes); return $value; } /** * @param mixed $value * @param array $classes */ function nullOrIsInstanceOfAny($value, array $classes): mixed { Assert::nullOrIsInstanceOfAny($value, $classes); return $value; } /** * @param mixed $value * @param array $classes */ function allIsInstanceOfAny($value, array $classes): mixed { Assert::allIsInstanceOfAny($value, $classes); return $value; } /** * @param mixed $value * @param array $classes */ function allNullOrIsInstanceOfAny($value, array $classes): mixed { Assert::allNullOrIsInstanceOfAny($value, $classes); return $value; } ================================================ FILE: tests/static-analysis/assert-isIterable.php ================================================ */ function isList(mixed $value): array { Assert::isList($value); return $value; } /** * @psalm-pure * * @param array $value * * @return list */ function isListWithKnownType(array $value): array { Assert::isList($value); return $value; } /** * @psalm-pure * * @param mixed $value * * @return null|list */ function nullOrIsList(mixed $value): ?array { Assert::nullOrIsList($value); return $value; } /** * @psalm-pure * * @param mixed $value */ function allIsList(mixed $value): iterable { Assert::allIsList($value); return $value; } /** * @psalm-pure * * @param mixed $value */ function allNullOrIsList(mixed $value): iterable { Assert::allNullOrIsList($value); return $value; } ================================================ FILE: tests/static-analysis/assert-isMap.php ================================================ */ function isMap(mixed $value): array { Assert::isMap($value); return $value; } /** * Verifying that the type of the elements in the array is preserved by the assertion * * @psalm-pure * * @param array $value * * @return array */ function isMapWithKnownType(array $value): array { Assert::isMap($value); return $value; } /** * @psalm-pure * * @param array $value * * @return array */ function isMapWithEmptyArray(array $value): array { Assert::isMap($value); Assert::isEmpty($value); return $value; } /** * @psalm-pure * * @param mixed $value * * @return null|array */ function nullOrIsMap(mixed $value): ?array { Assert::nullOrIsMap($value); return $value; } /** * @psalm-pure * * @param iterable> $value */ function allIsMap(iterable $value): iterable { Assert::allIsMap($value); return $value; } /** * @psalm-pure * * @param iterable> $value */ function allNullOrIsMap(iterable $value): iterable { Assert::allNullOrIsMap($value); return $value; } ================================================ FILE: tests/static-analysis/assert-isNonEmptyList.php ================================================ */ function isNonEmptyList(mixed $value): array { Assert::isNonEmptyList($value); return $value; } /** * @psalm-pure */ function isNonEmptyListWithRange(): mixed { $value = range(1, 100); Assert::isNonEmptyList($value); return $value[0]; } /** * @psalm-pure * * @param mixed $value * * @return null|non-empty-list */ function nullOrIsNonEmptyList(mixed $value): ?array { Assert::nullOrIsNonEmptyList($value); return $value; } /** * @psalm-pure * * @param mixed $value */ function allIsNonEmptyList(mixed $value): iterable { Assert::allIsNonEmptyList($value); return $value; } /** * @psalm-pure * * @param mixed $value */ function allNullOrIsNonEmptyList(mixed $value): iterable { Assert::allNullOrIsNonEmptyList($value); return $value; } ================================================ FILE: tests/static-analysis/assert-isNonEmptyMap.php ================================================ */ function isNonEmptyMap(mixed $value): array { Assert::isNonEmptyMap($value); return $value; } /** * Verifying that the type of the elements in the array is preserved by the assertion * * @psalm-pure * * @param array $value * * @return array */ function isNonEmptyMapWithKnownType(array $value): array { Assert::isNonEmptyMap($value); return $value; } /** * @psalm-pure * * @param mixed $value */ function nullOrIsNonEmptyMap(mixed $value): mixed { Assert::nullOrIsNonEmptyMap($value); return $value; } /** * @psalm-pure * * @param iterable> $value */ function allIsNonEmptyMap(iterable $value): iterable { Assert::allIsNonEmptyMap($value); return $value; } /** * @psalm-pure * * @param iterable> $value */ function allNullOrIsNonEmptyMap(iterable $value): iterable { Assert::allNullOrIsNonEmptyMap($value); return $value; } ================================================ FILE: tests/static-analysis/assert-isNotA.php ================================================ $class */ function nullOrIsNotA($value, $class): object|string|null { Assert::nullOrIsNotA($value, $class); return $value; } /** * @psalm-pure * * @param iterable $value * @param class-string $class */ function allIsNotA($value, $class): iterable { Assert::allIsNotA($value, $class); return $value; } /** * @psalm-pure * * @param iterable $value * @param class-string $class */ function allNullOrIsNotA($value, $class): iterable { Assert::allNullOrIsNotA($value, $class); return $value; } ================================================ FILE: tests/static-analysis/assert-isStatic.php ================================================ $array * @param array-key $key */ function allKeyExists(iterable $array, $key): iterable { Assert::allKeyExists($array, $key); return $array; } /** * @psalm-pure * * @param iterable $array * @param array-key $key */ function allNullOrKeyExists(iterable $array, $key): iterable { Assert::allNullOrKeyExists($array, $key); return $array; } ================================================ FILE: tests/static-analysis/assert-keyNotExists.php ================================================ $array * @param array-key $key */ function allKeyNotExists(iterable $array, $key): iterable { Assert::allKeyNotExists($array, $key); return $array; } /** * @psalm-pure * * @param iterable $array * @param array-key $key */ function allNullOrKeyNotExists(iterable $array, $key): iterable { Assert::allNullOrKeyNotExists($array, $key); return $array; } ================================================ FILE: tests/static-analysis/assert-length.php ================================================ $value */ function allLength(iterable $value, int $length): iterable { Assert::allLength($value, $length); return $value; } /** * @psalm-pure * * @param iterable $value */ function allNullOrLength(iterable $value, int $length): iterable { Assert::allNullOrLength($value, $length); return $value; } ================================================ FILE: tests/static-analysis/assert-lengthBetween.php ================================================ $value * * @return iterable */ function allLengthBetween(iterable $value, int $min, int $max): iterable { Assert::allLengthBetween($value, $min, $max); return $value; } /** * @psalm-pure * * @param iterable $value * * @return iterable */ function allNullOrLengthBetween(iterable $value, int $min, int $max): iterable { Assert::allNullOrLengthBetween($value, $min, $max); return $value; } ================================================ FILE: tests/static-analysis/assert-lessThan.php ================================================ $value */ function allLower(iterable $value): iterable { Assert::allLower($value); return $value; } /** * @psalm-pure * * @param iterable $value */ function allNullOrLower(iterable $value): iterable { Assert::allNullOrLower($value); return $value; } ================================================ FILE: tests/static-analysis/assert-maxCount.php ================================================ $array * @param int|float $max */ function allMaxCount(iterable $array, $max): iterable { Assert::allMaxCount($array, $max); return $array; } /** * @param iterable $array * @param int|float $max */ function allNullOrMaxCount(iterable $array, $max): iterable { Assert::allNullOrMaxCount($array, $max); return $array; } ================================================ FILE: tests/static-analysis/assert-maxLength.php ================================================ $value * * @return iterable */ function allMaxLength(iterable $value, int $max): iterable { Assert::allMaxLength($value, $max); return $value; } /** * @psalm-pure * * @param iterable $value * * @return iterable */ function allNullOrMaxLength(iterable $value, int $max): iterable { Assert::allMaxLength($value, $max); return $value; } ================================================ FILE: tests/static-analysis/assert-methodExists.php ================================================ $classOrObject * @param mixed $method */ function allMethodExists(iterable $classOrObject, $method): iterable { Assert::allMethodExists($classOrObject, $method); return $classOrObject; } /** * @psalm-pure * * @param iterable $classOrObject * @param mixed $method */ function allNullOrMethodExists(iterable $classOrObject, $method): iterable { Assert::allNullOrMethodExists($classOrObject, $method); return $classOrObject; } ================================================ FILE: tests/static-analysis/assert-methodNotExists.php ================================================ $classOrObject * @param mixed $method */ function allMethodNotExists(iterable $classOrObject, $method): iterable { Assert::allMethodNotExists($classOrObject, $method); return $classOrObject; } /** * @psalm-pure * * @param iterable $classOrObject * @param mixed $method */ function allNullOrMethodNotExists(iterable $classOrObject, $method): iterable { Assert::allNullOrMethodNotExists($classOrObject, $method); return $classOrObject; } ================================================ FILE: tests/static-analysis/assert-minCount.php ================================================ $array * @param int|float $min * * @return iterable */ function allMinCount($array, $min) { Assert::allMinCount($array, $min); return $array; } /** * @param iterable $array * @param int|float $min * * @return iterable */ function allNullOrMinCount($array, $min) { Assert::allNullOrMinCount($array, $min); return $array; } ================================================ FILE: tests/static-analysis/assert-minLength.php ================================================ $value * @param int|float $min */ function allMinLength(iterable $value, $min): iterable { Assert::allMinLength($value, $min); return $value; } /** * @psalm-pure * * @param iterable $value * @param int|float $min */ function allNullOrMinLength(iterable $value, $min): iterable { Assert::allNullOrMinLength($value, $min); return $value; } ================================================ FILE: tests/static-analysis/assert-natural.php ================================================ */ function allNegativeInteger(mixed $value): iterable { Assert::allNegativeInteger($value); return $value; } /** * @psalm-pure * * @param mixed $value * * @return iterable */ function allNullOrNegativeInteger(mixed $value): iterable { Assert::allNullOrNegativeInteger($value); return $value; } ================================================ FILE: tests/static-analysis/assert-notContains.php ================================================ $value */ function allNotContains(iterable $value, string $subString): iterable { Assert::allNotContains($value, $subString); return $value; } /** * @psalm-pure * * @param iterable $value */ function allNullOrNotContains(iterable $value, string $subString): iterable { Assert::allNullOrNotContains($value, $subString); return $value; } ================================================ FILE: tests/static-analysis/assert-notEmpty.php ================================================ $class */ function nullOrNotInstanceOf($value, $class): mixed { Assert::nullOrNotInstanceOf($value, $class); return $value; } /** * @psalm-template T of object * * @param mixed $value * @param class-string $class */ function allNotInstanceOf($value, $class): mixed { Assert::allNotInstanceOf($value, $class); return $value; } /** * @psalm-template T of object * * @param mixed $value * @param class-string $class */ function allNullOrNotInstanceOf($value, $class): mixed { Assert::allNullOrNotInstanceOf($value, $class); return $value; } ================================================ FILE: tests/static-analysis/assert-notNegativeInteger.php ================================================ */ function allNonNegativeInteger(mixed $value): iterable { Assert::allNotNegativeInteger($value); return $value; } /** * @psalm-pure * * @param mixed $value * * @return iterable */ function allNullOrNonNegativeInteger(mixed $value): iterable { Assert::allNullOrPositiveInteger($value); return $value; } ================================================ FILE: tests/static-analysis/assert-notNull.php ================================================ $value */ function allNotRegex(iterable $value, string $pattern): iterable { Assert::allNotRegex($value, $pattern); return $value; } /** * @psalm-pure * * @param iterable $value */ function allNullOrNotRegex(iterable $value, string $pattern): iterable { Assert::allNotRegex($value, $pattern); return $value; } ================================================ FILE: tests/static-analysis/assert-notSame.php ================================================ $value */ function allNotWhitespaceOnly(iterable $value): iterable { Assert::allNotWhitespaceOnly($value); return $value; } /** * @psalm-pure * * @param iterable $value */ function allNullOrNotWhitespaceOnly(iterable $value): iterable { Assert::allNullOrNotWhitespaceOnly($value); return $value; } ================================================ FILE: tests/static-analysis/assert-null.php ================================================ $classOrObject * @param mixed $property */ function allPropertyExists(iterable $classOrObject, $property): iterable { Assert::allPropertyExists($classOrObject, $property); return $classOrObject; } /** * @psalm-pure * * @param iterable $classOrObject * @param mixed $property */ function allNullOrPropertyExists(iterable $classOrObject, $property): iterable { Assert::allPropertyExists($classOrObject, $property); return $classOrObject; } ================================================ FILE: tests/static-analysis/assert-propertyNotExists.php ================================================ $classOrObject * @param mixed $property */ function allPropertyNotExists(iterable $classOrObject, $property): iterable { Assert::allPropertyNotExists($classOrObject, $property); return $classOrObject; } /** * @psalm-pure * * @param iterable $classOrObject * @param mixed $property */ function allNullOrPropertyNotExists(iterable $classOrObject, $property): iterable { Assert::allNullOrPropertyNotExists($classOrObject, $property); return $classOrObject; } ================================================ FILE: tests/static-analysis/assert-psalm-notRedundant.php ================================================ $value * * @return ArrayIterator */ function preserveContainerAllArrayIterator(mixed $value) { Assert::allString($value); return $value; } ================================================ FILE: tests/static-analysis/assert-psalm-preserveStringType.php ================================================ $value */ function allReadable(iterable $value): iterable { Assert::allReadable($value); return $value; } /** * @param iterable $value */ function allNullOrReadable(iterable $value): iterable { Assert::allNullOrReadable($value); return $value; } ================================================ FILE: tests/static-analysis/assert-regex.php ================================================ $value */ function allRegex(iterable $value, string $pattern): iterable { Assert::allRegex($value, $pattern); return $value; } /** * @psalm-pure * * @param iterable $value */ function allNullOrRegex(iterable $value, string $pattern): iterable { Assert::allRegex($value, $pattern); return $value; } ================================================ FILE: tests/static-analysis/assert-resource.php ================================================ $value */ function allStartsWith(iterable $value, string $prefix): iterable { Assert::allStartsWith($value, $prefix); return $value; } /** * @psalm-pure * * @param iterable $value */ function allNullOrStartsWith(iterable $value, string $prefix): iterable { Assert::allNullOrStartsWith($value, $prefix); return $value; } ================================================ FILE: tests/static-analysis/assert-startsWithLetter.php ================================================ |stdClass */ function subclassOf(mixed $value) { Assert::subclassOf($value, stdClass::class); return $value; } /** * @psalm-pure * * @param mixed $value * * @return null|class-string|stdClass */ function nullOrSubclassOf(mixed $value) { Assert::nullOrSubclassOf($value, stdClass::class); return $value; } /** * @psalm-pure * * @param mixed $value */ function allSubclassOf(mixed $value): iterable { Assert::allSubclassOf($value, stdClass::class); return $value; } /** * @psalm-pure * * @param mixed $value */ function allNullOrSubclassOf(mixed $value): iterable { Assert::allNullOrSubclassOf($value, stdClass::class); return $value; } ================================================ FILE: tests/static-analysis/assert-throws.php ================================================ $class */ function throws(Closure $value, $class): Closure { Assert::throws($value, $class); return $value; } /** * @param class-string $class */ function nullOrThrows(?Closure $value, $class): ?Closure { Assert::nullOrThrows($value, $class); return $value; } /** * @param iterable $value * @param class-string $class */ function allThrows(iterable $value, $class): iterable { Assert::allThrows($value, $class); return $value; } /** * @param iterable $value * @param class-string $class */ function allNullOrThrows(iterable $value, $class): iterable { Assert::allNullOrThrows($value, $class); return $value; } ================================================ FILE: tests/static-analysis/assert-true.php ================================================ $values */ function allUniqueValues(iterable $values): iterable { Assert::allUniqueValues($values); return $values; } /** * @param iterable $values */ function allNullOrUniqueValues(iterable $values): iterable { Assert::allNullOrUniqueValues($values); return $values; } ================================================ FILE: tests/static-analysis/assert-upper.php ================================================ $value */ function allUpper(iterable $value): iterable { Assert::allUpper($value); return $value; } /** * @psalm-pure * * @param iterable $value */ function allNullOrUpper(iterable $value): iterable { Assert::allNullOrUpper($value); return $value; } ================================================ FILE: tests/static-analysis/assert-uuid.php ================================================ $value */ function allUuid(iterable $value): iterable { Assert::allUuid($value); return $value; } /** * @psalm-pure * * @param iterable $value */ function allNullOrUuid(iterable $value): iterable { Assert::allNullOrUuid($value); return $value; } ================================================ FILE: tests/static-analysis/assert-validArrayKey.php ================================================ $value */ function allWritable(iterable $value): iterable { Assert::allWritable($value); return $value; } /** * @param iterable $value */ function allNullOrWritable(iterable $value): iterable { Assert::allNullOrWritable($value); return $value; } ================================================ FILE: tools/php-cs-fixer/composer.json ================================================ { "require": { "php": "^8.2" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.64" } } ================================================ FILE: tools/phpunit/composer.json ================================================ { "require": { "php": "^8.2" }, "require-dev": { "phpunit/phpunit": "^11.0" } } ================================================ FILE: tools/psalm/composer.json ================================================ { "require": { "php": "^8.2" }, "require-dev": { "vimeo/psalm": "^6.0" } } ================================================ FILE: tools/roave-bc-check/composer.json ================================================ { "require": { "php": "^8.2" }, "require-dev": { "roave/backward-compatibility-check": "^8.10" } }