Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHPUnit 11 | AssertArrayWithListKeys trait: polyfill the Assert::assertArrayIsEqualToArrayOnlyConsideringListOfKeys() et al methods #198

Merged
Merged
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
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,25 @@ These methods were later backported to the PHPUnit 9 branch and included in the
[`Assert::assertObjectHasProperty()`]: https://docs.phpunit.de/en/main/assertions.html#assertObjectHasProperty
[`Assert::assertObjectNotHasProperty()`]: https://docs.phpunit.de/en/main/assertions.html#assertObjectHasProperty

#### PHPUnit < 11.0.0: `Yoast\PHPUnitPolyfills\Polyfills\AssertArrayWithListKeys`

Polyfills the following method:
| | |
| -------------------------------------------------------------------- | ------------------------------------------------------------- |
| [`Assert::assertArrayIsEqualToArrayOnlyConsideringListOfKeys()`] | [`Assert::assertArrayIsEqualToArrayIgnoringListOfKeys()`] |
| [`Assert::assertArrayIsIdenticalToArrayOnlyConsideringListOfKeys()`] | [`Assert::assertArrayIsIdenticalToArrayIgnoringListOfKeys()`] |

These methods were introduced in PHPUnit 11.0.0.

This functionality resembles the functionality previously offered by the `Assert::assertArraySubset()` assertion, which was removed in PHPUnit 9.0.0, but with higher precision.

Refactoring tests which still use `Assert::assertArraySubset()` to use the new assertions should be considered as an upgrade path.

[`Assert::assertArrayIsEqualToArrayOnlyConsideringListOfKeys()`]: https://docs.phpunit.de/en/main/assertions.html#assertarrayisequaltoarrayonlyconsideringlistofkeys
[`Assert::assertArrayIsEqualToArrayIgnoringListOfKeys()`]: https://docs.phpunit.de/en/main/assertions.html#assertarrayisequaltoarrayignoringlistofkeys
[`Assert::assertArrayIsIdenticalToArrayOnlyConsideringListOfKeys()`]: https://docs.phpunit.de/en/main/assertions.html#assertarrayisidenticaltoarrayonlyconsideringlistofkeys
[`Assert::assertArrayIsIdenticalToArrayIgnoringListOfKeys()`]: https://docs.phpunit.de/en/main/assertions.html#assertarrayisidenticaltoarrayignoringlistofkeys


### TestCases

Expand Down
21 changes: 21 additions & 0 deletions phpunitpolyfills-autoload.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ public static function load( $className ) {
self::loadAssertObjectProperty();
return true;

case 'Yoast\PHPUnitPolyfills\Polyfills\AssertArrayWithListKeys':
self::loadAssertArrayWithListKeys();
return true;

case 'Yoast\PHPUnitPolyfills\TestCases\TestCase':
self::loadTestCase();
return true;
Expand Down Expand Up @@ -313,6 +317,23 @@ public static function loadAssertObjectProperty() {
require_once __DIR__ . '/src/Polyfills/AssertObjectProperty_Empty.php';
}

/**
* Load the AssertArrayWithListKeys polyfill or an empty trait with the same name
* if a PHPUnit version is used which already contains this functionality.
*
* @return void
*/
public static function loadAssertArrayWithListKeys() {
if ( \method_exists( Assert::class, 'assertArrayIsEqualToArrayOnlyConsideringListOfKeys' ) === false ) {
// PHPUnit < 11.0.0.
require_once __DIR__ . '/src/Polyfills/AssertArrayWithListKeys.php';
return;
}

// PHPUnit >= 11.0.0.
require_once __DIR__ . '/src/Polyfills/AssertArrayWithListKeys_Empty.php';
}

/**
* Load the appropriate TestCase class based on the PHPUnit version being used.
*
Expand Down
120 changes: 120 additions & 0 deletions src/Polyfills/AssertArrayWithListKeys.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

namespace Yoast\PHPUnitPolyfills\Polyfills;

/**
* Polyfill the Assert::assertArrayIsEqualToArrayOnlyConsideringListOfKeys(),
* Assert::assertArrayIsEqualToArrayIgnoringListOfKeys(),
* Assert::assertArrayIsIdenticalToArrayOnlyConsideringListOfKeys(),
* and Assert::assertArrayIsIdenticalToArrayIgnoringListOfKeys() methods.
*
* Introduced in PHPUnit 11.0.0.
*
* This functionality resembles the functionality previously offered by the `Assert::assertArraySubset()`
* assertion, which was removed in PHPUnit 9.0.0, but with higher precision.
*
* Refactoring tests which still use `Assert::assertArraySubset()` to use the new assertions should be
* considered as an upgrade path.
*
* @link https://github.com/sebastianbergmann/phpunit/pull/5600
* @link https://github.com/sebastianbergmann/phpunit/pull/5716 Included in PHPUnit 11.0.4.
* @link https://github.com/sebastianbergmann/phpunit/pull/5729 Included in PHPUnit 11.0.6.
*
* @since 3.0.0
*/
trait AssertArrayWithListKeys {

/**
* Asserts that two arrays are equal while only considering array elements for which the keys have been specified.
*
* {@internal As the array type declarations don't lead to type juggling, even without strict_types,
* it is safe to let PHP handle the parameter validation.}
*
* @param array<mixed> $expected Expected value.
* @param array<mixed> $actual The variable to test.
* @param array<int|string> $keysToBeConsidered The array keys to take into account.
* @param string $message Optional failure message to display.
*
* @return void
*/
final public static function assertArrayIsEqualToArrayOnlyConsideringListOfKeys( array $expected, array $actual, array $keysToBeConsidered, string $message = '' ) {
$filteredExpected = [];
foreach ( $keysToBeConsidered as $key ) {
if ( isset( $expected[ $key ] ) ) {
$filteredExpected[ $key ] = $expected[ $key ];
}
}

$filteredActual = [];
foreach ( $keysToBeConsidered as $key ) {
if ( isset( $actual[ $key ] ) ) {
$filteredActual[ $key ] = $actual[ $key ];
}
}

static::assertEquals( $filteredExpected, $filteredActual, $message );
}

/**
* Asserts that two arrays are equal while ignoring array elements for which the keys have been specified.
*
* {@internal As the array type declarations don't lead to type juggling, even without strict_types,
* it is safe to let PHP handle the parameter validation.}
*
* @param array<mixed> $expected Expected value.
* @param array<mixed> $actual The variable to test.
* @param array<int|string> $keysToBeIgnored The array keys to ignore.
* @param string $message Optional failure message to display.
*
* @return void
*/
final public static function assertArrayIsEqualToArrayIgnoringListOfKeys( array $expected, array $actual, array $keysToBeIgnored, string $message = '' ) {
foreach ( $keysToBeIgnored as $key ) {
unset( $expected[ $key ], $actual[ $key ] );
}

static::assertEquals( $expected, $actual, $message );
}

/**
* Asserts that two arrays are identical while only considering array elements for which the keys have been specified.
*
* {@internal As the array type declarations don't lead to type juggling, even without strict_types,
* it is safe to let PHP handle the parameter validation.}
*
* @param array<mixed> $expected Expected value.
* @param array<mixed> $actual The variable to test.
* @param array<int|string> $keysToBeConsidered The array keys to take into account.
* @param string $message Optional failure message to display.
*
* @return void
*/
final public static function assertArrayIsIdenticalToArrayOnlyConsideringListOfKeys( array $expected, array $actual, array $keysToBeConsidered, string $message = '' ) {
$keysToBeConsidered = \array_combine( $keysToBeConsidered, $keysToBeConsidered );
$expected = \array_intersect_key( $expected, $keysToBeConsidered );
$actual = \array_intersect_key( $actual, $keysToBeConsidered );

static::assertSame( $expected, $actual, $message );
}

/**
* Asserts that two arrays are identical while ignoring array elements for which the keys have been specified.
*
* {@internal As the array type declarations don't lead to type juggling, even without strict_types,
* it is safe to let PHP handle the parameter validation.}
*
* @param array<mixed> $expected Expected value.
* @param array<mixed> $actual The variable to test.
* @param array<int|string> $keysToBeIgnored The array keys to ignore.
* @param string $message Optional failure message to display.
*
* @return void
*/
final public static function assertArrayIsIdenticalToArrayIgnoringListOfKeys( array $expected, array $actual, array $keysToBeIgnored, string $message = '' ) {
foreach ( $keysToBeIgnored as $key ) {
unset( $expected[ $key ], $actual[ $key ] );
}

static::assertSame( $expected, $actual, $message );
}
}
8 changes: 8 additions & 0 deletions src/Polyfills/AssertArrayWithListKeys_Empty.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Yoast\PHPUnitPolyfills\Polyfills;

/**
* Empty trait for use with PHPUnit >= 11.0.0 in which the polyfill is not needed.
*/
trait AssertArrayWithListKeys {}
2 changes: 2 additions & 0 deletions src/TestCases/TestCasePHPUnitGte8.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Yoast\PHPUnitPolyfills\TestCases;

use PHPUnit\Framework\TestCase as PHPUnit_TestCase;
use Yoast\PHPUnitPolyfills\Polyfills\AssertArrayWithListKeys;
use Yoast\PHPUnitPolyfills\Polyfills\AssertClosedResource;
use Yoast\PHPUnitPolyfills\Polyfills\AssertFileEqualsSpecializations;
use Yoast\PHPUnitPolyfills\Polyfills\AssertIgnoringLineEndings;
Expand All @@ -24,6 +25,7 @@
*/
abstract class TestCase extends PHPUnit_TestCase {

use AssertArrayWithListKeys;
use AssertClosedResource;
use AssertFileEqualsSpecializations;
use AssertIgnoringLineEndings;
Expand Down
2 changes: 2 additions & 0 deletions src/TestCases/TestCasePHPUnitLte7.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Yoast\PHPUnitPolyfills\TestCases;

use PHPUnit\Framework\TestCase as PHPUnit_TestCase;
use Yoast\PHPUnitPolyfills\Polyfills\AssertArrayWithListKeys;
use Yoast\PHPUnitPolyfills\Polyfills\AssertClosedResource;
use Yoast\PHPUnitPolyfills\Polyfills\AssertEqualsSpecializations;
use Yoast\PHPUnitPolyfills\Polyfills\AssertFileEqualsSpecializations;
Expand All @@ -27,6 +28,7 @@
*/
abstract class TestCase extends PHPUnit_TestCase {

use AssertArrayWithListKeys;
use AssertClosedResource;
use AssertEqualsSpecializations;
use AssertFileEqualsSpecializations;
Expand Down
2 changes: 2 additions & 0 deletions src/TestCases/XTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PHPUnit\Framework\Attributes\Before;
use PHPUnit\Framework\Attributes\BeforeClass;
use PHPUnit\Framework\TestCase as PHPUnit_TestCase;
use Yoast\PHPUnitPolyfills\Polyfills\AssertArrayWithListKeys;
use Yoast\PHPUnitPolyfills\Polyfills\AssertClosedResource;
use Yoast\PHPUnitPolyfills\Polyfills\AssertEqualsSpecializations;
use Yoast\PHPUnitPolyfills\Polyfills\AssertFileEqualsSpecializations;
Expand All @@ -33,6 +34,7 @@
*/
abstract class XTestCase extends PHPUnit_TestCase {

use AssertArrayWithListKeys;
use AssertClosedResource;
use AssertEqualsSpecializations;
use AssertFileEqualsSpecializations;
Expand Down
Loading