mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-02-09 02:59:27 +03:00
Merge branch '3.x'
This commit is contained in:
commit
363fd26f7c
64
.github/workflows/continuous-integration.yml
vendored
Normal file
64
.github/workflows/continuous-integration.yml
vendored
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# from doctrine/instantiator:
|
||||||
|
# https://github.com/doctrine/instantiator/blob/97aa11bb71ad6259a8c5a1161b4de2d6cdcc5501/.github/workflows/continuous-integration.yml
|
||||||
|
|
||||||
|
name: "CI"
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- "*.x"
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "*.x"
|
||||||
|
|
||||||
|
env:
|
||||||
|
fail-fast: true
|
||||||
|
COMPOSER_ROOT_VERSION: "1.4"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
phpunit:
|
||||||
|
name: "PHPUnit"
|
||||||
|
runs-on: "ubuntu-20.04"
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- php-version: 7.1
|
||||||
|
composer-flags: "--prefer-lowest"
|
||||||
|
- php-version: 7.2
|
||||||
|
symfony-require: "3.4.*"
|
||||||
|
- php-version: 7.3
|
||||||
|
symfony-require: "4.4.*"
|
||||||
|
- php-version: 7.3
|
||||||
|
symfony-require: "^5.0"
|
||||||
|
- php-version: 8.0
|
||||||
|
composer-flags: "--ignore-platform-reqs"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: "Checkout"
|
||||||
|
uses: "actions/checkout@v2"
|
||||||
|
with:
|
||||||
|
fetch-depth: 2
|
||||||
|
|
||||||
|
- name: "Install PHP without coverage"
|
||||||
|
uses: "shivammathur/setup-php@v2"
|
||||||
|
with:
|
||||||
|
php-version: "${{ matrix.php-version }}"
|
||||||
|
coverage: "none"
|
||||||
|
|
||||||
|
- name: "Cache dependencies installed with composer"
|
||||||
|
uses: "actions/cache@v2"
|
||||||
|
with:
|
||||||
|
path: "~/.composer/cache"
|
||||||
|
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
|
||||||
|
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
|
||||||
|
|
||||||
|
- name: "Install dependencies with composer"
|
||||||
|
env:
|
||||||
|
SYMFONY_REQUIRE: "${{ matrix.symfony-require }}"
|
||||||
|
run: |
|
||||||
|
composer global require --no-progress --no-scripts --no-plugins symfony/flex
|
||||||
|
composer update --no-interaction --no-progress ${{ matrix.composer-flags }}
|
||||||
|
|
||||||
|
- name: "Run PHPUnit"
|
||||||
|
run: "./phpunit"
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,5 +6,6 @@
|
|||||||
/.php_cs
|
/.php_cs
|
||||||
/phpunit.xml
|
/phpunit.xml
|
||||||
/.phpunit
|
/.phpunit
|
||||||
|
/.phpunit.result.cache
|
||||||
/Tests/Functional/cache
|
/Tests/Functional/cache
|
||||||
/Tests/Functional/logs
|
/Tests/Functional/logs
|
||||||
|
36
.travis.yml
36
.travis.yml
@ -1,36 +0,0 @@
|
|||||||
language: php
|
|
||||||
|
|
||||||
php:
|
|
||||||
- 7.1
|
|
||||||
- 7.2
|
|
||||||
- 7.3
|
|
||||||
- 7.4
|
|
||||||
|
|
||||||
sudo: false
|
|
||||||
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- .phpunit
|
|
||||||
- $HOME/.composer/cache
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
fast_finish: true
|
|
||||||
include:
|
|
||||||
- php: 7.1
|
|
||||||
env: COMPOSER_FLAGS="--prefer-lowest"
|
|
||||||
- php: 7.3
|
|
||||||
env: SYMFONY_VERSION=^4.0
|
|
||||||
- php: 7.3
|
|
||||||
env: SYMFONY_VERSION=^5.0
|
|
||||||
- php: 7.4
|
|
||||||
env: SYMFONY_VERSION=^4.0
|
|
||||||
- php: 7.4
|
|
||||||
env: SYMFONY_VERSION=^5.0
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
- phpenv config-rm xdebug.ini || true
|
|
||||||
- if [ "$SYMFONY_VERSION" != "" ]; then composer require "symfony/symfony:${SYMFONY_VERSION}" --dev --no-update; fi;
|
|
||||||
|
|
||||||
install: composer update --no-interaction $COMPOSER_FLAGS
|
|
||||||
|
|
||||||
script: ./phpunit
|
|
@ -11,7 +11,7 @@ You MUST follow the [PSR-1](http://www.php-fig.org/psr/psr-1/) and
|
|||||||
should really read the recommendations. Can't wait? Use the [PHP-CS-Fixer
|
should really read the recommendations. Can't wait? Use the [PHP-CS-Fixer
|
||||||
tool](http://cs.sensiolabs.org/).
|
tool](http://cs.sensiolabs.org/).
|
||||||
|
|
||||||
You MUST run the test suite.
|
You MUST run the test suite (run `composer update`, and then execute `vendor/bin/simple-phpunit`).
|
||||||
|
|
||||||
You MUST write (or update) unit tests.
|
You MUST write (or update) unit tests.
|
||||||
|
|
||||||
|
@ -61,5 +61,7 @@ final class SwaggerUiController
|
|||||||
Response::HTTP_OK,
|
Response::HTTP_OK,
|
||||||
['Content-Type' => 'text/html']
|
['Content-Type' => 'text/html']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return $response->setCharset('UTF-8');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,11 @@ final class ConfigurationPass implements CompilerPassInterface
|
|||||||
$container->register('nelmio_api_doc.model_describers.form', FormModelDescriber::class)
|
$container->register('nelmio_api_doc.model_describers.form', FormModelDescriber::class)
|
||||||
->setPublic(false)
|
->setPublic(false)
|
||||||
->addArgument(new Reference('form.factory'))
|
->addArgument(new Reference('form.factory'))
|
||||||
|
->addArgument(new Reference('annotation_reader'))
|
||||||
|
->addArgument($container->getParameter('nelmio_api_doc.media_types'))
|
||||||
->addTag('nelmio_api_doc.model_describer', ['priority' => 100]);
|
->addTag('nelmio_api_doc.model_describer', ['priority' => 100]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$container->getParameterBag()->remove('nelmio_api_doc.media_types');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@ final class NelmioApiDocExtension extends Extension implements PrependExtensionI
|
|||||||
->setFactory([new Reference('router'), 'getRouteCollection']);
|
->setFactory([new Reference('router'), 'getRouteCollection']);
|
||||||
|
|
||||||
$container->setParameter('nelmio_api_doc.areas', array_keys($config['areas']));
|
$container->setParameter('nelmio_api_doc.areas', array_keys($config['areas']));
|
||||||
|
$container->setParameter('nelmio_api_doc.media_types', $config['media_types']);
|
||||||
foreach ($config['areas'] as $area => $areaConfig) {
|
foreach ($config['areas'] as $area => $areaConfig) {
|
||||||
$nameAliases = $this->findNameAliases($config['models']['names'], $area);
|
$nameAliases = $this->findNameAliases($config['models']['names'], $area);
|
||||||
|
|
||||||
|
42
Exception/UndocumentedArrayItemsException.php
Normal file
42
Exception/UndocumentedArrayItemsException.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the NelmioApiDocBundle package.
|
||||||
|
*
|
||||||
|
* (c) Nelmio
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Nelmio\ApiDocBundle\Exception;
|
||||||
|
|
||||||
|
class UndocumentedArrayItemsException extends \LogicException
|
||||||
|
{
|
||||||
|
private $class;
|
||||||
|
private $path;
|
||||||
|
|
||||||
|
public function __construct(string $class = null, string $path = '')
|
||||||
|
{
|
||||||
|
$this->class = $class;
|
||||||
|
$this->path = $path;
|
||||||
|
|
||||||
|
$propertyName = '';
|
||||||
|
if (null !== $class) {
|
||||||
|
$propertyName = $class.'::';
|
||||||
|
}
|
||||||
|
$propertyName .= $path;
|
||||||
|
|
||||||
|
parent::__construct(sprintf('Property "%s" is an array, but its items type isn\'t specified. You can specify that by using the type `string[]` for instance or `@SWG\Property(type="array", @SWG\Items(type="string"))`.', $propertyName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getClass()
|
||||||
|
{
|
||||||
|
return $this->class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPath()
|
||||||
|
{
|
||||||
|
return $this->path;
|
||||||
|
}
|
||||||
|
}
|
@ -29,7 +29,7 @@ class DocumentationExtension extends AbstractTypeExtension
|
|||||||
public function configureOptions(OptionsResolver $resolver)
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
{
|
{
|
||||||
$resolver->setDefaults(['documentation' => []])
|
$resolver->setDefaults(['documentation' => []])
|
||||||
->setAllowedTypes('documentation', ['array']);
|
->setAllowedTypes('documentation', ['array', 'bool']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getExtendedType()
|
public function getExtendedType()
|
||||||
|
@ -11,9 +11,11 @@
|
|||||||
|
|
||||||
namespace Nelmio\ApiDocBundle\ModelDescriber;
|
namespace Nelmio\ApiDocBundle\ModelDescriber;
|
||||||
|
|
||||||
|
use Doctrine\Common\Annotations\Reader;
|
||||||
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface;
|
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface;
|
||||||
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait;
|
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait;
|
||||||
use Nelmio\ApiDocBundle\Model\Model;
|
use Nelmio\ApiDocBundle\Model\Model;
|
||||||
|
use Nelmio\ApiDocBundle\ModelDescriber\Annotations\AnnotationsReader;
|
||||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
@ -33,10 +35,22 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry
|
|||||||
use ModelRegistryAwareTrait;
|
use ModelRegistryAwareTrait;
|
||||||
|
|
||||||
private $formFactory;
|
private $formFactory;
|
||||||
|
private $doctrineReader;
|
||||||
|
private $mediaTypes;
|
||||||
|
|
||||||
public function __construct(FormFactoryInterface $formFactory = null)
|
public function __construct(FormFactoryInterface $formFactory = null, Reader $reader = null, array $mediaTypes = null)
|
||||||
{
|
{
|
||||||
$this->formFactory = $formFactory;
|
$this->formFactory = $formFactory;
|
||||||
|
$this->doctrineReader = $reader;
|
||||||
|
if (null === $reader) {
|
||||||
|
@trigger_error(sprintf('Not passing a doctrine reader to the constructor of %s is deprecated since version 3.8 and won\'t be allowed in version 5.', self::class), E_USER_DEPRECATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $mediaTypes) {
|
||||||
|
$mediaTypes = ['json'];
|
||||||
|
@trigger_error(sprintf('Not passing media types to the constructor of %s is deprecated since version 4.1 and won\'t be allowed in version 5.', self::class), E_USER_DEPRECATED);
|
||||||
|
}
|
||||||
|
$this->mediaTypes = $mediaTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function describe(Model $model, OA\Schema $schema)
|
public function describe(Model $model, OA\Schema $schema)
|
||||||
@ -52,6 +66,9 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry
|
|||||||
|
|
||||||
$class = $model->getType()->getClassName();
|
$class = $model->getType()->getClassName();
|
||||||
|
|
||||||
|
$annotationsReader = new AnnotationsReader($this->doctrineReader, $this->modelRegistry, $this->mediaTypes);
|
||||||
|
$annotationsReader->updateDefinition(new \ReflectionClass($class), $schema);
|
||||||
|
|
||||||
$form = $this->formFactory->create($class, null, $model->getOptions() ?? []);
|
$form = $this->formFactory->create($class, null, $model->getOptions() ?? []);
|
||||||
$this->parseForm($schema, $form);
|
$this->parseForm($schema, $form);
|
||||||
}
|
}
|
||||||
@ -65,6 +82,11 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry
|
|||||||
{
|
{
|
||||||
foreach ($form as $name => $child) {
|
foreach ($form as $name => $child) {
|
||||||
$config = $child->getConfig();
|
$config = $child->getConfig();
|
||||||
|
|
||||||
|
// This field must not be documented
|
||||||
|
if ($config->hasOption('documentation') && false === $config->getOption('documentation')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$property = Util::getProperty($schema, $name);
|
$property = Util::getProperty($schema, $name);
|
||||||
|
|
||||||
if ($config->getRequired()) {
|
if ($config->getRequired()) {
|
||||||
|
@ -14,6 +14,7 @@ namespace Nelmio\ApiDocBundle\ModelDescriber;
|
|||||||
use Doctrine\Common\Annotations\Reader;
|
use Doctrine\Common\Annotations\Reader;
|
||||||
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface;
|
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface;
|
||||||
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait;
|
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait;
|
||||||
|
use Nelmio\ApiDocBundle\Exception\UndocumentedArrayItemsException;
|
||||||
use Nelmio\ApiDocBundle\Model\Model;
|
use Nelmio\ApiDocBundle\Model\Model;
|
||||||
use Nelmio\ApiDocBundle\ModelDescriber\Annotations\AnnotationsReader;
|
use Nelmio\ApiDocBundle\ModelDescriber\Annotations\AnnotationsReader;
|
||||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
@ -148,7 +149,15 @@ class ObjectModelDescriber implements ModelDescriberInterface, ModelRegistryAwar
|
|||||||
$propertyDescriber->setModelRegistry($this->modelRegistry);
|
$propertyDescriber->setModelRegistry($this->modelRegistry);
|
||||||
}
|
}
|
||||||
if ($propertyDescriber->supports($types)) {
|
if ($propertyDescriber->supports($types)) {
|
||||||
$propertyDescriber->describe($types, $property, $model->getGroups());
|
try {
|
||||||
|
$propertyDescriber->describe($types, $property, $model->getGroups());
|
||||||
|
} catch (UndocumentedArrayItemsException $e) {
|
||||||
|
if (null !== $e->getClass()) {
|
||||||
|
throw $e; // This exception is already complete
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new UndocumentedArrayItemsException($model->getType()->getClassName(), sprintf('%s%s', $propertyName, $e->getPath()));
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ namespace Nelmio\ApiDocBundle\PropertyDescriber;
|
|||||||
|
|
||||||
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface;
|
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface;
|
||||||
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait;
|
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait;
|
||||||
|
use Nelmio\ApiDocBundle\Exception\UndocumentedArrayItemsException;
|
||||||
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
|
||||||
use OpenApi\Annotations as OA;
|
use OpenApi\Annotations as OA;
|
||||||
|
|
||||||
@ -33,7 +34,7 @@ class ArrayPropertyDescriber implements PropertyDescriberInterface, ModelRegistr
|
|||||||
{
|
{
|
||||||
$type = $types[0]->getCollectionValueType();
|
$type = $types[0]->getCollectionValueType();
|
||||||
if (null === $type) {
|
if (null === $type) {
|
||||||
throw new \LogicException(sprintf('Property "%s" is an array, but its items type isn\'t specified. You can specify that by using the type `string[]` for instance or `@OA\Property(type="array", @OA\Items(type="string"))`.', $property->property));
|
throw new UndocumentedArrayItemsException();
|
||||||
}
|
}
|
||||||
|
|
||||||
$property->type = 'array';
|
$property->type = 'array';
|
||||||
@ -45,7 +46,15 @@ class ArrayPropertyDescriber implements PropertyDescriberInterface, ModelRegistr
|
|||||||
$propertyDescriber->setModelRegistry($this->modelRegistry);
|
$propertyDescriber->setModelRegistry($this->modelRegistry);
|
||||||
}
|
}
|
||||||
if ($propertyDescriber->supports([$type])) {
|
if ($propertyDescriber->supports([$type])) {
|
||||||
$propertyDescriber->describe([$type], $property, $groups);
|
try {
|
||||||
|
$propertyDescriber->describe([$type], $property, $groups);
|
||||||
|
} catch (UndocumentedArrayItemsException $e) {
|
||||||
|
if (null !== $e->getClass()) {
|
||||||
|
throw $e; // This exception is already complete
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new UndocumentedArrayItemsException(null, sprintf('%s[]', $e->getPath()));
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
37
Tests/Functional/ArrayItemsErrorTest.php
Normal file
37
Tests/Functional/ArrayItemsErrorTest.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the NelmioApiDocBundle package.
|
||||||
|
*
|
||||||
|
* (c) Nelmio
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Nelmio\ApiDocBundle\Tests\Functional;
|
||||||
|
|
||||||
|
use Nelmio\ApiDocBundle\Exception\UndocumentedArrayItemsException;
|
||||||
|
|
||||||
|
class ArrayItemsErrorTest extends WebTestCase
|
||||||
|
{
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
static::createClient([], ['HTTP_HOST' => 'api.example.com']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testModelPictureDocumentation()
|
||||||
|
{
|
||||||
|
$this->expectException(UndocumentedArrayItemsException::class);
|
||||||
|
$this->expectExceptionMessage('Property "Nelmio\ApiDocBundle\Tests\Functional\Entity\ArrayItemsError\Bar::things[]" is an array, but its items type isn\'t specified.');
|
||||||
|
|
||||||
|
$this->getOpenApiDefinition();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function createKernel(array $options = [])
|
||||||
|
{
|
||||||
|
return new TestKernel(TestKernel::ERROR_ARRAY_ITEMS);
|
||||||
|
}
|
||||||
|
}
|
@ -125,6 +125,6 @@ class BazingaFunctionalTest extends WebTestCase
|
|||||||
|
|
||||||
protected static function createKernel(array $options = [])
|
protected static function createKernel(array $options = [])
|
||||||
{
|
{
|
||||||
return new TestKernel(true, true);
|
return new TestKernel(TestKernel::USE_JMS | TestKernel::USE_BAZINGA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
35
Tests/Functional/Controller/ArrayItemsErrorController.php
Normal file
35
Tests/Functional/Controller/ArrayItemsErrorController.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the NelmioApiDocBundle package.
|
||||||
|
*
|
||||||
|
* (c) Nelmio
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Nelmio\ApiDocBundle\Tests\Functional\Controller;
|
||||||
|
|
||||||
|
use Nelmio\ApiDocBundle\Annotation\Model;
|
||||||
|
use Nelmio\ApiDocBundle\Tests\Functional\Entity\ArrayItemsError\Foo;
|
||||||
|
use OpenApi\Annotations as OA;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Route(host="api.example.com")
|
||||||
|
*/
|
||||||
|
class ArrayItemsErrorController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @Route("/api/error", methods={"GET"})
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Success",
|
||||||
|
* @Model(type=Foo::class)
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function errorAction()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
22
Tests/Functional/Entity/ArrayItemsError/Bar.php
Normal file
22
Tests/Functional/Entity/ArrayItemsError/Bar.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the NelmioApiDocBundle package.
|
||||||
|
*
|
||||||
|
* (c) Nelmio
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Nelmio\ApiDocBundle\Tests\Functional\Entity\ArrayItemsError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Guilhem N. <guilhem@gniot.fr>
|
||||||
|
*/
|
||||||
|
class Bar
|
||||||
|
{
|
||||||
|
public $things;
|
||||||
|
|
||||||
|
public function addThing(array $thing) { }
|
||||||
|
}
|
28
Tests/Functional/Entity/ArrayItemsError/Foo.php
Normal file
28
Tests/Functional/Entity/ArrayItemsError/Foo.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the NelmioApiDocBundle package.
|
||||||
|
*
|
||||||
|
* (c) Nelmio
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Nelmio\ApiDocBundle\Tests\Functional\Entity\ArrayItemsError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Guilhem N. <guilhem@gniot.fr>
|
||||||
|
*/
|
||||||
|
class Foo
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $articles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Bar[]
|
||||||
|
*/
|
||||||
|
public $bars;
|
||||||
|
}
|
@ -12,6 +12,7 @@
|
|||||||
namespace Nelmio\ApiDocBundle\Tests\Functional\Form;
|
namespace Nelmio\ApiDocBundle\Tests\Functional\Form;
|
||||||
|
|
||||||
use Nelmio\ApiDocBundle\Tests\Functional\Entity\User;
|
use Nelmio\ApiDocBundle\Tests\Functional\Entity\User;
|
||||||
|
use OpenApi\Annotations as OA;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
@ -19,6 +20,11 @@ use Symfony\Component\Form\Extension\Core\Type\TextType;
|
|||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Schema(
|
||||||
|
* description="this is the description of an user"
|
||||||
|
* )
|
||||||
|
*/
|
||||||
class UserType extends AbstractType
|
class UserType extends AbstractType
|
||||||
{
|
{
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
@ -42,6 +48,7 @@ class UserType extends AbstractType
|
|||||||
->add('document', DocumentType::class, ['class' => 'Document'])
|
->add('document', DocumentType::class, ['class' => 'Document'])
|
||||||
->add('documents', DocumentType::class, ['class' => 'Document', 'multiple' => true])
|
->add('documents', DocumentType::class, ['class' => 'Document', 'multiple' => true])
|
||||||
->add('extended_builtin', ExtendedBuiltinType::class, ['required_option' => 'foo'])
|
->add('extended_builtin', ExtendedBuiltinType::class, ['required_option' => 'foo'])
|
||||||
|
->add('hidden', DummyType::class, ['documentation' => false])
|
||||||
->add('save', SubmitType::class);
|
->add('save', SubmitType::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,6 +224,7 @@ class FunctionalTest extends WebTestCase
|
|||||||
{
|
{
|
||||||
$this->assertEquals([
|
$this->assertEquals([
|
||||||
'type' => 'object',
|
'type' => 'object',
|
||||||
|
'description' => 'this is the description of an user',
|
||||||
'properties' => [
|
'properties' => [
|
||||||
'strings' => [
|
'strings' => [
|
||||||
'items' => ['type' => 'string'],
|
'items' => ['type' => 'string'],
|
||||||
|
@ -324,6 +324,6 @@ class JMSFunctionalTest extends WebTestCase
|
|||||||
|
|
||||||
protected static function createKernel(array $options = [])
|
protected static function createKernel(array $options = [])
|
||||||
{
|
{
|
||||||
return new TestKernel(true);
|
return new TestKernel(TestKernel::USE_JMS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ class SwaggerUiTest extends WebTestCase
|
|||||||
|
|
||||||
$response = $this->client->getResponse();
|
$response = $this->client->getResponse();
|
||||||
$this->assertEquals(200, $response->getStatusCode());
|
$this->assertEquals(200, $response->getStatusCode());
|
||||||
|
$this->assertEquals('UTF-8', $response->getCharset());
|
||||||
$this->assertEquals('text/html; charset=UTF-8', $response->headers->get('Content-Type'));
|
$this->assertEquals('text/html; charset=UTF-8', $response->headers->get('Content-Type'));
|
||||||
|
|
||||||
$expected = json_decode($this->getOpenApiDefinition()->toJson(), true);
|
$expected = json_decode($this->getOpenApiDefinition()->toJson(), true);
|
||||||
|
@ -33,17 +33,19 @@ use Symfony\Component\Serializer\Annotation\SerializedName;
|
|||||||
|
|
||||||
class TestKernel extends Kernel
|
class TestKernel extends Kernel
|
||||||
{
|
{
|
||||||
|
const USE_JMS = 1;
|
||||||
|
const USE_BAZINGA = 2;
|
||||||
|
const ERROR_ARRAY_ITEMS = 4;
|
||||||
|
|
||||||
use MicroKernelTrait;
|
use MicroKernelTrait;
|
||||||
|
|
||||||
private $useJMS;
|
private $flags;
|
||||||
private $useBazinga;
|
|
||||||
|
|
||||||
public function __construct(bool $useJMS = false, bool $useBazinga = false)
|
public function __construct(int $flags = 0)
|
||||||
{
|
{
|
||||||
parent::__construct('test'.(int) $useJMS.(int) $useBazinga, true);
|
parent::__construct('test'.$flags, true);
|
||||||
|
|
||||||
$this->useJMS = $useJMS;
|
$this->flags = $flags;
|
||||||
$this->useBazinga = $useBazinga;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,10 +63,10 @@ class TestKernel extends Kernel
|
|||||||
new FOSRestBundle(),
|
new FOSRestBundle(),
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($this->useJMS) {
|
if ($this->flags & self::USE_JMS) {
|
||||||
$bundles[] = new JMSSerializerBundle();
|
$bundles[] = new JMSSerializerBundle();
|
||||||
|
|
||||||
if ($this->useBazinga) {
|
if ($this->flags & self::USE_BAZINGA) {
|
||||||
$bundles[] = new BazingaHateoasBundle();
|
$bundles[] = new BazingaHateoasBundle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,11 +93,11 @@ class TestKernel extends Kernel
|
|||||||
$routes->import(__DIR__.'/Controller/SerializedNameController.php', '/', 'annotation');
|
$routes->import(__DIR__.'/Controller/SerializedNameController.php', '/', 'annotation');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->useJMS) {
|
if ($this->flags & self::USE_JMS) {
|
||||||
$routes->import(__DIR__.'/Controller/JMSController.php', '/', 'annotation');
|
$routes->import(__DIR__.'/Controller/JMSController.php', '/', 'annotation');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->useBazinga) {
|
if ($this->flags & self::USE_BAZINGA) {
|
||||||
$routes->import(__DIR__.'/Controller/BazingaController.php', '/', 'annotation');
|
$routes->import(__DIR__.'/Controller/BazingaController.php', '/', 'annotation');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -104,6 +106,10 @@ class TestKernel extends Kernel
|
|||||||
} catch (\ReflectionException $e) {
|
} catch (\ReflectionException $e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->flags & self::ERROR_ARRAY_ITEMS) {
|
||||||
|
$routes->import(__DIR__.'/Controller/ArrayItemsErrorController.php', '/', 'annotation');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -250,7 +256,7 @@ class TestKernel extends Kernel
|
|||||||
*/
|
*/
|
||||||
public function getCacheDir()
|
public function getCacheDir()
|
||||||
{
|
{
|
||||||
return parent::getCacheDir().'/'.(int) $this->useJMS;
|
return parent::getCacheDir().'/'.$this->flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -258,7 +264,7 @@ class TestKernel extends Kernel
|
|||||||
*/
|
*/
|
||||||
public function getLogDir()
|
public function getLogDir()
|
||||||
{
|
{
|
||||||
return parent::getLogDir().'/'.(int) $this->useJMS;
|
return parent::getLogDir().'/'.$this->flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function serialize()
|
public function serialize()
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.1",
|
"php": ">=7.1.3",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"symfony/framework-bundle": "^4.0|^5.0",
|
"symfony/framework-bundle": "^4.0|^5.0",
|
||||||
"symfony/options-resolver": "^4.0|^5.0",
|
"symfony/options-resolver": "^4.0|^5.0",
|
||||||
@ -43,7 +43,7 @@
|
|||||||
"doctrine/common": "^2.4",
|
"doctrine/common": "^2.4",
|
||||||
|
|
||||||
"api-platform/core": "^2.4",
|
"api-platform/core": "^2.4",
|
||||||
"friendsofsymfony/rest-bundle": "^2.0|^3.0@beta",
|
"friendsofsymfony/rest-bundle": "^2.0|^3.0@dev",
|
||||||
"willdurand/hateoas-bundle": "^1.0|^2.0",
|
"willdurand/hateoas-bundle": "^1.0|^2.0",
|
||||||
"jms/serializer-bundle": "^2.3|^3.0",
|
"jms/serializer-bundle": "^2.3|^3.0",
|
||||||
"jms/serializer": "^1.14|^3.0"
|
"jms/serializer": "^1.14|^3.0"
|
||||||
|
1
phpunit
1
phpunit
@ -5,5 +5,4 @@ if (!file_exists(__DIR__.'/vendor/symfony/phpunit-bridge/bin/simple-phpunit')) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
putenv('SYMFONY_PHPUNIT_DIR='.__DIR__.'/.phpunit');
|
putenv('SYMFONY_PHPUNIT_DIR='.__DIR__.'/.phpunit');
|
||||||
putenv('SYMFONY_PHPUNIT_VERSION=7.5');
|
|
||||||
require __DIR__.'/vendor/symfony/phpunit-bridge/bin/simple-phpunit';
|
require __DIR__.'/vendor/symfony/phpunit-bridge/bin/simple-phpunit';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user