diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml new file mode 100644 index 0000000..03d62cb --- /dev/null +++ b/.github/workflows/static-analysis.yml @@ -0,0 +1,50 @@ +on: + - push + +name: Run PHPStan checks + +jobs: + mutation: + name: PHPStan ${{ matrix.php }}-${{ matrix.os }} + + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: + - ubuntu-latest + + php: + - "8.1" + - "8.2" + - "8.3" + - "8.4" + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php }}" + coverage: pcov + ini-values: assert.exception=1, zend.assertions=1, error_reporting=-1, log_errors_max_len=0, display_errors=On + tools: composer:v2, cs2pr + + - name: Determine composer cache directory + run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV + + - name: Cache dependencies installed with composer + uses: actions/cache@v4 + with: + path: ${{ env.COMPOSER_CACHE_DIR }} + key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: | + php${{ matrix.php }}-composer- + + - name: Install dependencies with composer + run: composer install --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + + - name: Run static analysis with PHPStan + run: vendor/bin/phpstan analyse diff --git a/README.md b/README.md index f35dbc4..e708948 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,14 @@ This is Dotkernel's controller package that can be use like middleware inside Do It provides base classes for action based controllers similar to Laminas controller component. It is more lightweight though, but supports controller plugins and event listeners. +## Documentation + +Documentation is available at: https://docs.dotkernel.org/dot-controller/. + +## Badges + ![OSS Lifecycle](https://img.shields.io/osslifecycle/dotkernel/dot-controller) -![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-controller/4.0.1) +![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-controller/4.1.0) [![GitHub issues](https://img.shields.io/github/issues/dotkernel/dot-controller)](https://github.com/dotkernel/dot-controller/issues) [![GitHub forks](https://img.shields.io/github/forks/dotkernel/dot-controller)](https://github.com/dotkernel/dot-controller/network) @@ -14,6 +20,7 @@ It is more lightweight though, but supports controller plugins and event listene [![Build Static](https://github.com/dotkernel/dot-controller/actions/workflows/continuous-integration.yml/badge.svg?branch=4.0)](https://github.com/dotkernel/dot-controller/actions/workflows/continuous-integration.yml) [![codecov](https://codecov.io/gh/dotkernel/dot-controller/graph/badge.svg?token=VUBG5LM4CK)](https://codecov.io/gh/dotkernel/dot-controller) +[![PHPStan](https://github.com/dotkernel/dot-controller/actions/workflows/static-analysis.yml/badge.svg?branch=4.0)](https://github.com/dotkernel/dot-controller/actions/workflows/static-analysis.yml) ## Installation diff --git a/composer.json b/composer.json index 7182060..0f3796c 100644 --- a/composer.json +++ b/composer.json @@ -28,8 +28,9 @@ "require-dev": { "laminas/laminas-coding-standard": "^3.0", "laminas/laminas-diactoros": "^3.0", - "phpunit/phpunit": "^10.2", - "vimeo/psalm": "^6.0" + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.2" }, "autoload": { "psr-4": { @@ -50,8 +51,7 @@ "cs-check": "phpcs", "cs-fix": "phpcbf", "test": "phpunit --colors=always", - "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", - "static-analysis": "psalm --shepherd --stats" + "static-analysis": "phpstan analyse --memory-limit 1G" }, "config": { "sort-packages": true, diff --git a/docs/book/v4/overview.md b/docs/book/v4/overview.md index be4e4b6..f44077b 100644 --- a/docs/book/v4/overview.md +++ b/docs/book/v4/overview.md @@ -3,3 +3,17 @@ `dot-controller` is Dotkernel's controller package that can be use like middleware inside Dotkernel or Mezzio application. It provides base classes for action based controllers similar to Laminas controller component. It is more lightweight though, but supports controller plugins and event listeners. + +## Badges + +![OSS Lifecycle](https://img.shields.io/osslifecycle/dotkernel/dot-controller) +![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-controller/4.1.0) + +[![GitHub issues](https://img.shields.io/github/issues/dotkernel/dot-controller)](https://github.com/dotkernel/dot-controller/issues) +[![GitHub forks](https://img.shields.io/github/forks/dotkernel/dot-controller)](https://github.com/dotkernel/dot-controller/network) +[![GitHub stars](https://img.shields.io/github/stars/dotkernel/dot-controller)](https://github.com/dotkernel/dot-controller/stargazers) +[![GitHub license](https://img.shields.io/github/license/dotkernel/dot-controller)](https://github.com/dotkernel/dot-controller/blob/4.0/LICENSE.md) + +[![Build Static](https://github.com/dotkernel/dot-controller/actions/workflows/continuous-integration.yml/badge.svg?branch=4.0)](https://github.com/dotkernel/dot-controller/actions/workflows/continuous-integration.yml) +[![codecov](https://codecov.io/gh/dotkernel/dot-controller/graph/badge.svg?token=VUBG5LM4CK)](https://codecov.io/gh/dotkernel/dot-controller) +[![PHPStan](https://github.com/dotkernel/dot-controller/actions/workflows/static-analysis.yml/badge.svg?branch=4.0)](https://github.com/dotkernel/dot-controller/actions/workflows/static-analysis.yml) diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..8a8b704 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,13 @@ +includes: + - vendor/phpstan/phpstan-phpunit/extension.neon +parameters: + level: 5 + paths: + - src + - test + treatPhpDocTypesAsCertain: false + ignoreErrors: + - message: '#Call to an undefined method .*::somePlugin\(\)\.#' + path: test/AbstractControllerTest.php + - message: '#Call to an undefined method .*::callablePlugin\(\)\.#' + path: test/AbstractControllerTest.php diff --git a/psalm.xml b/psalm.xml deleted file mode 100644 index 7272b57..0000000 --- a/psalm.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - diff --git a/test/AbstractActionControllerTest.php b/test/AbstractActionControllerTest.php index 4f54ac7..831e888 100644 --- a/test/AbstractActionControllerTest.php +++ b/test/AbstractActionControllerTest.php @@ -28,7 +28,7 @@ public function testNonExistingActionWillReturnResponse(): void }; $response = $subject->process($request, $handler); - $this->assertInstanceOf(ResponseInterface::class, $response); + $this->assertContainsOnlyInstancesOf(ResponseInterface::class, [$response]); } /** @@ -49,6 +49,6 @@ public function indexAction(): ResponseInterface }; $response = $subject->process($request, $handler); - $this->assertInstanceOf(ResponseInterface::class, $response); + $this->assertContainsOnlyInstancesOf(ResponseInterface::class, [$response]); } } diff --git a/test/Factory/ControllerEventListenersInitializerTest.php b/test/Factory/ControllerEventListenersInitializerTest.php index 26ed7e5..62c5302 100644 --- a/test/Factory/ControllerEventListenersInitializerTest.php +++ b/test/Factory/ControllerEventListenersInitializerTest.php @@ -73,7 +73,5 @@ public function testAttachControllerListeners(): void ->with($this->isInstanceOf(ControllerEventListenerInterface::class), 1); $this->subject->attachControllerListeners($this->container, $this->controller); - - $this->assertTrue(true); } } diff --git a/test/Factory/PluginManagerFactoryTest.php b/test/Factory/PluginManagerFactoryTest.php index ef4f3b1..1d3c2b1 100644 --- a/test/Factory/PluginManagerFactoryTest.php +++ b/test/Factory/PluginManagerFactoryTest.php @@ -60,7 +60,7 @@ public function testInvokeWithUrlHelper(): void $pluginManager = $this->subject->__invoke($this->container); - $this->assertInstanceOf(PluginManager::class, $pluginManager); + $this->assertContainsOnlyInstancesOf(PluginManager::class, [$pluginManager]); $this->assertTrue($pluginManager->has('url')); $this->assertFalse($pluginManager->has('template')); $this->assertInstanceOf(UrlHelperPlugin::class, $pluginManager->get('url')); @@ -91,7 +91,7 @@ public function testInvokeWithTemplateRenderer(): void $pluginManager = $this->subject->__invoke($this->container); - $this->assertInstanceOf(PluginManager::class, $pluginManager); + $this->assertContainsOnlyInstancesOf(PluginManager::class, [$pluginManager]); $this->assertTrue($pluginManager->has('template')); $this->assertFalse($pluginManager->has('url')); $this->assertInstanceOf(TemplatePlugin::class, $pluginManager->get('template'));