Set of polyfills for changed PHPUnit functionality to allow for creating PHPUnit cross-version compatible tests

Overview

PHPUnit Polyfills

Version CS Build Status Lint Build Status Test Build Status Minimum PHP Version License: BSD3

Set of polyfills for changed PHPUnit functionality to allow for creating PHPUnit cross-version compatible tests.

Requirements

  • PHP 5.4 or higher.
  • PHPUnit 4.8 - 9.x (automatically required via Composer).

Installation

To install this package, run:

composer require --dev yoast/phpunit-polyfills

To update this package, run:

composer update --dev yoast/phpunit-polyfills --with-dependencies

Make sure to either use the Composer vendor/autoload.php file as your test bootstrap file; òr require the vendor/yoast/phpunit-polyfills/phpunitpolyfills-autoload.php file in your test bootstrap.

Why use the PHPUnit Polyfills?

This library is set up to allow for creating PHPUnit cross-version compatible tests by offering a number of polyfills for functionality which was introduced, split up or renamed in PHPUnit.

Write your tests for PHPUnit 9.x and run them on PHPUnit 4.8 - 9.x

The polyfills have been setup to allow tests to be forward-compatible. What that means is, that your tests can use the assertions supported by the latest PHPUnit version, even when running on older PHPUnit versions.

This puts the burden of upgrading to use the syntax of newer PHPUnit versions at the point when you want to start running your tests on a newer version. By doing so, dropping support for an older PHPUnit version becomes as straight-forward as removing it from the version constraint in your composer.json file.

Using this library

Each of the polyfills and helpers has been setup as a trait and can be imported and used in any test file which extends the PHPUnit native TestCase class.

If the polyfill is not needed for the particular PHPUnit version on which the tests are being run, the autoloader will automatically load an empty trait with that same name, so you can safely use these traits in tests which need to be PHPUnit cross-version compatible.

<?php

namespace Vendor\YourPackage\Tests;

use PHPUnit\Framework\TestCase;
use Yoast\PHPUnitPolyfills\Polyfills\AssertIsType;

class FooTest extends TestCase
{
    use AssertIsType;

    public function testSomething()
    {
        $this->assertIsBool( $maybeBool );
        self::assertIsNotIterable( $maybeIterable );
    }
}

Alternatively, you can use one of the TestCase classes provided by this library instead of using the PHPUnit native TestCase class.

In that case, all polyfills and helpers will be available whenever needed.

<?php

namespace Vendor\YourPackage\Tests;

use Yoast\PHPUnitPolyfills\TestCases\TestCase;

class FooTest extends TestCase
{
    public function testSomething()
    {
        $this->assertIsBool( $maybeBool );
        self::assertMatchesRegularExpression( $pattern, $string, $message );
    }
}

Supported ways of calling the assertions

By default, PHPUnit supports four ways of calling assertions:

  1. As a method in the TestCase class - $this->assertSomething().
  2. Statically as a method in the TestCase class - self/static/parent::assertSomething().
  3. Statically as a method of the Assert class - Assert::assertSomething().
  4. As a global function - assertSomething().

The polyfills in this library support the first two ways of calling the assertions as those are the most commonly used type of assertion calls.

For the polyfills to work, a test class is required to be a (grand-)child of the PHPUnit native TestCase class.

Use with PHPUnit < 5.7.0

If your library still needs to support PHP < 5.6 and therefore needs PHPUnit 4 for testing, there are a few caveats when using the traits stand-alone as we then enter "double-polyfill" territory.

To prevent "conflicting method names" errors when a trait is used multiple times in a class, the traits offered here do not attempt to solve this.

You will need to make sure to use any additional traits needed for the polyfills to work.

PHPUnit When use-ing this trait You also need to use this trait
4.8 < 5.2 ExpectExceptionObject ExpectException
4.8 < 5.2 ExpectPHPException ExpectException
4.8 < 5.2 ExpectExceptionMessageMatches ExpectException
4.8 < 5.6 AssertionRenames AssertFileDirectory

Note: this only applies to the stand-alone use of the traits. The TestCase classes provided by this library already take care of this automatically.

Code example testing for a PHP native warning in a test which needs to be able to run on PHPUnit 4.8:

<?php

namespace Vendor\YourPackage\Tests;

use PHPUnit\Framework\TestCase;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectException;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectPHPException;

class FooTest extends TestCase
{
    use ExpectException;
    use ExpectPHPException;

    public function testSomething()
    {
        $this->expectWarningMessage( 'A non-numeric value encountered' );
    }
}

Features

Polyfill traits

PHPUnit < 5.0.0: Yoast\PHPUnitPolyfills\Polyfills\AssertNumericType

Polyfills the following methods:

Assert::assertFinite() Assert::assertInfinite() Assert::assertNan()

These methods were introduced in PHPUnit 5.0.0.

PHPUnit < 5.2.0: Yoast\PHPUnitPolyfills\Polyfills\ExpectException

Polyfills the following methods:

TestCase::expectException() TestCase::expectExceptionMessage()
TestCase::expectExceptionCode() TestCase::expectExceptionMessageRegExp()

These methods were introduced in PHPUnit 5.2.0 as alternatives to the Testcase::setExpectedException() method which was deprecated in PHPUnit 5.2.0 and the Testcase::setExpectedExceptionRegExp() method which was deprecated in 5.6.0. Both these methods were removed in PHPUnit 6.0.0.

PHPUnit < 5.6.0: Yoast\PHPUnitPolyfills\Polyfills\AssertFileDirectory

Polyfills the following methods:

Assert::assertIsReadable() Assert::assertNotIsReadable()
Assert::assertIsWritable() Assert::assertNotIsWritable()
Assert::assertDirectoryExists() Assert::assertDirectoryNotExists()
Assert::assertDirectoryIsReadable() Assert::assertDirectoryNotIsReadable()
Assert::assertDirectoryIsWritable() Assert::assertDirectoryNotIsWritable()
Assert::assertFileIsReadable() Assert::assertFileNotIsReadable()
Assert::assertFileIsWritable() Assert::assertFileNotIsWritable()

These methods were introduced in PHPUnit 5.6.0.

PHPUnit < 6.4.0: Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionObject

Polyfills the TestCase::expectExceptionObject() method to test all aspects of an Exception by passing an object to the method.

This method was introduced in PHPUnit 6.4.0.

PHPUnit < 7.5.0: Yoast\PHPUnitPolyfills\Polyfills\AssertIsType

Polyfills the following methods:

Assert::assertIsArray() Assert::assertIsBool() Assert::assertIsFloat()
Assert::assertIsInt() Assert::assertIsNumeric() Assert::assertIsObject()
Assert::assertIsResource() Assert::assertIsString() Assert::assertIsScalar()
Assert::assertIsCallable() Assert::assertIsIterable()
Assert::assertIsNotArray() Assert::assertIsNotBool() Assert::assertIsNotFloat()
Assert::assertIsNotInt() Assert::assertIsNotNumeric() Assert::assertIsNotObject()
Assert::assertIsNotResource() Assert::assertIsNotString() Assert::assertIsNotScalar()
Assert::assertIsNotCallable() Assert::assertIsNotIterable()

These methods were introduced in PHPUnit 7.5.0 as alternatives to the Assert::assertInternalType() and Assert::assertNotInternalType() methods, which were soft deprecated in PHPUnit 7.5.0, hard deprecated (warning) in PHPUnit 8.0.0 and removed in PHPUnit 9.0.0.

PHPUnit < 7.5.0: Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains

Polyfills the following methods:

Assert::assertStringContainsString() Assert::assertStringNotContainsString()
Assert::assertStringContainsStringIgnoringCase() Assert::assertStringNotContainsStringIgnoringCase()

These methods were introduced in PHPUnit 7.5.0 as alternatives to using Assert::assertContains() and Assert::assertNotContains() with string haystacks. Passing string haystacks to these methods was soft deprecated in PHPUnit 7.5.0, hard deprecated (warning) in PHPUnit 8.0.0 and removed in PHPUnit 9.0.0.

PHPUnit < 7.5.0: Yoast\PHPUnitPolyfills\Polyfills\AssertEqualsSpecializations

Polyfills the following methods:

Assert::assertEqualsCanonicalizing() Assert::assertNotEqualsCanonicalizing()
Assert::assertEqualsIgnoringCase() Assert::assertNotEqualsIgnoringCase()
Assert::assertEqualsWithDelta() Assert::assertNotEqualsWithDelta()

These methods were introduced in PHPUnit 7.5.0 as alternatives to using Assert::assertEquals() and Assert::assertNotEquals() with these optional parameters. Passing the respective optional parameters to these methods was soft deprecated in PHPUnit 7.5.0, hard deprecated (warning) in PHPUnit 8.0.0 and removed in PHPUnit 9.0.0.

PHPUnit < 8.4.0: Yoast\PHPUnitPolyfills\Polyfills\ExpectPHPException

Polyfills the following methods:

TestCase::expectError() expectErrorMessage() expectErrorMessageMatches()
TestCase::expectWarning() expectWarningMessage() expectWarningMessageMatches()
TestCase::expectNotice() expectNoticeMessage() expectNoticeMessageMatches()
TestCase::expectDeprecation() expectDeprecationMessage() expectDeprecationMessageMatches()

These method were introduced in PHPUnit 8.4.0 as alternatives to using TestCase::expectException() et al for expecting PHP native errors, warnings and notices. Using TestCase::expectException*() for testing PHP native notices was soft deprecated in PHPUnit 8.4.0, hard deprecated (warning) in PHPUnit 9.0.0 and (will be) removed in PHPUnit 10.0.0.

PHPUnit < 8.4.0: Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches

Polyfills the TestCase::expectExceptionMessageMatches() method.

This method was introduced in PHPUnit 8.4.0 to improve the name of the TestCase::expectExceptionMessageRegExp() method. The TestCase::expectExceptionMessageRegExp() method was soft deprecated in PHPUnit 8.4.0, hard deprecated (warning) in PHPUnit 8.5.3 and removed in PHPUnit 9.0.0.

PHPUnit < 8.5.0: Yoast\PHPUnitPolyfills\Polyfills\AssertFileEqualsSpecializations

Polyfills the following methods:

Assert::assertFileEqualsCanonicalizing() Assert::assertFileNotEqualsCanonicalizing()
Assert::assertFileEqualsIgnoringCase() Assert::assertFileNotEqualsIgnoringCase()
Assert::assertStringEqualsFileCanonicalizing() Assert::assertStringNotEqualsFileCanonicalizing()
Assert::assertStringEqualsFileIgnoringCase() Assert::assertStringNotEqualsFileIgnoringCase()

These methods were introduced in PHPUnit 8.5.0 as alternatives to using Assert::assertFileEquals() and Assert::assertFileNotEquals() with these optional parameters. Passing the respective optional parameters to these methods was hard deprecated in PHPUnit 8.5.0 and removed in PHPUnit 9.0.0.

PHPUnit < 9.0.0: Yoast\PHPUnitPolyfills\Polyfills\EqualToSpecializations

Polyfills the following methods:

Assert::equalToCanonicalizing() Assert::equalToIgnoringCase()
Assert::equalToWithDelta()

These methods, which are typically used to verify parameters passed to Mock Objects, were introduced in PHPUnit 9.0.0 as alternatives to using Assert::EqualTo() with these optional parameters. Support for passing the respective optional parameters to Assert::EqualTo() was removed in PHPUnit 9.0.0.

PHPUnit < 9.1.0: Yoast\PHPUnitPolyfills\Polyfills\AssertionRenames

Polyfills the following renamed methods:

These methods were introduced in PHPUnit 9.1.0. The original methods these new methods replace were hard deprecated in PHPUnit 9.1.0 and (will be) removed in PHPUnit 10.0.0.

PHPUnit < 9.3.0: Yoast\PHPUnitPolyfills\Polyfills\AssertClosedResource

Polyfills the following methods:

Assert::assertIsClosedResource() Assert::assertIsNotClosedResource()

These methods were introduced in PHPUnit 9.3.0.

Additionally, this trait contains a helper method shouldClosedResourceAssertionBeSkipped().

Due to some bugs in PHP itself, the "is closed resource" determination cannot always be done reliably, most notably for the libxml extension.

This helper function can determine whether or not the current "value under test" in combination with the PHP version on which the test is being run is affected by these bugs.

⚠️ The PHPUnit native implementation of these assertions is also affected by these bugs! The shouldClosedResourceAssertionBeSkipped() helper method is therefore available cross-version.

Usage examples:

// Example: skipping the test completely.
if ( $this->shouldClosedResourceAssertionBeSkipped( $actual ) === true ) {
    $this->markTestSkipped('assertIs[Not]ClosedResource() cannot determine whether this resource is'
        . ' open or closed due to bugs in PHP (PHP ' . \PHP_VERSION . ').');
}

// Example: selectively skipping the assertion.
if ( self::shouldClosedResourceAssertionBeSkipped( $actual ) === false ) {
    $this->assertIsClosedResource( $actual );
}

👉 While this polyfill is tested extensively, testing for these kind of bugs exhaustively is hard. Please report any bugs found and include a clear code sample to reproduce the issue.

PHPUnit < 9.4.0: Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals

Polyfills the Assert::assertObjectEquals() method to verify two (value) objects are considered equal. This assertion expects an object to contain a comparator method in the object itself. This comparator method is subsequently called to verify the "equalness" of the objects.

The assertObjectEquals() assertion was introduced in PHPUnit 9.4.0.

ℹ️ Due to limitations in how this assertion is implemented in PHPUnit itself, it is currently not possible to create a single comparator method which will be compatible with both PHP < 7.0 and PHP 7.0 or higher.

In effect two declarations of the same object would be needed to be compatible with PHP < 7.0 and PHP 7.0 and higher and still allow for testing the object using the assertObjectEquals() assertion.

Due to this limitation, it is recommended to only use this assertion if the minimum supported PHP version of a project is PHP 7.0 or higher; or if the project does not run its tests on PHPUnit >= 9.4.0.

The implementation of this assertion in the Polyfills is PHP cross-version compatible.

Helper traits

Yoast\PHPUnitPolyfills\Helpers\AssertAttributeHelper

Helper to work around the removal of the assertAttribute*() methods.

The assertAttribute*() methods were deprecated in PHPUnit 8.0.0 and removed in PHPUnit 9.0.0.

Public properties can still be tested by accessing them directly:

$this->assertSame( 'value', $obj->propertyName );

Protected and private properties can no longer be tested using PHPUnit native functionality. The reasoning for the removal of these assertion methods is that private and protected properties are an implementation detail and should not be tested directly, but via methods in the class.

It is strongly recommended to refactor your tests, and if needs be, your classes to adhere to this.

However, if for some reason the value of protected or private properties still needs to be tested, this helper can be used to get access to their value and attributes.

The trait contains two helper methods:

  • public static getProperty( object $classInstance, string $propertyName ) : ReflectionProperty
  • public static getPropertyValue( object $classInstance, string $propertyName ) : mixed
// Test the value of a protected or private property.
$this->assertSame( 'value', $this->getPropertyValue( $objInstance, $propertyName ) );

// Retrieve a ReflectionProperty object to test other details of the property.
self::assertSame( $propertyName, self::getProperty( $objInstance, $propertyName )->getName() );

TestCases

PHPUnit 8.0.0 introduced a void return type declaration to the "fixture" methods - setUpBeforeClass(), setUp(), tearDown() and tearDownAfterClass(). As the void return type was not introduced until PHP 7.1, this makes it more difficult to create cross-version compatible tests when using fixtures, due to signature mismatches.

This library contains two basic TestCase options to overcome this issue.

Option 1: Yoast\PHPUnitPolyfills\TestCases\TestCase

This TestCase overcomes the signature mismatch by having two versions. The correct one will be loaded depending on the PHPUnit version being used.

When using this TestCase, if an individual test, or another TestCase which extends this TestCase, needs to overload any of the "fixture" methods, it should do so by using a snake_case variant of the original fixture method name, i.e. set_up_before_class(), set_up(), assert_pre_conditions(), assert_post_conditions(), tear_down() and tear_down_after_class().

The snake_case methods will automatically be called by PHPUnit.

IMPORTANT: The snake_case methods should not call the PHPUnit parent, i.e. do not use parent::setUp() from within an overloaded set_up() method. If necessary, DO call parent::set_up().

use Yoast\PHPUnitPolyfills\TestCases\TestCase;

class MyTest extends TestCase {
    public static function set_up_before_class() {
        parent::set_up_before_class();

        // Set up a database connection or other fixture which needs to be available.
    }

    protected function set_up() {
        parent::set_up();

        // Set up function mocks which need to be available for all tests in this class.
    }

    protected function assert_pre_conditions() {
        parent::assert_pre_conditions();

        // Perform assertions shared by all tests of a test case (before the test).
    }

    protected function assert_post_conditions() {
        // Performs assertions shared by all tests of a test case (after the test).

        parent::assert_post_conditions();
    }

    protected function tear_down() {
        // Any clean up needed related to `set_up()`.

        parent::tear_down();
    }

    public static function tear_down_after_class() {
        // Close database connection and other clean up related to `set_up_before_class()`.

        parent::tear_down_after_class();
    }
}

Option 2: Yoast\PHPUnitPolyfills\TestCases\XTestCase

This TestCase overcomes the signature mismatch by using the PHPUnit @before[Class] and @after[Class] annotations in combination with different methods names, i.e. setUpFixturesBeforeClass(), setUpFixtures(), tearDownFixtures() and tearDownFixturesAfterClass().

When using this TestCase, overloaded fixture methods need to use the @beforeClass, @before, @after and @afterClass annotations. The naming of the overloaded methods is open as long as the method names don't conflict with the PHPUnit native method names.

use Yoast\PHPUnitPolyfills\TestCases\XTestCase;

class MyTest extends XTestCase {
    /**
     * @beforeClass
     */
    public static function setUpFixturesBeforeClass() {
        parent::setUpFixturesBeforeClass();

        // Set up a database connection or other fixture which needs to be available.
    }

    /**
     * @before
     */
    protected function setUpFixtures() {
        parent::setUpFixtures();

        // Set up function mocks which need to be available for all tests in this class.
    }

    /**
     * @after
     */
    protected function tearDownFixtures() {
        // Any clean up needed related to `setUpFixtures()`.

        parent::tearDownFixtures();
    }

    /**
     * @afterClass
     */
    public static function tearDownFixturesAfterClass() {
        // Close database connection and other clean up related to `setUpFixturesBeforeClass()`.

        parent::tearDownFixturesAfterClass();
    }
}

TestListener

The method signatures in the PHPUnit TestListener interface have changed a number of times across versions. Additionally, the use of the TestListener principle has been deprecated in PHPUnit 7 in favour of using the TestRunner hook interfaces.

Note: while deprecated in PHPUnit 7, the TestListener interface has not yet been removed and is still supported in PHPUnit 9.x.

If your test suite does not need to support PHPUnit < 7, it is strongly recommended to use the TestRunner hook interfaces extensions instead.

However, for test suites that still need to support PHPUnit 6 or lower, implementing the TestListener interface is the only viable option.

Yoast\PHPUnitPolyfills\TestListeners\TestListenerDefaultImplementation

This TestListenerDefaultImplementation trait overcomes the signature mismatches by having multiple versions and loading the correct one depending on the PHPUnit version being used.

Similar to the TestCase implementation, snake_case methods without type declarations are used to get round the signature mismatches. The snake_case methods will automatically be called.

PHPUnit native method name Replacement Notes
addError() add_error($test, $e, $time)
addWarning() add_warning($test, $e, $time) Introduced in PHPUnit 6.
addFailure() add_failure($test, $e, $time)
addIncompleteTest() add_incomplete_test($test, $e, $time)
addRiskyTest() add_risky_test($test, $e, $time) Support appears to be flaky on PHPUnit 5.
addSkippedTest() add_skipped_test($test, $e, $time)
startTestSuite() start_test_suite($suite)
endTestSuite() end_test_suite($suite)
startTest() start_test($test)
endTest() end_test($test, $time)

Implementations of the TestListener interface may be using any of the following patterns:

// PHPUnit < 6.
class MyTestListener extends \PHPUnit_Framework_BaseTestListener {}

// PHPUnit 6.
class MyTestListener extends \PHPUnit\Framework\BaseTestListener {}

// PHPUnit 7+.
class MyTestListener implements \PHPUnit\Framework\TestListener {
    use \PHPUnit\Framework\TestListenerDefaultImplementation;
}

Replace these with:

use PHPUnit\Framework\TestListener;
use Yoast\PHPUnitPolyfills\TestListeners\TestListenerDefaultImplementation;

class MyTestListener implements TestListener {
    use TestListenerDefaultImplementation;

    // Implement any of the snakecase methods, for example:
    public function add_error( $test, $e, $time ) {
        // Do something when PHPUnit encounters an error.
    }
}

Frequently Asked Questions

Q: Will this package polyfill functionality which was removed from PHPUnit ?

As a rule of thumb, removed functionality will not be polyfilled in this package.

For frequently used, removed PHPUnit functionality, "helpers" may be provided. These helpers are only intended as an interim solution to allow users of this package more time to refactor their tests away from the removed functionality.

Removed functionality without PHPUnit native replacement

PHPUnit Removed Issue Remarks
9.0.0 assertArraySubset() #1 The dms/phpunit-arraysubset-asserts package polyfills this functionality.
As of version 0.3.0 this package can be installed in combination with PHP 5.4 - current and PHPUnit 4.8.36/5.7.21 - current.
Alternatively, tests can be refactored using the patterns outlined in issue #1.
9.0.0 assertAttribute*() #2 Refactor the tests to not directly test private/protected properties.
As an interim solution, the Yoast\PHPUnitPolyfills\Helpers\AssertAttributeHelper trait is available.

Q: Can this library be used when the tests are being run via a PHPUnit Phar file ?

Yes, this package can also be used when running tests via a PHPUnit Phar file.

In that case, make sure that the phpunitpolyfills-autoload.php file is explicitly required in the test bootstrap file. (Not necessary when the Composer vendor/autoload.php file is used as, or required in, the test bootstrap.)

Q: How do I run my tests when the library is installed via the GitHub Actions setup-php action ?

As of shivammathur/setup-php version 2.15.0, the PHPUnit Polyfills are available as one of the tools which can be installed directly by the Setup-PHP GitHub action.

- name: Setup PHP with tools
  uses: shivammathur/setup-php@v2
  with:
    php-version: '8.0'
    tools: phpunit-polyfills

The above step will install both the PHPUnit Polyfills, as well as PHPUnit, as Composer global packages.

After this step has run, you can run PHPUnit, like you would normally, by using phpunit.

- name: Run tests
  run: phpunit

👉 If you rely on Composer for autoloading your project files, you will still need to run composer dump-autoload --dev and include the project local vendor/autoload.php file as/in your test bootstrap.

🎓 Why this works:

Composer will place all files in the global Composer bin directory in the system path and the Composer installed PHPUnit version will load the Composer global autoload.php file, which will automatically also load the PHPUnit Polyfills.

Now you may wonder, "what about if I explicitly request both phpunit as well as phpunit-polyfills in tools?"

In that case, when you run phpunit, the PHPUnit PHAR will not know how to locate the PHPUnit Polyfills, so you will need to do some wizardry in your test bootstrap to get things working.

Q: How can I verify the version used of the PHPUnit Polyfills library ?

For complex test setups, like when the Polyfills are provided via a test suite dependency, or may already be loaded via an overarching project, it can be useful to be able to check that a version of the package is used which complies with the requirements for your test suite.

As of version 1.0.1, the PHPUnit Polyfills Autoload class contains a version number which can be used for this purpose.

Typically such a check would be done in the test suite bootstrap file and could look something like this:

if ( class_exists( '\Yoast\PHPUnitPolyfills\Autoload' ) === false ) {
    require_once 'vendor/yoast/phpunit-polyfills/phpunitpolyfills-autoload.php';
}

$versionRequirement = '1.0.1';
if ( defined( '\Yoast\PHPUnitPolyfills\Autoload::VERSION' ) === false
    || version_compare( \Yoast\PHPUnitPolyfills\Autoload::VERSION, $versionRequirement, '<' )
) {
    echo 'Error: Version mismatch detected for the PHPUnit Polyfills. Please ensure that PHPUnit Polyfills ',
        $versionRequirement, ' or higher is loaded.', PHP_EOL;
    exit(1);
} else {
    echo 'Error: Please run `composer update -W` before running the tests.' . PHP_EOL;
    echo 'You can still use a PHPUnit phar to run them, but the dependencies do need to be installed.', PHP_EOL;
    exit(1);
}

Contributing

Contributions to this project are welcome. Clone the repo, branch off from develop, make your changes, commit them and send in a pull request.

If you are unsure whether the changes you are proposing would be welcome, please open an issue first to discuss your proposal.

License

This code is released under the BSD-3-Clause License.

Comments
  • The `PHPUnit\Framework\TestCase::prophesize` method not polyfilled

    The `PHPUnit\Framework\TestCase::prophesize` method not polyfilled

    Since PHP 7.3 I'm seeing this warning:

    PHPUnit\Framework\TestCase::prophesize() is deprecated and will be removed in PHPUnit 10. Please use the trait provided by phpspec/prophecy-phpunit.
    

    I can't just require phpspec/prophecy-phpunit in the composer.json and use the trait it provides, because package itself won't even connect in PHP 7.2 and smaller versions.

    Status: wontfix 
    opened by aik099 16
  • Q: handling of 'void' return type on TestCase::fail and TestCase::run

    Q: handling of 'void' return type on TestCase::fail and TestCase::run

    In some of my own tests, which have been executed so far on php 5.5-7.4 (via phunit 4 and 5), I have reimplemented the fail and run methods in my TestCase subclass. I am now trying to make those same tests run as well on php 8.0, via phpunit 8 and this package. However, when trying to run the tests, I hit the same snag as with the setUp method, namely that the return type of my methods is not compatible with the one from the grand-parent class. Any suggestion on how to fix this? The easiest one seems to be to implement in PHPUnitPolyfills\TestCases\TestCase methods named f.e. _run and _fail, which work the same way as _setup, but it might be considered hackish...

    Type: question 
    opened by gggeek 8
  • Polyfill for equalTo constraint specializations

    Polyfill for equalTo constraint specializations

    This PR adds the EqualToSpecializations Trait that adds polyfills for the in PHPUnit 9.0.0 introduced methods equalToCanonicalizing, equalToIgnoringCase and equalToWithDelta.

    Since PHPUnit Version 9.0.0 equalTo constraints got their own specializations to replicate the assertEquals specializations. (see https://github.com/sebastianbergmann/phpunit/commit/43c01a4e0c74a4bf019a8d879bced5146af2fbb6) The usage of equalTo with these parameters never got deprecated and also had no replacement until the functionality was removed (see https://github.com/sebastianbergmann/phpunit/commit/e470a3ae6ce94b4db681f579a1012c44f473e6ae). This means that test cases that want to use equalTo with additional configuration cannot be written to work with both PHPUnit 8 (or older) and PHPUnit 9 without the use of a polyfill.

    Type: enhancement community-patch Feature: polyfills 
    opened by mergeMarc 7
  • Handle strings containing empty strings assertions

    Handle strings containing empty strings assertions

    PHPUnit 6.4.2 added a fix to gracefully handle the case when an empty string was passed to assertStringContainsString() and variant assertions. Versions earlier than that gave a "mb_strpos(): Empty delimiter" error instead.

    This change adds a fix to also handle that case, when using PHPUnit-Polyfills with versions of PHPUnit earlier than 6.4.2, and passing an empty needle string.

    The use of asserting true is true stops the test from being marked as risky, which is what would happen if we just return true;. This is hacky, and there may be a better way for this.

    Fixes #17.

    Type: enhancement community-patch Feature: polyfills 
    opened by GaryJones 7
  • ReflectionType::__toString() is deprecated

    ReflectionType::__toString() is deprecated

    Running PHPUnit 6.5.14 in PHP 7.4, generate the following error when using createMock

    Function ReflectionType::__toString() is deprecated
    

    I wonder if this library could patch this issue.

    PHPUnit issue https://github.com/sebastianbergmann/phpunit/issues/3728

    Status: wontfix 
    opened by spacedmonkey 6
  • [FR] Handle removed assertAttribute*() assertions

    [FR] Handle removed assertAttribute*() assertions

    A whole slew of `assertAttribute*() assertions were deprecated in PHPUnit 8.0.0 and removed in PHPUnit 9.0.0 without replacement.

    The reasoning behind the removal was that it was too easy to test private/protected properties which should be considered implementation details and that those should not be tested directly.

    Polyfilling this would require copying most of the removed code from PHPUnit, which I'm hesistant to do.

    Refs:

    • https://github.com/sebastianbergmann/phpunit/issues/3338
    • https://github.com/sebastianbergmann/phpunit/issues/3339
    Type: enhancement 
    opened by jrfnl 6
  • [FR] Handle removed assertEqualXMLStructure() assertion

    [FR] Handle removed assertEqualXMLStructure() assertion

    The Assert::assertEqualXMLStructure() assertion was deprecated in PHPUnit 9.1.0 and will be removed in PHPUnit 10.0.0 without replacement.

    Polyfilling this would require copying most of the code which will be removed from PHPUnit, which I'm hesistant to do.

    Refs:

    • https://github.com/sebastianbergmann/phpunit/issues/4091
    • https://github.com/sebastianbergmann/phpunit/issues/4092
    Status: wontfix 
    opened by jrfnl 5
  • mb_strpos(): Empty delimiter

    mb_strpos(): Empty delimiter

    This assertion:

    self::assertStringContainsString( $options['apikey'], $registry['parsely-analytics-for-wordpress']['payload'] );
    

    found in the test files of this PR (work in progress, so may change), gave a failure in a GitHub Action when run under PHP 5.6.40 and PHPUnit 5.7.27, with an error message of mb_strpos(): Empty delimiter.

    It points to this part of this repo, which then appears to rely on PHPUnit itself (assertContains()).

    The next PHP up in my workflow is PHP 7.0.33, and that uses PHPUnit 6.5.14, and that works fine.

    This issue in PHPUnit seems highly relevant, so I think I'm looking for a back-compat fix for assertContains() for PHPUnit 5.7.

    Could this be added in please @jrfnl?

    Type: enhancement 
    opened by GaryJones 4
  • Running the Tests in CI

    Running the Tests in CI

    First of all, this package is what i was looking for since months. I don't understand why the defacto standard testing library phpunit does not support a wide range of php versions, this just makes no sense to me. (The composer packages and libraries itself should make the php version restriction, not the test system). Anyhow!

    When running vendor/bin/phpunit --verbose --configuration actions.phpunit.xml in "not supported" php versions the output is This version of PHPUnit is supported on PHP 7.3 and PHP 7.4. (see https://github.com/luyadev/luya-testsuite/pull/39/checks?check_run_id=1485397698)

    Do we have to change anything regarding how to run the test suite?

    Thanks for your work!

    Type: question 
    opened by nadar 4
  • PHPUnit 10 support?

    PHPUnit 10 support?

    Will this package have PHPUnit 10 support?

    Seeing how PHPUnit 10 will only work with PHP 8.1 and above, not sure if that would clash with this package. And v10 is a pretty big rewrite from what I gathered.

    I tried to test one lib that I'm contributing to on PHP 8.2 and got into dependency issues, where some packages required certain versions of PHPUnit, and I noticed that polyfills support PHPUnit up to v9.

    Type: question 
    opened by dingo-d 2
  • Release version 1.0.4

    Release version 1.0.4

    Functional:

    • [x] Confirm that the most recent PHPUnit changelogs have been checked and that the library is still feature complete for those versions supported within the PHPUnit version constraints.
    • [x] Update the VERSION constant in the phpunitpolyfills-autoload.php file. - PR #85
    • [x] Composer: check if any dependencies/version constraints need updating.

    Release:

    • [x] Add changelog for the release - PR #85 Verify that a release link at the bottom of the CHANGELOG.md file has been added.
    • [x] Merge this PR.
    • [x] Make sure all CI builds are green.
    • [x] Tag the release (careful, GH defaults to develop!).
    • [x] Create a release from the tag (careful, GH defaults to develop!) & copy & paste the changelog to it. Make sure to copy the links to the issues and the links to the GH usernames from the bottom of the changelog!
    • [x] Close the milestone.
    • [x] Open a new milestone for the next release.
    • [x] If any open PRs/issues which were milestoned for the release did not make it into the release, update their milestone.

    Announce:

    • [x] Tweet about the release.
    opened by jrfnl 1
  • PHPUnit\Framework\MockObject\MockBuilder::onlyMethods is not polyfilled

    PHPUnit\Framework\MockObject\MockBuilder::onlyMethods is not polyfilled

    As per https://github.com/sebastianbergmann/phpunit/pull/3687, the PHPUnit\Framework\MockObject\MockBuilder::setMethods() method was deprecated (soft in PHPUnit 8, hard in PHPUnit 9) and scheduled for removal in PHPUnit 10. It was being replaced by onlyMethods() and addMethods().

    In my WordPress plugin codebase, I'm using PHPUnit from 7-9, but whereas various assertions from PHPUnit 9 are polyfilled, the onlyMethods method is not (I'm not using addMethods()).

    See https://github.com/Parsely/wp-parsely/runs/3754851373?check_suite_focus=true for a CI run that failed on PHP 7.1 when the test code used onlyMethods(). PHP 7.2 (PHPUnit 8) and above passed fine.

    Can these new methods please be polyfilled for earlier versions of PHPUnit?

    Type: enhancement 
    opened by GaryJones 1
Releases(1.0.4)
  • 1.0.4(Nov 16, 2022)

    This is a maintenance release.

    Changed

    • The Yoast\PHPUnitPolyfills\Autoload class is now final. PR #77.
    • README: clear up minor language confusion. Props @PhilETaylor and @fredericgboutin-yapla for pointing it out.
    • README: fix links which were broken due to an upstream branch rename. PR #80.
    • Verified PHP 8.2 compatibility.
    • General housekeeping.
    Source code(tar.gz)
    Source code(zip)
  • 1.0.3(Nov 23, 2021)

    Changed

    • General housekeeping.

    Fixed

    • The failure message thrown for the assertIsClosedResource() and assertIsNotClosedResource() assertions will now be more informative, most notably, when the value under test is a closed resource. PR #65, props Alain Schlesser for reporting.
    Source code(tar.gz)
    Source code(zip)
  • 1.0.2(Oct 3, 2021)

    As of version 2.15.0 of the shivammathur/setup-php action for GitHub Actions, the PHPUnit Polyfills can be installed directly from this action using the tools key.

    Added

    • README: FAQ section about installing and using the library via the shivammathur/setup-php action. PR #52

    Changed

    • README: minor textual clarifications and improvements. PRs #52, #54, props Pierre Gordon.
    • General housekeeping.

    Fixed

    • Autoloader: improved compatibility with packages which create a class_alias for the PHPUnit_Runner_Version or PHPUnit\Runner\Version class. PR #59
    Source code(tar.gz)
    Source code(zip)
  • 1.0.1(Aug 9, 2021)

    Added

    • The Yoast\PHPUnitPolyfills\Autoload class now contains a VERSION constant. Issue #46, PR #47, props Pascal Birchler for the suggestion. This version constant can be used by (complex) test setups to verify that the PHPUnit Polyfills which will be loaded, comply with the version requirements for the test suite.

    Changed

    • Minor documentation updates. #43
    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(Jun 21, 2021)

    Added

    • Yoast\PHPUnitPolyfills\Polyfills\AssertClosedResource trait to polyfill the Assert::assertIsClosedResource() and Assert::assertIsNotClosedResource() methods as introduced in PHPUnit 9.3.0. PR #27.
    • Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals trait to polyfill the Assert::assertObjectEquals() method as introduced in PHPUnit 9.4.0. PR #38. The behaviour of the polyfill closely matches the PHPUnit native implementation, but is not 100% the same. Most notably, the polyfill will check the type of the returned value from the comparator method instead of enforcing a return type declaration for the comparator method.
    • Yoast\PHPUnitPolyfills\Polyfills\EqualToSpecializations trait to polyfill the Assert::equalToCanonicalizing(), Assert::equalToIgnoringCase() and Assert::equalToWithDelta() methods as introduced in PHPUnit 9.0.0. PR #28, props Marc Siegrist.
    • Polyfills for the PHP native Error and TypeError classes as introduced in PHP 7.0. PR #36.
    • README: FAQ section covering functionality removed from PHPUnit and usage with a Phar.

    Changed

    • The minimum supported PHP version has been lowered to PHP 5.4 (was 5.5). PR #19.
    • XTestCase: the visibility of the setUpFixtures() and the tearDownFixtures() methods has been changed to protected (was public). Issue #10, PR #20, props Mark Baker for reporting.
    • README: re-ordered the sections and various other improvements.
    • Initial preparation for PHPUnit 10.0 compatibility.
    • General housekeeping.

    Fixed

    • Issue #17 via PR #18 - AssertStringContainString: PHPUnit < 6.4.2 would throw a "mb_strpos(): empty delimiter" PHP warning when the $needle passed was an empty string. Props Gary Jones.
    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Nov 25, 2020)

    Added

    • Yoast\PHPUnitPolyfills\TestListeners\TestListenerDefaultImplementation: a cross-version compatible base implementation for TestListeners using snake_case method names to replace the PHPUnit native method names.
    • Yoast\PHPUnitPolyfills\Helpers\AssertAttributeHelper trait containing a getProperty() and a getPropertyValue() method. This is a stop-gap solution for the removal of the PHPUnit assertAttribute*() methods in PHPUnit 9. It is strongly recommended to refactor your tests/classes in a way that protected and private properties no longer be tested directly as they should be considered an implementation detail. However, if for some reason the value of protected or private properties still needs to be tested, this helper can be used to get access to their value.
    • Yoast\PHPUnitPolyfills\Polyfills\AssertNumericType trait to polyfill the Assert::assertFinite(), Assert::assertInfinite() and Assert::assertNan() methods as introduced in PHPUnit 5.0.0.
    • Yoast\PHPUnitPolyfills\Polyfills\ExpectException trait to polyfill the TestCase::expectException(), TestCase::expectExceptionMessage(), TestCase::expectExceptionCode() and TestCase::expectExceptionMessageRegExp() methods, as introduced in PHPUnit 5.2.0 to replace the Testcase::setExpectedException() and the Testcase::setExpectedExceptionRegExp() method.
    • Yoast\PHPUnitPolyfills\Polyfills\AssertFileDirectory trait to polyfill the Assert::assertIsReadable(), Assert::assertIsWritable() methods and their file/directory based variations, as introduced in PHPUnit 5.6.0.
    • Yoast\PHPUnitPolyfills\TestCases\TestCase: support for the assertPreConditions() and assertPostConditions() methods.

    Changed

    • The minimum supported PHP version has been lowered to PHP 5.5 (was 5.6).
    • The minimum supported PHPUnit version has been lowered to PHP 4.8.36 (was 5.7). Note: for PHPUnit 4, only version 4.8.36 is supported, for PHPUnit 5, only PHPUnit >= 5.7.21 is supported.
    • Readme: documentation improvements.
    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Nov 13, 2020)

Owner
Yoast
This is where the Yoast.com team shares its public code: from our WordPress plugins to other small projects.
Yoast
Laravel Blog Package. Easiest way to add a blog to your Laravel website. A package which adds wordpress functionality to your website and is compatible with laravel 8.

Laravel Blog Have you worked with Wordpress? Developers call this package wordpress-like laravel blog. Give our package a Star to support us ⭐ ?? Inst

Binshops 279 Dec 28, 2022
Check if files are compatible with X version of PHP.

grumphp-php-compatibility Check if files are compatible with X version of PHP. grumphp.yml: parameters: tasks: php_compatibility:

Wunder 4 Mar 15, 2022
A PHP library for creating EDI 837 claim equivalent to paper-claim 1500. EDI X12 ANSI 837 File 5010 Version

EDI X12 ANSI 5010 PHP Library for creating EDI X12 ANSI 837 File 5010 Version A Simple PHP function for creating an EDI X12 ANSI 837 file version 0050

WalksWithMe 7 Jan 3, 2023
The Current US Version of PHP-Nuke Evolution Xtreme v3.0.1b-beta often known as Nuke-Evolution Xtreme. This is a hardened version of PHP-Nuke and is secure and safe. We are currently porting Xtreme over to PHP 8.0.3

2021 Nightly Builds Repository PHP-Nuke Evolution Xtreme Developers TheGhost - Ernest Allen Buffington (Lead Developer) SeaBeast08 - Sebastian Scott B

Ernest Buffington 7 Aug 28, 2022
Version is a library that helps with managing the version number of Git-hosted PHP projects

Version Version is a library that helps with managing the version number of Git-hosted PHP projects. Installation You can add this library as a local,

Sebastian Bergmann 6.3k Dec 26, 2022
Naive Bayes works by looking at a training set and making a guess based on that set.

Naive Bayes Naive Bayes works by looking at a training set and making a guess based on that set. It uses simple statistics and a bit of math to calcul

Assisted Mindfulness 29 Nov 27, 2022
Hprose is a cross-language RPC. This project is Hprose 3.0 for PHP

Hprose 3.0 for PHP Introduction Hprose is a High Performance Remote Object Service Engine. It is a modern, lightweight, cross-language, cross-platform

Hprose 2k Jan 4, 2023
HLedger is cross-platform accounting software for both power users and folks new to accounting

HLedger Plain Text Accounting on Nextcloud HLedger is cross-platform accounting software for both power users and folks new to accounting. It's good f

Ryan Boder 11 Jan 20, 2022
Fresns core library: Cross-platform general-purpose multiple content forms social network service software

About Fresns Fresns is a free and open source social network service software, a general-purpose community product designed for cross-platform, and su

Fresns 82 Dec 31, 2022
Silverstripe-sspy - Python based SSPAK export with higher reliability and cross-platform compatibility

SSPY - Python Stand-alone SSPAK solution © Simon Firesphere Erkelens; Moss Mossman Cantwell Usage: sspy [create|load|extract] (db|assets) --file=my.

Simon Erkelens 1 Jun 29, 2021
A cross-language remote procedure call(RPC) framework for rapid development of high performance distributed services.

Motan Overview Motan is a cross-language remote procedure call(RPC) framework for rapid development of high performance distributed services. Related

Weibo R&D Open Source Projects 5.8k Dec 20, 2022
Allow multiple options for Magento 2 checkout layout. Provides capabilities to AB test checkout changes and more.

Aimes_CheckoutDesigns Features Please note: This module is currently still considered a proof of concept. This module provides the ability to change c

Rob Aimes 30 Aug 8, 2022
Formcreator is a plugin which allow creation of custom forms of easy access

Formcreator is a plugin which allow creation of custom forms of easy access. At the same time, the plugin allow the creation of one or more tickets when the form is filled.

GLPI plugins 135 Dec 22, 2022
Allow your users to login with their Ethereum wallet.

Allow your users to login with their Ethereum wallet Allow your users to link their Ethereum wallet to their account to skip entering their login cred

Miguel Piedrafita 84 Nov 7, 2022
Methods to allow the mapping of cases to snake / camel for input / output

Methods to allow the mapping of cases to snake / camel for input / output This is where your description should go. Limit it to a paragraph or two. Co

Craig Smith 4 Aug 31, 2022
Allow players to see how well they are doing while pvping with the help of a combo counter

Combo-Counter Allow players to see how well they are doing while pvping with the help of a combo counter Settngs / Config #set to false if you dont wa

null 3 Jun 1, 2022
This plugin allow you play music from resources pack in minecraft

Music Player for PocketMine-MP Commands music-start songname music-stop songname IMPORTANT! You must add music resources pack to PocketMine resources

Excalibur 1 Oct 14, 2021
Provide blocks which allow positioning content within them in layouts.

Mini layouts Provide blocks which allow positioning content within them in layouts. Backdrop Installation Install and enable the module as usual. Go t

Backdrop CMS contributed projects 5 Dec 17, 2021
Allow SVG images to be used in Magento CMS blocks and pages via the TinyMCE Wysiwyg Editor.

Hyvä Themes - SVG support for the Magento CMS Wysiwyg Editor Allow SVG images to be used in CMS blocks and pages via the TinyMCE Wysiwyg Editor. hyva-

Hyvä 14 Dec 15, 2022