Skip to content

Commit

Permalink
Merge pull request #623 from PHPCSStandards/feature/tests-compatibili…
Browse files Browse the repository at this point in the history
…ty-with-phpunit-11

Allow for PHPUnit 11
  • Loading branch information
jrfnl authored Sep 8, 2024
2 parents cc4244b + 00721ba commit daea84b
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 26 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/quicktest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ jobs:
- name: Determine PHPUnit config file to use
id: phpunit_config
run: |
if [ "${{ startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }}" == "true" ]; then
if [ "${{ startsWith( steps.phpunit_version.outputs.VERSION, '11.' ) }}" == "true" ]; then
echo 'FILE=phpunit10.xml.dist' >> $GITHUB_OUTPUT
echo 'EXTRA_ARGS=' >> $GITHUB_OUTPUT
elif [ "${{ startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }}" == "true" ]; then
echo 'FILE=phpunit10.xml.dist' >> $GITHUB_OUTPUT
echo 'EXTRA_ARGS=' >> $GITHUB_OUTPUT
else
Expand Down
17 changes: 10 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,10 @@ jobs:
- name: Determine PHPUnit config file to use
id: phpunit_config
run: |
if [ "${{ startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }}" == "true" ]; then
if [ "${{ startsWith( steps.phpunit_version.outputs.VERSION, '11.' ) }}" == "true" ]; then
echo 'FILE=phpunit10.xml.dist' >> $GITHUB_OUTPUT
echo 'EXTRA_ARGS=' >> $GITHUB_OUTPUT
elif [ "${{ startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }}" == "true" ]; then
echo 'FILE=phpunit10.xml.dist' >> $GITHUB_OUTPUT
echo 'EXTRA_ARGS=' >> $GITHUB_OUTPUT
else
Expand Down Expand Up @@ -338,21 +341,21 @@ jobs:
# As of PHPUnit 9.3.4, a cache warming option is available.
# Using that option prevents issues with PHP-Parser backfilling PHP tokens when PHPCS does not (yet),
# which would otherwise cause tests to fail on tokens being available when they shouldn't be.
# As coverage is only run on high/low PHP, the high PHP version will use PHPUnit 10, so just check for that.
# As coverage is only run on high/low PHP, the high PHP version will use PHPUnit 11, so just check for that.
- name: "Warm the PHPUnit cache (PHPUnit 9.3+)"
if: ${{ startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }}
run: vendor/bin/phpunit -c phpunit10.xml.dist --coverage-cache ./build/phpunit-cache --warm-coverage-cache
if: ${{ startsWith( steps.phpunit_version.outputs.VERSION, '11.' ) }}
run: vendor/bin/phpunit -c phpunit10.xml.dist --warm-coverage-cache

- name: "Run the unit tests without caching with code coverage (PHPUnit < 10)"
if: ${{ ! startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }}
if: ${{ ! startsWith( steps.phpunit_version.outputs.VERSION, '11.' ) }}
run: vendor/bin/phpunit
env:
PHPCS_VERSION: ${{ matrix.phpcs_version }}
PHPCSUTILS_USE_CACHE: false

- name: "Run the unit tests without caching with code coverage (PHPUnit 10+)"
if: ${{ startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }}
run: vendor/bin/phpunit -c phpunit10.xml.dist --coverage-cache ./build/phpunit-cache
if: ${{ startsWith( steps.phpunit_version.outputs.VERSION, '11.' ) }}
run: vendor/bin/phpunit -c phpunit10.xml.dist
env:
PHPCS_VERSION: ${{ matrix.phpcs_version }}
PHPCSUTILS_USE_CACHE: false
Expand Down
10 changes: 9 additions & 1 deletion PHPCSUtils/TestUtils/UtilityMethodTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
use PHPCSUtils\Exceptions\TestMarkerNotFound;
use PHPCSUtils\Exceptions\TestTargetNotFound;
use PHPCSUtils\TestUtils\ConfigDouble;
use PHPUnit\Framework\Attributes\AfterClass;
use PHPUnit\Framework\Attributes\Before;
use PHPUnit\Framework\Attributes\BeforeClass;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
use ReflectionProperty;
Expand All @@ -30,7 +33,7 @@
* This class is compatible with PHP_CodeSniffer 3.x and contains preliminary compatibility with 4.x
* based on its currently known state/roadmap.
*
* This class is compatible with {@link https://phpunit.de/ PHPUnit} 4.5 - 9.x providing the PHPCSUtils
* This class is compatible with {@link https://phpunit.de/ PHPUnit} 4.5 - 11.x providing the PHPCSUtils
* autoload file is included in the test bootstrap. For more information about that, please consult
* the project's {@link https://github.com/PHPCSStandards/PHPCSUtils/blob/develop/README.md README}.
*
Expand Down Expand Up @@ -105,6 +108,8 @@
* for the PHPCSUtils utility functions themselves.
*
* @since 1.0.0
* @since 1.0.7 Compatible with PHPUnit 10.
* @since 1.1.0 Compatible with PHPUnit 11.
*/
abstract class UtilityMethodTestCase extends TestCase
{
Expand Down Expand Up @@ -194,6 +199,7 @@ abstract class UtilityMethodTestCase extends TestCase
*
* @return void
*/
#[BeforeClass]
public static function setUpTestFile()
{
parent::setUpBeforeClass();
Expand Down Expand Up @@ -283,6 +289,7 @@ protected static function parseFile($caseFile, Ruleset $ruleset, Config $config)
*
* @return void
*/
#[Before]
public function skipJSCSSTestsOnPHPCS4()
{
if (static::$fileExtension !== 'js' && static::$fileExtension !== 'css') {
Expand All @@ -308,6 +315,7 @@ public function skipJSCSSTestsOnPHPCS4()
*
* @return void
*/
#[AfterClass]
public static function resetTestFile()
{
/*
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ These classes take most of the heavy lifting away for some frequently occurring
### Test utilities

An abstract `UtilityMethodTestCase` class to support testing of your utility methods written for PHP_CodeSniffer.
Supports PHPUnit 4.x up to 9.x.
Supports PHPUnit 4.x up to 11.x.

### Use the latest version of PHP_CodeSniffer native utility functions

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,9 @@ public function testMultiLineLongArrayKeysTrailingComma()
[self::$phpcsFile, $target + 7, $target + 8, 1],
[self::$phpcsFile, $target + 15, $target + 16, 2],
[self::$phpcsFile, $target + 23, $target + 24, 3],
]
)->will($this->onConsecutiveCalls(null, null, true)); // Testing short-circuiting the loop.
],
[null, null, true] // Testing short-circuiting the loop.
);

$this->setExpectationWithConsecutiveArgs(
$mockObj,
Expand Down Expand Up @@ -665,16 +666,18 @@ public function testBowOutOnUnfinishedArray()
*/
private function getMockedClassUnderTest()
{
$mockedObj = $this->getMockBuilder('\PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff');
$mockedObj = $this->getMockBuilder(
'\PHPCSUtils\Tests\AbstractSniffs\AbstractArrayDeclaration\ArrayDeclarationSniffMock'
);

if (\method_exists($mockedObj, 'onlyMethods')) {
// PHPUnit 8+.
return $mockedObj->onlyMethods($this->methodsToMock)
->getMockForAbstractClass();
->getMock();
}

// PHPUnit < 8.
return $mockedObj->setMethods($this->methodsToMock)
->getMockForAbstractClass();
->getMock();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/**
* PHPCSUtils, utility functions and classes for PHP_CodeSniffer sniff developers.
*
* @package PHPCSUtils
* @copyright 2019-2020 PHPCSUtils Contributors
* @license https://opensource.org/licenses/LGPL-3.0 LGPL3
* @link https://github.com/PHPCSStandards/PHPCSUtils
*/

namespace PHPCSUtils\Tests\AbstractSniffs\AbstractArrayDeclaration;

use PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff;

/**
* Test mock for the AbstractArrayDeclarationSniff to allow for testing the logic of the abstract class.
*
* @since 1.1.0
*/
class ArrayDeclarationSniffMock extends AbstractArrayDeclarationSniff
{
}
32 changes: 28 additions & 4 deletions Tests/ExpectWithConsecutiveArgs.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@
* Previously, the `InvocationMocker->withConsecutive()` method could be used to test
* this, but that method was removed in PHPUnit 10.0.
*
* Furthermore, the use of `->will($this->onConsecutiveCalls(...))` was deprecated in PHPUnit 10/11
* and will be removed in PHPUnit 12.0. The typical replacement for this is `->willReturn(...)`.
* However, as this helper already uses `->willReturnCallback()`, if these two deprecations/removals
* collide in the same expectation setting, it would break, so this is now also worked around via the
* `$returnValues` parameter.
*
* @since 1.0.7
* @since 1.1.0 Now also works round the deprecation of `->will($this->onConsecutiveCalls(...))`
* via the new optional `$returnValues` parameter.
*/
trait ExpectWithConsecutiveArgs
{
Expand All @@ -30,11 +38,17 @@ trait ExpectWithConsecutiveArgs
* @param string $methodName The name of the method on which to set the expectations.
* @param array<array<mixed>> $expectedArgs Multi-dimentional array of arguments expected to be passed in
* consecutive calls.
* @param array<mixed> $returnValues Optional. Array of values to return on consecutive calls.
*
* @return object Expectation object.
*/
final public function setExpectationWithConsecutiveArgs($mockObject, $countMatcher, $methodName, $expectedArgs)
{
final public function setExpectationWithConsecutiveArgs(
$mockObject,
$countMatcher,
$methodName,
$expectedArgs,
$returnValues = []
) {
$methodExpectation = $mockObject->expects($countMatcher)
->method($methodName);

Expand All @@ -48,12 +62,18 @@ final public function setExpectationWithConsecutiveArgs($mockObject, $countMatch
}
}

return \call_user_func_array([$methodExpectation, 'withConsecutive'], $expectationsArray);
$methodExpectation = \call_user_func_array([$methodExpectation, 'withConsecutive'], $expectationsArray);

if (empty($returnValues)) {
return $methodExpectation;
}

return $methodExpectation->will(\call_user_func_array([$this, 'onConsecutiveCalls'], $returnValues));
}

// PHPUnit 10+.
return $methodExpectation->willReturnCallback(
function () use (&$expectedArgs, $countMatcher, $methodName) {
function () use (&$expectedArgs, $countMatcher, $methodName, $returnValues) {
$actualArgs = \func_get_args();
$expected = \array_shift($expectedArgs);

Expand All @@ -76,6 +96,10 @@ function () use (&$expectedArgs, $countMatcher, $methodName) {
$methodName
)
);

if (empty($returnValues) === false) {
return $returnValues[($countMatcher->numberOfInvocations() - 1)];
}
}
);
}
Expand Down
48 changes: 45 additions & 3 deletions Tests/PolyfilledTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use PHPCSUtils\Tests\ExpectWithConsecutiveArgs;
use PHPCSUtils\TestUtils\UtilityMethodTestCase;
use Yoast\PHPUnitPolyfills\Autoload;
use Yoast\PHPUnitPolyfills\Polyfills\AssertArrayWithListKeys;
use Yoast\PHPUnitPolyfills\Polyfills\AssertClosedResource;
use Yoast\PHPUnitPolyfills\Polyfills\AssertEqualsSpecializations;
use Yoast\PHPUnitPolyfills\Polyfills\AssertFileDirectory;
Expand All @@ -27,17 +28,58 @@
use Yoast\PHPUnitPolyfills\Polyfills\AssertIsType;
use Yoast\PHPUnitPolyfills\Polyfills\AssertNumericType;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectNotEquals;
use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectProperty;
use Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains;
use Yoast\PHPUnitPolyfills\Polyfills\EqualToSpecializations;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectException;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionObject;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectPHPException;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectUserDeprecation;

if (\version_compare(Autoload::VERSION, '2.0.0', '>=')) {
if (\version_compare(Autoload::VERSION, '3.0.0', '>=')) {
/**
* Abstract utility method base test case which includes all available polyfills (PHPUnit Polyfills 2.x compaible).
* Abstract utility method base test case which includes all available polyfills (PHPUnit Polyfills 3.x compatible).
*
* This test case includes all polyfills from the PHPUnit Polyfill library to make them
* available to the tests.
*
* Generally speaking, this testcase only needs to be used when the concrete test class will
* use functionality which has changed in PHPUnit cross-version.
* In all other cases, the `UtilityMethodTestCase` can be extended directly.
*
* {@internal The list of included polyfill traits should be reviewed after each new
* release of the PHPUnit Polyfill library.}
*
* @since 1.1.0
*/
abstract class PolyfilledTestCase extends UtilityMethodTestCase
{
// PHPCSUtils native helpers.
use AssertPropertySame;
use ExpectWithConsecutiveArgs;

// PHPUnit Polyfills.
use AssertArrayWithListKeys;
use AssertClosedResource;
use AssertEqualsSpecializations;
use AssertFileEqualsSpecializations;
use AssertIgnoringLineEndings;
use AssertionRenames;
use AssertIsList;
use AssertIsType;
use AssertObjectEquals;
use AssertObjectNotEquals;
use AssertObjectProperty;
use AssertStringContains;
use EqualToSpecializations;
use ExpectExceptionMessageMatches;
use ExpectUserDeprecation;
}
} elseif (\version_compare(Autoload::VERSION, '2.0.0', '>=')) {
/**
* Abstract utility method base test case which includes all available polyfills (PHPUnit Polyfills 2.x compatible).
*
* This test case includes all polyfills from the PHPUnit Polyfill library to make them
* available to the tests.
Expand Down Expand Up @@ -74,7 +116,7 @@ abstract class PolyfilledTestCase extends UtilityMethodTestCase
}
} else {
/**
* Abstract utility method base test case which includes all available polyfills (PHPUnit Polyfills 1.x compaible).
* Abstract utility method base test case which includes all available polyfills (PHPUnit Polyfills 1.x compatible).
*
* This test case includes all polyfills from the PHPUnit Polyfill library to make them
* available to the tests.
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"phpcsstandards/phpcsdevcs": "^1.1.6",
"php-parallel-lint/php-parallel-lint": "^1.3.2",
"php-parallel-lint/php-console-highlighter": "^1.0",
"yoast/phpunit-polyfills": "^1.1.0 || ^2.0.0"
"yoast/phpunit-polyfills": "^1.1.0 || ^2.0.0 || ^3.0.0"
},
"minimum-stability": "dev",
"prefer-stable": true,
Expand Down
2 changes: 1 addition & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<!--
A number of tests need process isolation to allow for recording code coverage on
the setting of function local static variables.
However, using process isolation runs into trouble with PHPUnit 4.x/PHPCS 2.6.0.
However, using process isolation runs into trouble with PHPUnit 4.x.
Executing these specific tests in a separate testsuite, which is run
before the full test suite, will allow for the code coverage for these methods
to be recorded properly, while still allowing the tests to run on all supported
Expand Down
7 changes: 5 additions & 2 deletions phpunit10.xml.dist
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/10.1/phpunit.xsd"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/10.5/phpunit.xsd"
backupGlobals="true"
bootstrap="./Tests/bootstrap.php"
beStrictAboutTestsThatDoNotTestAnything="true"
cacheDirectory="build/.phpunit-cache"
colors="true"
displayDetailsOnTestsThatTriggerErrors="true"
displayDetailsOnTestsThatTriggerWarnings="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnIncompleteTests="true"
displayDetailsOnSkippedTests="true"
displayDetailsOnPhpunitDeprecations="false"
failOnWarning="true"
failOnNotice="true"
failOnDeprecation="true"
failOnPhpunitDeprecation="false"
requireCoverageMetadata="true"
>
<testsuites>
Expand All @@ -30,7 +33,7 @@
<!--
A number of tests need process isolation to allow for recording code coverage on
the setting of function local static variables.
However, using process isolation runs into trouble with PHPUnit 4.x/PHPCS 2.6.0.
However, using process isolation runs into trouble with PHPUnit 4.x.
Executing these specific tests in a separate testsuite, which is run
before the full test suite, will allow for the code coverage for these methods
to be recorded properly, while still allowing the tests to run on all supported
Expand Down

0 comments on commit daea84b

Please sign in to comment.