Skip to content

Commit

Permalink
Merge pull request #48 from jrfnl/feature/allow-install-on-php-lt-7.3
Browse files Browse the repository at this point in the history
Allow installation on PHP < 7.3 icw PHPUnit < 9
  • Loading branch information
rdohms authored Apr 20, 2021
2 parents 494da46 + e609974 commit ab8c440
Show file tree
Hide file tree
Showing 15 changed files with 304 additions and 12 deletions.
23 changes: 21 additions & 2 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,21 @@ jobs:

strategy:
matrix:
php: ['8.0', '7.4', '7.3']
dependency-version: [prefer-lowest, prefer-stable]
php: ['8.0', '7.4', '7.3', '7.2', '7.1', '7.0', '5.6', '5.5', '5.4']
dependency-version: ['prefer-stable']
experimental: [false]

include:
- php: '7.3'
dependency-version: 'prefer-lowest'
experimental: false
- php: '7.4'
dependency-version: 'prefer-lowest'
experimental: false
- php: '8.0'
dependency-version: 'prefer-lowest'
experimental: false

- php: '8.1'
dependency-version: 'prefer-stable'
experimental: true
Expand All @@ -44,6 +54,15 @@ jobs:
coverage: none
tools: composer

# Remove the coding standards package as it has a higher minimum PHP
# requirement and would prevent running the tests on older PHP versions.
- name: 'Composer: remove CS dependency'
run: composer remove --dev --no-update dms/coding-standard

- name: 'Composer: update PHPUnit for testing lowest'
if: ${{ matrix.dependency-version == 'prefer-lowest' }}
run: composer require --no-update phpunit/phpunit:"^9.0"

- name: Install dependencies - normal
if: ${{ matrix.php < 8.1 }}
run: |
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ Simply use it by importing it with Composer
composer require --dev dms/phpunit-arraysubset-asserts
```

> :bulb: The package can be safely required on PHP 5.4 to current in combination with PHPUnit 4.8.36/5.7.21 to current.
>
> When the PHPUnit `assertArraySubset()` method is natively available (PHPUnit 4.x - 8.x), the PHPUnit native functionality will be used.
> For PHPUnit 9 and higher, the extension will kick in and polyfill the functionality which was removed from PHPUnit.
>
> Note: PHPUnit 8.x will show deprecation notices about the use of the `assertArraySubset()` method.
> With this extension in place, those can be safely ignored.

## Usage

You have two options to use this in your classes: either directly as a static call or as a trait if you wish to keep existing references working.
Expand Down
89 changes: 89 additions & 0 deletions assertarraysubset-autoload.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php

namespace DMS\PHPUnitExtensions\ArraySubset;

if (\class_exists('DMS\PHPUnitExtensions\ArraySubset\Autoload', false) === false) {

/**
* Custom autoloader.
*
* {@internal The code in this file must be PHP cross-version compatible for PHP 5.4 - current!}
*/
class Autoload
{
/**
* Loads a class.
*
* @param string $className The name of the class to load.
*
* @return bool
*/
public static function load($className)
{
// Only load classes belonging to this library.
if (\stripos($className, 'DMS\PHPUnitExtensions\ArraySubset') !== 0) {
return false;
}

switch ($className) {
case 'DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts':
if (\method_exists('\PHPUnit\Framework\Assert', 'assertArraySubset') === false) {
// PHPUnit >= 9.0.0.
require_once __DIR__ . '/src/ArraySubsetAsserts.php';

return true;
}

// PHPUnit < 9.0.0.
require_once __DIR__ . '/src/ArraySubsetAssertsEmpty.php';

return true;

case 'DMS\PHPUnitExtensions\ArraySubset\Assert':
if (\method_exists('\PHPUnit\Framework\Assert', 'assertArraySubset') === false) {
// PHPUnit >= 9.0.0.
require_once __DIR__ . '/src/Assert.php';

return true;
}

// PHPUnit < 9.0.0.
require_once __DIR__ . '/src/AssertFallThrough.php';

return true;

/*
* Handle arbitrary additional classes via PSR-4, but only allow loading on PHPUnit >= 9.0.0,
* as additional classes should only ever _need_ to be loaded when using PHPUnit >= 9.0.0.
*/
default:
if (\method_exists('\PHPUnit\Framework\Assert', 'assertArraySubset') === true) {
// PHPUnit < 9.0.0.
throw new \RuntimeException(
\sprintf(
'Using class "%s" is only supported in combination with PHPUnit >= 9.0.0',
$className
)
);
}

// PHPUnit >= 9.0.0.
$file = \realpath(
__DIR__ . \DIRECTORY_SEPARATOR
. 'src' . \DIRECTORY_SEPARATOR
. \strtr(\substr($className, 33), '\\', \DIRECTORY_SEPARATOR) . '.php'
);

if (\file_exists($file) === true) {
require_once $file;

return true;
}
}

return false;
}
}

\spl_autoload_register(__NAMESPACE__ . '\Autoload::load');
}
8 changes: 3 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"description": "This package provides ArraySubset and related asserts once deprecated in PHPUnit 8",
"type": "library",
"require": {
"phpunit/phpunit": "^9.0",
"php": "^7.3|^7.4|^8.0"
"phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0",
"php": "^5.4 || ^7.0 || ^8.0"
},
"license": "MIT",
"authors": [
Expand All @@ -18,9 +18,7 @@
"dms/coding-standard": "^8"
},
"autoload": {
"psr-4": {
"DMS\\PHPUnitExtensions\\ArraySubset\\": "src"
}
"files": ["assertarraysubset-autoload.php"]
},
"autoload-dev": {
"psr-4": {
Expand Down
4 changes: 2 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 30 additions & 1 deletion phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<arg name="cache" value=".phpcs.cache" /> <!-- cache the results and don't commit them -->
<arg value="np" /> <!-- n = ignore warnings, p = show progress -->

<file>assertarraysubset-autoload.php</file>
<file>src</file>
<file>tests</file>

Expand All @@ -15,6 +16,34 @@
</rule>

<rule ref="SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedEqualOperator">
<exclude-pattern>src/Constraint/ArraySubset.php</exclude-pattern>
<exclude-pattern>src/Constraint/ArraySubset\.php</exclude-pattern>
</rule>

<!-- BC-layer: exclude rules which would prevent code from being PHP cross-version compatible. -->
<rule ref="Squiz.Classes.ClassFileName.NoMatch">
<exclude-pattern>assertarraysubset-autoload\.php</exclude-pattern>
<exclude-pattern>src/ArraySubsetAssertsEmpty\.php</exclude-pattern>
<exclude-pattern>src/AssertFallThrough\.php</exclude-pattern>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing">
<exclude-pattern>assertarraysubset-autoload\.php</exclude-pattern>
<exclude-pattern>src/ArraySubsetAssertsEmpty\.php</exclude-pattern>
<exclude-pattern>src/AssertFallThrough\.php</exclude-pattern>
<exclude-pattern>tests/bootstrap\.php</exclude-pattern>
<exclude-pattern>tests/Availability/*\.php</exclude-pattern>
</rule>
<rule ref="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName">
<exclude-pattern>assertarraysubset-autoload\.php</exclude-pattern>
<exclude-pattern>tests/Availability/*\.php</exclude-pattern>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint">
<exclude-pattern>assertarraysubset-autoload\.php</exclude-pattern>
<exclude-pattern>src/AssertFallThrough\.php</exclude-pattern>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingNativeTypeHint">
<exclude-pattern>assertarraysubset-autoload\.php</exclude-pattern>
<exclude-pattern>src/AssertFallThrough\.php</exclude-pattern>
<exclude-pattern>tests/Availability/*\.php</exclude-pattern>
</rule>

</ruleset>
5 changes: 3 additions & 2 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
beStrictAboutChangesToGlobalState="true"
bootstrap="vendor/autoload.php"
bootstrap="tests/bootstrap.php"
>
<testsuites>
<testsuite name="unit">
<directory>tests</directory>
<directory>tests/Availability</directory>
<directory phpVersion="7.3.0" phpVersionOperator=">=">tests/Unit</directory>
</testsuite>
</testsuites>

Expand Down
15 changes: 15 additions & 0 deletions src/ArraySubsetAssertsEmpty.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace DMS\PHPUnitExtensions\ArraySubset;

/**
* ArraySubsetAsserts trait for use with PHPUnit 4.x - 8.x.
*
* As this trait is empty, calls to `assertArraySubset()` will automatically fall through
* to PHPUnit itself and will use the PHPUnit native `assertArraySubset()` method.
*
* {@internal The code in this file must be PHP cross-version compatible for PHP 5.4 - current!}
*/
trait ArraySubsetAsserts
{
}
33 changes: 33 additions & 0 deletions src/AssertFallThrough.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace DMS\PHPUnitExtensions\ArraySubset;

use PHPUnit\Framework\Assert as PhpUnitAssert;

/**
* Assert class for use with PHPUnit 4.x - 8.x.
*
* The method in this class will fall through to PHPUnit itself and use the PHPUnit
* native `assertArraySubset()` method.
*
* {@internal The code in this file must be PHP cross-version compatible for PHP 5.4 - current!}
*/
final class Assert
{
/**
* Asserts that an array has a specified subset.
*
* @param array|ArrayAccess|mixed[] $subset
* @param array|ArrayAccess|mixed[] $array
* @param bool $checkForObjectIdentity
* @param string $message
*
* @throws ExpectationFailedException
* @throws InvalidArgumentException
* @throws Exception
*/
public static function assertArraySubset($subset, $array, $checkForObjectIdentity = false, $message = '')
{
PhpUnitAssert::assertArraySubset($subset, $array, $checkForObjectIdentity, $message);
}
}
35 changes: 35 additions & 0 deletions tests/Availability/AutoloadExceptionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace DMS\PHPUnitExtensions\ArraySubset\Tests\Availibility;

use DMS\PHPUnitExtensions\ArraySubset\Constraint\ArraySubset;
use PHPUnit\Framework\TestCase;

/**
* Testing that autoloading classes which should only ever be loaded on PHPUnit >= 9 will
* generate an exception when attempted on PHPUnit < 9..
*
* Note: the autoloading in combination with PHPUnit 9+ is automatically tested via the
* actual tests for the polyfill as the class will be called upon.
*
* {@internal The code in this file must be PHP cross-version compatible for PHP 5.4 - current!}
*
* @requires PHPUnit < 9
*/
final class AutoloadExceptionTest extends TestCase
{
public function testAutoloadException()
{
$expection = '\RuntimeException';
$message = 'Using class "DMS\PHPUnitExtensions\ArraySubset\Constraint\ArraySubset" is only supported in combination with PHPUnit >= 9.0.0';

if (\method_exists('\PHPUnit\Framework\TestCase', 'expectException') === true) {
$this->expectException($expection);
$this->expectExceptionMessage($message);
} else {
$this->setExpectedException($expection, $message);
}

new ArraySubset();
}
}
19 changes: 19 additions & 0 deletions tests/Availability/AvailibilityViaClassTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace DMS\PHPUnitExtensions\ArraySubset\Tests\Availibility;

use DMS\PHPUnitExtensions\ArraySubset\Assert;
use PHPUnit\Framework\TestCase;

/**
* Testing that the autoloading of the fall-through `Assert` class for PHPUnit 4.x - 8.x works correctly.
*
* {@internal The code in this file must be PHP cross-version compatible for PHP 5.4 - current!}
*/
final class AvailibilityViaClassTest extends TestCase
{
public function testAssertArraySubsetisAvailabe()
{
Assert::assertArraySubset([1, 2], [1, 2, 3]);
}
}
22 changes: 22 additions & 0 deletions tests/Availability/AvailibilityViaTraitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace DMS\PHPUnitExtensions\ArraySubset\Tests\Availibility;

use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
use PHPUnit\Framework\TestCase;

/**
* Testing that the autoloading of the empty `ArraySubsetAsserts` trait for PHPUnit 4.x - 8.x works correctly.
*
* {@internal The code in this file must be PHP cross-version compatible for PHP 5.4 - current!}
*/
final class AvailibilityViaTraitTest extends TestCase
{
use ArraySubsetAsserts;

public function testAssertArraySubsetisAvailabe()
{
static::assertArraySubset([1, 2], [1, 2, 3]);
$this->assertArraySubset([1, 2], [1, 2, 3]);
}
}
3 changes: 3 additions & 0 deletions tests/Unit/AssertTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
use PHPUnit\Framework\ExpectationFailedException;
use PHPUnit\Framework\TestCase;

/**
* @requires PHPUnit >= 9
*/
final class AssertTest extends TestCase
{
public function testAssertArraySubsetPassesStrictConfig(): void
Expand Down
3 changes: 3 additions & 0 deletions tests/Unit/Constraint/ArraySubsetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

use function sprintf;

/**
* @requires PHPUnit >= 9
*/
final class ArraySubsetTest extends TestCase
{
/**
Expand Down
Loading

0 comments on commit ab8c440

Please sign in to comment.