From 1d8243b73e1ff55ded6c497bed5b8474f19caef2 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 29 Aug 2026 09:00:40 +0200 Subject: [PATCH] Cleanup PHPUnit compatibility --- CHANGELOG | 2 ++ doc/advanced.rst | 8 +++--- extra/cache-extra/Tests/IntegrationTest.php | 4 +-- .../Tests/IntegrationTest.php | 2 +- extra/html-extra/Tests/IntegrationTest.php | 2 +- extra/inky-extra/Tests/IntegrationTest.php | 2 +- extra/intl-extra/Tests/IntegrationTest.php | 2 +- .../markdown-extra/Tests/IntegrationTest.php | 2 +- extra/string-extra/Tests/IntegrationTest.php | 2 +- src/Test/IntegrationTestCase.php | 18 ++++++------- src/Test/NodeTestCase.php | 13 +-------- tests/ExpressionParserTest.php | 3 --- tests/IntegrationTest.php | 2 +- tests/Node/TextTest.php | 3 --- tests/NodeVisitor/CorrectnessTest.php | 9 ------- tests/ParserTest.php | 3 --- tests/TemplateTest.php | 21 --------------- tests/Test/IntegrationTestCaseTest.php | 27 +++++++++++++++++++ 18 files changed, 51 insertions(+), 74 deletions(-) create mode 100644 tests/Test/IntegrationTestCaseTest.php diff --git a/CHANGELOG b/CHANGELOG index 91d99d5a14c..cbfecdd8edf 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ # 4.0.0 (2026-XX-XX) * Add an optional `string $template = ''` argument to `IncludeNode::addGetTemplate()`; subclasses overriding this method must declare a compatible parameter + * Remove the obsolete `Twig\Test\NodeTestCase::getTests()` method; override `provideTests()` instead + * Add native return types to the protected extension points in `Twig\Test\IntegrationTestCase` and `Twig\Test\NodeTestCase` and require overriding methods to declare compatible return types * Remove `TemplateVariable` and `AssignTemplateVariable`; use `MacroVariable` and `AssignMacroVariable` instead * Add the `isAlwaysAllowedInSandbox()` method to `Twig\TwigCallableInterface` and `Twig\TokenParser\TokenParserInterface` * Always allow printing a `Markup` object in a sandbox, whatever the security policy is diff --git a/doc/advanced.rst b/doc/advanced.rst index fd9d8b770f2..fd5a1a062d5 100644 --- a/doc/advanced.rst +++ b/doc/advanced.rst @@ -1042,7 +1042,7 @@ The ``IntegrationTest.php`` file should look like this:: class IntegrationTest extends IntegrationTestCase { - public function getExtensions() + protected function getExtensions(): array { return [ new CustomTwigExtension1(), @@ -1050,7 +1050,7 @@ The ``IntegrationTest.php`` file should look like this:: ]; } - public function getFixturesDir() + protected static function getFixturesDirectory(): string { return __DIR__.'/Fixtures/'; } @@ -1066,5 +1066,5 @@ Testing the node visitors can be complex, so extend your test cases from ``\Twig\Test\NodeTestCase``. Examples can be found in the Twig repository `tests/Twig/Node`_ directory. -.. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/3.x/tests/Fixtures -.. _`tests/Twig/Node`: https://github.com/twigphp/Twig/tree/3.x/tests/Node +.. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/4.x/tests/Fixtures +.. _`tests/Twig/Node`: https://github.com/twigphp/Twig/tree/4.x/tests/Node diff --git a/extra/cache-extra/Tests/IntegrationTest.php b/extra/cache-extra/Tests/IntegrationTest.php index ab72d6442da..651c767844c 100644 --- a/extra/cache-extra/Tests/IntegrationTest.php +++ b/extra/cache-extra/Tests/IntegrationTest.php @@ -19,14 +19,14 @@ class IntegrationTest extends IntegrationTestCase { - public function getExtensions() + public function getExtensions(): array { return [ new CacheExtension(), ]; } - protected function getRuntimeLoaders() + protected function getRuntimeLoaders(): array { return [ new class implements RuntimeLoaderInterface { diff --git a/extra/cssinliner-extra/Tests/IntegrationTest.php b/extra/cssinliner-extra/Tests/IntegrationTest.php index 7004b5e99ac..f0acd6316a1 100644 --- a/extra/cssinliner-extra/Tests/IntegrationTest.php +++ b/extra/cssinliner-extra/Tests/IntegrationTest.php @@ -16,7 +16,7 @@ class IntegrationTest extends IntegrationTestCase { - public function getExtensions() + public function getExtensions(): array { return [ new CssInlinerExtension(), diff --git a/extra/html-extra/Tests/IntegrationTest.php b/extra/html-extra/Tests/IntegrationTest.php index 8e2f94e38b9..d5cbb145d1f 100644 --- a/extra/html-extra/Tests/IntegrationTest.php +++ b/extra/html-extra/Tests/IntegrationTest.php @@ -16,7 +16,7 @@ class IntegrationTest extends IntegrationTestCase { - public function getExtensions() + public function getExtensions(): array { return [ new HtmlExtension(), diff --git a/extra/inky-extra/Tests/IntegrationTest.php b/extra/inky-extra/Tests/IntegrationTest.php index d9420dd09bf..10180139d8f 100644 --- a/extra/inky-extra/Tests/IntegrationTest.php +++ b/extra/inky-extra/Tests/IntegrationTest.php @@ -16,7 +16,7 @@ class IntegrationTest extends IntegrationTestCase { - public function getExtensions() + public function getExtensions(): array { return [ new InkyExtension(), diff --git a/extra/intl-extra/Tests/IntegrationTest.php b/extra/intl-extra/Tests/IntegrationTest.php index fa22b570801..d1f422f94de 100644 --- a/extra/intl-extra/Tests/IntegrationTest.php +++ b/extra/intl-extra/Tests/IntegrationTest.php @@ -16,7 +16,7 @@ class IntegrationTest extends IntegrationTestCase { - public function getExtensions() + public function getExtensions(): array { return [ new IntlExtension(), diff --git a/extra/markdown-extra/Tests/IntegrationTest.php b/extra/markdown-extra/Tests/IntegrationTest.php index 7db95c9190f..d1b04d273eb 100644 --- a/extra/markdown-extra/Tests/IntegrationTest.php +++ b/extra/markdown-extra/Tests/IntegrationTest.php @@ -16,7 +16,7 @@ class IntegrationTest extends IntegrationTestCase { - public function getExtensions() + public function getExtensions(): array { return [ new MarkdownExtension(), diff --git a/extra/string-extra/Tests/IntegrationTest.php b/extra/string-extra/Tests/IntegrationTest.php index ddf6abfe509..1fda2fcbc0b 100644 --- a/extra/string-extra/Tests/IntegrationTest.php +++ b/extra/string-extra/Tests/IntegrationTest.php @@ -16,7 +16,7 @@ class IntegrationTest extends IntegrationTestCase { - public function getExtensions() + public function getExtensions(): array { return [ new StringExtension(), diff --git a/src/Test/IntegrationTestCase.php b/src/Test/IntegrationTestCase.php index ecfcc63f874..a4fe9b05ff8 100644 --- a/src/Test/IntegrationTestCase.php +++ b/src/Test/IntegrationTestCase.php @@ -12,6 +12,7 @@ namespace Twig\Test; use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\IgnoreDeprecations; use PHPUnit\Framework\Constraint\Exception; use PHPUnit\Framework\TestCase; @@ -38,7 +39,7 @@ abstract protected static function getFixturesDirectory(): string; /** * @return RuntimeLoaderInterface[] */ - protected function getRuntimeLoaders() + protected function getRuntimeLoaders(): array { return []; } @@ -46,7 +47,7 @@ protected function getRuntimeLoaders() /** * @return ExtensionInterface[] */ - protected function getExtensions() + protected function getExtensions(): array { return []; } @@ -54,7 +55,7 @@ protected function getExtensions() /** * @return TwigFilter[] */ - protected function getTwigFilters() + protected function getTwigFilters(): array { return []; } @@ -62,7 +63,7 @@ protected function getTwigFilters() /** * @return TwigFunction[] */ - protected function getTwigFunctions() + protected function getTwigFunctions(): array { return []; } @@ -70,7 +71,7 @@ protected function getTwigFunctions() /** * @return TwigTest[] */ - protected function getTwigTests() + protected function getTwigTests(): array { return []; } @@ -113,10 +114,7 @@ public function testIntegration($file, $message, $condition, $templates, $except $this->doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs, $deprecation); } - /** - * @group legacy - */ - #[DataProvider('getLegacyTests'), IgnoreDeprecations] + #[DataProvider('getLegacyTests'), Group('legacy'), IgnoreDeprecations] public function testLegacyIntegration($file, $message, $condition, $templates, $exception, $outputs, $deprecation = ''): void { $this->doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs, $deprecation); @@ -331,7 +329,7 @@ protected function doIntegrationTest($file, $message, $condition, $templateSourc /** * @return array */ - protected static function parseTemplates($test) + protected static function parseTemplates($test): array { $templates = []; preg_match_all('/--TEMPLATE(?:\((.*?)\))?--(.*?)(?=\-\-TEMPLATE|$)/s', $test, $matches, \PREG_SET_ORDER); diff --git a/src/Test/NodeTestCase.php b/src/Test/NodeTestCase.php index e7e03722472..a32b32fb648 100644 --- a/src/Test/NodeTestCase.php +++ b/src/Test/NodeTestCase.php @@ -22,14 +22,6 @@ abstract class NodeTestCase extends TestCase { private Environment $currentEnv; - /** - * @return iterable - */ - public function getTests() - { - return []; - } - /** * @return iterable */ @@ -53,10 +45,7 @@ public function assertNodeCompilation($source, Node $node, ?Environment $environ } } - /** - * @return Compiler - */ - protected function getCompiler(?Environment $environment = null) + protected function getCompiler(?Environment $environment = null): Compiler { return new Compiler($environment ?? $this->getEnvironment()); } diff --git a/tests/ExpressionParserTest.php b/tests/ExpressionParserTest.php index 6d15f655d31..dcd9be69724 100644 --- a/tests/ExpressionParserTest.php +++ b/tests/ExpressionParserTest.php @@ -250,9 +250,6 @@ public function testSequenceDestructuringUsesAssignmentTargets(): void $this->assertSame('third', $pairs[2]['value']->getAttribute('name')); } - /** - * @dataProvider getEmptyDestructuringTests - */ #[DataProvider('getEmptyDestructuringTests')] public function testEmptyDestructuringThrows(string $template): void { diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index 2454c2ba1b7..ca035ef983d 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -47,7 +47,7 @@ function html() class IntegrationTest extends IntegrationTestCase { - public function getExtensions() + public function getExtensions(): array { $policy = new SecurityPolicy([], [], [], [], ['dump']); diff --git a/tests/Node/TextTest.php b/tests/Node/TextTest.php index 9cd1bb85ff0..a2c64d56531 100644 --- a/tests/Node/TextTest.php +++ b/tests/Node/TextTest.php @@ -41,9 +41,6 @@ public static function provideTests(): iterable return $tests; } - /** - * @dataProvider getIsBlankData - */ #[DataProvider('getIsBlankData')] public function testIsBlank($blank): void { diff --git a/tests/NodeVisitor/CorrectnessTest.php b/tests/NodeVisitor/CorrectnessTest.php index a9fdd80dc6d..c500e9f3a53 100644 --- a/tests/NodeVisitor/CorrectnessTest.php +++ b/tests/NodeVisitor/CorrectnessTest.php @@ -33,9 +33,6 @@ class CorrectnessTest extends TestCase { - /** - * @dataProvider getFilterBodyNodesData - */ #[DataProvider('getFilterBodyNodesData')] public function testFilterBodyNodes($input, $expected): void { @@ -56,9 +53,6 @@ public static function getFilterBodyNodesData() ]; } - /** - * @dataProvider getFilterBodyNodesDataThrowsException - */ #[DataProvider('getFilterBodyNodesDataThrowsException')] public function testFilterBodyNodesThrowsException($input): void { @@ -76,9 +70,6 @@ public static function getFilterBodyNodesDataThrowsException() ]; } - /** - * @dataProvider getFilterBodyNodesWithBOMData - */ #[DataProvider('getFilterBodyNodesWithBOMData')] public function testFilterBodyNodesWithBOM($emptyText): void { diff --git a/tests/ParserTest.php b/tests/ParserTest.php index a69834cd754..3827c77457e 100644 --- a/tests/ParserTest.php +++ b/tests/ParserTest.php @@ -127,9 +127,6 @@ public function testGetVarName(): void $this->addToAssertionCount(1); } - /** - * @dataProvider provideMacroTargetExpressions - */ #[DataProvider('provideMacroTargetExpressions')] public function testMacroTargetsOnlyCompileAsMacroReferences(string $expression): void { diff --git a/tests/TemplateTest.php b/tests/TemplateTest.php index a38931f2aa8..e193d6c16c3 100644 --- a/tests/TemplateTest.php +++ b/tests/TemplateTest.php @@ -239,9 +239,6 @@ public function testArrayWithStringableKeyIsConsistentAcrossStrictModes(bool $st $this->assertSame('value', $twig->render('index', ['array' => ['string' => 'value'], 'object' => $key])); } - /** - * @dataProvider getStringableKeyArrayAccessContainers - */ #[DataProvider('getStringableKeyArrayAccessContainers')] public function testStringableKeyIsCoercedForInternalArrayAccess(bool $strict, bool $sandboxed, \ArrayAccess $data): void { @@ -269,9 +266,6 @@ public static function getStringableKeyArrayAccessContainers(): iterable } } - /** - * @dataProvider getStrictVariablesModes - */ #[DataProvider('getStrictVariablesModes')] public function testArrayAccessWithObjectKeyKeepsTheObjectKey(bool $strict): void { @@ -288,9 +282,6 @@ public function testArrayAccessWithObjectKeyKeepsTheObjectKey(bool $strict): voi $this->assertSame(0, $key->toStringCalls); } - /** - * @dataProvider getStrictVariablesModes - */ #[DataProvider('getStrictVariablesModes')] public function testArrayAccessLookupDoesNotRepeatOffsetChecks(bool $strict): void { @@ -319,9 +310,6 @@ public function testArrayAccessDefinedTestDoesNotReadTheOffset(): void $this->assertSame([], $data->offsetGetCalls); } - /** - * @dataProvider getStrictVariablesModes - */ #[DataProvider('getStrictVariablesModes')] public function testRejectedStringableArrayAccessKeyRethrowsOriginalTypeError(bool $strict): void { @@ -344,9 +332,6 @@ public function testRejectedStringableArrayAccessKeyRethrowsOriginalTypeError(bo $this->assertSame(0, $key->toStringCalls); } - /** - * @dataProvider getStrictVariablesModes - */ #[DataProvider('getStrictVariablesModes')] public function testSandboxDoesNotAuthorizeStringPropertyForArrayAccessObjectKey(bool $strict): void { @@ -368,9 +353,6 @@ public function testSandboxDoesNotAuthorizeStringPropertyForArrayAccessObjectKey } } - /** - * @dataProvider getStrictVariablesModes - */ #[DataProvider('getStrictVariablesModes')] public function testArrayWithStringableKeyIsCheckedBySandbox(bool $strict): void { @@ -395,9 +377,6 @@ public function testArrayWithStringableKeyIsCheckedBySandbox(bool $strict): void $this->assertSame(1, $key->toStringCalls); } - /** - * @dataProvider getStrictVariablesModes - */ #[DataProvider('getStrictVariablesModes')] public function testInternalArrayAccessWithStringableKeyIsCheckedBySandbox(bool $strict): void { diff --git a/tests/Test/IntegrationTestCaseTest.php b/tests/Test/IntegrationTestCaseTest.php new file mode 100644 index 00000000000..654ba7d7a05 --- /dev/null +++ b/tests/Test/IntegrationTestCaseTest.php @@ -0,0 +1,27 @@ +getAttributes(Group::class); + + $this->assertCount(1, $attributes); + $this->assertSame('legacy', $attributes[0]->newInstance()->name()); + } +}