No flags found
Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.
e.g., #unittest #integration
#production #enterprise
#frontend #backend
248a052
... +21 ...
f98914a
Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.
e.g., #unittest #integration
#production #enterprise
#frontend #backend
19 | 19 | } |
|
20 | 20 | ||
21 | 21 | /** |
|
22 | - | * @param array $action |
|
22 | + | * @param array|Route $routeOrAction |
|
23 | 23 | * |
|
24 | 24 | * @return array|null |
|
25 | 25 | */ |
|
26 | - | public static function getRouteActionUses(array $action) |
|
26 | + | public static function getRouteClassAndMethodNames($routeOrAction) |
|
27 | 27 | { |
|
28 | + | $action = $routeOrAction instanceof Route ? $routeOrAction->getAction() : $routeOrAction; |
|
29 | + | ||
28 | 30 | if ($action['uses'] !== null) { |
|
29 | 31 | if (is_array($action['uses'])) { |
|
30 | 32 | return $action['uses']; |
1 | + | <?php |
|
2 | + | ||
3 | + | namespace Mpociot\ApiDoc\Strategies\Responses; |
|
4 | + | ||
5 | + | use Illuminate\Routing\Route; |
|
6 | + | use Mpociot\Reflection\DocBlock; |
|
7 | + | use Mpociot\Reflection\DocBlock\Tag; |
|
8 | + | use Mpociot\ApiDoc\Strategies\Strategy; |
|
9 | + | use Mpociot\ApiDoc\Tools\RouteDocBlocker; |
|
10 | + | ||
11 | + | /** |
|
12 | + | * Get a response from the docblock ( @response ). |
|
13 | + | */ |
|
14 | + | class UseResponseTag extends Strategy |
|
15 | + | { |
|
16 | + | /** |
|
17 | + | * @param Route $route |
|
18 | + | * @param \ReflectionClass $controller |
|
19 | + | * @param \ReflectionMethod $method |
|
20 | + | * @param array $routeRules |
|
21 | + | * @param array $context |
|
22 | + | * |
|
23 | + | * @throws \Exception |
|
24 | + | * |
|
25 | + | * @return array|null |
|
26 | + | */ |
|
27 | + | public function __invoke(Route $route, \ReflectionClass $controller, \ReflectionMethod $method, array $routeRules, array $context = []) |
|
28 | + | { |
|
29 | + | $docBlocks = RouteDocBlocker::getDocBlocksFromRoute($route); |
|
30 | + | /** @var DocBlock $methodDocBlock */ |
|
31 | + | $methodDocBlock = $docBlocks['method']; |
|
32 | + | ||
33 | + | return $this->getDocBlockResponses($methodDocBlock->getTags()); |
|
34 | + | } |
|
35 | + | ||
36 | + | /** |
|
37 | + | * Get the response from the docblock if available. |
|
38 | + | * |
|
39 | + | * @param array $tags |
|
40 | + | * |
|
41 | + | * @return array|null |
|
42 | + | */ |
|
43 | + | protected function getDocBlockResponses(array $tags) |
|
44 | + | { |
|
45 | + | $responseTags = array_values( |
|
46 | + | array_filter($tags, function ($tag) { |
|
47 | + | return $tag instanceof Tag && strtolower($tag->getName()) === 'response'; |
|
48 | + | }) |
|
49 | + | ); |
|
50 | + | ||
51 | + | if (empty($responseTags)) { |
|
52 | + | return null; |
|
53 | + | } |
|
54 | + | ||
55 | + | $responses = array_map(function (Tag $responseTag) { |
|
56 | + | preg_match('/^(\d{3})?\s?([\s\S]*)$/', $responseTag->getContent(), $result); |
|
57 | + | ||
58 | + | $status = $result[1] ?: 200; |
|
59 | + | $content = $result[2] ?: '{}'; |
|
60 | + | ||
61 | + | return [$content, (int) $status]; |
|
62 | + | }, $responseTags); |
|
63 | + | ||
64 | + | // Convert responses to [200 => 'response', 401 => 'response'] |
|
65 | + | return collect($responses)->pluck('0', '1')->toArray(); |
|
66 | + | } |
|
67 | + | } |
1 | + | <?php |
|
2 | + | ||
3 | + | namespace Mpociot\ApiDoc\Tools\Traits; |
|
4 | + | ||
5 | + | use Mpociot\Reflection\DocBlock\Tag; |
|
6 | + | ||
7 | + | trait DocBlockParamHelpers |
|
8 | + | { |
|
9 | + | use ParamHelpers; |
|
10 | + | ||
11 | + | /** |
|
12 | + | * Allows users to specify that we shouldn't generate an example for the parameter |
|
13 | + | * by writing 'No-example'. |
|
14 | + | * |
|
15 | + | * @param Tag $tag |
|
16 | + | * |
|
17 | + | * @return bool Whether no example should be generated |
|
18 | + | */ |
|
19 | + | protected function shouldExcludeExample(Tag $tag) |
|
20 | + | { |
|
21 | + | return strpos($tag->getContent(), ' No-example') !== false; |
|
22 | + | } |
|
23 | + | ||
24 | + | /** |
|
25 | + | * Allows users to specify an example for the parameter by writing 'Example: the-example', |
|
26 | + | * to be used in example requests and response calls. |
|
27 | + | * |
|
28 | + | * @param string $description |
|
29 | + | * @param string $type The type of the parameter. Used to cast the example provided, if any. |
|
30 | + | * |
|
31 | + | * @return array The description and included example. |
|
32 | + | */ |
|
33 | + | protected function parseParamDescription(string $description, string $type) |
|
34 | + | { |
|
35 | + | $example = null; |
|
36 | + | if (preg_match('/(.*)\s+Example:\s*(.*)\s*/', $description, $content)) { |
|
37 | + | $description = $content[1]; |
|
38 | + | ||
39 | + | // examples are parsed as strings by default, we need to cast them properly |
|
40 | + | $example = $this->castToType($content[2], $type); |
|
41 | + | } |
|
42 | + | ||
43 | + | return [$description, $example]; |
|
44 | + | } |
|
45 | + | } |
247 | 247 | */ |
|
248 | 248 | private function isValidRoute(Route $route) |
|
249 | 249 | { |
|
250 | - | $action = Utils::getRouteActionUses($route->getAction()); |
|
250 | + | $action = Utils::getRouteClassAndMethodNames($route->getAction()); |
|
251 | 251 | if (is_array($action)) { |
|
252 | 252 | $action = implode('@', $action); |
|
253 | 253 | } |
264 | 264 | */ |
|
265 | 265 | private function isRouteVisibleForDocumentation(array $action) |
|
266 | 266 | { |
|
267 | - | list($class, $method) = Utils::getRouteActionUses($action); |
|
267 | + | list($class, $method) = Utils::getRouteClassAndMethodNames($action); |
|
268 | 268 | $reflection = new ReflectionClass($class); |
|
269 | 269 | ||
270 | 270 | if (! $reflection->hasMethod($method)) { |
2 | 2 | ||
3 | 3 | namespace Mpociot\ApiDoc\Tools\Traits; |
|
4 | 4 | ||
5 | - | use Illuminate\Support\Arr; |
|
6 | - | use Illuminate\Support\Str; |
|
5 | + | use Faker\Factory; |
|
7 | 6 | ||
8 | 7 | trait ParamHelpers |
|
9 | 8 | { |
|
9 | + | protected function generateDummyValue(string $type) |
|
10 | + | { |
|
11 | + | $faker = Factory::create(); |
|
12 | + | if ($this->config->get('faker_seed')) { |
|
13 | + | $faker->seed($this->config->get('faker_seed')); |
|
14 | + | } |
|
15 | + | $fakeFactories = [ |
|
16 | + | 'integer' => function () use ($faker) { |
|
17 | + | return $faker->numberBetween(1, 20); |
|
18 | + | }, |
|
19 | + | 'number' => function () use ($faker) { |
|
20 | + | return $faker->randomFloat(); |
|
21 | + | }, |
|
22 | + | 'float' => function () use ($faker) { |
|
23 | + | return $faker->randomFloat(); |
|
24 | + | }, |
|
25 | + | 'boolean' => function () use ($faker) { |
|
26 | + | return $faker->boolean(); |
|
27 | + | }, |
|
28 | + | 'string' => function () use ($faker) { |
|
29 | + | return $faker->word; |
|
30 | + | }, |
|
31 | + | 'array' => function () { |
|
32 | + | return []; |
|
33 | + | }, |
|
34 | + | 'object' => function () { |
|
35 | + | return new \stdClass; |
|
36 | + | }, |
|
37 | + | ]; |
|
38 | + | ||
39 | + | $fakeFactory = $fakeFactories[$type] ?? $fakeFactories['string']; |
|
40 | + | ||
41 | + | return $fakeFactory(); |
|
42 | + | } |
|
43 | + | ||
10 | 44 | /** |
|
11 | - | * Create proper arrays from dot-noted parameter names. Also filter out parameters which were excluded from having examples. |
|
45 | + | * Cast a value from a string to a specified type. |
|
12 | 46 | * |
|
13 | - | * @param array $params |
|
47 | + | * @param string $value |
|
48 | + | * @param string $type |
|
14 | 49 | * |
|
15 | - | * @return array |
|
50 | + | * @return mixed |
|
16 | 51 | */ |
|
17 | - | protected function cleanParams(array $params) |
|
52 | + | protected function castToType(string $value, string $type) |
|
18 | 53 | { |
|
19 | - | $values = []; |
|
20 | - | $params = array_filter($params, function ($details) { |
|
21 | - | return ! is_null($details['value']); |
|
22 | - | }); |
|
54 | + | $casts = [ |
|
55 | + | 'integer' => 'intval', |
|
56 | + | 'number' => 'floatval', |
|
57 | + | 'float' => 'floatval', |
|
58 | + | 'boolean' => 'boolval', |
|
59 | + | ]; |
|
60 | + | ||
61 | + | // First, we handle booleans. We can't use a regular cast, |
|
62 | + | //because PHP considers string 'false' as true. |
|
63 | + | if ($value == 'false' && $type == 'boolean') { |
|
64 | + | return false; |
|
65 | + | } |
|
23 | 66 | ||
24 | - | foreach ($params as $name => $details) { |
|
25 | - | $this->cleanValueFrom($name, $details['value'], $values); |
|
67 | + | if (isset($casts[$type])) { |
|
68 | + | return $casts[$type]($value); |
|
26 | 69 | } |
|
27 | 70 | ||
28 | - | return $values; |
|
71 | + | return $value; |
|
29 | 72 | } |
|
30 | 73 | ||
31 | 74 | /** |
|
32 | - | * Converts dot notation names to arrays and sets the value at the right depth. |
|
75 | + | * Normalizes the stated "type" of a parameter (eg "int", "integer", "double") |
|
76 | + | * to a number of standard types (integer, boolean, float). |
|
33 | 77 | * |
|
34 | - | * @param string $name |
|
35 | - | * @param mixed $value |
|
36 | - | * @param array $values The array that holds the result |
|
78 | + | * @param string $type |
|
37 | 79 | * |
|
38 | - | * @return void |
|
80 | + | * @return mixed|string |
|
39 | 81 | */ |
|
40 | - | protected function cleanValueFrom($name, $value, array &$values = []) |
|
82 | + | protected function normalizeParameterType(string $type) |
|
41 | 83 | { |
|
42 | - | if (Str::contains($name, '[')) { |
|
43 | - | $name = str_replace(['][', '[', ']', '..'], ['.', '.', '', '.*.'], $name); |
|
44 | - | } |
|
45 | - | Arr::set($values, str_replace('.*', '.0', $name), $value); |
|
84 | + | $typeMap = [ |
|
85 | + | 'int' => 'integer', |
|
86 | + | 'bool' => 'boolean', |
|
87 | + | 'double' => 'float', |
|
88 | + | ]; |
|
89 | + | ||
90 | + | return $type ? ($typeMap[$type] ?? $type) : 'string'; |
|
46 | 91 | } |
|
47 | 92 | } |
Learn more Showing 7 files with coverage changes found.
src/Strategies/BodyParameters/GetFromBodyParamTag.php
src/Strategies/Strategy.php
src/Strategies/Metadata/GetFromDocBlocks.php
src/Strategies/Responses/UseResponseTag.php
src/Tools/Traits/DocBlockParamHelpers.php
src/Strategies/QueryParameters/GetFromQueryParamTag.php
src/Tools/RouteDocBlocker.php
Files | Complexity | Coverage |
---|---|---|
src | ø | 0.43% 90.86% |
Project Totals (19 files) | 315 | 90.86% |
f98914a
ec8f257
555fb86
90560e9
44bdabe
f86286e
a2f3e7f
c5ae3ae
ffb3563
2d1be5b
4572ffe
1a0bff3
ffee319
7ae97a0
a5b1fb6
c3cc561
148dabf
1da32f9
d209dff
c0ecc1b
29df468
67c61fe
248a052