diff --git a/.gitignore b/.gitignore index 5b407a0..68b52d3 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ !/web/*/custom/** !/_lessons/** +!/phpstan.neon +!/tests/** diff --git a/build.yaml b/build.yaml index 23ef6c0..032fa9f 100644 --- a/build.yaml +++ b/build.yaml @@ -11,6 +11,8 @@ flake: git: ignore: - '!/_lessons/**' + - '!/phpstan.neon' + - '!/tests/**' experimental: createTmuxStartupFile: true diff --git a/composer.json b/composer.json index ff80648..d51cbaf 100644 --- a/composer.json +++ b/composer.json @@ -98,6 +98,12 @@ "brianium/paratest": "^6.11", "dealerdirect/phpcodesniffer-composer-installer": "^1.0", "drupal/coder": "^8.3", - "drupal/core-dev": "^10.2" + "drupal/core-dev": "^10.2", + "phpat/phpat": "^0.10.13" + }, + "autoload": { + "psr-4": { + "Tests\\Architecture\\": "tests/Architecture" + } } } diff --git a/composer.lock b/composer.lock index 922abde..6f00ac5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bb0170d2be16b500e494326ee69377a3", + "content-hash": "50098baf2c6068540532ef1fe95aa155", "packages": [ { "name": "asm89/stack-cors", @@ -8594,6 +8594,63 @@ }, "time": "2023-11-08T12:57:08+00:00" }, + { + "name": "phpat/phpat", + "version": "0.10.13", + "source": { + "type": "git", + "url": "https://github.com/carlosas/phpat.git", + "reference": "4954eebf9b456837720b07486d29828461ed24fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/carlosas/phpat/zipball/4954eebf9b456837720b07486d29828461ed24fc", + "reference": "4954eebf9b456837720b07486d29828461ed24fc", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^1.3" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "kubawerlos/php-cs-fixer-custom-fixers": "^3.16", + "phpunit/phpunit": "^9.0", + "vimeo/psalm": "^4.0 || ^5.0" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "files": [ + "helpers.php" + ], + "psr-4": { + "PHPat\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Carlos Alandete Sastre", + "email": "carlos.alandete@gmail.com" + } + ], + "description": "PHP Architecture Tester", + "support": { + "issues": "https://github.com/carlosas/phpat/issues", + "source": "https://github.com/carlosas/phpat/tree/0.10.13" + }, + "time": "2024-01-04T17:18:43+00:00" + }, { "name": "phpdocumentor/reflection-common", "version": "2.2.0", diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..379a188 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,10 @@ +parameters: + level: 5 + paths: + - web/modules/custom + +services: + - + class: Tests\Architecture\ArchTest + tags: + - phpat.test diff --git a/tests/Architecture/ArchTest.php b/tests/Architecture/ArchTest.php new file mode 100644 index 0000000..cfdd9d2 --- /dev/null +++ b/tests/Architecture/ArchTest.php @@ -0,0 +1,34 @@ +classes(Selector::inNamespace('Drupal\atdc')) + ->shouldBeFinal(); + } + + public function test_controllers_should_extend_ControllerBase(): Rule { + return PHPat::rule() + ->classes(Selector::inNamespace('Drupal\atdc\Controller')) + ->shouldExtend() + ->classes(Selector::classname(ControllerBase::class)); + } + + public function test_controllers_should_have_the_Controller_suffix(): Rule { + return PHPat::rule() + ->classes(Selector::inNamespace('Drupal\atdc\Controller')) + ->shouldBeNamed( + classname: '/Controller$/', + regex: TRUE, + ); + } + +} diff --git a/web/modules/custom/atdc/src/Controller/BlogPageController.php b/web/modules/custom/atdc/src/Controller/BlogPageController.php index fb1e3fe..1d4978d 100644 --- a/web/modules/custom/atdc/src/Controller/BlogPageController.php +++ b/web/modules/custom/atdc/src/Controller/BlogPageController.php @@ -6,7 +6,7 @@ use Drupal\atdc\Repository\PostNodeRepository; use Drupal\Core\Controller\ControllerBase; use Symfony\Component\DependencyInjection\ContainerInterface; -class BlogPageController extends ControllerBase { +final class BlogPageController extends ControllerBase { public function __construct( private PostNodeRepository $postNodeRepository,