diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b00bc0 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,17 @@ +* text=auto + +/.codecov.yml export-ignore +/.editorconfig export-ignore +/.gitattributes export-ignore +/.github export-ignore +/.gitignore export-ignore +/.phan export-ignore +/.scrutinizer.yml export-ignore +/changelog.md export-ignore +/docs export-ignore +/examples export-ignore +/phpcs.xml.dist export-ignore +/phpdoc.dist.xml export-ignore +/phpunit.xml.dist export-ignore +/test export-ignore +/UPGRADING.md export-ignore diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index af876c8..8f09c87 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,6 +1,10 @@ name: LINT -on: ['push'] +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] jobs: coding-standard: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 385b9f7..208b8f8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,6 +1,10 @@ name: TESTS -on: ['push'] +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] jobs: test: diff --git a/rector.php b/rector.php index 786aa8e..c76e210 100755 --- a/rector.php +++ b/rector.php @@ -23,6 +23,7 @@ use Rector\Privatization\Rector\ClassMethod\PrivatizeFinalClassMethodRector; use Rector\Privatization\Rector\Property\PrivatizeFinalClassPropertyRector; use Rector\Set\ValueObject\SetList; +use Rector\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector; use Rector\TypeDeclaration\Rector\ClassMethod\AddVoidReturnTypeWhereNoReturnRector; use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromReturnDirectArrayRector; use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictNewArrayRector; @@ -64,6 +65,7 @@ ]); $rectorConfig->skip([ + DisallowedEmptyRuleFixerRector::class, CompactToVariablesRector::class, RemoveEmptyClassMethodRector::class, RemoveNonExistingVarAnnotationRector::class, diff --git a/src/Documentations/BodyParamDoc.php b/src/Documentations/BodyParamDoc.php new file mode 100644 index 0000000..dadca8d --- /dev/null +++ b/src/Documentations/BodyParamDoc.php @@ -0,0 +1,37 @@ + $laravelDataClass + * @param array> $attributeArguments + */ + public function __construct( + public string $laravelDataClass, + public array $attributeArguments, + public DocumentationConfig $config, + ) { + } + + /** @return ?array> */ + public function generate(): ?array + { + if (empty($this->laravelDataClass)) { + return null; + } + + $attributesDoc = (new AtrToBodyParamTransform($this->attributeArguments))->transform(); + $bodyParamsDoc = (new BodyParams($this->laravelDataClass, $this->config))->generate(); + + return array_merge($bodyParamsDoc, $attributesDoc); + } +} diff --git a/src/Documentations/Doc.php b/src/Documentations/Doc.php new file mode 100644 index 0000000..5555b59 --- /dev/null +++ b/src/Documentations/Doc.php @@ -0,0 +1,11 @@ +> */ + public function generate(): ?array; +} diff --git a/src/Extractors/Attributes/AttributeExtract.php b/src/Extractors/Attributes/AttributeExtract.php new file mode 100644 index 0000000..d716665 --- /dev/null +++ b/src/Extractors/Attributes/AttributeExtract.php @@ -0,0 +1,11 @@ +> */ + public function extract(): array; +} diff --git a/src/Extractors/Attributes/BodyParamAttributeExtract.php b/src/Extractors/Attributes/BodyParamAttributeExtract.php new file mode 100644 index 0000000..d7185b3 --- /dev/null +++ b/src/Extractors/Attributes/BodyParamAttributeExtract.php @@ -0,0 +1,34 @@ +[] $attributes Method to analyze */ + public function __construct( + public array $attributes, + ) { + } + + /** @return list Get array arguments or empty array */ + public function extract(): array + { + $arguments = []; + + foreach ($this->attributes as $attribute) { + if (!is_a($attribute->getName(), BodyParam::class, true)) { + continue; + } + + $arguments[] = $attribute->getArguments(); + } + + return $arguments; + } +} diff --git a/src/Extractors/Classes/ClassExtract.php b/src/Extractors/Classes/ClassExtract.php new file mode 100644 index 0000000..7cebfe2 --- /dev/null +++ b/src/Extractors/Classes/ClassExtract.php @@ -0,0 +1,10 @@ +method?->getParameters(); + /** @var ReflectionAttribute[] $attributes */ + $attributes = $endpointData->method?->getAttributes(); /** @var class-string $laravelDataClass */ - $laravelDataClass = (new ParametersExtractor($parameters))->extract(); + $laravelDataClass = (new LaravelDataClassExtract($parameters))->extract(); + /** @var array> $attributeArguments */ + $attributeArguments = (new BodyParamAttributeExtract($attributes))->extract(); - if (empty($laravelDataClass)) { - return null; - } - - return (new BodyParams($laravelDataClass, $this->config))->generate(); + return (new BodyParamDoc($laravelDataClass, $attributeArguments, $this->config))->generate(); } } diff --git a/src/Transforms/BodyParam/AtrToBodyParamTransform.php b/src/Transforms/BodyParam/AtrToBodyParamTransform.php new file mode 100644 index 0000000..34bf2bf --- /dev/null +++ b/src/Transforms/BodyParam/AtrToBodyParamTransform.php @@ -0,0 +1,39 @@ +> $attributeArguments */ + public function __construct( + public array $attributeArguments, + ) { + } + + /** @return array> */ + public function transform(): array + { + $argumentsDoc = []; + + foreach ($this->attributeArguments as $arguments) { + try { + /** @phpstan-ignore-next-line */ + $bodyParam = new BodyParam(...$arguments); + + /** @var array $dataDoc */ + $dataDoc = $bodyParam->toArray(); + + $argumentsDoc[$bodyParam->name] = $dataDoc; + } catch (TypeError) { + continue; + } + } + + return $argumentsDoc; + } +} diff --git a/src/Transforms/BodyParam/BodyParamTransform.php b/src/Transforms/BodyParam/BodyParamTransform.php new file mode 100644 index 0000000..39fbdc7 --- /dev/null +++ b/src/Transforms/BodyParam/BodyParamTransform.php @@ -0,0 +1,13 @@ +> + */ + public function transform(): array; +} diff --git a/tests/Fixtures/BodyParams/ParamsAddBodyParamsFromAttr.php b/tests/Fixtures/BodyParams/ParamsAddBodyParamsFromAttr.php new file mode 100644 index 0000000..5d3413c --- /dev/null +++ b/tests/Fixtures/BodyParams/ParamsAddBodyParamsFromAttr.php @@ -0,0 +1,59 @@ + [ + 'name' => 'name', + 'required' => true, + 'type' => 'string', + 'description' => 'Must not be greater than 100 characters.', + 'nullable' => false, + ], + 'description' => [ + 'name' => 'description', + 'required' => true, + 'type' => 'string', + 'description' => 'Must not be greater than 500 characters.', + 'nullable' => false, + ], + 'price' => [ + 'name' => 'price', + 'required' => true, + 'type' => 'number', + 'description' => 'Must be at least 0. Must not be greater than 9999.99.', + 'nullable' => false, + ], + 'items' => [ + 'name' => 'items', + 'required' => true, + 'type' => 'object[]', + 'description' => 'Must have at least 1 items.', + 'nullable' => false, + ], + 'items[].product_id' => [ + 'name' => 'items[].product_id', + 'required' => true, + 'type' => 'integer', + 'description' => 'The id of an existing record in the products table.', + 'nullable' => false, + ], + 'items[].quantity' => [ + 'name' => 'items[].quantity', + 'required' => true, + 'type' => 'integer', + 'description' => 'Must be at least 1. Must not be greater than 10.', + 'nullable' => false, + ], + 'new' => [ + 'name' => 'new', + 'description' => 'add new params', + 'type' => 'string', + 'required' => false, + 'enumValues' => [ + 'Example One', + 'Example Two', + ], + 'nullable' => false, + ], +]; diff --git a/tests/Fixtures/BodyParams/ParamsUpdateAllBodyParamsFromAttr.php b/tests/Fixtures/BodyParams/ParamsUpdateAllBodyParamsFromAttr.php new file mode 100644 index 0000000..6b00b03 --- /dev/null +++ b/tests/Fixtures/BodyParams/ParamsUpdateAllBodyParamsFromAttr.php @@ -0,0 +1,22 @@ + [ + 'name' => 'phone', + 'description' => 'updated phone', + 'type' => 'bool', + 'required' => true, + 'enumValues' => [], + 'nullable' => false, + ], + 'password' => [ + 'name' => 'password', + 'description' => 'updated password', + 'type' => 'string', + 'required' => true, + 'enumValues' => [], + 'nullable' => false, + ], +]; diff --git a/tests/Fixtures/BodyParams/ParamsUpdateOneBodyParamsFromAttr.php b/tests/Fixtures/BodyParams/ParamsUpdateOneBodyParamsFromAttr.php new file mode 100644 index 0000000..a2b1950 --- /dev/null +++ b/tests/Fixtures/BodyParams/ParamsUpdateOneBodyParamsFromAttr.php @@ -0,0 +1,106 @@ + [ + 'name' => 'name', + 'description' => 'updated name', + 'type' => 'int', + 'required' => false, + 'enumValues' => ['one', 'two'], + 'nullable' => true, + ], + 'email' => [ + 'name' => 'email', + 'required' => true, + 'type' => 'string', + 'description' => 'Must be a valid email address.', + 'nullable' => false, + ], + 'price' => [ + 'name' => 'price', + 'required' => true, + 'type' => 'number', + 'description' => 'Must be between 0 and 100.', + 'nullable' => false, + ], + 'age' => [ + 'name' => 'age', + 'required' => true, + 'type' => 'integer', + 'description' => 'Must be at least 18.', + 'nullable' => false, + ], + 'code' => [ + 'name' => 'code', + 'required' => true, + 'type' => 'string', + 'description' => 'Must be 10 characters.', + 'nullable' => false, + ], + 'active' => [ + 'name' => 'active', + 'required' => false, + 'type' => 'boolean', + 'description' => '', + 'nullable' => false, + ], + 'items' => [ + 'name' => 'items', + 'required' => true, + 'type' => 'object', + 'description' => '', + 'nullable' => false, + ], + 'start_date' => [ + 'name' => 'start_date', + 'required' => true, + 'type' => 'string', + 'description' => 'Must be a valid date. Must be a date after today.', + 'nullable' => false, + ], + 'end_date' => [ + 'name' => 'end_date', + 'required' => true, + 'type' => 'string', + 'description' => 'Must be a valid date. Must be a date before start_date.', + 'nullable' => false, + ], + 'status' => [ + 'name' => 'status', + 'required' => true, + 'type' => 'string', + 'description' => '', + 'nullable' => false, + 'enumValues' => ['active', 'inactive', 'pending'], + ], + 'account_type' => [ + 'name' => 'account_type', + 'required' => true, + 'type' => 'string', + 'description' => 'Must not be one of banned or suspended.', + 'nullable' => false, + ], + 'proper_name' => [ + 'name' => 'proper_name', + 'required' => false, + 'type' => 'string', + 'description' => 'Must match the regex /^[A-Z][a-z]+$/.', + 'nullable' => true, + ], + 'website' => [ + 'name' => 'website', + 'required' => true, + 'type' => 'string', + 'description' => 'Must be a valid URL.', + 'nullable' => false, + ], + 'identifier' => [ + 'name' => 'identifier', + 'required' => true, + 'type' => 'string', + 'description' => 'Must be a valid UUID.', + 'nullable' => false, + ], +]; diff --git a/tests/Fixtures/Controllers/LaravelDataController.php b/tests/Fixtures/Controllers/LaravelDataController.php index 5fe1714..f80e0c5 100644 --- a/tests/Fixtures/Controllers/LaravelDataController.php +++ b/tests/Fixtures/Controllers/LaravelDataController.php @@ -4,6 +4,8 @@ namespace Tests\Fixtures\Controllers; +use Knuckles\Scribe\Attributes\BodyParam; +use Tests\Fixtures\Enums\ExampleEnum; use Tests\Fixtures\LaravelData\AttributeRules; use Tests\Fixtures\LaravelData\CustomAttributeRules; use Tests\Fixtures\LaravelData\ManualRules; @@ -57,4 +59,20 @@ public function requestAndLaravelData(RequestRules $requestRules, AttributeRules public function requestAndEmptyLaravelData(RequestRules $requestRules, ParentClassLaravelData $parentClassLaravelData): void { } + + #[BodyParam('name', 'int', 'updated name', false, 1, ['one', 'two'], true)] + public function updateOneBodyParamsFromAttr(AttributeRules $attributeRules): void + { + } + + #[BodyParam('phone', 'bool', 'updated phone', required: true, example: true)] + #[BodyParam('password', 'string', 'updated password', true, 'pass', null, false)] + public function updateAllBodyParamsFromAttr(CustomAttributeRules $customAttributeRules): void + { + } + + #[BodyParam('new', 'string', 'add new params', required: false, example: 'param', enum: ExampleEnum::class)] + public function addBodyParamsFromAttr(ManualRules $manualRules): void + { + } } diff --git a/tests/TestCase.php b/tests/TestCase.php index e888a24..dd7e30e 100755 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -20,6 +20,21 @@ protected function deleteExampleKey(array &$array): void data_forget($array, '*.example'); } + protected function getParamsAddBodyParamsFromAttr(): array + { + return include __DIR__ . '/Fixtures/BodyParams/ParamsAddBodyParamsFromAttr.php'; + } + + protected function getParamsUpdateAllBodyParamsFromAttr(): array + { + return include __DIR__ . '/Fixtures/BodyParams/ParamsUpdateAllBodyParamsFromAttr.php'; + } + + protected function getParamsUpdateOneBodyParamsFromAttr(): array + { + return include __DIR__ . '/Fixtures/BodyParams/ParamsUpdateOneBodyParamsFromAttr.php'; + } + protected function getParamsAttributeRules(): array { return include __DIR__ . '/Fixtures/BodyParams/ParamsAttributeRules.php'; diff --git a/tests/Unit/Documentations/BodyParamDoc/GenerateTest.php b/tests/Unit/Documentations/BodyParamDoc/GenerateTest.php new file mode 100644 index 0000000..7b2e4e3 --- /dev/null +++ b/tests/Unit/Documentations/BodyParamDoc/GenerateTest.php @@ -0,0 +1,261 @@ +method->getParameters()))->extract(), + (new BodyParamAttributeExtract($extractMethod->method->getAttributes()))->extract(), + new DocumentationConfig() + ); + + $result = $doc->generate(); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + + expect($result)->toEqual($this->getParamsAttributeRules()); +}); + +test('generate doc body params from method with customAttributeRules', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'customAttributeRules']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $doc = new BodyParamDoc( + (new LaravelDataClassExtract($extractMethod->method->getParameters()))->extract(), + (new BodyParamAttributeExtract($extractMethod->method->getAttributes()))->extract(), + new DocumentationConfig() + ); + + $result = $doc->generate(); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + + expect($result)->toEqual($this->getParamsCustomAttributeRules()); +}); + +test('generate doc body params from method with manualRules', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'manualRules']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $doc = new BodyParamDoc( + (new LaravelDataClassExtract($extractMethod->method->getParameters()))->extract(), + (new BodyParamAttributeExtract($extractMethod->method->getAttributes()))->extract(), + new DocumentationConfig() + ); + + $result = $doc->generate(); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + + expect($result)->toEqual($this->getParamsManualRules()); +}); + +test('generate doc body params from method with noRules', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'noRules']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $doc = new BodyParamDoc( + (new LaravelDataClassExtract($extractMethod->method->getParameters()))->extract(), + (new BodyParamAttributeExtract($extractMethod->method->getAttributes()))->extract(), + new DocumentationConfig() + ); + + $result = $doc->generate(); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + + expect($result)->toEqual($this->getParamsNoRules()); +}); + +test('generate doc body params from method with withoutLaravelData', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'withoutLaravelData']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $doc = new BodyParamDoc( + (new LaravelDataClassExtract($extractMethod->method->getParameters()))->extract(), + (new BodyParamAttributeExtract($extractMethod->method->getAttributes()))->extract(), + new DocumentationConfig() + ); + + $result = $doc->generate(); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + + expect($result)->toBeEmpty(); +}); + +test('generate doc body params from method with emptyLaravelData', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'emptyLaravelData']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $doc = new BodyParamDoc( + (new LaravelDataClassExtract($extractMethod->method->getParameters()))->extract(), + (new BodyParamAttributeExtract($extractMethod->method->getAttributes()))->extract(), + new DocumentationConfig() + ); + + $result = $doc->generate(); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + + expect($result)->toBeEmpty(); +}); + +test('generate doc body params from method with empty emptyMethod', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'emptyMethod']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $doc = new BodyParamDoc( + (new LaravelDataClassExtract($extractMethod->method->getParameters()))->extract(), + (new BodyParamAttributeExtract($extractMethod->method->getAttributes()))->extract(), + new DocumentationConfig() + ); + + $result = $doc->generate(); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + + expect($result)->toBeEmpty(); +}); + +test('generate doc body params from method with more moreParameters', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'moreParameters']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $doc = new BodyParamDoc( + (new LaravelDataClassExtract($extractMethod->method->getParameters()))->extract(), + (new BodyParamAttributeExtract($extractMethod->method->getAttributes()))->extract(), + new DocumentationConfig() + ); + + $result = $doc->generate(); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + + expect($result)->toBeEmpty(); +}); + +test('generate doc body params from method with requestRules', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'requestRules']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $doc = new BodyParamDoc( + (new LaravelDataClassExtract($extractMethod->method->getParameters()))->extract(), + (new BodyParamAttributeExtract($extractMethod->method->getAttributes()))->extract(), + new DocumentationConfig() + ); + + $result = $doc->generate(); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + + expect($result)->toBeEmpty(); +}); + +test('generate doc body params from method with requestAndLaravelData', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'requestAndLaravelData']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $doc = new BodyParamDoc( + (new LaravelDataClassExtract($extractMethod->method->getParameters()))->extract(), + (new BodyParamAttributeExtract($extractMethod->method->getAttributes()))->extract(), + new DocumentationConfig() + ); + + $result = $doc->generate(); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + + expect($result)->toEqual($this->getParamsAttributeRules()); +}); + +test('generate doc body params from method with updateOneBodyParamsFromAttr', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'updateOneBodyParamsFromAttr']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $doc = new BodyParamDoc( + (new LaravelDataClassExtract($extractMethod->method->getParameters()))->extract(), + (new BodyParamAttributeExtract($extractMethod->method->getAttributes()))->extract(), + new DocumentationConfig() + ); + + $result = $doc->generate(); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + expect($result)->toEqual($this->getParamsUpdateOneBodyParamsFromAttr()); +}); + +test('generate doc body params from method with updateAllBodyParamsFromAttr', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'updateAllBodyParamsFromAttr']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $doc = new BodyParamDoc( + (new LaravelDataClassExtract($extractMethod->method->getParameters()))->extract(), + (new BodyParamAttributeExtract($extractMethod->method->getAttributes()))->extract(), + new DocumentationConfig() + ); + + $result = $doc->generate(); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + + expect($result)->toEqual($this->getParamsUpdateAllBodyParamsFromAttr()); +}); + +test('generate doc body params from method with addBodyParamsFromAttr', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'addBodyParamsFromAttr']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $doc = new BodyParamDoc( + (new LaravelDataClassExtract($extractMethod->method->getParameters()))->extract(), + (new BodyParamAttributeExtract($extractMethod->method->getAttributes()))->extract(), + new DocumentationConfig() + ); + + $result = $doc->generate(); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + + expect($result)->toEqual($this->getParamsAddBodyParamsFromAttr()); +}); + +test('generate doc body params from empty data', function (): void { + $doc = new BodyParamDoc( + '', + [], + new DocumentationConfig() + ); + + $result = $doc->generate(); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + + expect($result)->toBeEmpty(); +}); diff --git a/tests/Unit/Extractors/BodyParamAttributeExtract/ExtractTest.php b/tests/Unit/Extractors/BodyParamAttributeExtract/ExtractTest.php new file mode 100644 index 0000000..72e4485 --- /dev/null +++ b/tests/Unit/Extractors/BodyParamAttributeExtract/ExtractTest.php @@ -0,0 +1,58 @@ +method->getAttributes()); + $result = $attributeArguments->extract(); + + expect($result) + ->toBeArray() + ->toHaveCount(1); +}); + +test('extract body param attribute from updateAllBodyParamsFromAttr', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'updateAllBodyParamsFromAttr']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $attributeArguments = new BodyParamAttributeExtract($extractMethod->method->getAttributes()); + $result = $attributeArguments->extract(); + + expect($result) + ->toBeArray() + ->toHaveCount(2); +}); + +test('extract body param attribute from addBodyParamsFromAttr', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'addBodyParamsFromAttr']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $attributeArguments = new BodyParamAttributeExtract($extractMethod->method->getAttributes()); + $result = $attributeArguments->extract(); + + expect($result) + ->toBeArray() + ->toHaveCount(1); +}); + +test('extract body param attribute from emptyLaravelData', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'emptyLaravelData']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $attributeArguments = new BodyParamAttributeExtract($extractMethod->method->getAttributes()); + $result = $attributeArguments->extract(); + + expect($result) + ->toBeArray() + ->toBeEmpty(); +}); diff --git a/tests/Unit/Extractors/ParametersExtractor/ExtractTest.php b/tests/Unit/Extractors/LaravelDataClassExtract/ExtractTest.php similarity index 73% rename from tests/Unit/Extractors/ParametersExtractor/ExtractTest.php rename to tests/Unit/Extractors/LaravelDataClassExtract/ExtractTest.php index 688f9ca..10dc899 100644 --- a/tests/Unit/Extractors/ParametersExtractor/ExtractTest.php +++ b/tests/Unit/Extractors/LaravelDataClassExtract/ExtractTest.php @@ -2,21 +2,21 @@ declare(strict_types=1); -namespace Tests\Unit\Extractors\ParametersExtractor; +namespace Tests\Unit\Extractors\LaravelDataClassExtract; -use DenisKorbakov\LaravelDataScribe\Extractors\ParametersExtractor; +use DenisKorbakov\LaravelDataScribe\Extractors\Classes\LaravelDataClassExtract; use Illuminate\Routing\Route; use Knuckles\Camel\Extraction\ExtractedEndpointData; use Tests\Fixtures\Controllers\LaravelDataController; use Tests\Fixtures\ParentClasses\ParentClassLaravelData; -mutates(ParametersExtractor::class); +mutates(LaravelDataClassExtract::class); test('extract class laravel data from emptyLaravelData', function (): void { $route = new Route('', '', [LaravelDataController::class, 'emptyLaravelData']); $extractMethod = ExtractedEndpointData::fromRoute($route); - $laravelDataExtractor = new ParametersExtractor($extractMethod->method->getParameters()); + $laravelDataExtractor = new LaravelDataClassExtract($extractMethod->method->getParameters()); $result = $laravelDataExtractor->extract(); @@ -27,7 +27,7 @@ $route = new Route('', '', [LaravelDataController::class, 'withoutLaravelData']); $extractMethod = ExtractedEndpointData::fromRoute($route); - $laravelDataExtractor = new ParametersExtractor($extractMethod->method->getParameters()); + $laravelDataExtractor = new LaravelDataClassExtract($extractMethod->method->getParameters()); $result = $laravelDataExtractor->extract(); @@ -38,7 +38,7 @@ $route = new Route('', '', [LaravelDataController::class, 'emptyMethod']); $extractMethod = ExtractedEndpointData::fromRoute($route); - $laravelDataExtractor = new ParametersExtractor($extractMethod->method->getParameters()); + $laravelDataExtractor = new LaravelDataClassExtract($extractMethod->method->getParameters()); $result = $laravelDataExtractor->extract(); @@ -49,7 +49,7 @@ $route = new Route('', '', [LaravelDataController::class, 'moreParameters']); $extractMethod = ExtractedEndpointData::fromRoute($route); - $laravelDataExtractor = new ParametersExtractor($extractMethod->method->getParameters()); + $laravelDataExtractor = new LaravelDataClassExtract($extractMethod->method->getParameters()); $result = $laravelDataExtractor->extract(); @@ -60,7 +60,7 @@ $route = new Route('', '', [LaravelDataController::class, 'requestRules']); $extractMethod = ExtractedEndpointData::fromRoute($route); - $laravelDataExtractor = new ParametersExtractor($extractMethod->method->getParameters()); + $laravelDataExtractor = new LaravelDataClassExtract($extractMethod->method->getParameters()); $result = $laravelDataExtractor->extract(); @@ -71,7 +71,7 @@ $route = new Route('', '', [LaravelDataController::class, 'requestAndEmptyLaravelData']); $extractMethod = ExtractedEndpointData::fromRoute($route); - $laravelDataExtractor = new ParametersExtractor($extractMethod->method->getParameters()); + $laravelDataExtractor = new LaravelDataClassExtract($extractMethod->method->getParameters()); $result = $laravelDataExtractor->extract(); diff --git a/tests/Unit/LaravelDataBodyParamTest.php b/tests/Unit/LaravelDataBodyParamTest.php index 65a54b2..486d683 100644 --- a/tests/Unit/LaravelDataBodyParamTest.php +++ b/tests/Unit/LaravelDataBodyParamTest.php @@ -129,3 +129,39 @@ expect($result)->toEqual($this->getParamsAttributeRules()); }); + +test('generate doc body params from method with updateOneBodyParamsFromAttr', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'updateOneBodyParamsFromAttr']); + $laravelDataBodyParam = new LaravelDataBodyParam(new DocumentationConfig()); + + $result = $laravelDataBodyParam(ExtractedEndpointData::fromRoute($route)); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + + expect($result)->toEqual($this->getParamsUpdateOneBodyParamsFromAttr()); +}); + +test('generate doc body params from method with updateAllBodyParamsFromAttr', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'updateAllBodyParamsFromAttr']); + $laravelDataBodyParam = new LaravelDataBodyParam(new DocumentationConfig()); + + $result = $laravelDataBodyParam(ExtractedEndpointData::fromRoute($route)); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + + expect($result)->toEqual($this->getParamsUpdateAllBodyParamsFromAttr()); +}); + +test('generate doc body params from method with addBodyParamsFromAttr', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'addBodyParamsFromAttr']); + $laravelDataBodyParam = new LaravelDataBodyParam(new DocumentationConfig()); + + $result = $laravelDataBodyParam(ExtractedEndpointData::fromRoute($route)); + if (is_array($result)) { + $this->deleteExampleKey($result); + } + + expect($result)->toEqual($this->getParamsAddBodyParamsFromAttr()); +}); diff --git a/tests/Unit/Transforms/AtrToBodyParamTransform/TransformTest.php b/tests/Unit/Transforms/AtrToBodyParamTransform/TransformTest.php new file mode 100644 index 0000000..f6981c2 --- /dev/null +++ b/tests/Unit/Transforms/AtrToBodyParamTransform/TransformTest.php @@ -0,0 +1,90 @@ +method->getAttributes()))->extract(); + $result = (new AtrToBodyParamTransform($attributeArguments))->transform(); + + expect($result) + ->toBeArray() + ->toHaveCount(1); +}); + +test('transform to body param from updateAllBodyParamsFromAttr', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'updateAllBodyParamsFromAttr']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $attributeArguments = (new BodyParamAttributeExtract($extractMethod->method->getAttributes()))->extract(); + $result = (new AtrToBodyParamTransform($attributeArguments))->transform(); + + expect($result) + ->toBeArray() + ->toHaveCount(2); +}); + +test('transform to body param from addBodyParamsFromAttr', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'addBodyParamsFromAttr']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $attributeArguments = (new BodyParamAttributeExtract($extractMethod->method->getAttributes()))->extract(); + $result = (new AtrToBodyParamTransform($attributeArguments))->transform(); + + expect($result) + ->toBeArray() + ->toHaveCount(1); +}); + +test('transform to body param from emptyLaravelData', function (): void { + $route = new Route('', '', [LaravelDataController::class, 'emptyLaravelData']); + $extractMethod = ExtractedEndpointData::fromRoute($route); + + $attributeArguments = (new BodyParamAttributeExtract($extractMethod->method->getAttributes()))->extract(); + $result = (new AtrToBodyParamTransform($attributeArguments))->transform(); + + expect($result) + ->toBeArray() + ->toBeEmpty(); +}); + +test('transform to body param from []', function (): void { + $result = (new AtrToBodyParamTransform([]))->transform(); + + expect($result) + ->toBeArray() + ->toBeEmpty(); +}); + +test('transform to body param from other args', function (): void { + $args = [['random', 'args', 123, true]]; + $result = (new AtrToBodyParamTransform($args))->transform(); + + expect($result) + ->toBeArray() + ->toBeEmpty(); +}); + +test('transform to body param from more arg', function (): void { + $args = [ + ['name', 'int', 'updated name', false, 1, ['one', 'two'], true], + ['random', 'args', 123, true], + ['name 2', 'string', 'updated name 2', true, 'test', ExampleEnum::class, false], + ]; + $result = (new AtrToBodyParamTransform($args))->transform(); + + expect($result) + ->toBeArray() + ->toHaveCount(2); +});