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

Merged
merged 1 commit into from
Aug 19, 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
5 changes: 5 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ jobs:
phpunit: '8.1.6'
coverage: true
experimental: false
- php: '7.4'
# Specifically set at 9.6.10 to test functioning on 9.x before the 9.6.11 assertObject*() backports came in.
phpunit: '9.6.10'
coverage: true
experimental: false
- php: '8.0'
phpunit: '8.5.16'
# PHPUnit 8.x does not support code coverage on PHP 8.x.
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,21 @@ The `assertObjectEquals()` assertion was introduced in PHPUnit 9.4.0.

[`Assert::assertObjectEquals()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertobjectequals

#### PHPUnit < 9.6.11: `Yoast\PHPUnitPolyfills\Polyfills\AssertObjectProperty`

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.

These methods were later backported to the PHPUnit 9 branch and included in the PHPUnit 9.6.11 release.

<!--
COMMENT: No documentation available (yet) for these assertions on the PHPUnit site.
-->


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

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

case 'Yoast\PHPUnitPolyfills\TestCases\TestCase':
self::loadTestCase();
return true;
Expand Down Expand Up @@ -421,6 +425,23 @@ public static function loadAssertObjectEquals() {
require_once __DIR__ . '/src/Polyfills/AssertObjectEquals_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( '\PHPUnit\Framework\Assert', 'assertObjectHasProperty' ) === false ) {
// PHPUnit < 9.6.11.
require_once __DIR__ . '/src/Polyfills/AssertObjectProperty.php';
return;
}

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

/**
* Load the appropriate TestCase class based on the PHPUnit version being used.
*
Expand Down
155 changes: 155 additions & 0 deletions src/Polyfills/AssertObjectProperty.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<?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 and PHPUnit 9.6.11.
*
* 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
* @link https://github.com/sebastianbergmann/phpunit/issues/5478
*
* @since 1.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 off 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( '\PHPUnit\Framework\Assert', 'assertObjectHasAttribute' )
&& \version_compare( Autoload::getPHPUnitVersion(), '9.6.0', '<=' )
) {
// PHPUnit <= 9.6.0.
static::assertObjectHasAttribute( $propertyName, $object, $message );
return;
}

/*
* PHPUnit 9.6.1+.
* 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 off 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( '\PHPUnit\Framework\Assert', 'assertObjectNotHasAttribute' )
&& \version_compare( Autoload::getPHPUnitVersion(), '9.6.0', '<=' )
) {
// PHPUnit <= 9.6.0.
static::assertObjectNotHasAttribute( $propertyName, $object, $message );
return;
}

/*
* PHPUnit 9.6.1+.
* 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 >= 9.6.11 in which this polyfill is not needed.
*
* @since 1.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 @@ -8,6 +8,7 @@
use Yoast\PHPUnitPolyfills\Polyfills\AssertFileEqualsSpecializations;
use Yoast\PHPUnitPolyfills\Polyfills\AssertionRenames;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectProperty;
use Yoast\PHPUnitPolyfills\Polyfills\EqualToSpecializations;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectPHPException;
Expand All @@ -28,6 +29,7 @@ abstract class TestCase extends PHPUnit_TestCase {
use AssertFileEqualsSpecializations;
use AssertionRenames;
use AssertObjectEquals;
use AssertObjectProperty;
use EqualToSpecializations;
use ExpectExceptionMessageMatches;
use ExpectPHPException;
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\AssertIsType;
use Yoast\PHPUnitPolyfills\Polyfills\AssertNumericType;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectProperty;
use Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains;
use Yoast\PHPUnitPolyfills\Polyfills\EqualToSpecializations;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectException;
Expand Down Expand Up @@ -39,6 +40,7 @@ abstract class TestCase extends PHPUnit_TestCase {
use AssertIsType;
use AssertNumericType;
use AssertObjectEquals;
use AssertObjectProperty;
use AssertStringContains;
use EqualToSpecializations;
use ExpectException;
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\AssertIsType;
use Yoast\PHPUnitPolyfills\Polyfills\AssertNumericType;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectProperty;
use Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains;
use Yoast\PHPUnitPolyfills\Polyfills\EqualToSpecializations;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectException;
Expand Down Expand Up @@ -41,6 +42,7 @@ abstract class XTestCase extends PHPUnit_TestCase {
use AssertIsType;
use AssertNumericType;
use AssertObjectEquals;
use AssertObjectProperty;
use AssertStringContains;
use EqualToSpecializations;
use ExpectException;
Expand Down
Loading
Loading