Make IntegrationTestCase and NodeTestCase compatible with PHPUnit 11

This commit is contained in:
Fabien Potencier
2026-06-03 18:17:03 +02:00
parent 2a2f058f70
commit ee8ab447d7
4 changed files with 82 additions and 1 deletions
+1
View File
@@ -1,5 +1,6 @@
# 3.27.2 (2026-XX-XX)
* Make the `IntegrationTestCase` and `NodeTestCase` test helpers compatible with PHPUnit 11
* Skip the sandbox `__toString` check on arguments whose PHP parameter type cannot implicitly coerce to string
# 3.27.1 (2026-05-30)
+21
View File
@@ -11,6 +11,8 @@
namespace Twig\Test;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\TestCase;
use Twig\Environment;
use Twig\Error\Error;
@@ -118,10 +120,13 @@ abstract class IntegrationTestCase extends TestCase
}
/**
* The annotation feeds PHPUnit < 10; the attribute feeds PHPUnit >= 10 and must point to a static provider, as PHPUnit >= 11 rejects non-static ones.
*
* @dataProvider getTests
*
* @return void
*/
#[DataProvider('provideTests')]
public function testIntegration($file, $message, $condition, $templates, $exception, $outputs, $deprecation = '')
{
$this->doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs, $deprecation);
@@ -134,11 +139,22 @@ abstract class IntegrationTestCase extends TestCase
*
* @return void
*/
#[DataProvider('provideLegacyTests'), Group('legacy')]
public function testLegacyIntegration($file, $message, $condition, $templates, $exception, $outputs, $deprecation = '')
{
$this->doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs, $deprecation);
}
final public static function provideTests(): iterable
{
return self::assembleTests(false, static::getFixturesDirectory());
}
final public static function provideLegacyTests(): iterable
{
return self::assembleTests(true, static::getFixturesDirectory());
}
/**
* @return iterable
*
@@ -153,6 +169,11 @@ abstract class IntegrationTestCase extends TestCase
$fixturesDir = $this->getFixturesDir();
}
return self::assembleTests($legacyTests, $fixturesDir);
}
private static function assembleTests(bool $legacyTests, string $fixturesDir): array
{
$fixturesDir = realpath($fixturesDir);
$tests = [];
+3 -1
View File
@@ -45,12 +45,14 @@ abstract class NodeTestCase extends TestCase
}
/**
* The non-static "getTests" is intentionally not mirrored as an attribute: PHPUnit >= 11 rejects non-static providers, so PHPUnit >= 10 relies on the static "provideTests" instead.
*
* @dataProvider getTests
* @dataProvider provideTests
*
* @return void
*/
#[DataProvider('getTests'), DataProvider('provideTests')]
#[DataProvider('provideTests')]
public function testCompile($node, $source, $environment = null, $isPattern = false)
{
$this->assertNodeCompilation($source, $node, $environment, $isPattern);
@@ -0,0 +1,57 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Twig\Tests\Test;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Twig\Test\IntegrationTestCase;
use Twig\Test\NodeTestCase;
/**
* Guards that the shipped test case classes stay usable on PHPUnit >= 11,
* which rejects non-static data providers.
*/
class DataProviderCompatibilityTest extends TestCase
{
/**
* @return iterable<array{class-string}>
*/
public static function provideTestCaseClasses(): iterable
{
yield [IntegrationTestCase::class];
yield [NodeTestCase::class];
}
/**
* @dataProvider provideTestCaseClasses
*
* @param class-string $class
*/
#[DataProvider('provideTestCaseClasses')]
public function testDataProviderAttributesReferenceStaticMethods(string $class): void
{
// Read attribute metadata via reflection without instantiating the attribute,
// so the check also runs under PHPUnit < 10 where the attribute class is absent.
$found = false;
foreach ((new \ReflectionClass($class))->getMethods() as $method) {
foreach ($method->getAttributes(DataProvider::class) as $attribute) {
$found = true;
$provider = $attribute->getArguments()[0];
$r = new \ReflectionMethod($class, $provider);
$this->assertTrue($r->isStatic(), \sprintf('Data provider "%s::%s()" referenced by "%s()" must be static for PHPUnit >= 11.', $class, $provider, $method->getName()));
$this->assertSame(0, $r->getNumberOfRequiredParameters(), \sprintf('Data provider "%s::%s()" must not require arguments.', $class, $provider));
}
}
$this->assertTrue($found, \sprintf('"%s" should declare at least one "#[DataProvider]" attribute.', $class));
}
}