Skip to content

Commit

Permalink
Use real symfony application for the functional testing (#70)
Browse files Browse the repository at this point in the history
* Setup functional tests and added info about conflict with `nelmio/api-doc-bundle` lower than `3.4`
* Use `kernel.project_dir` instead `kernel.root_dir`
* Added conflict with `doctrine/annotations` lower than `1.7` and increased minimal version for the `zircote/swagger-php:^2.0.15`
* Added real resolving into Functional test
* Changed `get_declared_classes` with scan `project_dir` for the `NelmioApiDocConfigurationLoader`.
* Moved `registerOperationResources` by Router into base class and removed `AbstractAnnotationConfigurationLoader` as redundant.
* Reorganized `AbstractSwaggerConfigurationLoader` to avoid illogical check for unexisted route in the `registerOperationResources`.
  • Loading branch information
adrenalinkin committed Jan 22, 2022
1 parent 1e41e0f commit 2b86518
Show file tree
Hide file tree
Showing 23 changed files with 835 additions and 191 deletions.
20 changes: 10 additions & 10 deletions .github/workflows/lint.yml
Expand Up @@ -6,15 +6,15 @@ jobs:
php-cs-fixer:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@v2

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 7.4
coverage: none
tools: php-cs-fixer:2.19.3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 7.4
coverage: none
tools: php-cs-fixer:2.19.3

- name: Run PHP-CS-Fixer
run: php-cs-fixer fix --dry-run --diff
- name: Run PHP-CS-Fixer
run: php-cs-fixer fix --dry-run --diff
59 changes: 17 additions & 42 deletions .github/workflows/unit-tests.yml
Expand Up @@ -4,44 +4,24 @@ on: [push, pull_request]

jobs:
tests:
name: "PHP ${{ matrix.php }} + Symfony ${{ matrix.symfony }} + Composer ${{ matrix.dependency }}"
name: "PHP${{ matrix.php }} Symfony${{ matrix.symfony}} ${{ matrix.composer-flags }}"
runs-on: ubuntu-latest

strategy:
fail-fast: true
fail-fast: false
matrix:
include:
# Lowest PHP with the lowest dependencies for every supported lowest major version of the Symfony
- php: '7.1'
coverage: xdebug
dependency: lowest
symfony: '^3.4'
- php: '7.1'
coverage: xdebug
dependency: lowest
symfony: '^4.0'
- php: '7.2'
coverage: xdebug
dependency: lowest
symfony: '^5.0'

# All supported php versions with the highest dependencies for any supported Symfony version
- php: '7.1'
coverage: xdebug
dependency: highest
symfony: 'any'
coverage: 'xdebug'
composer-flags: '--prefer-lowest'
- php: '7.2'
coverage: pcov
dependency: highest
symfony: 'any'
symfony: '^4.0'
- php: '7.3'
coverage: pcov
dependency: highest
symfony: 'any'
symfony: '^5.0'
- php: '7.4'
coverage: pcov
dependency: highest
symfony: 'any'
symfony: '^5.0'
coverage: 'pcov'

steps:
- name: Checkout source
Expand All @@ -51,35 +31,30 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: ${{ matrix.coverage }}
coverage: ${{ matrix.coverage || 'none' }}

- name: Require Symfony version
if: matrix.symfony != 'any'
run: |
composer global require --no-interaction --no-progress symfony/flex:^1.11
composer config extra.symfony.require ${{ matrix.symfony }}
- name: Install Symfony Flex
run: composer global require -o --no-interaction --no-progress symfony/flex:^1.11

- name: Validate composer.json
run: composer validate
- name: Require Symfony version
run: composer config extra.symfony.require ${{ matrix.symfony }}

- name: Update composer dependencies
uses: ramsey/composer-install@v1
with:
dependency-versions: ${{ matrix.dependency }}
run: composer update -o --no-interaction --no-progress ${{ matrix.composer-flags }}

- name: Run test suite
run: ./vendor/bin/simple-phpunit -v

- name: Install php-coveralls
run: composer global require --no-interaction --no-progress php-coveralls/php-coveralls
run: composer global require -o --no-interaction --no-progress php-coveralls/php-coveralls

- name: Upload coverage results to Coveralls
if: matrix.coverage
uses: nick-invision/retry@v2
env:
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_PARALLEL: true
COVERALLS_FLAG_NAME: |
"PHP ${{ matrix.php }} + Symfony ${{ matrix.symfony }} + Composer ${{ matrix.dependency }}"
COVERALLS_FLAG_NAME: "PHP${{ matrix.php }} Symfony${{ matrix.symfony}}"
with:
timeout_seconds: 60
max_attempts: 3
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -8,6 +8,7 @@
- Removed all unnecessary rows from the `.gitignore` according to `.gitignore_global` use instead.
### Fixed
- Fixed incompatible with Symfony 5 according to new contract in `OptionResolver::offsetGet()`.
- Added conflict with `nelmio/api-doc-bundle` version lower than `3.4`.
- Fixed error when `SwaggerResolver` without any validator.
- Fixed incorrect behavior of the `multipleOf` validation when received value and `multipleOf` was a float type.
- Fixed not worked array validation for the `multi` format.
Expand Down
1 change: 1 addition & 0 deletions DependencyInjection/LinkinSwaggerResolverExtension.php
Expand Up @@ -129,6 +129,7 @@ private function getConfigurationLoaderDefinition(ContainerBuilder $container, a
return $loaderDefinition
->setClass(NelmioApiDocConfigurationLoader::class)
->addArgument(new Reference(sprintf('nelmio_api_doc.generator.%s', $this->globalAreaName)))
->addArgument($container->getParameter('kernel.project_dir'))
;
}

Expand Down
51 changes: 0 additions & 51 deletions Loader/AbstractAnnotationConfigurationLoader.php

This file was deleted.

95 changes: 48 additions & 47 deletions Loader/AbstractSwaggerConfigurationLoader.php
Expand Up @@ -21,6 +21,8 @@
use Linkin\Bundle\SwaggerResolverBundle\Collection\SchemaOperationCollection;
use Linkin\Bundle\SwaggerResolverBundle\Exception\OperationNotFoundException;
use Linkin\Bundle\SwaggerResolverBundle\Merger\OperationParameterMerger;
use ReflectionClass;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Routing\RouterInterface;

/**
Expand All @@ -38,11 +40,6 @@ abstract class AbstractSwaggerConfigurationLoader implements SwaggerConfiguratio
*/
private $operationCollection;

/**
* @var array
*/
private $mapPathToRouteName;

/**
* @var OperationParameterMerger
*/
Expand All @@ -53,6 +50,16 @@ abstract class AbstractSwaggerConfigurationLoader implements SwaggerConfiguratio
*/
private $router;

/**
* @var string[][]
*/
private $mapPathToRouteName = [];

/**
* @var FileResource[]
*/
private $mapRouteNameToSourceFile = [];

public function __construct(OperationParameterMerger $parameterMerger, RouterInterface $router)
{
$this->parameterMerger = $parameterMerger;
Expand Down Expand Up @@ -96,65 +103,49 @@ abstract protected function registerDefinitionResources(SchemaDefinitionCollecti
/**
* Add file resources for swagger operations.
*/
abstract protected function registerOperationResources(SchemaOperationCollection $operationCollection): void;

protected function getRouter(): RouterInterface
protected function registerOperationResources(SchemaOperationCollection $operationCollection): void
{
return $this->router;
}

protected function getRouteNameByPath(string $path, string $method): string
{
if (!$this->mapPathToRouteName) {
$this->initMapPathToRouteName();
}

$route = $this->mapPathToRouteName[$path][$method] ?? null;

if (!$route) {
throw new OperationNotFoundException($path, $method);
foreach ($operationCollection->getIterator() as $routeName => $methodList) {
$operationCollection->addSchemaResource($routeName, $this->mapRouteNameToSourceFile[$routeName]);
}

return (string) $route;
}

/**
* Initialize map real path into appropriated route name.
*/
private function initMapPathToRouteName(): void
private function normalizeMethod(string $method): string
{
foreach ($this->router->getRouteCollection() as $routeName => $route) {
foreach ($route->getMethods() as $method) {
$method = $this->normalizeMethod($method);
$this->mapPathToRouteName[$route->getPath()][$method] = $routeName;
}
}
return strtolower($method);
}

/**
* Register collection according to loaded Swagger object.
*/
private function registerCollections(): void
{
$this->initRouteMaps();
$swaggerConfiguration = $this->loadConfiguration();

$definitionCollection = new SchemaDefinitionCollection();
$operationCollection = new SchemaOperationCollection();
$this->definitionCollection = new SchemaDefinitionCollection();
$this->operationCollection = new SchemaOperationCollection();

foreach ($swaggerConfiguration->getDefinitions()->getIterator() as $definitionName => $definition) {
$definitionCollection->addSchema($definitionName, $definition);
$this->definitionCollection->addSchema($definitionName, $definition);
}

$this->registerDefinitionResources($definitionCollection);
$this->registerDefinitionResources($this->definitionCollection);

/** @var Path $pathObject */
foreach ($swaggerConfiguration->getPaths()->getIterator() as $path => $pathObject) {
/** @var Operation $operation */
foreach ($pathObject->getOperations() as $method => $operation) {
$method = $this->normalizeMethod($method);
$routeName = $this->mapPathToRouteName[$path][$method] ?? null;

if (null === $routeName) {
throw new OperationNotFoundException($path, $method);
}

$schema = $this->parameterMerger->merge($operation, $swaggerConfiguration->getDefinitions());
$routeName = $this->getRouteNameByPath($path, $method);
$operationCollection->addSchema($routeName, $method, $schema);

$this->operationCollection->addSchema($routeName, $method, $schema);

/** @var Parameter $parameter */
foreach ($operation->getParameters()->getIterator() as $parameter) {
Expand All @@ -167,21 +158,31 @@ private function registerCollections(): void
$explodedName = explode('/', $ref);
$definitionName = end($explodedName);

foreach ($definitionCollection->getSchemaResources($definitionName) as $fileResource) {
$operationCollection->addSchemaResource($routeName, $fileResource);
foreach ($this->definitionCollection->getSchemaResources($definitionName) as $fileResource) {
$this->operationCollection->addSchemaResource($routeName, $fileResource);
}
}
}
}

$this->registerOperationResources($operationCollection);

$this->definitionCollection = $definitionCollection;
$this->operationCollection = $operationCollection;
$this->registerOperationResources($this->operationCollection);
}

private function normalizeMethod(string $method): string
private function initRouteMaps(): void
{
return strtolower($method);
$this->mapPathToRouteName = [];
$this->mapRouteNameToSourceFile = [];

foreach ($this->router->getRouteCollection() as $routeName => $route) {
foreach ($route->getMethods() as $method) {
$defaults = $route->getDefaults();
$exploded = explode('::', $defaults['_controller']);
$controllerName = reset($exploded);
$fullClassName = (new ReflectionClass($controllerName))->getFileName();

$this->mapPathToRouteName[$route->getPath()][$this->normalizeMethod($method)] = $routeName;
$this->mapRouteNameToSourceFile[$routeName] = new FileResource($fullClassName);
}
}
}
}

0 comments on commit 2b86518

Please sign in to comment.