ソースを参照

Add support for multiple scenario descriptions in @responseFile tag

shalvah 5 年 前
コミット
9a5c51617d

+ 20 - 7
src/Extracting/Strategies/Responses/UseResponseFileTag.php

@@ -5,6 +5,7 @@ namespace Knuckles\Scribe\Extracting\Strategies\Responses;
 use Illuminate\Routing\Route;
 use Knuckles\Scribe\Extracting\RouteDocBlocker;
 use Knuckles\Scribe\Extracting\Strategies\Strategy;
+use Knuckles\Scribe\Tools\AnnotationParser;
 use Mpociot\Reflection\DocBlock;
 use Mpociot\Reflection\DocBlock\Tag;
 
@@ -54,18 +55,30 @@ class UseResponseFileTag extends Strategy
         }
 
         $responses = array_map(function (Tag $responseFileTag) {
-            preg_match('/^(\d{3})?\s?([\S]*[\s]*?)(\{.*\})?$/', $responseFileTag->getContent(), $result);
-            $relativeFilePath = trim($result[2]);
+            preg_match('/^(\d{3})?\s*(.*?)({.*})?$/', $responseFileTag->getContent(), $result);
+            [$_, $status, $mainContent] = $result;
+            $json = $result[3] ?? null;
+
+            ['attributes' => $attributes, 'content' => $relativeFilePath] = AnnotationParser::parseIntoContentAndAttributes($mainContent, ['status', 'scenario']);
+
+            $status = $attributes['status'] ?: ($status ?: 200);
+            $description = $attributes['scenario'] ? "$status, {$attributes['scenario']}" : "$status";
+
             $filePath = storage_path($relativeFilePath);
             if (! file_exists($filePath)) {
                 throw new \Exception('@responseFile ' . $relativeFilePath . ' does not exist');
             }
-            $status = $result[1] ?: 200;
-            $content = $result[2] ? file_get_contents($filePath, true) : '{}';
-            $json = ! empty($result[3]) ? str_replace("'", '"', $result[3]) : '{}';
-            $merged = array_merge(json_decode($content, true), json_decode($json, true));
+            $content = file_get_contents($filePath, true);
+            if ($json) {
+                $json = str_replace("'", '"', $json);
+                $content = json_encode(array_merge(json_decode($content, true), json_decode($json, true)));
+            }
 
-            return ['content' => json_encode($merged), 'status' => (int) $status];
+            return [
+                'content' => $content,
+                'status' => (int) $status,
+                'description' => $description
+            ];
         }, $responseFileTags);
 
         return $responses;

+ 2 - 1
src/Tools/AnnotationParser.php

@@ -31,7 +31,8 @@ class AnnotationParser
         if (count($result) == 1) { // No key-value pairs
             return [
                 'content' => trim($result[0]),
-                'attributes' => $defaults];
+                'attributes' => $defaults
+            ];
         }
 
         // Separate the main content

+ 48 - 30
tests/Extracting/Strategies/Responses/UseResponseFileTagTest.php

@@ -20,51 +20,30 @@ class UseResponseFileTagTest extends TestCase
         ];
     }
 
-    /** @test */
-    public function can_fetch_from_responsefile_tag()
+    /**
+     * @test
+     * @dataProvider responseFileTags
+     */
+    public function allows_multiple_responsefile_tags_for_multiple_statuses_and_scenarios(array $tags, array $expected)
     {
-        $filePath = __DIR__ . '/../../../Fixtures/response_test.json';
-        copy($filePath, storage_path('response_test.json'));
-
-        $strategy = new UseResponseFileTag(new DocumentationConfig([]));
-        $tags = [
-            new Tag('responseFile', 'response_test.json'),
-        ];
-        $results = $strategy->getFileResponses($tags);
-
-        $fixtureFileJson = file_get_contents($filePath);
-        $this->assertArraySubset([
-            [
-                'status' => 200,
-                'content' => $fixtureFileJson,
-            ],
-        ], $results);
-
-        unlink(storage_path('response_test.json'));
-    }
+        $filePath =  __DIR__ . '/../../../Fixtures/response_test.json';
+        $filePath2 =  __DIR__ . '/../../../Fixtures/response_error_test.json';
 
-    /** @test */
-    public function allows_multiple_responsefile_tags_for_multiple_statuses()
-    {
-        $filePath = __DIR__ . '/../../../Fixtures/response_test.json';
-        $filePath2 = __DIR__ . '/../../../Fixtures/response_error_test.json';
         copy($filePath, storage_path('response_test.json'));
         copy($filePath2, storage_path('response_error_test.json'));
 
         $strategy = new UseResponseFileTag(new DocumentationConfig([]));
-        $tags = [
-            new Tag('responseFile', '200 response_test.json'),
-            new Tag('responseFile', '401 response_error_test.json'),
-        ];
         $results = $strategy->getFileResponses($tags);
 
         $this->assertArraySubset([
             [
                 'status' => 200,
+                'description' => $expected[0]['description'],
                 'content' => file_get_contents($filePath),
             ],
             [
                 'status' => 401,
+                'description' => $expected[1]['description'],
                 'content' => file_get_contents($filePath2),
             ],
         ], $results);
@@ -93,4 +72,43 @@ class UseResponseFileTagTest extends TestCase
             ],
         ], $results);
     }
+
+    public function responseFileTags()
+    {
+        return [
+            "with status as initial position" => [
+                [
+                    new Tag('responseFile', 'response_test.json'),
+                    new Tag('responseFile', '401 response_error_test.json'),
+                ],
+                [
+                    [
+                        'status' => 200,
+                        'description' => '200',
+                    ],
+                    [
+                        'status' => 401,
+                        'description' => '401',
+                    ],
+                ],
+            ],
+
+            "with attributes" => [
+                [
+                    new Tag('responseFile', 'scenario="success" response_test.json'),
+                    new Tag('responseFile', 'status=401 scenario=\'auth problem\' response_error_test.json'),
+                ],
+                [
+                    [
+                        'status' => 200,
+                        'description' => '200, success',
+                    ],
+                    [
+                        'status' => 401,
+                        'description' => '401, auth problem',
+                    ],
+                ],
+            ],
+        ];
+    }
 }

+ 0 - 2
tests/Extracting/Strategies/Responses/UseResponseTagTest.php

@@ -20,8 +20,6 @@ class UseResponseTagTest extends TestCase
     {
         $strategy = new UseResponseTag(new DocumentationConfig([]));
         $results = $strategy->getDocBlockResponses($tags);
-var_dump($expected);
-var_dump($results);
 
         $this->assertEquals($expected[0]['status'], $results[0]['status']);
         $this->assertEquals($expected[1]['status'], $results[1]['status']);