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);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |