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 10.1 | AssertObjectProperty trait: polyfill the Assert::assertObject[Not]HasProperty() methods #116

Merged
merged 1 commit into from
Apr 16, 2023
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
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,18 @@ This method was introduced in PHPUnit 10.0.0.

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

#### PHPUnit < 10.1.0: `Yoast\PHPUnitPolyfills\Polyfills\AssertIsList`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong trait name

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ow! Thanks for catching that @garak !

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(and yes, I have fixed it locally and that commit will be included in the 2.0.0 release.)


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

These methods were introduced in PHPUnit 10.1.0 as alternatives to the `Assert::assertObjectHasAttribute()` and `Assert::assertObjectNotHasAttribute()` methods, which were hard deprecated (warning) in PHPUnit 9.6.1 and removed in PHPUnit 10.0.0.

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


### 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 @@ -99,6 +99,10 @@ public static function load( $className ) {
self::loadAssertIgnoringLineEndings();
return true;

case 'Yoast\PHPUnitPolyfills\Polyfills\AssertObjectProperty':
self::loadAssertObjectProperty();
return true;

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

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

// PHPUnit >= 10.1.0.
require_once __DIR__ . '/src/Polyfills/AssertObjectProperty_Empty.php';
}

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

namespace Yoast\PHPUnitPolyfills\Polyfills;

use PHPUnit\Framework\Assert;
use ReflectionObject;
use TypeError;
use Yoast\PHPUnitPolyfills\Autoload;

/**
* Polyfill the Assert::assertObjectHasProperty() and Assert::assertObjectNotHasProperty() methods,
* which replace the Assert::assertObjectHasAttribute() and Assert::assertObjectNotHasAttribute() methods.
*
* Introduced in PHPUnit 10.1.0.
*
* The Assert::assertObjectHasAttribute() and Assert::assertObjectNotHasAttribute() methods
* were deprecated in PHPUnit 9.6.1 and removed in PHPUnit 10.0.0.
*
* @link https://github.com/sebastianbergmann/phpunit/pull/5231
*
* @since 2.1.0
*/
trait AssertObjectProperty {

/**
* Asserts that an object has a specified property.
*
* @param string $propertyName The name of the property.
* @param object $object The object on which to check whether the property exists.
* @param string $message Optional failure message to display.
*
* @return void
*
* @throws TypeError When any of the passed arguments do not meet the required type.
*/
final public static function assertObjectHasProperty( $propertyName, $object, $message = '' ) {
/*
* Parameter input validation.
* In PHPUnit this is done via PHP native type declarations. Emulating this for the polyfill,
* including for those PHPUnit versions where we hand to a native PHPUnit alternative, as
* otherwise the method referenced in the error message would get very confusing and inconsistent.
*/
if ( \is_string( $propertyName ) === false ) {
throw new TypeError(
\sprintf(
'Argument 1 passed to assertObjectHasProperty() must be of type string, %s given',
\gettype( $propertyName )
)
);
}
if ( \is_object( $object ) === false ) {
throw new TypeError(
\sprintf(
'Argument 2 passed to assertObjectHasProperty() must be of type object, %s given',
\gettype( $object )
)
);
}

if ( \method_exists( Assert::class, 'assertObjectHasAttribute' )
&& \version_compare( Autoload::getPHPUnitVersion(), '9.6.0', '<=' )
) {
// PHPUnit <= 9.6.0.
static::assertObjectHasAttribute( $propertyName, $object, $message );
return;
}

/*
* PHPUnit 9.6.1+ and PHPUnit 10.0.x.
* Note: letting this polyfill code kick in for PHPUnit 9.6.1+ as well
* to prevent the PHPUnit deprecation notice showing.
*/
$msg = self::assertObjectHasPropertyFailureDescription( $object );
$msg .= \sprintf( ' has property "%s".', $propertyName );
if ( $message !== '' ) {
$msg = $message . \PHP_EOL . $msg;
}

$hasProperty = ( new ReflectionObject( $object ) )->hasProperty( $propertyName );
static::assertTrue( $hasProperty, $msg );
}

/**
* Asserts that an object does not have a specified property.
*
* @param string $propertyName The name of the property.
* @param object $object The object on which to check whether the property exists.
* @param string $message Optional failure message to display.
*
* @return void
*
* @throws TypeError When any of the passed arguments do not meet the required type.
*/
final public static function assertObjectNotHasProperty( $propertyName, $object, $message = '' ) {
/*
* Parameter input validation.
* In PHPUnit this is done via PHP native type declarations. Emulating this for the polyfill,
* including for those PHPUnit versions where we hand to a native PHPUnit alternative, as
* otherwise the method referenced in the error message would get very confusing and inconsistent.
*/
if ( \is_string( $propertyName ) === false ) {
throw new TypeError(
\sprintf(
'Argument 1 passed to assertObjectNotHasProperty() must be of type string, %s given',
\gettype( $propertyName )
)
);
}
if ( \is_object( $object ) === false ) {
throw new TypeError(
\sprintf(
'Argument 2 passed to assertObjectNotHasProperty() must be of type object, %s given',
\gettype( $object )
)
);
}

if ( \method_exists( Assert::class, 'assertObjectNotHasAttribute' )
&& \version_compare( Autoload::getPHPUnitVersion(), '9.6.0', '<=' )
) {
// PHPUnit <= 9.6.0.
static::assertObjectNotHasAttribute( $propertyName, $object, $message );
return;
}

/*
* PHPUnit 9.6.1+ and PHPUnit 10.0.x.
* Note: letting this polyfill code kick in for PHPUnit 9.6.1+ as well
* to prevent the PHPUnit deprecation notice showing.
*/
$msg = self::assertObjectHasPropertyFailureDescription( $object );
$msg .= \sprintf( ' does not have property "%s".', $propertyName );
if ( $message !== '' ) {
$msg = $message . \PHP_EOL . $msg;
}

$hasProperty = ( new ReflectionObject( $object ) )->hasProperty( $propertyName );
static::assertFalse( $hasProperty, $msg );
}

/**
* Returns the description of the failure.
*
* @param object $object The object under test.
*
* @return string
*/
private static function assertObjectHasPropertyFailureDescription( $object ) {
return \sprintf(
'Failed asserting that object of class "%s"',
\get_class( $object )
);
}
}
10 changes: 10 additions & 0 deletions src/Polyfills/AssertObjectProperty_Empty.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Yoast\PHPUnitPolyfills\Polyfills;

/**
* Empty trait for use with PHPUnit >= 10.1.0 in which this polyfill is not needed.
*
* @since 2.1.0
*/
trait AssertObjectProperty {}
2 changes: 2 additions & 0 deletions src/TestCases/TestCasePHPUnitGte8.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Yoast\PHPUnitPolyfills\Polyfills\AssertionRenames;
use Yoast\PHPUnitPolyfills\Polyfills\AssertIsList;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectProperty;
use Yoast\PHPUnitPolyfills\Polyfills\EqualToSpecializations;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches;

Expand All @@ -31,6 +32,7 @@ abstract class TestCase extends PHPUnit_TestCase {
use AssertionRenames;
use AssertIsList;
use AssertObjectEquals;
use AssertObjectProperty;
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 @@ -12,6 +12,7 @@
use Yoast\PHPUnitPolyfills\Polyfills\AssertIsList;
use Yoast\PHPUnitPolyfills\Polyfills\AssertIsType;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectProperty;
use Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains;
use Yoast\PHPUnitPolyfills\Polyfills\EqualToSpecializations;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches;
Expand All @@ -37,6 +38,7 @@ abstract class TestCase extends PHPUnit_TestCase {
use AssertIsList;
use AssertIsType;
use AssertObjectEquals;
use AssertObjectProperty;
use AssertStringContains;
use EqualToSpecializations;
use ExpectExceptionMessageMatches;
Expand Down
2 changes: 2 additions & 0 deletions src/TestCases/XTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Yoast\PHPUnitPolyfills\Polyfills\AssertIsList;
use Yoast\PHPUnitPolyfills\Polyfills\AssertIsType;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectProperty;
use Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains;
use Yoast\PHPUnitPolyfills\Polyfills\EqualToSpecializations;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches;
Expand Down Expand Up @@ -39,6 +40,7 @@ abstract class XTestCase extends PHPUnit_TestCase {
use AssertIsList;
use AssertIsType;
use AssertObjectEquals;
use AssertObjectProperty;
use AssertStringContains;
use EqualToSpecializations;
use ExpectExceptionMessageMatches;
Expand Down
Loading