diff --git a/composer.json b/composer.json index 5e083fe..f13a583 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ }, "require": { "php": "^8.0", - "yoanm/jsonrpc-server-doc-sdk": "^1.0" + "yoanm/jsonrpc-server-doc-sdk": "^1.0.1" }, "require-dev": { "ext-json": "*", diff --git a/features/method-doc.feature b/features/method-doc.feature index db1ac41..7381942 100644 --- a/features/method-doc.feature +++ b/features/method-doc.feature @@ -72,9 +72,7 @@ Feature: MethodDocNormalizer "array-val": { "type": "array", "x-nullable": true, - "items": { - "type": "string" - } + "items": {} } } } @@ -111,9 +109,7 @@ Feature: MethodDocNormalizer "array-val": { "type": "array", "x-nullable": true, - "items": { - "type": "string" - } + "items": {} } } } @@ -384,9 +380,7 @@ Feature: MethodDocNormalizer "array-val": { "type": "array", "x-nullable": true, - "items": { - "type": "string" - } + "items": {} } } }, @@ -401,9 +395,7 @@ Feature: MethodDocNormalizer "array-val": { "type": "array", "x-nullable": true, - "items": { - "type": "string" - } + "items": {} } } }, diff --git a/features/type-doc.feature b/features/type-doc.feature index a3f8a98..5d7fa22 100644 --- a/features/type-doc.feature +++ b/features/type-doc.feature @@ -7,7 +7,6 @@ Feature: TypeDoc normalization Then I should have the following TypeDoc: """ { - "type": "string", "x-nullable": true } """ @@ -19,7 +18,6 @@ Feature: TypeDoc normalization Then I should have the following TypeDoc: """ { - "type": "string", "x-nullable": true } """ @@ -93,9 +91,7 @@ Feature: TypeDoc normalization { "type": "array", "x-nullable": true, - "items": { - "type": "string" - } + "items": {} } """ @@ -108,9 +104,7 @@ Feature: TypeDoc normalization { "type": "array", "x-nullable": true, - "items": { - "type": "string" - } + "items": {} } """ diff --git a/features/type-doc_fully-configured.feature b/features/type-doc_fully-configured.feature index c0378e7..3f3e9bb 100644 --- a/features/type-doc_fully-configured.feature +++ b/features/type-doc_fully-configured.feature @@ -20,7 +20,6 @@ Feature: TypeDoc normalization """ { "description": "type-b-description", - "type": "string", "x-nullable": false, "default": "type-b-default", "example": "type-b-example", @@ -48,7 +47,6 @@ Feature: TypeDoc normalization """ { "description": "type-b-description", - "type": "string", "x-nullable": false, "default": "type-b-default", "example": "type-b-example", @@ -265,9 +263,7 @@ Feature: TypeDoc normalization "enum": [["type-b-allowed-value-a"], ["type-b-allowed-value-b"]], "minItems": 2, "maxItems": 8, - "items": { - "type": "string" - } + "items": {} } """ @@ -304,10 +300,7 @@ Feature: TypeDoc normalization "enum": [["type-b-allowed-value-a"], ["type-b-allowed-value-b"]], "minItems": 2, "maxItems": 8, - "items": { - "type": "string", - "x-nullable": true - } + "items": {"x-nullable": true} } """ diff --git a/src/App/Normalizer/Component/SchemaTypeNormalizer.php b/src/App/Normalizer/Component/SchemaTypeNormalizer.php index bcc2d80..9e6bb0e 100644 --- a/src/App/Normalizer/Component/SchemaTypeNormalizer.php +++ b/src/App/Normalizer/Component/SchemaTypeNormalizer.php @@ -33,11 +33,11 @@ class SchemaTypeNormalizer /** * @param TypeDoc $doc * - * @return string + * @return ?string * * @throws \ReflectionException */ - public function normalize(TypeDoc $doc) : string + public function normalize(TypeDoc $doc) : ?string { $type = str_replace('Doc', '', lcfirst((new \ReflectionClass($doc))->getShortName())); if (in_array($type, self::MANAGED_TYPE_LIST)) { @@ -46,6 +46,6 @@ public function normalize(TypeDoc $doc) : string return self::RENAMED_TYPE_LIST[$type]; } - return 'string'; + return null; } } diff --git a/src/App/Normalizer/Component/TypeDocNormalizer.php b/src/App/Normalizer/Component/TypeDocNormalizer.php index 5155d39..bed5317 100644 --- a/src/App/Normalizer/Component/TypeDocNormalizer.php +++ b/src/App/Normalizer/Component/TypeDocNormalizer.php @@ -47,7 +47,7 @@ public function normalize(TypeDoc $doc) : array $format = ($doc instanceof StringDoc ? $doc->getFormat() : null); return $this->appendIfValueNotNull('description', $doc->getDescription()) - + ['type' => $this->schemaTypeNormalizer->normalize($doc)] + + $this->appendIfValueNotNull('type', $this->schemaTypeNormalizer->normalize($doc)) + $this->appendIfValueNotNull('format', $format) + ['x-nullable' => $doc->isNullable()] + $paramDocRequired @@ -104,7 +104,8 @@ protected function appendArrayDoc(TypeDoc $doc, array $siblingsDoc) : array if ($doc instanceof ArrayDoc && null !== $doc->getItemValidation()) { $siblingsDoc['items'] = $this->normalize($doc->getItemValidation()); } else { - $siblingsDoc['items']['type'] = $this->guessItemsType($doc->getSiblingList()); + $type = $this->guessItemsType($doc->getSiblingList()); + $siblingsDoc['items'] = null !== $type ? ['type' => $type] : []; } return $siblingsDoc; @@ -162,21 +163,24 @@ function (array $carry, TypeDoc $sibling) { * * @return string */ - protected function guessItemsType(array $siblingList) : string + protected function guessItemsType(array $siblingList) : ?string { $self = $this; $uniqueTypeList = array_unique( - array_map( - function (TypeDoc $sibling) use ($self) { - return $self->schemaTypeNormalizer->normalize($sibling); - }, - $siblingList + array_filter( + array_map( + function (TypeDoc $sibling) use ($self) { + return $self->schemaTypeNormalizer->normalize($sibling); + }, + $siblingList + ), + static fn ($value) => (null !== $value) ) ); if (count($uniqueTypeList) !== 1) { // default string if sub item type not guessable - return 'string'; + return null; } return array_shift($uniqueTypeList); diff --git a/tests/Functional/App/Normalizer/Component/SchemaTypeNormalizerTest.php b/tests/Functional/App/Normalizer/Component/SchemaTypeNormalizerTest.php index 6d12182..cfb187e 100644 --- a/tests/Functional/App/Normalizer/Component/SchemaTypeNormalizerTest.php +++ b/tests/Functional/App/Normalizer/Component/SchemaTypeNormalizerTest.php @@ -39,10 +39,10 @@ public function testShouldHandle($typeDoc, $expected) ); } - public function testShouldFallbackToString() + public function testShouldFallbackToUnknownType() { $this->assertSame( - 'string', + null, $this->normalizer->normalize(new NotManagedTypeDoc()) ); } @@ -53,6 +53,10 @@ public function testShouldFallbackToString() public function provideManagedTypeDocClassList() { return [ + 'unknown type' => [ + 'typeDocClass' => new TypeDocNS\TypeDoc(), + 'expected' => null, + ], 'array type' => [ 'typeDocClass' => new TypeDocNS\ArrayDoc(), 'expected' => 'array' @@ -83,7 +87,7 @@ public function provideManagedTypeDocClassList() ], 'scalar type' => [ 'typeDocClass' => new TypeDocNS\ScalarDoc(), - 'expected' => 'string' + 'expected' => null, // Swagger 2.0 doesn't allow multiple type ! ], 'string type' => [ 'typeDocClass' => new TypeDocNS\StringDoc(), diff --git a/tests/Functional/App/Normalizer/Component/TypeDocNormalizerTest.php b/tests/Functional/App/Normalizer/Component/TypeDocNormalizerTest.php index 5bab611..da1cd17 100644 --- a/tests/Functional/App/Normalizer/Component/TypeDocNormalizerTest.php +++ b/tests/Functional/App/Normalizer/Component/TypeDocNormalizerTest.php @@ -48,14 +48,12 @@ public function provideSimpleManagedTypeDocList() 'Simple Doc' => [ 'typeDoc' => new TypeDocNs\TypeDoc(), 'expected' => [ - 'type' => 'string', 'x-nullable' => true, ], ], 'Simple ScalarDoc' => [ 'typeDoc' => new TypeDocNs\ScalarDoc(), 'expected' => [ - 'type' => 'string', 'x-nullable' => true, ], ], @@ -99,7 +97,7 @@ public function provideSimpleManagedTypeDocList() 'expected' => [ 'type' => 'array', 'x-nullable' => true, - 'items' => ['type' => 'string'] + 'items' => [] ], ], 'Simple ArrayDoc' => [ @@ -107,7 +105,7 @@ public function provideSimpleManagedTypeDocList() 'expected' => [ 'type' => 'array', 'x-nullable' => true, - 'items' => ['type' => 'string'] + 'items' => [] ], ], 'Simple ObjectDoc' => [ @@ -138,7 +136,6 @@ public function provideFullyDefinedManagedTypeDocList() ->setDefault('my-default'), 'expected' => [ 'description' => 'my-description', - 'type' => 'string', 'x-nullable' => false, 'default' => 'my-default', 'example' => 'my-example', @@ -155,7 +152,6 @@ public function provideFullyDefinedManagedTypeDocList() ->setDefault('my-default'), 'expected' => [ 'description' => 'my-description', - 'type' => 'string', 'x-nullable' => false, 'default' => 'my-default', 'example' => 'my-example', @@ -290,7 +286,7 @@ public function provideFullyDefinedManagedTypeDocList() 'example' => ['my-example'], 'minItems' => 2, 'maxItems' => 5, - 'items' => ['type' => 'string'], + 'items' => [], ], ], 'Fully defined ArrayDoc' => [ @@ -363,7 +359,6 @@ public function provideBasicManagedTypeDocList() ->addAllowedValue(1) ->addAllowedValue(23), 'expected' => [ - 'type' => 'string', 'x-nullable' => true, 'enum' => [1, 23], ], @@ -376,7 +371,6 @@ public function provideBasicManagedTypeDocList() , 'expected' => [ 'description' => 'my-description', - 'type' => 'string', 'x-nullable' => false, 'example' => 'my-example', ], @@ -474,7 +468,7 @@ public function provideBasicManagedTypeDocList() 'example' => ['my-example'], 'minItems' => 2, 'maxItems' => 5, - 'items' => ['type' => 'string'], + 'items' => [], ], ], 'Basic ObjectDoc' => [