From 08f478af09d617f2e0c340d470de555d1287ae32 Mon Sep 17 00:00:00 2001 From: Ulrich Mathes Date: Wed, 17 Jul 2024 12:12:07 +0200 Subject: [PATCH 1/6] update testing to PHPUnit 11 and PHP 8.2, 8.3 --- .github/workflows/test.yml | 6 +-- composer.json | 4 +- ...AbstractTest.php => AbstractTestClass.php} | 2 +- tests/Unit/ComponentStructureTest.php | 38 +++++++++++-------- tests/Unit/ComponentVariablesCheckTest.php | 29 +++++++------- tests/Unit/ContentVariableCheckTest.php | 25 ++++++------ tests/Unit/ParamCountCheckTest.php | 21 +++++----- 7 files changed, 68 insertions(+), 57 deletions(-) rename tests/Unit/{AbstractTest.php => AbstractTestClass.php} (95%) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e660e04..cb18d52 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,7 +29,7 @@ jobs: - name: Install composer dependencies - run: composer install --prefer-dist --no-progress --no-suggest + run: composer install --prefer-dist --no-progress - name: PHP Linting @@ -45,7 +45,7 @@ jobs: strategy: max-parallel: 2 matrix: - php-version: [8.0, 8.1, 8.2] + php-version: [8.3, 8.2] name: Unit (PHP ${{ matrix.php-version }}) steps: @@ -71,7 +71,7 @@ jobs: - name: Install composer dependencies - run: composer install --prefer-dist --no-progress --no-suggest + run: composer install --prefer-dist --no-progress - name: PHP Unit Testing diff --git a/composer.json b/composer.json index 5d82b1c..7af280c 100644 --- a/composer.json +++ b/composer.json @@ -21,9 +21,9 @@ "require-dev": { "editorconfig-checker/editorconfig-checker": "^10.0", "squizlabs/php_codesniffer": "^3.0", - "phpunit/phpunit": "^9.2", + "phpunit/phpunit": "^11.2", "symfony/var-dumper": "^5.1", - "phpstan/phpstan": "^0.12.38" + "phpstan/phpstan": "^1.11" }, "autoload": { "psr-4": { diff --git a/tests/Unit/AbstractTest.php b/tests/Unit/AbstractTestClass.php similarity index 95% rename from tests/Unit/AbstractTest.php rename to tests/Unit/AbstractTestClass.php index c79ce61..0c535c7 100644 --- a/tests/Unit/AbstractTest.php +++ b/tests/Unit/AbstractTestClass.php @@ -8,7 +8,7 @@ use Sitegeist\FluidComponentsLinter\Fluid\ViewHelper\ViewHelperResolver; use TYPO3Fluid\Fluid\View\TemplateView; -abstract class AbstractTest extends TestCase +abstract class AbstractTestClass extends TestCase { public function createComponent(string $componentSource, bool $strictSyntax = false): Component { diff --git a/tests/Unit/ComponentStructureTest.php b/tests/Unit/ComponentStructureTest.php index e152dcb..130a55e 100644 --- a/tests/Unit/ComponentStructureTest.php +++ b/tests/Unit/ComponentStructureTest.php @@ -4,59 +4,67 @@ namespace Sitegeist\FluidComponentsLinter\Tests\Unit; -final class ComponentStructureTest extends AbstractTest +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; +use Sitegeist\FluidComponentsLinter\Exception\ComponentStructureException; +use Sitegeist\FluidComponentsLinter\Exception\StrictComponentStructureException; +use TYPO3Fluid\Fluid\Core\Parser\Exception; + +final class ComponentStructureTest extends AbstractTestClass { - public function dataProvider() + public static function dataProvider() { return [ 'fluidSyntax' => [ '', false, - \TYPO3Fluid\Fluid\Core\Parser\Exception::class + Exception::class ], 'missingComponent' => [ 'some content', false, - \Sitegeist\FluidComponentsLinter\Exception\ComponentStructureException::class + ComponentStructureException::class ], 'missingRenderer1' => [ 'some content', false, - \Sitegeist\FluidComponentsLinter\Exception\ComponentStructureException::class + ComponentStructureException::class ], 'missingRenderer2' => [ '', false, - \Sitegeist\FluidComponentsLinter\Exception\ComponentStructureException::class + ComponentStructureException::class ], 'strictComponentStructure1' => [ 'some content', true, - \Sitegeist\FluidComponentsLinter\Exception\StrictComponentStructureException::class + StrictComponentStructureException::class ], 'strictComponentStructure2' => [ 'some content', true, - \Sitegeist\FluidComponentsLinter\Exception\StrictComponentStructureException::class + StrictComponentStructureException::class ], 'strictComponentStructure3' => [ 'some content', true, - \Sitegeist\FluidComponentsLinter\Exception\StrictComponentStructureException::class + StrictComponentStructureException::class ], 'strictComponentStructure4' => [ 'some content', true, - \Sitegeist\FluidComponentsLinter\Exception\StrictComponentStructureException::class + StrictComponentStructureException::class ] ]; } - /** - * @dataProvider dataProvider - */ - public function testComponentStructure(string $componentSource, bool $strictSyntax, string $expectedException): void - { + #[Test] + #[DataProvider('dataProvider')] + public function testComponentStructure( + string $componentSource, + bool $strictSyntax, + string $expectedException + ): void { $this->expectException($expectedException); $this->createComponent($componentSource, $strictSyntax); } diff --git a/tests/Unit/ComponentVariablesCheckTest.php b/tests/Unit/ComponentVariablesCheckTest.php index e697f73..83d0a37 100644 --- a/tests/Unit/ComponentVariablesCheckTest.php +++ b/tests/Unit/ComponentVariablesCheckTest.php @@ -4,60 +4,62 @@ namespace Sitegeist\FluidComponentsLinter\Tests\Unit; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use Sitegeist\FluidComponentsLinter\CodeQuality\Check\ComponentVariablesCheck; use Sitegeist\FluidComponentsLinter\CodeQuality\Issue\IssueInterface; -final class ComponentVariablesCheckTest extends AbstractTest +final class ComponentVariablesCheckTest extends AbstractTestClass { - public function dataProvider() + public static function dataProvider() { return [ 'requirePrefixerPrefixUsed' => [ - $this->generateConfiguration(true, IssueInterface::SEVERITY_MAJOR, false, IssueInterface::SEVERITY_MAJOR), + static::generateConfiguration(true, IssueInterface::SEVERITY_MAJOR, false, IssueInterface::SEVERITY_MAJOR), '{component.prefix}', 0, IssueInterface::SEVERITY_MAJOR ], 'requirePrefixerClassUsed' => [ - $this->generateConfiguration(true, IssueInterface::SEVERITY_MAJOR, false, IssueInterface::SEVERITY_MAJOR), + static::generateConfiguration(true, IssueInterface::SEVERITY_MAJOR, false, IssueInterface::SEVERITY_MAJOR), '{component.class}', 0, IssueInterface::SEVERITY_MAJOR ], 'requirePrefixerMinorSeverity' => [ - $this->generateConfiguration(true, IssueInterface::SEVERITY_MINOR, false, IssueInterface::SEVERITY_MAJOR), + static::generateConfiguration(true, IssueInterface::SEVERITY_MINOR, false, IssueInterface::SEVERITY_MAJOR), '', 1, IssueInterface::SEVERITY_MINOR ], 'requirePrefixerDisabled' => [ - $this->generateConfiguration(false, IssueInterface::SEVERITY_MAJOR, false, IssueInterface::SEVERITY_MAJOR), + static::generateConfiguration(false, IssueInterface::SEVERITY_MAJOR, false, IssueInterface::SEVERITY_MAJOR), '', 0, IssueInterface::SEVERITY_MAJOR ], 'requireClassClassUsed' => [ - $this->generateConfiguration(false, IssueInterface::SEVERITY_MAJOR, true, IssueInterface::SEVERITY_MAJOR), + static::generateConfiguration(false, IssueInterface::SEVERITY_MAJOR, true, IssueInterface::SEVERITY_MAJOR), '{class}', 0, IssueInterface::SEVERITY_MAJOR ], 'requireClassMinorSeverity' => [ - $this->generateConfiguration(false, IssueInterface::SEVERITY_MAJOR, true, IssueInterface::SEVERITY_MINOR), + static::generateConfiguration(false, IssueInterface::SEVERITY_MAJOR, true, IssueInterface::SEVERITY_MINOR), '', 1, IssueInterface::SEVERITY_MINOR ], 'requireClassDisabled' => [ - $this->generateConfiguration(false, IssueInterface::SEVERITY_MAJOR, false, IssueInterface::SEVERITY_MAJOR), + static::generateConfiguration(false, IssueInterface::SEVERITY_MAJOR, false, IssueInterface::SEVERITY_MAJOR), '', 0, IssueInterface::SEVERITY_MAJOR ], 'combination' => [ - $this->generateConfiguration(true, IssueInterface::SEVERITY_MAJOR, true, IssueInterface::SEVERITY_MAJOR), + static::generateConfiguration(true, IssueInterface::SEVERITY_MAJOR, true, IssueInterface::SEVERITY_MAJOR), '', 2, IssueInterface::SEVERITY_MAJOR @@ -65,9 +67,8 @@ public function dataProvider() ]; } - /** - * @dataProvider dataProvider - */ + #[Test] + #[DataProvider('dataProvider')] public function testChecksForMinimumMaximumParameterCount( array $configuration, string $componentSource, @@ -83,7 +84,7 @@ public function testChecksForMinimumMaximumParameterCount( } } - public function generateConfiguration( + public static function generateConfiguration( bool $requirePrefixer, string $requirePrefixerSeverity, bool $requireClass, diff --git a/tests/Unit/ContentVariableCheckTest.php b/tests/Unit/ContentVariableCheckTest.php index 4b39d52..9c3bb3b 100644 --- a/tests/Unit/ContentVariableCheckTest.php +++ b/tests/Unit/ContentVariableCheckTest.php @@ -3,28 +3,30 @@ namespace Sitegeist\FluidComponentsLinter\Tests\Unit; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use Sitegeist\FluidComponentsLinter\CodeQuality\Check\ContentVariableCheck; use Sitegeist\FluidComponentsLinter\CodeQuality\Issue\IssueInterface; -final class ContentVariableCheckTest extends AbstractTest +final class ContentVariableCheckTest extends AbstractTestClass { - public function dataProvider() + public static function dataProvider() { return [ 'rawViewHelper' => [ - $this->generateConfiguration(true, IssueInterface::SEVERITY_MAJOR), + static::generateConfiguration(true, IssueInterface::SEVERITY_MAJOR), '{content}', 0, IssueInterface::SEVERITY_MAJOR ], 'rawInlineViewHelper' => [ - $this->generateConfiguration(true, IssueInterface::SEVERITY_MAJOR), + static::generateConfiguration(true, IssueInterface::SEVERITY_MAJOR), '{content->f:format.raw()}', 0, IssueInterface::SEVERITY_MAJOR ], 'nestedRawViewHelper' => [ - $this->generateConfiguration(true, IssueInterface::SEVERITY_MAJOR), + static::generateConfiguration(true, IssueInterface::SEVERITY_MAJOR), ' contentcontent{content}contentcontent ', @@ -32,19 +34,19 @@ public function dataProvider() IssueInterface::SEVERITY_MAJOR ], 'missingViewHelper' => [ - $this->generateConfiguration(true, IssueInterface::SEVERITY_MAJOR), + static::generateConfiguration(true, IssueInterface::SEVERITY_MAJOR), '{content}', 1, IssueInterface::SEVERITY_MAJOR ], 'minorSeverity' => [ - $this->generateConfiguration(true, IssueInterface::SEVERITY_MINOR), + static::generateConfiguration(true, IssueInterface::SEVERITY_MINOR), '{content}', 1, IssueInterface::SEVERITY_MINOR ], 'disabledCheck' => [ - $this->generateConfiguration(false, IssueInterface::SEVERITY_MAJOR), + static::generateConfiguration(false, IssueInterface::SEVERITY_MAJOR), '{content}', 0, IssueInterface::SEVERITY_MAJOR @@ -52,9 +54,8 @@ public function dataProvider() ]; } - /** - * @dataProvider dataProvider - */ + #[Test] + #[DataProvider('dataProvider')] public function testChecksForMinimumMaximumParameterCount( array $configuration, string $componentSource, @@ -70,7 +71,7 @@ public function testChecksForMinimumMaximumParameterCount( } } - public function generateConfiguration(bool $check, string $severity): array + public static function generateConfiguration(bool $check, string $severity): array { return [ 'renderer' => [ diff --git a/tests/Unit/ParamCountCheckTest.php b/tests/Unit/ParamCountCheckTest.php index abda1f5..8311f67 100644 --- a/tests/Unit/ParamCountCheckTest.php +++ b/tests/Unit/ParamCountCheckTest.php @@ -3,22 +3,24 @@ namespace Sitegeist\FluidComponentsLinter\Tests\Unit; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use Sitegeist\FluidComponentsLinter\CodeQuality\Check\ParamCountCheck; use Sitegeist\FluidComponentsLinter\CodeQuality\Issue\IssueInterface; -final class ParamCountCheckTest extends AbstractTest +final class ParamCountCheckTest extends AbstractTestClass { - public function dataProvider() + public static function dataProvider() { return [ 'tooFewParameters' => [ - $this->generateConfiguration(3, 10, IssueInterface::SEVERITY_MAJOR), + static::generateConfiguration(3, 10, IssueInterface::SEVERITY_MAJOR), '', 1, IssueInterface::SEVERITY_MAJOR ], 'parametersInAllowedRange' => [ - $this->generateConfiguration(3, 5, IssueInterface::SEVERITY_MAJOR), + static::generateConfiguration(3, 5, IssueInterface::SEVERITY_MAJOR), ' @@ -29,7 +31,7 @@ public function dataProvider() IssueInterface::SEVERITY_MAJOR ], 'tooManyParameters' => [ - $this->generateConfiguration(1, 5, IssueInterface::SEVERITY_MAJOR), + static::generateConfiguration(1, 5, IssueInterface::SEVERITY_MAJOR), ' @@ -43,7 +45,7 @@ public function dataProvider() IssueInterface::SEVERITY_MAJOR ], 'minorSeverity' => [ - $this->generateConfiguration(3, 10, IssueInterface::SEVERITY_MINOR), + static::generateConfiguration(3, 10, IssueInterface::SEVERITY_MINOR), '', 1, IssueInterface::SEVERITY_MINOR @@ -51,9 +53,8 @@ public function dataProvider() ]; } - /** - * @dataProvider dataProvider - */ + #[Test] + #[DataProvider('dataProvider')] public function testChecksForMinimumMaximumParameterCount( array $configuration, string $componentSource, @@ -69,7 +70,7 @@ public function testChecksForMinimumMaximumParameterCount( } } - public function generateConfiguration(int $min, int $max, string $severity): array + public static function generateConfiguration(int $min, int $max, string $severity): array { return [ 'params' => [ From c8a04903d785e7c2631c40aa5dff5d867bb65845 Mon Sep 17 00:00:00 2001 From: Ulrich Mathes Date: Wed, 17 Jul 2024 12:14:01 +0200 Subject: [PATCH 2/6] update composer requirements to match also with TYPO3 13 --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 7af280c..4f0d1d4 100644 --- a/composer.json +++ b/composer.json @@ -13,9 +13,9 @@ "issues": "https://github.com/sitegeist/fluid-components-linter/issues" }, "require": { - "php": ">=8.0.0", - "symfony/config": "^5.0 || ^6.0", - "symfony/console": "^5.0 || ^6.0", + "php": ">=8.2.0", + "symfony/config": "^5.0 || ^6.0 || ^7.0", + "symfony/console": "^5.0 || ^6.0 || ^7.0", "typo3fluid/fluid": "^2.6" }, "require-dev": { From b990ebbcdee1f216cbf41ac043a396df844a3917 Mon Sep 17 00:00:00 2001 From: Ulrich Mathes Date: Wed, 17 Jul 2024 12:17:05 +0200 Subject: [PATCH 3/6] solve deprecated ParserRuntimeOnly trait --- .../ViewHelpers/ComponentViewHelper.php | 21 ++++++++++++++++--- .../ViewHelpers/IntrospectionViewHelper.php | 21 ++++++++++++++++--- src/Classes/ViewHelpers/ParamViewHelper.php | 20 ++++++++++++++++-- .../ViewHelpers/RendererViewHelper.php | 19 +++++++++++++++-- 4 files changed, 71 insertions(+), 10 deletions(-) diff --git a/src/Classes/ViewHelpers/ComponentViewHelper.php b/src/Classes/ViewHelpers/ComponentViewHelper.php index 8686991..01398ff 100644 --- a/src/Classes/ViewHelpers/ComponentViewHelper.php +++ b/src/Classes/ViewHelpers/ComponentViewHelper.php @@ -3,15 +3,30 @@ namespace Sitegeist\FluidComponentsLinter\ViewHelpers; +use TYPO3Fluid\Fluid\Core\Compiler\TemplateCompiler; +use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\ViewHelperNode; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; -use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\ParserRuntimeOnly; class ComponentViewHelper extends AbstractViewHelper { - use ParserRuntimeOnly; - public function initializeArguments() { $this->registerArgument('description', 'string', 'Description of the component'); } + + /** + * ViewHelper only has functionality during parsing + */ + public function render() + { + return null; + } + + /** + * ViewHelper only has functionality during parsing + */ + public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler) + { + return ''; + } } diff --git a/src/Classes/ViewHelpers/IntrospectionViewHelper.php b/src/Classes/ViewHelpers/IntrospectionViewHelper.php index ac9e61b..2092f28 100644 --- a/src/Classes/ViewHelpers/IntrospectionViewHelper.php +++ b/src/Classes/ViewHelpers/IntrospectionViewHelper.php @@ -4,13 +4,12 @@ namespace Sitegeist\FluidComponentsLinter\ViewHelpers; +use TYPO3Fluid\Fluid\Core\Compiler\TemplateCompiler; +use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\ViewHelperNode; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; -use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\ParserRuntimeOnly; class IntrospectionViewHelper extends AbstractViewHelper { - use ParserRuntimeOnly; - public $namespaceIdentifier; public $methodIdentifier; @@ -35,4 +34,20 @@ public function validateAdditionalArguments(array $arguments) { // Allow all arguments } + + /** + * ViewHelper only has functionality during parsing + */ + public function render() + { + return null; + } + + /** + * ViewHelper only has functionality during parsing + */ + public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler) + { + return ''; + } } diff --git a/src/Classes/ViewHelpers/ParamViewHelper.php b/src/Classes/ViewHelpers/ParamViewHelper.php index 986d469..ba62216 100644 --- a/src/Classes/ViewHelpers/ParamViewHelper.php +++ b/src/Classes/ViewHelpers/ParamViewHelper.php @@ -3,13 +3,13 @@ namespace Sitegeist\FluidComponentsLinter\ViewHelpers; +use TYPO3Fluid\Fluid\Core\Compiler\TemplateCompiler; +use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\ViewHelperNode; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\ParserRuntimeOnly; class ParamViewHelper extends AbstractViewHelper { - use ParserRuntimeOnly; - public function initializeArguments() { $this->registerArgument('name', 'string', 'Parameter name', true); @@ -18,4 +18,20 @@ public function initializeArguments() $this->registerArgument('default', 'string', 'Default value'); $this->registerArgument('description', 'string', 'Description of the parameter'); } + + /** + * ViewHelper only has functionality during parsing + */ + public function render() + { + return null; + } + + /** + * ViewHelper only has functionality during parsing + */ + public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler) + { + return ''; + } } diff --git a/src/Classes/ViewHelpers/RendererViewHelper.php b/src/Classes/ViewHelpers/RendererViewHelper.php index 4d6c7af..4ef5d80 100644 --- a/src/Classes/ViewHelpers/RendererViewHelper.php +++ b/src/Classes/ViewHelpers/RendererViewHelper.php @@ -3,10 +3,25 @@ namespace Sitegeist\FluidComponentsLinter\ViewHelpers; +use TYPO3Fluid\Fluid\Core\Compiler\TemplateCompiler; +use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\ViewHelperNode; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; -use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\ParserRuntimeOnly; class RendererViewHelper extends AbstractViewHelper { - use ParserRuntimeOnly; + /** + * ViewHelper only has functionality during parsing + */ + public function render() + { + return null; + } + + /** + * ViewHelper only has functionality during parsing + */ + public function compile($argumentsName, $closureName, &$initializationPhpCode, ViewHelperNode $node, TemplateCompiler $compiler) + { + return ''; + } } From 50b7123bc430939da6b6db45877a841230d74cd5 Mon Sep 17 00:00:00 2001 From: Ulrich Mathes Date: Wed, 17 Jul 2024 14:27:24 +0200 Subject: [PATCH 4/6] set name of LintCommand via function --- src/Classes/Command/LintCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Classes/Command/LintCommand.php b/src/Classes/Command/LintCommand.php index a40a361..20994aa 100644 --- a/src/Classes/Command/LintCommand.php +++ b/src/Classes/Command/LintCommand.php @@ -20,7 +20,6 @@ class LintCommand extends Command { - protected static $defaultName = 'lint'; /** * Define severities which will lead to an exit status 0 @@ -36,6 +35,7 @@ class LintCommand extends Command protected function configure() { $this + ->setName('lint') ->setDescription('Validates fluid components based on a specified ruleset') ->addArgument( 'paths', From df6e2cb18a7bb5b88be4dde61c9307b1f66eb698 Mon Sep 17 00:00:00 2001 From: Ulrich Mathes Date: Wed, 17 Jul 2024 14:29:11 +0200 Subject: [PATCH 5/6] improve readability and use PHP 8 features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the help of rector and ☕ --- .../Check/ComponentVariablesCheck.php | 4 +-- .../Check/DocumentationFixtureCheck.php | 4 +-- .../Check/ParamTypeNamespaceCheck.php | 2 +- .../CodeQuality/Check/ViewHelpersCheck.php | 8 +++--- src/Classes/CodeQuality/Issue/Issue.php | 27 +++++++++---------- .../CodeQuality/Issue/IssueInterface.php | 12 ++++----- src/Classes/Command/LintCommand.php | 19 +++++-------- .../Configuration/LintConfiguration.php | 2 +- .../Fluid/ViewHelper/ViewHelperResolver.php | 7 ++--- src/Classes/Service/CodeQualityService.php | 19 +++++-------- src/Classes/Service/ComponentService.php | 22 ++++----------- src/Classes/Service/FluidService.php | 4 +-- .../ViewHelpers/ComponentViewHelper.php | 2 +- .../ViewHelpers/IntrospectionViewHelper.php | 2 +- src/Classes/ViewHelpers/ParamViewHelper.php | 2 +- src/FcLint.php | 2 +- 16 files changed, 53 insertions(+), 85 deletions(-) diff --git a/src/Classes/CodeQuality/Check/ComponentVariablesCheck.php b/src/Classes/CodeQuality/Check/ComponentVariablesCheck.php index 72b7a20..a153eca 100644 --- a/src/Classes/CodeQuality/Check/ComponentVariablesCheck.php +++ b/src/Classes/CodeQuality/Check/ComponentVariablesCheck.php @@ -36,8 +36,6 @@ protected function extractUsedVariables(): array $this->component->rootNode, ObjectAccessorNode::class ); - return array_map(function (ObjectAccessorNode $node) { - return $node->getObjectPath(); - }, $usedVariables); + return array_map(fn(ObjectAccessorNode $node) => $node->getObjectPath(), $usedVariables); } } diff --git a/src/Classes/CodeQuality/Check/DocumentationFixtureCheck.php b/src/Classes/CodeQuality/Check/DocumentationFixtureCheck.php index 87b404a..0bba4be 100644 --- a/src/Classes/CodeQuality/Check/DocumentationFixtureCheck.php +++ b/src/Classes/CodeQuality/Check/DocumentationFixtureCheck.php @@ -35,9 +35,7 @@ public function check(): array return $issues; } - $fixtureFiles = array_map(function ($fixtureFile) use ($directory, $name) { - return sprintf($fixtureFile, $directory, $name); - }, $this->fixtureFiles); + $fixtureFiles = array_map(fn($fixtureFile) => sprintf($fixtureFile, $directory, $name), $this->fixtureFiles); $fixtureFile = array_filter($fixtureFiles, 'file_exists'); $fixtureFile = reset($fixtureFile); diff --git a/src/Classes/CodeQuality/Check/ParamTypeNamespaceCheck.php b/src/Classes/CodeQuality/Check/ParamTypeNamespaceCheck.php index 63daaf0..f9bebfb 100644 --- a/src/Classes/CodeQuality/Check/ParamTypeNamespaceCheck.php +++ b/src/Classes/CodeQuality/Check/ParamTypeNamespaceCheck.php @@ -15,7 +15,7 @@ public function check(): array $issues = []; foreach ($this->component->paramNodes as $paramNode) { $arguments = $paramNode->getArguments(); - if (substr((string) $arguments['type'], 0, 1) === '\\') { + if (str_starts_with((string) $arguments['type'], '\\')) { $issues[] = $this->issue('Type is specified with leading backslash for parameter %s: %s', [ $arguments['name'], $arguments['type'] diff --git a/src/Classes/CodeQuality/Check/ViewHelpersCheck.php b/src/Classes/CodeQuality/Check/ViewHelpersCheck.php index cdcfb38..5c517cc 100644 --- a/src/Classes/CodeQuality/Check/ViewHelpersCheck.php +++ b/src/Classes/CodeQuality/Check/ViewHelpersCheck.php @@ -16,7 +16,7 @@ public function check(): array foreach ($this->configuration['renderer']['viewHelperRestrictions'] as $restriction) { $pattern = $this->createViewHelperPattern($restriction['viewHelperName']); foreach ($usedViewHelpers as $tagName) { - if (preg_match($pattern, $tagName)) { + if (preg_match($pattern, (string) $tagName)) { $issues[] = $this->issue($restriction['message'], [ $tagName ])->setSeverity($restriction['severity']); @@ -30,7 +30,7 @@ public function check(): array protected function createViewHelperPattern(string $viewHelperName): string { $pattern = preg_quote($viewHelperName, '#'); - if (substr($viewHelperName, -1, 1) !== '.') { + if (!str_ends_with($viewHelperName, '.')) { $pattern .= '$'; } return '#^' . $pattern . '#'; @@ -42,9 +42,7 @@ protected function extractUsedViewHelpers(): array $this->component->rootNode, ViewHelperNode::class ); - $introspectedViewHelpers = array_filter($usedViewHelpers, function (ViewHelperNode $node) { - return $node->getUninitializedViewHelper() instanceof IntrospectionViewHelper; - }); + $introspectedViewHelpers = array_filter($usedViewHelpers, fn(ViewHelperNode $node) => $node->getUninitializedViewHelper() instanceof IntrospectionViewHelper); return array_map(function (ViewHelperNode $node) { /** @var IntrospectionViewHelper */ $introspectionViewHelper = $node->getUninitializedViewHelper(); diff --git a/src/Classes/CodeQuality/Issue/Issue.php b/src/Classes/CodeQuality/Issue/Issue.php index 4f1673d..7908615 100644 --- a/src/Classes/CodeQuality/Issue/Issue.php +++ b/src/Classes/CodeQuality/Issue/Issue.php @@ -5,21 +5,18 @@ class Issue implements IssueInterface { - protected $checkName = ''; - protected $description; - protected $data; - - protected $categories = []; - protected $severity = IssueInterface::SEVERITY_MAJOR; - - protected $file = ''; - protected $line = null; - protected $column = null; - - public function __construct(string $description, array $data, string $file, int $line = null, int $column = null) - { - $this->description = $description; - $this->data = $data; + protected string $checkName = ''; + + protected array $categories = []; + protected string $severity = IssueInterface::SEVERITY_MAJOR; + + public function __construct( + protected string $description, + protected array $data, + protected string $file, + protected ?int $line = null, + protected ?int $column = null, + ) { $this->setLocation($file, $line, $column); } diff --git a/src/Classes/CodeQuality/Issue/IssueInterface.php b/src/Classes/CodeQuality/Issue/IssueInterface.php index 3a84cd2..4416cae 100644 --- a/src/Classes/CodeQuality/Issue/IssueInterface.php +++ b/src/Classes/CodeQuality/Issue/IssueInterface.php @@ -5,16 +5,16 @@ interface IssueInterface { - const SEVERITY_INFO = 'info'; - const SEVERITY_MINOR = 'minor'; - const SEVERITY_MAJOR = 'major'; - const SEVERITY_CRITICAL = 'critical'; - const SEVERITY_BLOCKER = 'blocker'; + public const SEVERITY_INFO = 'info'; + public const SEVERITY_MINOR = 'minor'; + public const SEVERITY_MAJOR = 'major'; + public const SEVERITY_CRITICAL = 'critical'; + public const SEVERITY_BLOCKER = 'blocker'; /** * Ordered list of severities based on their... severity */ - const SEVERITIES = [ + public const SEVERITIES = [ self::SEVERITY_INFO, self::SEVERITY_MINOR, self::SEVERITY_MAJOR, diff --git a/src/Classes/Command/LintCommand.php b/src/Classes/Command/LintCommand.php index 20994aa..eb7aa8e 100644 --- a/src/Classes/Command/LintCommand.php +++ b/src/Classes/Command/LintCommand.php @@ -6,12 +6,10 @@ use Sitegeist\FluidComponentsLinter\CodeQuality\Issue\IssueInterface; use Sitegeist\FluidComponentsLinter\CodeQuality\Output\GroupedOutput; use Sitegeist\FluidComponentsLinter\CodeQuality\Output\JsonOutput; -use Sitegeist\FluidComponentsLinter\Configuration\LintConfiguration; -use Sitegeist\FluidComponentsLinter\Exception\ConfigurationException; use Sitegeist\FluidComponentsLinter\Service\CodeQualityService; use Sitegeist\FluidComponentsLinter\Service\ComponentService; use Sitegeist\FluidComponentsLinter\Service\ConfigurationService; -use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -20,19 +18,16 @@ class LintCommand extends Command { - /** * Define severities which will lead to an exit status 0 - * - * @var array */ - protected $fatalSeverities = [ + protected array $fatalSeverities = [ IssueInterface::SEVERITY_BLOCKER, IssueInterface::SEVERITY_CRITICAL, IssueInterface::SEVERITY_MAJOR ]; - protected function configure() + protected function configure(): void { $this ->setName('lint') @@ -85,7 +80,7 @@ protected function configure() ); } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { try { $configurationService = new ConfigurationService; @@ -121,9 +116,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $skipSeverities = $this->determineSeveritiesToSkip($input->getOption('severity')); if (!empty($skipSeverities)) { - $issues = array_filter($issues, function (IssueInterface $issue) use ($skipSeverities) { - return !in_array($issue->getSeverity(), $skipSeverities); - }); + $issues = array_filter($issues, fn(IssueInterface $issue) => !in_array($issue->getSeverity(), $skipSeverities)); } if ($input->getOption('json')) { @@ -154,7 +147,7 @@ protected function determineExitStatus(array $issues): int return 0; } - protected function determineSeveritiesToSkip(string $minSeverity) + protected function determineSeveritiesToSkip(string $minSeverity): array { $skipSeverities = []; foreach (IssueInterface::SEVERITIES as $severity) { diff --git a/src/Classes/Configuration/LintConfiguration.php b/src/Classes/Configuration/LintConfiguration.php index 4182173..71ba78f 100644 --- a/src/Classes/Configuration/LintConfiguration.php +++ b/src/Classes/Configuration/LintConfiguration.php @@ -9,7 +9,7 @@ class LintConfiguration implements ConfigurationInterface { - public function getConfigTreeBuilder() + public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder('fclint'); /** @var TreeNode */ diff --git a/src/Classes/Fluid/ViewHelper/ViewHelperResolver.php b/src/Classes/Fluid/ViewHelper/ViewHelperResolver.php index 41dec23..0bfc74c 100644 --- a/src/Classes/Fluid/ViewHelper/ViewHelperResolver.php +++ b/src/Classes/Fluid/ViewHelper/ViewHelperResolver.php @@ -4,12 +4,13 @@ namespace Sitegeist\FluidComponentsLinter\Fluid\ViewHelper; -use TYPO3Fluid\Fluid\Core\Parser\Exception as ParserException; use Sitegeist\FluidComponentsLinter\ViewHelpers\IntrospectionViewHelper; +use TYPO3Fluid\Fluid\Core\Parser\Exception as ParserException; +use TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperInterface; class ViewHelperResolver extends \TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperResolver { - public function createViewHelperInstanceFromClassName($viewHelperClassName) + public function createViewHelperInstanceFromClassName($viewHelperClassName): ViewHelperInterface { $parts = explode('\\', $viewHelperClassName); $methodIdentifier = array_pop($parts); @@ -25,7 +26,7 @@ public function resolveViewHelperClassName($namespaceIdentifier, $methodIdentifi { try { return parent::resolveViewHelperClassName($namespaceIdentifier, $methodIdentifier); - } catch (ParserException $e) { + } catch (ParserException) { // Redirect missing ViewHelpers to introspection placeholder return sprintf( '%s\\%s\\%s', diff --git a/src/Classes/Service/CodeQualityService.php b/src/Classes/Service/CodeQualityService.php index c5e70ea..5443bb7 100644 --- a/src/Classes/Service/CodeQualityService.php +++ b/src/Classes/Service/CodeQualityService.php @@ -9,22 +9,17 @@ use Sitegeist\FluidComponentsLinter\CodeQuality\Issue\IssueInterface; use Sitegeist\FluidComponentsLinter\Exception\ComponentStructureException; use Sitegeist\FluidComponentsLinter\Fluid\ViewHelper\ViewHelperResolver; +use TYPO3Fluid\Fluid\Core\Parser\Exception; use TYPO3Fluid\Fluid\View\TemplateView; class CodeQualityService { - /** @var array */ - protected $configuration; + protected ?TemplateView $view = null; - /** @var string[] */ - protected $checks; - - /** @var TemplateView */ - protected $view; - - public function __construct(array $configuration, array $checks) - { - $this->configuration = $configuration; + public function __construct( + protected array $configuration, + protected array $checks, // @var string[] + ) { $this->initializeChecks($checks); $this->initializeView(); } @@ -60,7 +55,7 @@ public function validateComponent(string $path): array file_get_contents($path), $path ); - } catch (\TYPO3Fluid\Fluid\Core\Parser\Exception $e) { + } catch (Exception $e) { preg_match('#in template .+, line ([0-9]+) at character ([0-9]+).#', $e->getMessage(), $matches); $issue = $this->blocker($e->getMessage(), $path, (int) $matches[1], (int) $matches[2]); return [$issue]; diff --git a/src/Classes/Service/ComponentService.php b/src/Classes/Service/ComponentService.php index f5e8ef0..5dbd2df 100644 --- a/src/Classes/Service/ComponentService.php +++ b/src/Classes/Service/ComponentService.php @@ -8,10 +8,8 @@ class ComponentService /** * Collection of paths that have already been scanned for components; * this prevents infinite loops caused by circular symlinks - * - * @var array */ - protected $scannedPaths; + protected array $scannedPaths = []; /** * Finds all components in the specified paths @@ -22,10 +20,10 @@ class ComponentService */ public function findComponentsInPaths(array $paths, string $ext): array { - $components = $this->scannedPaths = []; + $components = []; foreach ($paths as $path) { if (!is_dir($path)) { - if (file_exists($path) && substr($path, - strlen($ext)) == $ext) { + if (file_exists($path) && str_ends_with((string) $path, $ext)) { $components[] = $path; } continue; @@ -42,10 +40,6 @@ public function findComponentsInPaths(array $paths, string $ext): array /** * Removes all items from the provided array of component paths * that match the provided ignore list - * - * @param array $components - * @param array $ignoreList - * @return array */ public function removeComponentsFromIgnoreList(array $components, array $ignoreList): array { @@ -53,7 +47,7 @@ public function removeComponentsFromIgnoreList(array $components, array $ignoreL return $components; } - $ignorePattern = $this->buildPattern($ignoreList); + $ignorePattern = static::buildPattern($ignoreList); if (!$ignorePattern) { throw new \Exception(sprintf( 'Invalid ignore pattern provided: %s', @@ -61,17 +55,11 @@ public function removeComponentsFromIgnoreList(array $components, array $ignoreL ), 1601484307); } - return array_filter($components, function ($path) use ($ignorePattern) { - return !preg_match($ignorePattern, $path); - }); + return array_filter($components, fn($path) => !preg_match($ignorePattern, (string) $path)); } /** * Searches recursively for component files in a directory - * - * @param string $path - * @param string $ext - * @return array */ protected function scanForComponents(string $path, string $ext): array { diff --git a/src/Classes/Service/FluidService.php b/src/Classes/Service/FluidService.php index 0ced9df..a9d38ad 100644 --- a/src/Classes/Service/FluidService.php +++ b/src/Classes/Service/FluidService.php @@ -48,14 +48,14 @@ public function generateNodeExceptionPreview(NodeInterface $node): string if ($uninitializedViewHelper instanceof IntrospectionViewHelper) { return $uninitializedViewHelper->getViewhelperTag(); } else { - return get_class($uninitializedViewHelper); + return $uninitializedViewHelper::class; } } elseif ($node instanceof TextNode) { return trim($node->getText()); } elseif ($node instanceof ObjectAccessorNode) { return '{' . $node->getObjectPath() . '}'; } else { - return get_class($node); + return $node::class; } } diff --git a/src/Classes/ViewHelpers/ComponentViewHelper.php b/src/Classes/ViewHelpers/ComponentViewHelper.php index 01398ff..0fbabf2 100644 --- a/src/Classes/ViewHelpers/ComponentViewHelper.php +++ b/src/Classes/ViewHelpers/ComponentViewHelper.php @@ -9,7 +9,7 @@ class ComponentViewHelper extends AbstractViewHelper { - public function initializeArguments() + public function initializeArguments(): void { $this->registerArgument('description', 'string', 'Description of the component'); } diff --git a/src/Classes/ViewHelpers/IntrospectionViewHelper.php b/src/Classes/ViewHelpers/IntrospectionViewHelper.php index 2092f28..268cfd7 100644 --- a/src/Classes/ViewHelpers/IntrospectionViewHelper.php +++ b/src/Classes/ViewHelpers/IntrospectionViewHelper.php @@ -30,7 +30,7 @@ public function getViewhelperTagName(): string return sprintf('%s:%s', $this->namespaceIdentifier, $this->methodIdentifier); } - public function validateAdditionalArguments(array $arguments) + public function validateAdditionalArguments(array $arguments): void { // Allow all arguments } diff --git a/src/Classes/ViewHelpers/ParamViewHelper.php b/src/Classes/ViewHelpers/ParamViewHelper.php index ba62216..c157894 100644 --- a/src/Classes/ViewHelpers/ParamViewHelper.php +++ b/src/Classes/ViewHelpers/ParamViewHelper.php @@ -10,7 +10,7 @@ class ParamViewHelper extends AbstractViewHelper { - public function initializeArguments() + public function initializeArguments(): void { $this->registerArgument('name', 'string', 'Parameter name', true); $this->registerArgument('type', 'string', 'Parameter type', true); diff --git a/src/FcLint.php b/src/FcLint.php index 8ab1c6d..c42ff77 100644 --- a/src/FcLint.php +++ b/src/FcLint.php @@ -9,7 +9,7 @@ $autoloadLocations = [ $GLOBALS['_composer_autoload_path'] ?? null, dirname(__DIR__) . '/vendor/autoload.php', - dirname(dirname(dirname(__DIR__))) . '/autoload.php' + dirname(__DIR__, 3) . '/autoload.php' ]; $autoloadLocations = array_filter(array_filter($autoloadLocations), 'file_exists'); From 2e56d977e1b37cf21d89b0440ab15a8041899b12 Mon Sep 17 00:00:00 2001 From: Ulrich Mathes Date: Mon, 30 Sep 2024 14:01:54 +0200 Subject: [PATCH 6/6] allow fluid v4 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 4f0d1d4..b588879 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "php": ">=8.2.0", "symfony/config": "^5.0 || ^6.0 || ^7.0", "symfony/console": "^5.0 || ^6.0 || ^7.0", - "typo3fluid/fluid": "^2.6" + "typo3fluid/fluid": "^4.0 || ^2.6" }, "require-dev": { "editorconfig-checker/editorconfig-checker": "^10.0",