From c265658370696f4953402433b9134167e33c35f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20B=C3=BCttner?= Date: Fri, 14 Aug 2020 15:28:23 +0200 Subject: [PATCH] updating tools (#10) --- .phan/config.php | 78 +++++++++++++ .travis.yml | 107 +++++------------- composer.json | 5 +- install-phalcon.sh | 21 +++- phpstan.neon.dist | 10 -- src/Implementations/Controller.php | 17 ++- src/Implementations/DefaultResponse.php | 16 ++- .../NoValueConversionMerger.php | 17 ++- src/Implementations/PhalconPath2PathArray.php | 31 +++-- src/Implementations/Reflector.php | 95 +++++++++++----- src/Interfaces/Controller.php | 15 ++- src/Interfaces/Path2PathConverter.php | 12 +- .../PathTargetAnnotationResolver.php | 9 +- src/Interfaces/RecursiveMerger.php | 11 +- src/ServiceProvider.php | 74 ++++++++---- test/ControllerTest.php | 58 +++------- test/NoValueConversionMergerTest.php | 20 +--- test/Path2PathTest.php | 2 +- test/ReflectorTest.php | 2 +- 19 files changed, 358 insertions(+), 242 deletions(-) create mode 100644 .phan/config.php delete mode 100644 phpstan.neon.dist diff --git a/.phan/config.php b/.phan/config.php new file mode 100644 index 0000000..f044798 --- /dev/null +++ b/.phan/config.php @@ -0,0 +1,78 @@ + false, + 'guess_unknown_parameter_type_using_default' => true, + 'allow_overriding_vague_return_types' => true, + 'infer_default_properties_in_construct' => true, + 'enable_extended_internal_return_type_plugins' => true, + 'dead_code_detection' => true, + 'unused_variable_detection' => true, + 'force_tracking_references' => true, + 'redundant_condition_detection' => true, + 'error_prone_truthy_condition_detection' => true, + 'warn_about_redundant_use_namespaced_class' => true, + 'simplify_ast' => true, + 'generic_types_enabled' => true, + 'exclude_file_regex' => '@^vendor/phalcon/ide-stubs/|vendor/.*/Test.php@', + 'enable_include_path_checks' => true, + 'directory_list' => [ + 'src', + 'vendor', + // @todo reactivate + //'test', + ], + 'enable_class_alias_support' => true, + 'analyzed_file_extensions' => ['php'], + 'exclude_analysis_directory_list' => [ + 'vendor/' + ], + 'skip_slow_php_options_warning' => false, + 'ignore_undeclared_functions_with_known_signatures' => false, + 'plugin_config' => [ + 'has_phpdoc_check_duplicates' => true, + 'empty_statement_list_ignore_todos' => true, + 'infer_pure_methods' => true, + 'regex_warn_if_newline_allowed_at_end' => true, + ], + 'suppress_issue_types' => [ + 'PhanPluginRedundantReturnComment', + 'PhanPluginRedundantMethodComment', + 'PhanPluginRedundantClosureComment', + 'PhanUnreferencedPublicMethod', + 'PhanPluginDescriptionlessCommentOnPrivateProperty', + 'PhanPluginCanUsePHP71Void', + 'PhanUnreferencedClosure', + 'PhanPluginPossiblyStaticPrivateMethod', + 'PhanPluginPossiblyStaticClosure', + //@ todo reactivate + + ], + 'plugins' => [ + 'AlwaysReturnPlugin', + 'DollarDollarPlugin', + 'UnreachableCodePlugin', + 'DuplicateArrayKeyPlugin', + 'PrintfCheckerPlugin', + 'PHPUnitAssertionPlugin', + 'UseReturnValuePlugin', + 'UnknownElementTypePlugin', + 'DuplicateExpressionPlugin', + 'WhitespacePlugin', + 'InlineHTMLPlugin', + 'PossiblyStaticMethodPlugin', + 'HasPHPDocPlugin', + 'PHPDocToRealTypesPlugin', + 'PHPDocRedundantPlugin', + 'PreferNamespaceUsePlugin', + 'EmptyStatementListPlugin', + 'EmptyMethodAndFunctionPlugin', + 'LoopVariableReusePlugin', + 'RedundantAssignmentPlugin', + 'StrictComparisonPlugin', + 'StrictLiteralComparisonPlugin', + 'ShortArrayPlugin', + 'SimplifyExpressionPlugin', + 'RemoveDebugStatementPlugin', + ], +]; diff --git a/.travis.yml b/.travis.yml index 472d8e0..57e8b7b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,10 +12,11 @@ cache: - ~/cphalcon jobs: include: + # PHP Linting - stage: PHP Linting - php: 7.3 - name: PHP 7.3 + php: 7.4 + name: PHP 7.4 before_install: - phpenv config-rm xdebug.ini || true - mkdir ../tools && composer init --name=putg/tools --working-dir=../tools @@ -43,26 +44,33 @@ jobs: install: true script: - ../tools/vendor/bin/parallel-lint --exclude vendor . - - stage: PHP Linting - php: 7.1 - name: PHP 7.1 + +# Static Code Analysis + - stage: Static Code Analysis + php: 7.4 + name: "PHP Codesniffer: PSR12" before_install: - phpenv config-rm xdebug.ini || true - mkdir ../tools && composer init --name=putg/tools --working-dir=../tools - - composer require jakub-onderka/php-parallel-lint:^1 --working-dir=../tools + - composer require squizlabs/php_codesniffer:^3.5.6 --working-dir=../tools install: true script: - - ../tools/vendor/bin/parallel-lint --exclude vendor . - - stage: PHP Linting - php: 7.0 - name: PHP 7.0 + - ../tools/vendor/bin/phpcs -p --standard=PSR12 . + - stage: Static Code Analysis + php: 7.4 + name: PHAN@4 before_install: - phpenv config-rm xdebug.ini || true - mkdir ../tools && composer init --name=putg/tools --working-dir=../tools - - composer require jakub-onderka/php-parallel-lint:^1 --working-dir=../tools - install: true + - composer require phan/phan --working-dir=../tools + - pecl install psr + - pecl install ast + - sh install-phalcon.sh + install: + - composer update script: - - ../tools/vendor/bin/parallel-lint --exclude vendor . + - ../tools/vendor/bin/phan + # Unit Tests - stage: Test php: 7.4 @@ -70,6 +78,7 @@ jobs: before_install: - mkdir ../tools && composer init --name=putg/tools --working-dir=../tools - composer require codacy/coverage:dev-master --working-dir=../tools + - pecl install psr - sh install-phalcon.sh install: - composer update @@ -82,6 +91,7 @@ jobs: before_install: - mkdir ../tools && composer init --name=putg/tools --working-dir=../tools - composer require codacy/coverage:dev-master --working-dir=../tools + - pecl install psr - sh install-phalcon.sh install: - composer update @@ -94,77 +104,14 @@ jobs: before_install: - mkdir ../tools && composer init --name=putg/tools --working-dir=../tools - composer require codacy/coverage:dev-master --working-dir=../tools + - pecl install psr - sh install-phalcon.sh install: - composer update script: - vendor/bin/phpunit --testdox --coverage-text --coverage-clover clover.xml --whitelist src/ test/ - ../tools/vendor/bin/codacycoverage clover clover.xml - - stage: Test - php: 7.1 - name: PHP 7.1 - before_install: - - phpenv config-rm xdebug.ini || true - - sh install-phalcon.sh - install: - - composer update - script: - - vendor/bin/phpunit --testdox test/ - - stage: Test - php: 7.0 - name: PHP 7.0 - before_install: - - phpenv config-rm xdebug.ini || true - - sh install-phalcon.sh - install: - - composer update - script: - - vendor/bin/phpunit --testdox test/ -# Static Code Analysis - - stage: Static Code Analysis - php: 7.4 - name: PHP Assumptions - before_install: - - phpenv config-rm xdebug.ini || true - - mkdir ../tools && composer init --name=putg/tools --working-dir=../tools - - composer require rskuipers/php-assumptions:^0.7.0 --working-dir=../tools - - sh install-phalcon.sh - install: composer update - script: - - ../tools/vendor/bin/phpa --exclude=./vendor ./ - - stage: Static Code Analysis - php: 7.4 - name: "PHP Codesniffer: PSR2" - before_install: - - phpenv config-rm xdebug.ini || true - - mkdir ../tools && composer init --name=putg/tools --working-dir=../tools - - composer require squizlabs/php_codesniffer:^3.2.2 --working-dir=../tools - install: true - script: - - ../tools/vendor/bin/phpcs -p --standard=PSR2 . - - stage: Static Code Analysis - php: 7.4 - name: Composer Require Checker - before_install: - - phpenv config-rm xdebug.ini || true - - mkdir ../tools && composer init --name=putg/tools --working-dir=../tools - - composer config repositories.maglnet/composer-require-checker '{"type":"vcs","url":"https://github.com/idrinth/ComposerRequireChecker","no-api":true}' --working-dir=../tools && composer require maglnet/composer-require-checker:dev-bandaid --working-dir=../tools - - sh install-phalcon.sh - install: composer update - script: - - ../tools/vendor/bin/composer-require-checker check --register-namespace=nikic/php-parser:PhpParser\\:lib/PhpParser ./composer.json - - stage: Static Code Analysis - php: 7.4 - name: PHPstan - before_install: - - phpenv config-rm xdebug.ini || true - - mkdir ../tools && composer init --name=putg/tools --working-dir=../tools - - composer require phpstan/phpstan:^0.11 phpstan/phpstan-phpunit phpstan/phpstan-strict-rules:^0.11 --working-dir=../tools - - sh install-phalcon.sh - install: - - composer update - script: - - ../tools/vendor/bin/phpstan analyse --level max src test + # Pre-Tag - stage: Pre-Tag php: 7.4 @@ -172,7 +119,8 @@ jobs: before_install: - phpenv config-rm xdebug.ini || true - mkdir ../tools && composer init --name=putg/tools --working-dir=../tools - - composer require phpmetrics/phpmetrics:^2.4.1 --working-dir=../tools + - composer require phpmetrics/phpmetrics:^2.7.4 --working-dir=../tools + - pecl install psr - sh install-phalcon.sh install: - composer update @@ -185,6 +133,7 @@ jobs: - phpenv config-rm xdebug.ini || true - mkdir ../tools && composer init --name=putg/tools --working-dir=../tools - composer create-project tomzx/php-semver-checker-git:^0.7 --working-dir=../tools + - pecl install psr - sh install-phalcon.sh install: composer update script: diff --git a/composer.json b/composer.json index d53ff1e..35c9707 100644 --- a/composer.json +++ b/composer.json @@ -12,9 +12,10 @@ ], "require": { "php": "^7", - "ext-phalcon": "^3.2", + "ext-phalcon": "^4", "ext-json": "*", - "phpdocumentor/reflection-docblock": "^4.3.0" + "phpdocumentor/reflection-docblock": "^4.3.0", + "ocramius/package-versions": "^1 <1.10" }, "autoload": { "psr-4": { diff --git a/install-phalcon.sh b/install-phalcon.sh index 0490fd5..1016c7e 100644 --- a/install-phalcon.sh +++ b/install-phalcon.sh @@ -1,9 +1,24 @@ #!/bin/sh + mkdir tmp && \ mv composer.json tmp/ && \ -composer require --dev techpivot/phalcon-ci-installer && \ -vendor/bin/install-phalcon.sh 3.2.x && \ + +git clone git://github.com/phalcon/php-zephir-parser.git && \ +cd php-zephir-parser && \ +phpize && \ +./configure && \ +make && \ +make install && \ +echo "extension = zephir_parser.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini &&\ +cd .. && \ + +composer init --name tmp/tmp && \ +composer config repositories.phalcon-zephir-update '{"type":"vcs","url":"https://github.com/idrinth/phalcon-ci-installer","no-api":true}' && \ +composer require --dev techpivot/phalcon-ci-installer:dev-patch-1 && \ +vendor/bin/install-phalcon.sh 4.0.x && \ + rm composer.lock && \ rm composer.json && \ mv tmp/composer.json ./ && \ -rmdir tmp +rmdir tmp && \ +rm -rf php-zephir-parser diff --git a/phpstan.neon.dist b/phpstan.neon.dist deleted file mode 100644 index 46a9c2e..0000000 --- a/phpstan.neon.dist +++ /dev/null @@ -1,10 +0,0 @@ -includes: -- ../tools/vendor/phpstan/phpstan-phpunit/extension.neon -- ../tools/vendor/phpstan/phpstan-phpunit/rules.neon -- ../tools/vendor/phpstan/phpstan-strict-rules/rules.neon -parameters: - ignoreErrors: - - '#^Parameter \#3 \$subject of function preg_replace expects array\|string, string\|null given\.$#' - - '#^Access to an undefined property De\\Idrinth\\PhalconRoutes2OpenApi\\Implementations\\Controller::\$(router|request|di|response)\.$#' - - '#^Parameter \#4 \.\.\.\$sets of method De\\Idrinth\\PhalconRoutes2OpenApi\\Implementations\\NoValueConversionMerger::mergeAll\(\) expects array, string given\.$#' - - '#^Parameter \#1 \$sets \(array\) of method De\\Idrinth\\PhalconRoutes2OpenApi\\Implementations\\NoValueConversionMerger::mergeAll\(\) should be contravariant with parameter \$sets \(array\) of method De\\Idrinth\\PhalconRoutes2OpenApi\\Interfaces\\RecursiveMerger::mergeAll\(\)$#' diff --git a/src/Implementations/Controller.php b/src/Implementations/Controller.php index 712fb19..7a7ca4e 100644 --- a/src/Implementations/Controller.php +++ b/src/Implementations/Controller.php @@ -1,4 +1,6 @@ -getCorsEnabledResponse() ->setJsonContent( [ + 'openapi' => '3.0.1', 'paths' => $this->di->get(RMI::class)->mergeAll(...$paths), 'info' => [ - "title"=> Versions::ROOT_PACKAGE_NAME, - "version"=> Versions::getVersion(Versions::ROOT_PACKAGE_NAME) + "title" => Versions::ROOT_PACKAGE_NAME, + "version" => Versions::getVersion(Versions::ROOT_PACKAGE_NAME) ] ] ); @@ -48,6 +54,7 @@ public function indexAction(): ResponseInterface /** * Generates an overview over routes registered + * @suppress PhanPluginDuplicateMethodDescription * @return-204 {"type":"string","maxLength":0} * @return ResponseInterface */ @@ -60,6 +67,7 @@ public function options(): ResponseInterface /** * Generates an overview over routes registered + * @suppress PhanPluginDuplicateMethodDescription * @return-204 {"type":"string","maxLength":0} * @return ResponseInterface */ @@ -69,6 +77,7 @@ public function optionsAction(): ResponseInterface } /** + * Return the Response with added Cross-Origin-Resource-Sharing-Headers * @return ResponseInterface */ private function getCorsEnabledResponse(): ResponseInterface diff --git a/src/Implementations/DefaultResponse.php b/src/Implementations/DefaultResponse.php index a43829f..dc3c451 100644 --- a/src/Implementations/DefaultResponse.php +++ b/src/Implementations/DefaultResponse.php @@ -1,21 +1,27 @@ - [ - "description" => 'unknown return', + 'description' => 'unknown return', 'content' => [ '*/*' => [ 'schema' => new stdClass() diff --git a/src/Implementations/NoValueConversionMerger.php b/src/Implementations/NoValueConversionMerger.php index 1efa4ab..5578879 100644 --- a/src/Implementations/NoValueConversionMerger.php +++ b/src/Implementations/NoValueConversionMerger.php @@ -1,13 +1,19 @@ - $set) { + foreach ($sets as $set) { $initial = $this->merge($initial, $set); } return $initial; diff --git a/src/Implementations/PhalconPath2PathArray.php b/src/Implementations/PhalconPath2PathArray.php index 8debc89..2e7e91b 100644 --- a/src/Implementations/PhalconPath2PathArray.php +++ b/src/Implementations/PhalconPath2PathArray.php @@ -1,4 +1,6 @@ - $openapi * @return void */ private function handleParams(string &$path, array &$openapi) @@ -73,7 +80,7 @@ private function handleParams(string &$path, array &$openapi) ] ]; if (count($parts) === 2) { - $path = str_replace($match, '{'.$parts[0].'}', $path); + $path = str_replace($match, '{' . $parts[0] . '}', $path); } $openapi['parameters'][] = $param; } @@ -81,8 +88,9 @@ private function handleParams(string &$path, array &$openapi) } /** + * Add queries to openapi array * @param string $path - * @param array $openapi + * @param array $openapi * @param RouteInterface $route * @return void */ @@ -91,7 +99,7 @@ private function handleQuery(string &$path, array &$openapi, RouteInterface $rou if ((int) preg_match_all('/\((.+?)\)/', $path, $matches) > 0) { $names = $route->getReversedPaths(); foreach ($matches[1] as $pos => $match) { - $name = $names[$pos+1]; + $name = $names[$pos + 1]; $openapi['parameters'][] = [ 'name' => $name, 'in' => 'path', @@ -101,16 +109,17 @@ private function handleQuery(string &$path, array &$openapi, RouteInterface $rou 'pattern' => $match ] ]; - $path = preg_replace('/'.preg_quote('('.$match.')', '/').'/', '{'.$name.'}', $path, 1); + $path = preg_replace('/' . preg_quote('(' . $match . ')', '/') . '/', '{' . $name . '}', $path, 1); } } } /** + * Create data array from Route * @param RouteInterface $route - * @return array + * @return array> */ - public function convert(RouteInterface $route):array + public function convert(RouteInterface $route): array { $openapi = [ "description" => "" @@ -125,10 +134,10 @@ public function convert(RouteInterface $route):array $methods = ['get']; foreach ((array)$route->getHttpMethods() as $method) { $methods[] = strtolower($method); - $openapi[strtolower($method)] = $this->merger->merge((array) ($openapi[strtolower($method)]??[]), $data); + $openapi[strtolower($method)] = $this->merger->merge((array) ($openapi[strtolower($method)] ?? []), $data); } foreach (array_unique($methods) as $method) { - $openapi[$method] = DefaultResponse::add($openapi[$method]??[]); + $openapi[$method] = DefaultResponse::add($openapi[$method] ?? []); } ksort($openapi); return [$path => $openapi]; diff --git a/src/Implementations/Reflector.php b/src/Implementations/Reflector.php index a061cf9..c6edf4b 100644 --- a/src/Implementations/Reflector.php +++ b/src/Implementations/Reflector.php @@ -1,21 +1,33 @@ -> */ private $cache = []; + /** + * @var array + */ + private $classes = []; + /** * @var DocBlockFactoryInterface */ @@ -40,63 +52,84 @@ public function __construct(DocBlockFactoryInterface $parser, RecursiveMerger $m * Tries to find references to return codes in the method's phpdoc * @param string $class * @param string $method - * @return array + * @return array */ - public function __invoke(string $class, string $method):array + public function __invoke(string $class, string $method): array { try { - if (!isset($this->cache[$class])) { - $this->cache[$class]['#'] = new ReflectionClass($class); - } + $this->classes[$class] = $this->classes[$class] ?? new ReflectionClass($class); if (!isset($this->cache[$class][$method])) { $this->cache[$class][$method] = DefaultResponse::add( - $this->getReflect($this->cache[$class]['#'], $method) + $this->getReflect($this->classes[$class], $method) ); } } catch (Exception $e) { $this->cache[$class][$method] = DefaultResponse::add([ - "summary" => 'unretrievable definition', - "description" => "$class::$method could not be reflected on.", + 'summary' => 'unretrievable definition', + 'description' => "$class::$method could not be reflected on.\n$e", ]); } return $this->cache[$class][$method]; } /** - * @param ReflectionClass $class - * @param string $method - * @return array + * Adds default + * @param Tag $tag + * @return string[] */ - private function getReflect(ReflectionClass $class, string $method):array + private function addDefaultParts(Tag $tag): array + { + $parts = explode(" ", "$tag", 2); + if (!isset($parts[0]) || $parts[0] === '' || $parts[0][0] === '{') { + array_unshift($parts, '*/*'); + if (isset($parts[2])) { + $parts[1] .= " " . array_pop($parts); + } + } + return $parts; + } + + /** + * Retrieve tags from doc block + * @param DocBlock $docBlock + * @return array|array + */ + private function getDocBlockData(DocBlock $docBlock): array { - $docBlock = $this->parser->create($class->getMethod($method)); $data = []; foreach ($docBlock->getTags() as $tag) { if ((int) preg_match('/^return-([1-9][0-9]{2})$/', $tag->getName(), $matches) > 0) { - $parts = explode(" ", "$tag", 2); - if (!isset($parts[0]) || $parts[0] === '' || $parts[0]{0} === '{') { - array_unshift($parts, '*/*'); - if (isset($parts[2])) { - $parts[1] .= " " . array_pop($parts); - } - } + $parts = $this->addDefaultParts($tag); $data[$matches[1]] = $this->merger->merge( - $data[$matches[1]]??[], + $data[$matches[1]] ?? [], [ - "description" => '', - "content" => [ + 'description' => '', + 'content' => [ $parts[0] => [ - "schema" => json_decode($parts[1] ?? '{}') ?: new stdClass() + 'schema' => json_decode($parts[1] ?? '{}') ?: new stdClass() ] ] ] ); } } + return $data; + } + + /** + * Retrieve doc block information and build route data from it + * @param ReflectionClass $class + * @param string $method + * @return array|array + */ + private function getReflect(ReflectionClass $class, string $method): array + { + $docBlock = $this->parser->create($class->getMethod($method)->getDocComment()); + $data = $this->getDocBlockData($docBlock); return [ - "description" => $docBlock->getDescription().'', - "summary" => $docBlock->getSummary().'', - "responses" => $data + 'description' => $docBlock->getDescription() . '', + 'summary' => $docBlock->getSummary() . '', + 'responses' => $data ]; } } diff --git a/src/Interfaces/Controller.php b/src/Interfaces/Controller.php index 6b14da1..41cb436 100644 --- a/src/Interfaces/Controller.php +++ b/src/Interfaces/Controller.php @@ -1,9 +1,14 @@ - + */ public function convert(RouteInterface $route): array; } diff --git a/src/Interfaces/PathTargetAnnotationResolver.php b/src/Interfaces/PathTargetAnnotationResolver.php index e9d8af9..00675fa 100644 --- a/src/Interfaces/PathTargetAnnotationResolver.php +++ b/src/Interfaces/PathTargetAnnotationResolver.php @@ -1,14 +1,19 @@ - */ public function __invoke(string $class, string $method): array; } diff --git a/src/Interfaces/RecursiveMerger.php b/src/Interfaces/RecursiveMerger.php index 28e9bac..2c91b65 100644 --- a/src/Interfaces/RecursiveMerger.php +++ b/src/Interfaces/RecursiveMerger.php @@ -1,19 +1,28 @@ -registerServices($serviceContainer); $this->registerRoutes($serviceContainer->get('router')); } /** + * Register Services * @param DiInterface $serviceContainer - * @param string $root * @return void */ - private function registerServices(DiInterface $serviceContainer) + private function registerServices(DiInterface $serviceContainer): void { - $serviceContainer->set(Controller::class, function () { - return (new ControllerImplementation()); - }); - $serviceContainer->set(Path2PathConverter::class, function () use (&$serviceContainer) { - return new PhalconPath2PathArray( - $serviceContainer->get(PathTargetAnnotationResolver::class), - $serviceContainer->get(RecursiveMerger::class) - ); - }); - $serviceContainer->set(DocBlockFactoryInterface::class, function () { - return DocBlockFactory::createInstance(); - }); - $serviceContainer->set(PathTargetAnnotationResolver::class, function () use (&$serviceContainer) { - return new Reflector( - $serviceContainer->get(DocBlockFactoryInterface::class), - $serviceContainer->get(RecursiveMerger::class) - ); - }); + $serviceContainer->set(Controller::class, ControllerImplementation::class); + $serviceContainer->set( + Path2PathConverter::class, + /** + * @return Path2PathConverter + */ + function () use (&$serviceContainer): Path2PathConverter { + return new PhalconPath2PathArray( + $serviceContainer->get(PathTargetAnnotationResolver::class), + $serviceContainer->get(RecursiveMerger::class) + ); + } + ); + $serviceContainer->set( + DocBlockFactoryInterface::class, + /** + * @return DocBlockFactory + */ + function (): DocBlockFactoryInterface { + return DocBlockFactory::createInstance(); + } + ); + $serviceContainer->set( + PathTargetAnnotationResolver::class, + /** + * Creates a Reflector + * @return PathTargetAnnotationResolver + */ + function () use (&$serviceContainer): PathTargetAnnotationResolver { + return new Reflector( + $serviceContainer->get(DocBlockFactoryInterface::class), + $serviceContainer->get(RecursiveMerger::class) + ); + } + ); $serviceContainer->set(RecursiveMerger::class, NoValueConversionMerger::class); } /** + * Register routes * @param RouterInterface $router * @return void */ - private function registerRoutes(RouterInterface $router) + private function registerRoutes(RouterInterface $router): void { $router->addGet('/', ['controller' => Controller::class, 'action' => 'index']); $router->addOptions('/', ['controller' => Controller::class, 'action' => 'options']); diff --git a/test/ControllerTest.php b/test/ControllerTest.php index 0f2f00d..500746d 100644 --- a/test/ControllerTest.php +++ b/test/ControllerTest.php @@ -5,9 +5,10 @@ use De\Idrinth\PhalconRoutes2OpenApi\Implementations\Controller; use De\Idrinth\PhalconRoutes2OpenApi\Interfaces\Path2PathConverter; use De\Idrinth\PhalconRoutes2OpenApi\Interfaces\RecursiveMerger; -use Phalcon\DiInterface; -use Phalcon\Http\ResponseInterface; +use PackageVersions\Versions; +use Phalcon\Di\DiInterface; use Phalcon\Http\RequestInterface; +use Phalcon\Http\ResponseInterface; use Phalcon\Mvc\Router\RouteInterface; use Phalcon\Mvc\RouterInterface; use PHPUnit\Framework\Constraint\IsInstanceOf; @@ -24,7 +25,9 @@ private function buildRouterMock(): RouterInterface $router->expects(static::once()) ->method('getRoutes') ->with() - ->willReturn([$this->getMockBuilder(RouteInterface::class)->getMock()]); + ->willReturn([ + $this->getMockBuilder(RouteInterface::class)->getMock() + ]); return $router; } @@ -37,12 +40,12 @@ public function provideIndex(): array [ $this->buildRouterMock(), [ - "openapi" => "3.0.1", - "info" => [ - "title" => "unknown", - "version" => "1.0.0" + 'openapi' => '3.0.1', + 'info' => [ + 'title' => Versions::ROOT_PACKAGE_NAME, + 'version' => Versions::getVersion(Versions::ROOT_PACKAGE_NAME) ], - "paths" => [ + 'paths' => [ '/abc' => [ 'get' => [] ] @@ -52,12 +55,12 @@ public function provideIndex(): array [ $this->buildRouterMock(), [ - "openapi" => "3.0.1", - "info" => [ - "title" => "unknown", - "version" => "1.0.0" + 'openapi' => '3.0.1', + 'info' => [ + 'title' => Versions::ROOT_PACKAGE_NAME, + 'version' => Versions::getVersion(Versions::ROOT_PACKAGE_NAME) ], - "paths" => [ + 'paths' => [ '/abc' => [ 'get' => [] ] @@ -112,33 +115,8 @@ private function getPreparedInstance(RouterInterface $router, array $result): Co ->with(new IsInstanceOf(RouteInterface::class)) ->willReturn(['/abc' => ['get' => []]]); $merger = $this->getMockBuilder(RecursiveMerger::class)->getMock(); - $merger->expects(static::once()) - ->method('merge') - ->with( - [ - "openapi"=> "3.0.1", - "info"=> [ - "title"=> "unknown", - "version"=> "1.0.0" - ] - ], - [ - "paths" => [ - '/abc' => ['get' => []] - ], - "info" => [] - ] - ) - ->willReturn([ - "openapi"=> "3.0.1", - "info"=> [ - "title"=> "unknown", - "version"=> "1.0.0" - ], - "paths" => [ - '/abc' => ['get' => []] - ] - ]); + $merger->expects(static::never()) + ->method('merge'); $merger->expects(static::once()) ->method('mergeAll') ->with(['/abc' => ['get' => []]]) diff --git a/test/NoValueConversionMergerTest.php b/test/NoValueConversionMergerTest.php index cc11978..27d73a2 100644 --- a/test/NoValueConversionMergerTest.php +++ b/test/NoValueConversionMergerTest.php @@ -34,7 +34,7 @@ public function testMerge(array $in1, array $in2, array $out) { static::assertEquals( $out, - (new NoValueConversionMerger)->merge($in1, $in2) + (new NoValueConversionMerger())->merge($in1, $in2) ); } @@ -46,27 +46,11 @@ public function testMergeAll() { static::assertEquals( ['a' => [1, 2, 4, 'z' => 77], '1hh'], - (new NoValueConversionMerger)->mergeAll( + (new NoValueConversionMerger())->mergeAll( ['a' => [1, 2]], ['a' => [4, 'z' => 11]], ['a' => ['z' => 77], '1hh'] ) ); } - - /** - * @test - * @expectedException InvalidargumentException - * @expectedExceptionMessage Set #4 is not an array, but a(n) string. - * @return void - */ - public function testMergeAllThrowsInvalidArgumentException() - { - (new NoValueConversionMerger)->mergeAll( - ['a' => [1, 2]], - ['a' => [4, 'z' => 11]], - ['a' => ['z' => 77], '1hh'], - "something else" - ); - } } diff --git a/test/Path2PathTest.php b/test/Path2PathTest.php index 2fb65d3..ec71a12 100644 --- a/test/Path2PathTest.php +++ b/test/Path2PathTest.php @@ -23,7 +23,7 @@ private function makeRoute( array $methods, int $calls = 0, array $config = array() - ):RouteInterface { + ): RouteInterface { $route = $this->getMockBuilder(RouteInterface::class)->getMock(); $route->expects(static::once())->method('getPattern')->with()->willReturn($path); $route->expects(static::once())->method('getHttpMethods')->with()->willReturn($methods); diff --git a/test/ReflectorTest.php b/test/ReflectorTest.php index 99bd3c5..e3fa0f1 100644 --- a/test/ReflectorTest.php +++ b/test/ReflectorTest.php @@ -11,7 +11,7 @@ use PHPUnit\Framework\TestCase; use stdClass; -class ReflectorTest extends TestCase +final class ReflectorTest extends TestCase { private function getTag(string $name, string $description): Generic {