279 lines
10 KiB
PHP
279 lines
10 KiB
PHP
<?php declare(strict_types=1);
|
|
|
|
/**
|
|
* @license Apache 2.0
|
|
*/
|
|
|
|
namespace OpenApi\Tests\Processors;
|
|
|
|
use OpenApi\Analysis;
|
|
use OpenApi\Annotations\Components;
|
|
use OpenApi\Annotations\Info;
|
|
use OpenApi\Annotations\PathItem;
|
|
use OpenApi\Annotations\Schema;
|
|
use OpenApi\Generator;
|
|
use OpenApi\Processors\AugmentProperties;
|
|
use OpenApi\Processors\AugmentSchemas;
|
|
use OpenApi\Processors\BuildPaths;
|
|
use OpenApi\Processors\CleanUnmerged;
|
|
use OpenApi\Processors\ExpandInterfaces;
|
|
use OpenApi\Processors\InheritProperties;
|
|
use OpenApi\Processors\InheritTraits;
|
|
use OpenApi\Processors\MergeIntoComponents;
|
|
use OpenApi\Processors\MergeIntoOpenApi;
|
|
use OpenApi\Tests\OpenApiTestCase;
|
|
|
|
class InheritPropertiesTest extends OpenApiTestCase
|
|
{
|
|
protected function validate(Analysis $analysis)
|
|
{
|
|
$analysis->openapi->info = new Info(['title' => 'test', 'version' => '1.0.0']);
|
|
$analysis->openapi->paths = [new PathItem(['path' => '/test'])];
|
|
$analysis->validate();
|
|
}
|
|
|
|
public function testInheritProperties()
|
|
{
|
|
$analysis = $this->analysisFromFixtures(
|
|
[
|
|
'AnotherNamespace/Child.php',
|
|
'InheritProperties/GrandAncestor.php',
|
|
'InheritProperties/Ancestor.php',
|
|
]
|
|
);
|
|
$analysis->process([
|
|
new MergeIntoOpenApi(),
|
|
new MergeIntoComponents(),
|
|
new ExpandInterfaces(),
|
|
new InheritTraits(),
|
|
new AugmentSchemas(),
|
|
new AugmentProperties(),
|
|
new BuildPaths(),
|
|
]);
|
|
$this->validate($analysis);
|
|
|
|
$schemas = $analysis->getAnnotationsOfType(Schema::class);
|
|
$childSchema = $schemas[0];
|
|
$this->assertSame('Child', $childSchema->schema);
|
|
$this->assertCount(1, $childSchema->properties);
|
|
|
|
$analysis->process([
|
|
new InheritProperties(),
|
|
new CleanUnmerged(),
|
|
]);
|
|
$this->validate($analysis);
|
|
|
|
$this->assertCount(3, $childSchema->properties);
|
|
}
|
|
|
|
/**
|
|
* Tests, if InheritProperties works even without any
|
|
* docBlocks at all in the parent class.
|
|
*/
|
|
public function testInheritPropertiesWithoutDocBlocks()
|
|
{
|
|
$analysis = $this->analysisFromFixtures([
|
|
// this class has docblocks
|
|
'AnotherNamespace/ChildWithDocBlocks.php',
|
|
// this one doesn't
|
|
'InheritProperties/AncestorWithoutDocBlocks.php',
|
|
]);
|
|
$analysis->process([
|
|
new MergeIntoOpenApi(),
|
|
new MergeIntoComponents(),
|
|
new ExpandInterfaces(),
|
|
new InheritTraits(),
|
|
new AugmentSchemas(),
|
|
new AugmentProperties(),
|
|
new BuildPaths(),
|
|
new InheritProperties(),
|
|
new CleanUnmerged(),
|
|
]);
|
|
$this->validate($analysis);
|
|
|
|
$schemas = $analysis->getAnnotationsOfType(Schema::class);
|
|
$childSchema = $schemas[0];
|
|
$this->assertSame('ChildWithDocBlocks', $childSchema->schema);
|
|
$this->assertCount(1, $childSchema->properties);
|
|
|
|
// no error occurs
|
|
$analysis->process(new InheritProperties());
|
|
$this->assertCount(1, $childSchema->properties);
|
|
}
|
|
|
|
/**
|
|
* Tests inherit properties with all of block.
|
|
*/
|
|
public function testInheritPropertiesWithAllOf()
|
|
{
|
|
$analysis = $this->analysisFromFixtures([
|
|
// this class has all of
|
|
'InheritProperties/Extended.php',
|
|
'InheritProperties/Base.php',
|
|
]);
|
|
$analysis->process([
|
|
new MergeIntoOpenApi(),
|
|
new MergeIntoComponents(),
|
|
new ExpandInterfaces(),
|
|
new InheritTraits(),
|
|
new AugmentSchemas(),
|
|
new AugmentProperties(),
|
|
new BuildPaths(),
|
|
new InheritProperties(),
|
|
new CleanUnmerged(),
|
|
]);
|
|
// $this->validate($analysis);
|
|
|
|
$schemas = $analysis->getAnnotationsOfType(Schema::class, true);
|
|
$this->assertCount(3, $schemas);
|
|
|
|
/* @var Schema $extendedSchema */
|
|
$extendedSchema = $schemas[0];
|
|
$this->assertSame('ExtendedModel', $extendedSchema->schema);
|
|
$this->assertSame(Generator::UNDEFINED, $extendedSchema->properties);
|
|
|
|
$this->assertArrayHasKey(1, $extendedSchema->allOf);
|
|
$this->assertEquals($extendedSchema->allOf[1]->properties[0]->property, 'extendedProperty');
|
|
|
|
/* @var $includeSchemaWithRef Schema */
|
|
$includeSchemaWithRef = $schemas[1];
|
|
$this->assertSame(Generator::UNDEFINED, $includeSchemaWithRef->properties);
|
|
}
|
|
|
|
/**
|
|
* Tests for inherit properties without all of block.
|
|
*/
|
|
public function testInheritPropertiesWithOutAllOf()
|
|
{
|
|
$analysis = $this->analysisFromFixtures([
|
|
// this class has all of
|
|
'InheritProperties/ExtendedWithoutAllOf.php',
|
|
'InheritProperties/Base.php',
|
|
]);
|
|
$analysis->process([
|
|
new MergeIntoOpenApi(),
|
|
new MergeIntoComponents(),
|
|
new ExpandInterfaces(),
|
|
new InheritTraits(),
|
|
new AugmentSchemas(),
|
|
new AugmentProperties(),
|
|
new BuildPaths(),
|
|
new InheritProperties(),
|
|
new CleanUnmerged(),
|
|
]);
|
|
$this->validate($analysis);
|
|
|
|
$schemas = $analysis->getAnnotationsOfType(Schema::class, true);
|
|
$this->assertCount(2, $schemas);
|
|
|
|
/* @var Schema $extendedSchema */
|
|
$extendedSchema = $schemas[0];
|
|
$this->assertSame('ExtendedWithoutAllOf', $extendedSchema->schema);
|
|
$this->assertSame(Generator::UNDEFINED, $extendedSchema->properties);
|
|
|
|
$this->assertCount(2, $extendedSchema->allOf);
|
|
|
|
$this->assertEquals($extendedSchema->allOf[0]->ref, Components::SCHEMA_REF . 'Base');
|
|
$this->assertEquals($extendedSchema->allOf[1]->properties[0]->property, 'extendedProperty');
|
|
}
|
|
|
|
/**
|
|
* Tests for inherit properties in object with two schemas in the same context.
|
|
*/
|
|
public function testInheritPropertiesWitTwoChildSchemas()
|
|
{
|
|
$analysis = $this->analysisFromFixtures([
|
|
// this class has all of
|
|
'InheritProperties/ExtendedWithTwoSchemas.php',
|
|
'InheritProperties/Base.php',
|
|
]);
|
|
$analysis->process([
|
|
new MergeIntoOpenApi(),
|
|
new MergeIntoComponents(),
|
|
new ExpandInterfaces(),
|
|
new InheritTraits(),
|
|
new AugmentSchemas(),
|
|
new AugmentProperties(),
|
|
new BuildPaths(),
|
|
new InheritProperties(),
|
|
new CleanUnmerged(),
|
|
]);
|
|
$this->validate($analysis);
|
|
|
|
$schemas = $analysis->getAnnotationsOfType(Schema::class, true);
|
|
$this->assertCount(3, $schemas);
|
|
|
|
/* @var Schema $extendedSchema */
|
|
$extendedSchema = $schemas[0];
|
|
$this->assertSame('ExtendedWithTwoSchemas', $extendedSchema->schema);
|
|
$this->assertSame(Generator::UNDEFINED, $extendedSchema->properties);
|
|
|
|
$this->assertCount(2, $extendedSchema->allOf);
|
|
$this->assertEquals($extendedSchema->allOf[0]->ref, Components::SCHEMA_REF . 'Base');
|
|
$this->assertEquals($extendedSchema->allOf[1]->properties[0]->property, 'nested');
|
|
$this->assertEquals($extendedSchema->allOf[1]->properties[1]->property, 'extendedProperty');
|
|
|
|
/* @var $nestedSchema Schema */
|
|
$nestedSchema = $schemas[1];
|
|
$this->assertSame(Generator::UNDEFINED, $nestedSchema->allOf);
|
|
$this->assertCount(1, $nestedSchema->properties);
|
|
$this->assertEquals($nestedSchema->properties[0]->property, 'nestedProperty');
|
|
}
|
|
|
|
/**
|
|
* Tests inherit properties with interface.
|
|
*/
|
|
public function testPreserveExistingAllOf()
|
|
{
|
|
$analysis = $this->analysisFromFixtures([
|
|
'InheritProperties/BaseInterface.php',
|
|
'InheritProperties/ExtendsBaseThatImplements.php',
|
|
'InheritProperties/BaseThatImplements.php',
|
|
'InheritProperties/TraitUsedByExtendsBaseThatImplements.php',
|
|
]);
|
|
$analysis->process([
|
|
new MergeIntoOpenApi(),
|
|
new MergeIntoComponents(),
|
|
new ExpandInterfaces(),
|
|
new InheritTraits(),
|
|
new AugmentSchemas(),
|
|
new AugmentProperties(),
|
|
new BuildPaths(),
|
|
new InheritProperties(),
|
|
new CleanUnmerged(),
|
|
]);
|
|
$this->validate($analysis);
|
|
|
|
$analysis->openapi->info = new Info(['title' => 'test', 'version' => '1.0.0']);
|
|
$analysis->openapi->paths = [new PathItem(['path' => '/test'])];
|
|
$analysis->validate();
|
|
|
|
/* @var Schema[] $schemas */
|
|
$schemas = $analysis->getAnnotationsOfType(Schema::class, true);
|
|
$this->assertCount(4, $schemas);
|
|
|
|
$baseInterface = $schemas[0];
|
|
$this->assertSame('BaseInterface', $baseInterface->schema);
|
|
$this->assertEquals($baseInterface->properties[0]->property, 'interfaceProperty');
|
|
$this->assertEquals(Generator::UNDEFINED, $baseInterface->allOf);
|
|
|
|
$extendsBaseThatImplements = $schemas[1];
|
|
$this->assertSame('ExtendsBaseThatImplements', $extendsBaseThatImplements->schema);
|
|
$this->assertEquals(Generator::UNDEFINED, $extendsBaseThatImplements->properties);
|
|
$this->assertNotEquals(Generator::UNDEFINED, $extendsBaseThatImplements->allOf);
|
|
// base, trait and own properties
|
|
$this->assertCount(3, $extendsBaseThatImplements->allOf);
|
|
|
|
$baseThatImplements = $schemas[2];
|
|
$this->assertSame('BaseThatImplements', $baseThatImplements->schema);
|
|
$this->assertEquals(Generator::UNDEFINED, $baseThatImplements->properties);
|
|
$this->assertNotEquals(Generator::UNDEFINED, $baseThatImplements->allOf);
|
|
$this->assertCount(2, $baseThatImplements->allOf);
|
|
|
|
$traitUsedByExtendsBaseThatImplements = $schemas[3];
|
|
$this->assertSame('TraitUsedByExtendsBaseThatImplements', $traitUsedByExtendsBaseThatImplements->schema);
|
|
$this->assertEquals($traitUsedByExtendsBaseThatImplements->properties[0]->property, 'traitProperty');
|
|
$this->assertEquals(Generator::UNDEFINED, $traitUsedByExtendsBaseThatImplements->allOf);
|
|
}
|
|
}
|