diff --git a/ChangeLog-11.5.md b/ChangeLog-11.5.md index aaee144ec8..eaccfbb10f 100644 --- a/ChangeLog-11.5.md +++ b/ChangeLog-11.5.md @@ -9,9 +9,9 @@ All notable changes of the PHPUnit 11.5 release series are documented in this fi * [#5948](https://github.com/sebastianbergmann/phpunit/pull/5948): Support for Property Hooks in Test Doubles * [#5954](https://github.com/sebastianbergmann/phpunit/issues/5954): Provide a way to stop execution at a particular deprecation * Method `assertContainsNotOnlyInstancesOf()` in the `PHPUnit\Framework\Assert` class as the inverse of the `assertContainsOnlyInstancesOf()` method -* Methods `assertContainsOnlyArray()`, `assertContainsOnlyBool()`, `assertContainsOnlyCallable()`, `assertContainsOnlyFloat()`, `assertContainsOnlyInt()`, `assertContainsOnlyIterable()`, `assertContainsOnlyNumeric()`, `assertContainsOnlyObject()`, `assertContainsOnlyResource()`, `assertContainsOnlyClosedResource()`, `assertContainsOnlyScalar()`, and `assertContainsOnlyString()` in the `PHPUnit\Framework\Assert` class as specialized alternatives for the generic `assertContainsOnly()` method -* Methods `assertContainsNotOnlyArray()`, `assertContainsNotOnlyBool()`, `assertContainsNotOnlyCallable()`, `assertContainsNotOnlyFloat()`, `assertContainsNotOnlyInt()`, `assertContainsNotOnlyIterable()`, `assertContainsNotOnlyNumeric()`, `assertContainsNotOnlyObject()`, `assertContainsNotOnlyResource()`, `assertContainsNotOnlyClosedResource()`, `assertContainsNotOnlyScalar()`, and `assertContainsNotOnlyString()` in the `PHPUnit\Framework\Assert` class as specialized alternatives for the generic `assertNotContainsOnly()` method -* Methods `containsOnlyArray()`, `containsOnlyBool()`, `containsOnlyCallable()`, `containsOnlyFloat()`, `containsOnlyInt()`, `containsOnlyIterable()`, `containsOnlyNumeric()`, `containsOnlyObject()`, `containsOnlyResource()`, `containsOnlyClosedResource()`, `containsOnlyScalar()`, and `containsOnlyString()` in the `PHPUnit\Framework\Assert` class as specialized alternatives for the generic `containsOnly()` method +* Methods `assertContainsOnlyArray()`, `assertContainsOnlyBool()`, `assertContainsOnlyCallable()`, `assertContainsOnlyFloat()`, `assertContainsOnlyInt()`, `assertContainsOnlyIterable()`, `assertContainsOnlyNull()`, `assertContainsOnlyNumeric()`, `assertContainsOnlyObject()`, `assertContainsOnlyResource()`, `assertContainsOnlyClosedResource()`, `assertContainsOnlyScalar()`, and `assertContainsOnlyString()` in the `PHPUnit\Framework\Assert` class as specialized alternatives for the generic `assertContainsOnly()` method +* Methods `assertContainsNotOnlyArray()`, `assertContainsNotOnlyBool()`, `assertContainsNotOnlyCallable()`, `assertContainsNotOnlyFloat()`, `assertContainsNotOnlyInt()`, `assertContainsNotOnlyIterable()`, `assertContainsNotOnlyNull()`, `assertContainsNotOnlyNumeric()`, `assertContainsNotOnlyObject()`, `assertContainsNotOnlyResource()`, `assertContainsNotOnlyClosedResource()`, `assertContainsNotOnlyScalar()`, and `assertContainsNotOnlyString()` in the `PHPUnit\Framework\Assert` class as specialized alternatives for the generic `assertNotContainsOnly()` method +* Methods `containsOnlyArray()`, `containsOnlyBool()`, `containsOnlyCallable()`, `containsOnlyFloat()`, `containsOnlyInt()`, `containsOnlyIterable()`, `containsOnlyNull()`, `containsOnlyNumeric()`, `containsOnlyObject()`, `containsOnlyResource()`, `containsOnlyClosedResource()`, `containsOnlyScalar()`, and `containsOnlyString()` in the `PHPUnit\Framework\Assert` class as specialized alternatives for the generic `containsOnly()` method * Methods `isArray()`, `isBool()`, `isCallable()`, `isFloat()`, `isInt()`, `isIterable()`, `isNumeric()`, `isObject()`, `isResource()`, `isClosedResource()`, `isScalar()`, `isString()` in the `PHPUnit\Framework\Assert` class as specialized alternatives for the generic `isType()` method * `TestRunner\ChildProcessStarted` and `TestRunner\ChildProcessFinished` events diff --git a/composer.json b/composer.json index 0419b5c0e7..56f4938457 100644 --- a/composer.json +++ b/composer.json @@ -87,6 +87,7 @@ "tests/unit/Framework/Assert/assertContainsOnlyInstancesOfTest.php", "tests/unit/Framework/Assert/assertContainsOnlyIntTest.php", "tests/unit/Framework/Assert/assertContainsOnlyIterableTest.php", + "tests/unit/Framework/Assert/assertContainsOnlyNullTest.php", "tests/unit/Framework/Assert/assertContainsOnlyNumericTest.php", "tests/unit/Framework/Assert/assertContainsOnlyObjectTest.php", "tests/unit/Framework/Assert/assertContainsOnlyResourceTest.php", diff --git a/src/Framework/Assert.php b/src/Framework/Assert.php index f39ed6c3db..056a1bd0ee 100644 --- a/src/Framework/Assert.php +++ b/src/Framework/Assert.php @@ -399,6 +399,24 @@ final public static function assertContainsOnlyIterable(iterable $haystack, stri ); } + /** + * Asserts that a haystack contains only values of type null. + * + * @param iterable $haystack + * + * @throws ExpectationFailedException + */ + final public static function assertContainsOnlyNull(iterable $haystack, string $message = ''): void + { + self::assertThat( + $haystack, + new TraversableContainsOnly( + NativeType::Null->value, + ), + $message, + ); + } + /** * Asserts that a haystack contains only values of type numeric. * @@ -677,6 +695,26 @@ final public static function assertContainsNotOnlyIterable(iterable $haystack, s ); } + /** + * Asserts that a haystack does not contain only values of type null. + * + * @param iterable $haystack + * + * @throws ExpectationFailedException + */ + final public static function assertContainsNotOnlyNull(iterable $haystack, string $message = ''): void + { + self::assertThat( + $haystack, + new LogicalNot( + new TraversableContainsOnly( + NativeType::Null->value, + ), + ), + $message, + ); + } + /** * Asserts that a haystack does not contain only values of type numeric. * diff --git a/src/Framework/Assert/Functions.php b/src/Framework/Assert/Functions.php index 65b17797d0..0f66023c59 100644 --- a/src/Framework/Assert/Functions.php +++ b/src/Framework/Assert/Functions.php @@ -407,6 +407,24 @@ function assertContainsOnlyIterable(iterable $haystack, string $message = ''): v } } +if (!function_exists('PHPUnit\Framework\assertContainsOnlyNull')) { + /** + * Asserts that a haystack contains only values of type null. + * + * @param iterable $haystack + * + * @throws ExpectationFailedException + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + * + * @see Assert::assertContainsOnlyNull + */ + function assertContainsOnlyNull(iterable $haystack, string $message = ''): void + { + Assert::assertContainsOnlyNull(...func_get_args()); + } +} + if (!function_exists('PHPUnit\Framework\assertContainsOnlyNumeric')) { /** * Asserts that a haystack contains only values of type numeric. @@ -665,6 +683,24 @@ function assertContainsNotOnlyIterable(iterable $haystack, string $message = '') } } +if (!function_exists('PHPUnit\Framework\assertContainsNotOnlyNull')) { + /** + * Asserts that a haystack does not contain only values of type null. + * + * @param iterable $haystack + * + * @throws ExpectationFailedException + * + * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit + * + * @see Assert::assertContainsNotOnlyNull + */ + function assertContainsNotOnlyNull(iterable $haystack, string $message = ''): void + { + Assert::assertContainsNotOnlyNull(...func_get_args()); + } +} + if (!function_exists('PHPUnit\Framework\assertContainsNotOnlyNumeric')) { /** * Asserts that a haystack does not contain only values of type numeric. diff --git a/tests/unit/Framework/Assert/assertContainsNotOnlyNullTest.php b/tests/unit/Framework/Assert/assertContainsNotOnlyNullTest.php new file mode 100644 index 0000000000..61ca652ce8 --- /dev/null +++ b/tests/unit/Framework/Assert/assertContainsNotOnlyNullTest.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use PHPUnit\Framework\Attributes\CoversMethod; +use PHPUnit\Framework\Attributes\DataProviderExternal; +use PHPUnit\Framework\Attributes\Small; +use PHPUnit\Framework\Attributes\TestDox; + +#[CoversMethod(Assert::class, 'assertContainsNotOnlyNull')] +#[TestDox('assertContainsNotOnlyNull()')] +#[Small] +final class assertContainsNotOnlyNullTest extends TestCase +{ + #[DataProviderExternal(assertContainsOnlyNullTest::class, 'failureProvider')] + public function testSucceedsWhenConstraintEvaluatesToTrue(iterable $haystack): void + { + $this->assertContainsNotOnlyNull($haystack); + } + + #[DataProviderExternal(assertContainsOnlyNullTest::class, 'successProvider')] + public function testFailsWhenConstraintEvaluatesToFalse(iterable $haystack): void + { + $this->expectException(AssertionFailedError::class); + + $this->assertContainsNotOnlyNull($haystack); + } +} diff --git a/tests/unit/Framework/Assert/assertContainsOnlyNullTest.php b/tests/unit/Framework/Assert/assertContainsOnlyNullTest.php new file mode 100644 index 0000000000..6ddcf346b7 --- /dev/null +++ b/tests/unit/Framework/Assert/assertContainsOnlyNullTest.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use PHPUnit\Framework\Attributes\CoversMethod; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Small; +use PHPUnit\Framework\Attributes\TestDox; + +#[CoversMethod(Assert::class, 'assertContainsOnlyNull')] +#[TestDox('assertContainsOnlyNull()')] +#[Small] +final class assertContainsOnlyNullTest extends TestCase +{ + /** + * @return non-empty-list + */ + public static function successProvider(): array + { + return [ + [[null]], + ]; + } + + /** + * @return non-empty-list + */ + public static function failureProvider(): array + { + return [ + [[true]], + ]; + } + + #[DataProvider('successProvider')] + public function testSucceedsWhenConstraintEvaluatesToTrue(iterable $haystack): void + { + $this->assertContainsOnlyNull($haystack); + } + + #[DataProvider('failureProvider')] + public function testFailsWhenConstraintEvaluatesToFalse(iterable $haystack): void + { + $this->expectException(AssertionFailedError::class); + + $this->assertContainsOnlyNull($haystack); + } +}