diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 87a68b3..9e3e566 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,21 +20,18 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '7.4' + php-version: '8.0' coverage: pcov - name: Cache dependencies uses: actions/cache@v1 with: path: ~/.composer/cache/files - key: dependencies-composer-${{ hashFiles('composer.json') }}-v1 + key: dependencies-composer-${{ hashFiles('composer.json') }}-v3 - name: Install dependencies run: composer install --no-suggest --no-interaction --verbose - - name: Install linting tools - run: composer bin linting install --no-suggest --no-interaction --verbose - - name: Check platform requirements run: composer check-platform-reqs --verbose @@ -119,11 +116,11 @@ jobs: uses: actions/cache@v1 with: path: ~/.composer/cache/files - key: dependencies-${{ matrix.dependency-version }}-laravel-${{ matrix.laravel }}-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}-v1 + key: dependencies-${{ matrix.dependency-version }}-laravel-${{ matrix.laravel }}-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}-v3 - name: Install dependencies run: | - composer remove 'phpunit/phpunit' 'ergebnis/composer-normalize' 'orchestra/testbench' 'infection/infection' --dev --no-update --no-interaction --verbose + composer remove 'infection/infection' 'phpunit/phpunit' 'ergebnis/composer-normalize' 'orchestra/testbench' 'orchestra/testbench' 'phpstan/phpstan' 'phpunit/phpunit' 'timacdonald/php-style' 'vimeo/psalm' --dev --no-update --no-interaction --verbose composer require 'illuminate/support:${{ matrix.laravel }}' 'orchestra/testbench:${{ matrix.testbench }}' --no-update --no-interaction --verbose composer update --${{ matrix.dependency-version }} --no-suggest --no-interaction --verbose diff --git a/.gitignore b/.gitignore index 31e5c13..417d292 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ -vendor/ -composer.lock +/vendor +/composer.lock /.phpunit.result.cache /.php_cs.cache /coverage diff --git a/composer.json b/composer.json index 79b61ad..0009490 100644 --- a/composer.json +++ b/composer.json @@ -16,15 +16,17 @@ } ], "require": { - "php": ">=7.1", + "php": "^7.1 || ^8.0", "illuminate/support": "~5.5.0 || ~5.6.0 || ~5.7.0 || ~5.8.0 || ^6.0 || ^7.0 || ^8.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", "ergebnis/composer-normalize": "^2.0", - "infection/infection": "^0.16", + "infection/infection": "^0.21", "orchestra/testbench": "^6.0", - "phpunit/phpunit": "^9.0" + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^9.0", + "timacdonald/php-style": "dev-master", + "vimeo/psalm": "^4.0" }, "config": { "preferred-install": "dist", @@ -45,13 +47,11 @@ "scripts": { "fix": [ "clear", - "@composer bin linting install", "@composer normalize", "./vendor/bin/php-cs-fixer fix" ], "lint": [ "clear", - "@composer bin linting install", "@composer normalize --dry-run", "./vendor/bin/php-cs-fixer fix --dry-run", "./vendor/bin/psalm --threads=8", diff --git a/phpstan.neon b/phpstan.neon index cddc7d2..2904568 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -4,4 +4,5 @@ parameters: paths: - src - tests - ignoreErrors: + excludePaths: + - tests/Middleware/OptionalRequired.php diff --git a/src/HasParameters.php b/src/HasParameters.php index f5c3420..6ffd9db 100644 --- a/src/HasParameters.php +++ b/src/HasParameters.php @@ -4,10 +4,8 @@ namespace TiMacDonald\Middleware; -use function assert; use Illuminate\Support\Arr; use Illuminate\Support\Collection; -use function is_string; use ReflectionMethod; use ReflectionParameter; use TypeError; @@ -159,6 +157,7 @@ private static function validateArgumentMap(Collection $parameters, Collection $ private static function validateParametersAreOptional(Collection $parameters): void { + /** @var ?ReflectionParameter */ $missingRequiredParameter = $parameters->reject(static function (ReflectionParameter $parameter): bool { return $parameter->isDefaultValueAvailable() || $parameter->isVariadic(); }) @@ -168,8 +167,6 @@ private static function validateParametersAreOptional(Collection $parameters): v return; } - assert($missingRequiredParameter instanceof ReflectionParameter); - throw new TypeError('Missing required argument $'.$missingRequiredParameter->getName().' for middleware '.static::class.'::handle()'); } @@ -189,6 +186,7 @@ private static function validateArgumentMapIsAnAssociativeArray(Collection $argu private static function validateNoUnexpectedArguments(Collection $parameters, Collection $arguments): void { + /** @var ?string */ $unexpectedArgument = $arguments->keys() ->first(static function (string $name) use ($parameters): bool { return ! $parameters->has($name); @@ -198,8 +196,6 @@ private static function validateNoUnexpectedArguments(Collection $parameters, Co return; } - assert(is_string($unexpectedArgument)); - throw new TypeError('Unknown argument $'.$unexpectedArgument.' passed to middleware '.static::class.'::handle()'); } } diff --git a/tests/HasParametersTest.php b/tests/HasParametersTest.php index fc56ffa..d24b729 100644 --- a/tests/HasParametersTest.php +++ b/tests/HasParametersTest.php @@ -77,17 +77,26 @@ public function testListDoesNotAcceptSubArray(): void Basic::in(['laravel', ['vue', 'react']]); } - public function testListDetectsRequiredParametersThatHaveNotBeenProvided(): void + public function testListDetectsRequiredParametersThatHaveNotBeenProvidedAfterAnOptional(): void { if (PHP_MAJOR_VERSION >= 8) { $this->markTestSkipped('Cannot have optional parameter before required parameter in PHP >=8.0.'); } + $this->expectException(TypeError::class); $this->expectExceptionMessage('Missing required argument $required for middleware Tests\\Middleware\\OptionalRequired::handle()'); OptionalRequired::in(['laravel']); } + public function testListDetectsRequiredParametersThatHaveNotBeenProvided(): void + { + $this->expectException(TypeError::class); + $this->expectExceptionMessage('Missing required argument $required for middleware Tests\\Middleware\\Required::handle()'); + + Required::in([]); + } + public function testListDoesNotAcceptAssociativeArray(): void { $this->expectException(TypeError::class); @@ -185,7 +194,7 @@ public function testMap(): void $result = Variadic::with(['variadic' => false]); $this->assertSame('Tests\\Middleware\\Variadic:0', $result); - // Required parameters after optional parameters are no longer allowed as of PHP 8.0. + // Cannot have optional parameter before required parameter in PHP >=8.0. if (PHP_MAJOR_VERSION < 8) { $result = OptionalRequired::with(['required' => 'laravel']); $this->assertSame('Tests\\Middleware\\OptionalRequired:default,laravel', $result); diff --git a/tests/Middleware/OptionalRequired.php b/tests/Middleware/OptionalRequired.php index 21be7ac..d973914 100644 --- a/tests/Middleware/OptionalRequired.php +++ b/tests/Middleware/OptionalRequired.php @@ -6,14 +6,18 @@ use Closure; use Illuminate\Http\Request; +use const PHP_MAJOR_VERSION; use TiMacDonald\Middleware\HasParameters; -class OptionalRequired -{ - use HasParameters; - - public function handle(Request $request, Closure $next, string $optional = 'default', string $required): void +// Cannot have optional parameter before required parameter in PHP >=8.0. +if (PHP_MAJOR_VERSION < 8) { + class OptionalRequired { - // + use HasParameters; + + public function handle(Request $request, Closure $next, string $optional = 'default', string $required): void + { + // + } } } diff --git a/vendor-bin/linting/composer.json b/vendor-bin/linting/composer.json deleted file mode 100644 index c537f5c..0000000 --- a/vendor-bin/linting/composer.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "require": { - "timacdonald/php-style": "dev-master", - "vimeo/psalm": "^4.0", - "phpstan/phpstan": "^0.12.42" - } -}