Skip to content

Commit

Permalink
Add static analysis with PHPStan
Browse files Browse the repository at this point in the history
  • Loading branch information
canvural authored and scaytrase committed Dec 18, 2020
1 parent adc58e9 commit aab6881
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 18 deletions.
28 changes: 26 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ on: [push, pull_request]

jobs:

build:
name: Build
tests:
name: Tests
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
strategy:
Expand Down Expand Up @@ -68,3 +68,27 @@ jobs:

- name: Run tests
run: ./vendor/bin/phpcs

static-analysis:
name: Static analysis
runs-on: ubuntu-latest

strategy:
matrix:
php:
- '7.2'

steps:
- name: Set up PHP
uses: shivammathur/[email protected]
with:
php-version: ${{ matrix.php }}

- name: Checkout code
uses: actions/checkout@v2

- name: Download dependencies
run: composer update --no-interaction --prefer-dist --optimize-autoloader --prefer-stable

- name: Run PHPStan
run: ./vendor/bin/phpstan analyse --memory-limit 512M
4 changes: 4 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
"require-dev": {
"doctrine/coding-standard": "^8.0",
"guzzlehttp/psr7": "^1.5",
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "^0.12.59",
"phpstan/phpstan-phpunit": "^0.12.16",
"phpstan/phpstan-webmozart-assert": "^0.12.7",
"phpunit/phpunit": "^7|^8|^9",
"symfony/cache": "^5.1"
},
Expand Down
77 changes: 77 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
parameters:
ignoreErrors:
-
message: "#^Parameter \\#4 \\$prev of static method League\\\\OpenAPIValidation\\\\PSR7\\\\Exception\\\\Validation\\\\InvalidCookies\\:\\:becauseValueDoesNotMatchSchema\\(\\) expects League\\\\OpenAPIValidation\\\\Schema\\\\Exception\\\\SchemaMismatch, Throwable\\|null given\\.$#"
count: 1
path: src/PSR7/Validators/CookiesValidator/ServerRequestCookieValidator.php

-
message: "#^Parameter \\#1 \\$openApiSpec of class League\\\\OpenAPIValidation\\\\PSR7\\\\PathFinder constructor expects cebe\\\\openapi\\\\spec\\\\OpenApi, cebe\\\\openapi\\\\SpecObjectInterface given\\.$#"
count: 2
path: tests/FromCommunity/Issue79Test.php

-
message: "#^Generator expects value type string, array\\<int, string\\> given\\.$#"
count: 7
path: tests/FromCommunity/Issue79Test.php

-
message: "#^Parameter \\#1 \\$openApiSpec of class League\\\\OpenAPIValidation\\\\PSR7\\\\PathFinder constructor expects cebe\\\\openapi\\\\spec\\\\OpenApi, cebe\\\\openapi\\\\SpecObjectInterface given\\.$#"
count: 4
path: tests/PSR7/PathFinderTest.php

-
message: "#^Method League\\\\OpenAPIValidation\\\\Tests\\\\PSR7\\\\Validators\\\\BodyValidator\\\\MultipartValidatorTest\\:\\:dataProviderMultipartRed\\(\\) should return array\\<array\\<string, string\\>\\> but returns array\\<int, array\\<int, string\\>\\>\\.$#"
count: 1
path: tests/PSR7/Validators/BodyValidator/MultipartValidatorTest.php

-
message: "#^Method League\\\\OpenAPIValidation\\\\Tests\\\\PSR7\\\\Validators\\\\BodyValidatorTest\\:\\:dataProviderGreen\\(\\) should return array\\<array\\<string, string\\>\\> but returns array\\<int, array\\<int, League\\\\OpenAPIValidation\\\\PSR7\\\\OperationAddress\\|string\\>\\>\\.$#"
count: 1
path: tests/PSR7/Validators/BodyValidatorTest.php

-
message: "#^Method League\\\\OpenAPIValidation\\\\Tests\\\\PSR7\\\\Validators\\\\BodyValidatorTest\\:\\:dataProviderRed\\(\\) should return array\\<array\\<string, string\\>\\> but returns array\\<int, array\\<int, string\\>\\>\\.$#"
count: 1
path: tests/PSR7/Validators/BodyValidatorTest.php

-
message: "#^Method League\\\\OpenAPIValidation\\\\Tests\\\\Schema\\\\Keywords\\\\PatternTest\\:\\:validDataProvider\\(\\) should return array\\<array\\<string, string\\>\\> but returns array\\<int, array\\<int, string\\>\\>\\.$#"
count: 1
path: tests/Schema/Keywords/PatternTest.php

-
message: "#^Method League\\\\OpenAPIValidation\\\\Tests\\\\Schema\\\\Keywords\\\\TypeTest\\:\\:validDataProvider\\(\\) should return array\\<array\\<string, mixed\\>\\> but returns array\\<int, array\\<int, array\\<int\\|string, int\\|string\\>\\|bool\\|float\\|int\\|string\\|null\\>\\>\\.$#"
count: 1
path: tests/Schema/Keywords/TypeTest.php

-
message: "#^Method League\\\\OpenAPIValidation\\\\Tests\\\\Schema\\\\Keywords\\\\TypeTest\\:\\:invalidDataProvider\\(\\) should return array\\<array\\<string, mixed\\>\\> but returns array\\<int, array\\<int, array\\<int\\|string, int\\>\\|float\\|int\\|stdClass\\|string\\>\\>\\.$#"
count: 1
path: tests/Schema/Keywords/TypeTest.php

-
message: "#^Method League\\\\OpenAPIValidation\\\\Tests\\\\Schema\\\\Keywords\\\\UniqueItemsTest\\:\\:dataProviderGreen\\(\\) should return array\\<array\\<string, array\\>\\> but returns array\\<int, array\\<int, array\\<int, array\\<int\\|string, array\\<string, int\\>\\|int\\>\\|bool\\|float\\|int\\|string\\>\\|string\\>\\>\\.$#"
count: 1
path: tests/Schema/Keywords/UniqueItemsTest.php

-
message: "#^Method League\\\\OpenAPIValidation\\\\Tests\\\\Schema\\\\Keywords\\\\UniqueItemsTest\\:\\:dataProviderRed\\(\\) should return array\\<array\\<string, array\\>\\> but returns array\\<int, array\\<int, array\\<int, array\\<int\\|string, array\\<string, int\\>\\|int\\>\\|bool\\|int\\|string\\>\\|string\\>\\>\\.$#"
count: 1
path: tests/Schema/Keywords/UniqueItemsTest.php

-
message: "#^Access to an undefined property cebe\\\\openapi\\\\SpecObjectInterface\\:\\:\\$schema\\.$#"
count: 2
path: tests/Schema/SchemaValidatorTest.php

-
message: "#^Method League\\\\OpenAPIValidation\\\\Tests\\\\Schema\\\\TypeFormats\\\\StringDateTimeTest\\:\\:dateTimeGreenDataProvider\\(\\) should return array\\<string\\> but returns array\\<int, array\\<int, string\\>\\>\\.$#"
count: 1
path: tests/Schema/TypeFormats/StringDateTimeTest.php

-
message: "#^Method League\\\\OpenAPIValidation\\\\Tests\\\\Schema\\\\TypeFormats\\\\StringDateTimeTest\\:\\:dateTimeRedDataProvider\\(\\) should return array\\<string\\> but returns array\\<int, array\\<int, string\\>\\>\\.$#"
count: 1
path: tests/Schema/TypeFormats/StringDateTimeTest.php

11 changes: 11 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
includes:
- phpstan-baseline.neon
parameters:
level: 6
paths:
- src
- tests
treatPhpDocTypesAsCertain: false
ignoreErrors:
- '#Unsafe usage of new static\(\)\.#'
- '#Method [a-zA-Z0-9_\\]+::[a-zA-Z0-9_]+\(\) should return cebe\\openapi\\spec\\OpenApi but returns cebe\\openapi\\SpecObjectInterface\.#'
1 change: 1 addition & 0 deletions src/PSR7/SchemaFactory/JsonFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ final class JsonFactory extends StringFactory
{
public function createSchema(): OpenApi
{
/** @var OpenApi $schema */
$schema = Reader::readFromJson($this->getContent());

$schema->resolveReferences(new ReferenceContext($schema, '/'));
Expand Down
8 changes: 5 additions & 3 deletions src/PSR7/SpecFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use cebe\openapi\exceptions\TypeErrorException;
use cebe\openapi\spec\Callback;
use cebe\openapi\spec\Header;
use cebe\openapi\spec\Header as HeaderSpec;
use cebe\openapi\spec\MediaType;
use cebe\openapi\spec\OpenApi;
Expand Down Expand Up @@ -210,7 +209,7 @@ public function findResponseSpec($addr): ResponseSpec

$operation = $this->findOperationSpec($addr);

$response = $operation->responses->getResponse($addr->responseCode());
$response = $operation->responses->getResponse((string) $addr->responseCode());

if (! $response) {
$response = $operation->responses->getResponse('default');
Expand All @@ -228,7 +227,7 @@ public function findResponseSpec($addr): ResponseSpec
}

/**
* @return Header[]
* @return array<string, HeaderSpec|Parameter>
*
* @throws NoPath
*/
Expand All @@ -244,7 +243,9 @@ public function findHeaderSpecs(OperationAddress $addr): array
// 1. Collect operation level headers from "parameters" keyword
// An API call may require that custom headers be sent with an HTTP request. OpenAPI lets you define custom
// request headers as in: header parameters.
/** @var array<string, HeaderSpec|Parameter> $headerSpecs */
$headerSpecs = [];

foreach ($spec->parameters as $p) {
if ($p->in !== 'header') {
continue;
Expand All @@ -262,6 +263,7 @@ public function findHeaderSpecs(OperationAddress $addr): array
// 2. Collect path-level headers from "parameters" keyword
// Path level params are fall-backs
$pathSpec = $this->findPathSpec($addr);

foreach ($pathSpec->parameters as $p) {
if ($p->in !== 'header') {
continue;
Expand Down
5 changes: 1 addition & 4 deletions src/PSR7/Validators/BodyValidator/MultipartValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,6 @@ public function validate(OperationAddress $addr, MessageInterface $message): voi
}
}

/**
* @param MediaType[] $mediaTypeSpecs
*/
private function validatePlainBodyMultipart(
OperationAddress $addr,
MessageInterface $message,
Expand Down Expand Up @@ -198,7 +195,7 @@ private function parseMultipartData(OperationAddress $addr, StreamedPart $docume
return $multipartData;
}

private function detectEncondingContentType(Encoding $encoding, StreamedPart $part, Schema $partSchema): ?string
private function detectEncondingContentType(Encoding $encoding, StreamedPart $part, Schema $partSchema): string
{
$contentType = $encoding->contentType;

Expand Down
9 changes: 5 additions & 4 deletions src/PSR7/Validators/SecurityValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use League\OpenAPIValidation\Schema\Exception\InvalidSchema;
use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ServerRequestInterface;

use function count;
use function preg_match;
Expand Down Expand Up @@ -45,7 +46,7 @@ public function validate(OperationAddress $addr, MessageInterface $message): voi
// Security schemes combined via OR are alternatives – any one can be used in the given context.
// Security schemes combined via AND must be used simultaneously in the same request.
// @see https://swagger.io/docs/specification/authentication/
if (! ($message instanceof RequestInterface)) {
if (! ($message instanceof ServerRequestInterface)) {
return;
}

Expand All @@ -55,7 +56,7 @@ public function validate(OperationAddress $addr, MessageInterface $message): voi
/**
* @throws ValidationFailed
*/
private function validateServerRequest(OperationAddress $addr, RequestInterface $request): void
private function validateServerRequest(OperationAddress $addr, ServerRequestInterface $request): void
{
$securitySpecs = $this->finder->findSecuritySpecs($addr);

Expand Down Expand Up @@ -84,7 +85,7 @@ private function validateServerRequest(OperationAddress $addr, RequestInterface
*/
private function validateSecurityScheme(
OperationAddress $addr,
RequestInterface $request,
ServerRequestInterface $request,
SecurityRequirement $spec
): void {
// Here I implement AND-union
Expand Down Expand Up @@ -162,7 +163,7 @@ private function validateHTTPSecurityScheme(
*/
private function validateApiKeySecurityScheme(
OperationAddress $addr,
RequestInterface $request,
ServerRequestInterface $request,
SecurityScheme $securityScheme
): void {
switch ($securityScheme->in) {
Expand Down
6 changes: 3 additions & 3 deletions src/Schema/BreadCrumb.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@
// It can address an index in the compound array(object)
class BreadCrumb
{
/** @var string */
/** @var string|null */
protected $compoundIndex;
/** @var self link to a previous crumb */
/** @var self|null link to a previous crumb */
protected $prevCrumb;

/**
* @param int|string|null $compoundIndex suitable for array index
*/
public function __construct($compoundIndex = null)
{
if (! is_scalar($compoundIndex) && ($compoundIndex !== null)) {
if (($compoundIndex !== null) && ! is_scalar($compoundIndex)) {
throw new RuntimeException(sprintf('BreadCrumb cannot have non-scalar index: %s', $compoundIndex));
}

Expand Down
2 changes: 0 additions & 2 deletions tests/PSR7/OperationAddressTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ public function dataProviderParseRed(): array
}

/**
* @param mixed[] $result
*
* @dataProvider dataProviderParseRed
*/
public function testItThrowsIfParsingNotPossible(string $spec, string $url): void
Expand Down

0 comments on commit aab6881

Please sign in to comment.