Skip to content

Commit

Permalink
PHPUnit 10 | AssertIsList trait: polyfill the Assert::assertIsList() …
Browse files Browse the repository at this point in the history
…method

PHPUnit 10.0.0 introduces the new `Assert::assertIsList()` method.

This commit:
* Adds two traits with the same name.
    One to polyfill the methods when not available in PHPUnit.
    The other - an empty trait - to allow for `use`-ing the trait in PHPUnit versions in which the methods are already natively available.
* Logic to the custom autoloader which will load the correct trait depending on the PHPUnit version used.
* Functional tests for the functionality polyfilled.

Note: the methods use `static::` to call the PHPUnit native functionality. This allows for existing method overloads in a child class of the PHPUnit native `TestCase` to be respected.

Includes:
* Adding the new polyfill to the existing `TestCases` classes and adding a test for the polyfill availability to the `TestCaseTestTrait`.

Refs:
* sebastianbergmann/phpunit#4818
* sebastianbergmann/phpunit@71f5074
* sebastianbergmann/phpunit@e04a947
* sebastianbergmann/phpunit@2bc1aea

Co-authored-by: Jaroslav Hanslík <kukulich@kukulich.cz>
Co-authored-by: Sebastian Bergmann <sb@sebastian-bergmann.de>
  • Loading branch information
3 people committed Mar 30, 2023
1 parent f4b0421 commit 58c867f
Show file tree
Hide file tree
Showing 9 changed files with 368 additions and 0 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,17 @@ These methods were introduced in PHPUnit 10.0.0.
[`Assert::assertStringEqualsStringIgnoringLineEndings()`]: https://docs.phpunit.de/en/main/assertions.html#assertstringequalsstringignoringlineendings
[`Assert::assertStringContainsStringIgnoringLineEndings()`]: https://docs.phpunit.de/en/main/assertions.html#assertstringcontainsstringignoringlineendings

#### PHPUnit < 10.0.0: `Yoast\PHPUnitPolyfills\Polyfills\AssertIsList`

Polyfills the following method:
| |
|---------------------------------|
| [`Assert::assertIsList()`] |

This method was introduced in PHPUnit 10.0.0.

[`Assert::assertIsList()`]: https://docs.phpunit.de/en/main/assertions.html#assertislist


### Helper traits

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

case 'Yoast\PHPUnitPolyfills\Polyfills\AssertIsList':
self::loadAssertIsList();
return true;

case 'Yoast\PHPUnitPolyfills\Polyfills\AssertIgnoringLineEndings':
self::loadAssertIgnoringLineEndings();
return true;
Expand Down Expand Up @@ -293,6 +297,23 @@ public static function loadAssertObjectEquals() {
require_once __DIR__ . '/src/Polyfills/AssertObjectEquals_Empty.php';
}

/**
* Load the AssertIsList 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 loadAssertIsList() {
if ( \method_exists( Assert::class, 'assertIsList' ) === false ) {
// PHPUnit < 10.0.0.
require_once __DIR__ . '/src/Polyfills/AssertIsList.php';
return;
}

// PHPUnit >= 10.0.0.
require_once __DIR__ . '/src/Polyfills/AssertIsList_Empty.php';
}

/**
* Load the AssertIgnoringLineEndings polyfill or an empty trait with the same name
* if a PHPUnit version is used which already contains this functionality.
Expand Down
100 changes: 100 additions & 0 deletions src/Polyfills/AssertIsList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php

namespace Yoast\PHPUnitPolyfills\Polyfills;

use PHPUnit\Framework\Assert;

/**
* Polyfill the Assert::assertIsList() method.
*
* Introduced in PHPUnit 10.0.0.
*
* @link https://github.com/sebastianbergmann/phpunit/pull/4818
*/
trait AssertIsList {

/**
* Asserts that an array is list.
*
* @param mixed $array The value to test.
* @param string $message Optional failure message to display.
*
* @return void
*/
final public static function assertIsList( $array, $message = '' ) {
$msg = self::assertIsListFailureDescription( $array );
if ( $message !== '' ) {
$msg = $message . \PHP_EOL . $msg;
}

if ( \is_array( $array ) === false ) {
if ( \method_exists( Assert::class, 'assertIsArray' ) ) {
static::assertIsArray( $array, $msg );
return;
}

static::assertInternalType( 'array', $array, $msg );
return;
}

if ( $array === [] ) {
static::assertSame( $array, $array, $msg );
return;
}

if ( \function_exists( 'array_is_list' ) ) {
// phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.array_is_listFound -- PHP 8.1+.
static::assertTrue( \array_is_list( $array ), $msg );
return;
}

$expected = \range( 0, ( \count( $array ) - 1 ) );

static::assertSame( $expected, \array_keys( $array ), $msg );
}

/**
* Returns the description of the failure.
*
* @param mixed $other The value under test.
*
* @return string
*/
private static function assertIsListFailureDescription( $other ) {
$type = \strtolower( \gettype( $other ) );

switch ( $type ) {
case 'double':
$description = 'a float';
break;

case 'resource (closed)':
$description = 'a closed resource';
break;

case 'array':
case 'integer':
case 'object':
$description = 'an ' . $type;
break;

case 'boolean':
case 'closed resource':
case 'float':
case 'resource':
case 'string':
$description = 'a ' . $type;
break;

case 'null':
$description = 'null';
break;

default:
$description = 'a value of ' . $type;
break;
}

return \sprintf( 'Failed asserting that %s is a list.', $description );
}
}
8 changes: 8 additions & 0 deletions src/Polyfills/AssertIsList_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 >= 10.0.0 in which this polyfill is not needed.
*/
trait AssertIsList {}
2 changes: 2 additions & 0 deletions src/TestCases/TestCasePHPUnitGte8.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Yoast\PHPUnitPolyfills\Polyfills\AssertFileEqualsSpecializations;
use Yoast\PHPUnitPolyfills\Polyfills\AssertIgnoringLineEndings;
use Yoast\PHPUnitPolyfills\Polyfills\AssertionRenames;
use Yoast\PHPUnitPolyfills\Polyfills\AssertIsList;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals;
use Yoast\PHPUnitPolyfills\Polyfills\EqualToSpecializations;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches;
Expand All @@ -28,6 +29,7 @@ abstract class TestCase extends PHPUnit_TestCase {
use AssertFileEqualsSpecializations;
use AssertIgnoringLineEndings;
use AssertionRenames;
use AssertIsList;
use AssertObjectEquals;
use EqualToSpecializations;
use ExpectExceptionMessageMatches;
Expand Down
2 changes: 2 additions & 0 deletions src/TestCases/TestCasePHPUnitLte7.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Yoast\PHPUnitPolyfills\Polyfills\AssertFileEqualsSpecializations;
use Yoast\PHPUnitPolyfills\Polyfills\AssertIgnoringLineEndings;
use Yoast\PHPUnitPolyfills\Polyfills\AssertionRenames;
use Yoast\PHPUnitPolyfills\Polyfills\AssertIsList;
use Yoast\PHPUnitPolyfills\Polyfills\AssertIsType;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals;
use Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains;
Expand All @@ -33,6 +34,7 @@ abstract class TestCase extends PHPUnit_TestCase {
use AssertFileEqualsSpecializations;
use AssertIgnoringLineEndings;
use AssertionRenames;
use AssertIsList;
use AssertIsType;
use AssertObjectEquals;
use AssertStringContains;
Expand Down
2 changes: 2 additions & 0 deletions src/TestCases/XTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Yoast\PHPUnitPolyfills\Polyfills\AssertFileEqualsSpecializations;
use Yoast\PHPUnitPolyfills\Polyfills\AssertIgnoringLineEndings;
use Yoast\PHPUnitPolyfills\Polyfills\AssertionRenames;
use Yoast\PHPUnitPolyfills\Polyfills\AssertIsList;
use Yoast\PHPUnitPolyfills\Polyfills\AssertIsType;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals;
use Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains;
Expand All @@ -35,6 +36,7 @@ abstract class XTestCase extends PHPUnit_TestCase {
use AssertFileEqualsSpecializations;
use AssertIgnoringLineEndings;
use AssertionRenames;
use AssertIsList;
use AssertIsType;
use AssertObjectEquals;
use AssertStringContains;
Expand Down

0 comments on commit 58c867f

Please sign in to comment.