Skip to content

Commit

Permalink
Support merging of parameter data from successive stages
Browse files Browse the repository at this point in the history
  • Loading branch information
shalvah committed Aug 4, 2022
1 parent 936ddce commit d29718c
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Nested response fields are now collapsed ([00b09bb](https://github.com/knuckleswtf/scribe/commit/00b09bbea8ec64006db864bf807004d48926c6d3))
- Inlined routes (no more Scribe/Controller class)
- Changed signature of Strategy#invoke ($routeRules is now optional)
- Parameter data from successive stages is now merged

## 3.35.0 (27 July 2022)
### Modified
Expand Down
10 changes: 8 additions & 2 deletions camel/BaseDTO.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,19 @@ class BaseDTO extends DataTransferObject implements Arrayable
*/
public array $custom = [];

public static function create(BaseDTO|array $data): static
public static function create(BaseDTO|array $data, BaseDTO|array $inheritFrom = []): static
{
if ($data instanceof static) {
return $data;
}

return new static($data);
$mergedData = $inheritFrom instanceof static ? $inheritFrom->toArray() : $inheritFrom;

foreach ($data as $property => $value) {
$mergedData[$property] = $value;
}

return new static($mergedData);
}

protected function parseArray(array $array): array
Expand Down
8 changes: 4 additions & 4 deletions src/Extracting/Extractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ protected function fetchUrlParameters(ExtractedEndpointData $endpointData, array
if (empty($item['name'])) {
$item['name'] = $key;
}
$endpointData->urlParameters[$key] = Parameter::create($item);
$endpointData->urlParameters[$key] = Parameter::create($item, $endpointData->urlParameters[$key] ?? []);
}
});
}
Expand All @@ -127,7 +127,7 @@ protected function fetchQueryParameters(ExtractedEndpointData $endpointData, arr
if (empty($item['name'])) {
$item['name'] = $key;
}
$endpointData->queryParameters[$key] = Parameter::create($item);
$endpointData->queryParameters[$key] = Parameter::create($item, $endpointData->queryParameters[$key] ?? []);
}
});
}
Expand All @@ -139,7 +139,7 @@ protected function fetchBodyParameters(ExtractedEndpointData $endpointData, arra
if (empty($item['name'])) {
$item['name'] = $key;
}
$endpointData->bodyParameters[$key] = Parameter::create($item);
$endpointData->bodyParameters[$key] = Parameter::create($item, $endpointData->bodyParameters[$key] ?? []);
}
});
}
Expand All @@ -158,7 +158,7 @@ protected function fetchResponseFields(ExtractedEndpointData $endpointData, arra
{
$this->iterateThroughStrategies('responseFields', $endpointData, $rulesToApply, function ($results) use ($endpointData) {
foreach ($results as $key => $item) {
$endpointData->responseFields[$key] = ResponseField::create($item);
$endpointData->responseFields[$key] = Parameter::create($item, $endpointData->responseFields[$key] ?? []);
}
});
}
Expand Down
2 changes: 2 additions & 0 deletions src/Extracting/Strategies/UrlParameters/GetFromLaravelAPI.php
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ protected function setTypesAndExamplesForOthers(array $parameters, ExtractedEndp
protected function getNameOfUrlThing(string $url, string $paramName, string $alternateParamName = null): ?string
{
$parts = explode("/", $url);
if (count($parts) === 1) return null; // URL was "/{thing}"

$paramIndex = array_search("{{$paramName}}", $parts);

if ($paramIndex === false) {
Expand Down
31 changes: 16 additions & 15 deletions tests/Unit/ExtractorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
use Illuminate\Routing\Route;
use Knuckles\Camel\Extraction\Parameter;
use Knuckles\Scribe\Attributes\UrlParam;
use Knuckles\Scribe\Extracting\Extractor;
use Knuckles\Scribe\Tests\Fixtures\TestController;
use Knuckles\Scribe\Tools\DocumentationConfig;
Expand Down Expand Up @@ -133,7 +134,7 @@ public function clean_can_properly_parse_array_keys()
/** @test */
public function does_not_generate_values_for_excluded_params_and_excludes_them_from_clean_params()
{
$route = $this->createRoute('POST', '/api/test', 'withExcludedExamples');
$route = $this->createRouteOldSyntax('POST', '/api/test', 'withExcludedExamples');
$parsed = $this->extractor->processRoute($route)->toArray();
$cleanBodyParameters = $parsed['cleanBodyParameters'];
$cleanQueryParameters = $parsed['cleanQueryParameters'];
Expand Down Expand Up @@ -166,19 +167,19 @@ public function does_not_generate_values_for_excluded_params_and_excludes_them_f
/** @test */
public function can_parse_route_methods()
{
$route = $this->createRoute('GET', '/get', 'withEndpointDescription');
$route = $this->createRouteOldSyntax('GET', '/get', 'withEndpointDescription');
$parsed = $this->extractor->processRoute($route);
$this->assertEquals(['GET'], $parsed->httpMethods);

$route = $this->createRoute('POST', '/post', 'withEndpointDescription');
$route = $this->createRouteOldSyntax('POST', '/post', 'withEndpointDescription');
$parsed = $this->extractor->processRoute($route);
$this->assertEquals(['POST'], $parsed->httpMethods);

$route = $this->createRoute('PUT', '/put', 'withEndpointDescription');
$route = $this->createRouteOldSyntax('PUT', '/put', 'withEndpointDescription');
$parsed = $this->extractor->processRoute($route);
$this->assertEquals(['PUT'], $parsed->httpMethods);

$route = $this->createRoute('DELETE', '/delete', 'withEndpointDescription');
$route = $this->createRouteOldSyntax('DELETE', '/delete', 'withEndpointDescription');
$parsed = $this->extractor->processRoute($route);
$this->assertEquals(['DELETE'], $parsed->httpMethods);
}
Expand All @@ -189,7 +190,7 @@ public function can_parse_route_methods()
*/
public function adds_appropriate_field_based_on_configured_auth_type($config, $expected)
{
$route = $this->createRoute('POST', '/withAuthenticatedTag', 'withAuthenticatedTag', true);
$route = $this->createRouteOldSyntax('POST', '/withAuthenticatedTag', 'withAuthenticatedTag');
$generator = new Extractor(new DocumentationConfig(array_merge($this->config, $config)));
$parsed = $generator->processRoute($route, [])->toArray();
$this->assertNotNull($parsed[$expected['where']][$expected['name']]);
Expand All @@ -200,7 +201,7 @@ public function adds_appropriate_field_based_on_configured_auth_type($config, $e
/** @test */
public function generates_consistent_examples_when_faker_seed_is_set()
{
$route = $this->createRoute('POST', '/withBodyParameters', 'withBodyParameters');
$route = $this->createRouteOldSyntax('POST', '/withBodyParameters', 'withBodyParameters');

$paramName = 'room_id';
$results = [];
Expand All @@ -225,7 +226,7 @@ public function generates_consistent_examples_when_faker_seed_is_set()
/** @test */
public function can_use_arrays_in_routes_uses()
{
$route = $this->createRouteUsesArray('GET', '/api/array/test', 'withEndpointDescription');
$route = $this->createRoute('GET', '/api/array/test', 'withEndpointDescription');

$parsed = $this->extractor->processRoute($route);

Expand All @@ -245,7 +246,7 @@ public function can_use_closure_in_routes_uses()
* @bodyParam name required Name of the location
*/
$handler = fn () => 'hi';
$route = $this->createRouteUsesCallable('POST', '/api/closure/test', $handler);
$route = $this->createClosureRoute('POST', '/api/closure/test', $handler);

$parsed = $this->extractor->processRoute($route);

Expand All @@ -260,22 +261,22 @@ public function can_use_closure_in_routes_uses()
/** @test */
public function endpoint_metadata_supports_custom_declarations()
{
$route = $this->createRoute('POST', '/api/test', 'dummy');
$route = $this->createRouteOldSyntax('POST', '/api/test', 'dummy');
$parsed = $this->extractor->processRoute($route);
$this->assertSame('some custom metadata', $parsed->metadata->custom['myProperty']);
}

public function createRoute(string $httpMethod, string $path, string $controllerMethod, $register = false, $class = TestController::class)
public function createRoute(string $httpMethod, string $path, string $controllerMethod, $class = TestController::class)
{
return new Route([$httpMethod], $path, ['uses' => $class . "@$controllerMethod"]);
return new Route([$httpMethod], $path, ['uses' => [$class, $controllerMethod]]);
}

public function createRouteUsesArray(string $httpMethod, string $path, string $controllerMethod, $register = false, $class = TestController::class)
public function createRouteOldSyntax(string $httpMethod, string $path, string $controllerMethod, $class = TestController::class)
{
return new Route([$httpMethod], $path, ['uses' => [$class, $controllerMethod]]);
return new Route([$httpMethod], $path, ['uses' => $class . "@$controllerMethod"]);
}

public function createRouteUsesCallable(string $httpMethod, string $path, callable $handler, $register = false)
public function createClosureRoute(string $httpMethod, string $path, callable $handler)
{
return new Route([$httpMethod], $path, ['uses' => $handler]);
}
Expand Down

0 comments on commit d29718c

Please sign in to comment.