Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 31 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,36 +82,37 @@ 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
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
`isNotInstanceOfAny($value, array $classes, $message = '')` | Check that a value is not an `instanceof` at least one class on the array of classes
`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

Expand Down
30 changes: 30 additions & 0 deletions src/Assert.php
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,36 @@ public static function isInstanceOfAny(mixed $value, mixed $classes, string $mes
));
}

/**
* @template T
*
* @psalm-assert T $value
*
* @param T $value
*
* @return T
*
* @throws InvalidArgumentException
*/
public static function isNotInstanceOfAny(mixed $value, mixed $classes, string $message = ''): mixed
{
static::isIterable($classes);

foreach ($classes as $class) {
static::string($class, 'Expected class as a string. Got: %s');

if ($value instanceof $class) {
static::reportInvalidArgument(\sprintf(
$message ?: 'Expected not an instance of %2$s. Got: %s',
static::typeToString($value),
\implode(', ', \array_map(static::valueToString(...), \iterator_to_array($classes)))
));
}
}

return $value;
}

/**
* @psalm-pure
*
Expand Down
59 changes: 59 additions & 0 deletions src/Mixin.php
Original file line number Diff line number Diff line change
Expand Up @@ -1313,6 +1313,65 @@ public static function allNullOrIsInstanceOfAny(mixed $value, mixed $classes, st
return $value;
}

/**
* @template T
* @psalm-assert T|null $value
*
* @param T|null $value
*
* @return T|null
*
* @throws InvalidArgumentException
*/
public static function nullOrIsNotInstanceOfAny(mixed $value, mixed $classes, string $message = ''): mixed
{
null === $value || static::isNotInstanceOfAny($value, $classes, $message);

return $value;
}

/**
* @template T
* @psalm-assert iterable<T> $value
*
* @param iterable<T> $value
*
* @return iterable<T>
*
* @throws InvalidArgumentException
*/
public static function allIsNotInstanceOfAny(mixed $value, mixed $classes, string $message = ''): iterable
{
static::isIterable($value);

foreach ($value as $entry) {
static::isNotInstanceOfAny($entry, $classes, $message);
}

return $value;
}

/**
* @template T
* @psalm-assert iterable<T|null> $value
*
* @param iterable<T|null> $value
*
* @return iterable<T|null>
*
* @throws InvalidArgumentException
*/
public static function allNullOrIsNotInstanceOfAny(mixed $value, mixed $classes, string $message = ''): iterable
{
static::isIterable($value);

foreach ($value as $entry) {
null === $entry || static::isNotInstanceOfAny($entry, $classes, $message);
}

return $value;
}

/**
* @psalm-pure
*
Expand Down
5 changes: 5 additions & 0 deletions tests/AssertTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@ public static function getTests(): array
['isInstanceOfAny', [new Exception(), ['ArrayAccess', 'Countable']], false],
['isInstanceOfAny', [123, ['stdClass']], false],
['isInstanceOfAny', [[], ['stdClass']], false],
['isNotInstanceOfAny', [new ArrayIterator(), ['Exception', 'Countable']], false],
['isNotInstanceOfAny', [new Exception(), ['ArrayAccess', 'Countable']], true],
['isNotInstanceOfAny', [new Exception(), ['Exception', 'Countable']], false],
['isNotInstanceOfAny', [123, ['stdClass']], true],
['isNotInstanceOfAny', [[], ['stdClass']], true],
['isAOf', ['stdClass', 'stdClass'], true],
['isAOf', ['stdClass', 123], false],
['isAOf', ['Iterator', 'ArrayIterator'], false],
Expand Down
51 changes: 51 additions & 0 deletions tests/static-analysis/assert-isNotInstanceOfAny.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace Webmozart\Assert\Tests\StaticAnalysis;

use Webmozart\Assert\Assert;

/**
* @param mixed $value
* @param array<class-string> $classes
*/
function isNotInstanceOfAny($value, array $classes): mixed
{
Assert::isNotInstanceOfAny($value, $classes);

return $value;
}

/**
* @param mixed $value
* @param array<class-string> $classes
*/
function nullOrIsNotInstanceOfAny($value, array $classes): mixed
{
Assert::nullOrIsNotInstanceOfAny($value, $classes);

return $value;
}

/**
* @param mixed $value
* @param array<class-string> $classes
*/
function allIsNotInstanceOfAny($value, array $classes): mixed
{
Assert::allIsNotInstanceOfAny($value, $classes);

return $value;
}

/**
* @param mixed $value
* @param array<class-string> $classes
*/
function allNullOrIsNotInstanceOfAny($value, array $classes): mixed
{
Assert::allNullOrIsNotInstanceOfAny($value, $classes);

return $value;
}
Loading