Explorar el Código

Merge remote-tracking branch 'origin/master' into v2

shalvah hace 4 años
padre
commit
c9822c181f

+ 1 - 2
.travis.yml

@@ -21,8 +21,7 @@ matrix:
     - php: 7.3
       env: SETUP=lowest
     - php: 7.4
-    - php: 7.4
-      env: SETUP=lowest
+      # No lowest for 7.4 because the lowest (Laravel 5.8) doesn't support 7.4
 
 cache:
   directories:

+ 5 - 5
src/Extracting/ParamHelpers.php

@@ -138,7 +138,7 @@ trait ParamHelpers
      * Normalizes the stated "type" of a parameter (eg "int", "integer", "double")
      * to a number of standard types (integer, boolean, number). Will return the input if no match.
      *
-     * @param string $type
+     * @param string $typeName
      *
      * @return string
      */
@@ -148,15 +148,15 @@ trait ParamHelpers
             return 'string';
         }
 
-        $base = preg_replace('/\[]/g', '', strtolower($typeName));
+        $base = preg_replace('/\[]/', '', strtolower($typeName));
         switch ($base) {
             case 'int':
-                return preg_replace($base, 'integer', $typeName);
+                return preg_replace("/$base/", 'integer', $typeName);
             case 'float':
             case 'double':
-                return preg_replace($base, 'number', $typeName);
+                return preg_replace("/$base/", 'number', $typeName);
             case 'bool':
-                return preg_replace($base, 'boolean', $typeName);
+                return preg_replace("/$base/", 'boolean', $typeName);
             default:
                 return $typeName;
         }

+ 4 - 0
src/Extracting/Strategies/BodyParameters/GetFromFormRequest.php

@@ -42,6 +42,10 @@ class GetFromFormRequest extends Strategy
 
             $parameterClassName = $paramType->getName();
 
+            if (!class_exists($parameterClassName)) {
+                continue;
+            }
+
             try {
                 $parameterClass = new ReflectionClass($parameterClassName);
             } catch (ReflectionException $e) {

+ 0 - 171
tests/Fixtures/collection-overridden.json

@@ -1,171 +0,0 @@
-{
-    "variable": [],
-    "info": {
-        "name": "Custom API",
-        "_postman_id": "",
-        "description": "",
-        "schema": "https:\/\/schema.getpostman.com\/json\/collection\/v2.1.0\/collection.json",
-        "version": "3.9.9"
-    },
-    "item": [
-        {
-            "name": "Group A",
-            "description": "",
-            "item": [
-                {
-                    "name": "Example title.",
-                    "request": {
-                        "url": {
-                            "protocol": "http",
-                            "host": "localhost",
-                            "path": "api\/withDescription",
-                            "query": [],
-                            "raw": "http:\/\/localhost\/api\/withDescription"
-                        },
-                        "method": "GET",
-                        "header": [
-                            {
-                                "key": "Content-Type",
-                                "value": "application\/json"
-                            },
-                            {
-                                "key": "Accept",
-                                "value": "application\/json"
-                            }
-                        ],
-                        "body": null,
-                        "description": "This will be the long description.\nIt can also be multiple lines long.",
-                        "auth": {
-                            "type": "noauth"
-                        }
-                    },
-                    "response": []
-                },
-                {
-                    "name": "api\/withResponseTag",
-                    "request": {
-                        "url": {
-                            "protocol": "http",
-                            "host": "localhost",
-                            "path": "api\/withResponseTag",
-                            "query": [],
-                            "raw": "http:\/\/localhost\/api\/withResponseTag"
-                        },
-                        "method": "GET",
-                        "header": [
-                            {
-                                "key": "Content-Type",
-                                "value": "application\/json"
-                            },
-                            {
-                                "key": "Accept",
-                                "value": "application\/json"
-                            }
-                        ],
-                        "body": null,
-                        "description": "",
-                        "auth": {
-                            "type": "noauth"
-                        }
-                    },
-                    "response": []
-                },
-                {
-                    "name": "Endpoint with body parameters.",
-                    "request": {
-                        "url": {
-                            "protocol": "http",
-                            "host": "localhost",
-                            "path": "api\/withBodyParameters",
-                            "query": [],
-                            "raw": "http:\/\/localhost\/api\/withBodyParameters"
-                        },
-                        "method": "POST",
-                        "header": [
-                            {
-                                "key": "Content-Type",
-                                "value": "application\/json"
-                            },
-                            {
-                                "key": "Accept",
-                                "value": "application\/json"
-                            }
-                        ],
-                        "body": {
-                            "mode": "raw",
-                            "raw": "{\n    \"user_id\": 9,\n    \"room_id\": \"consequatur\",\n    \"forever\": false,\n    \"another_one\": 11613.31890586,\n    \"yet_another_param\": {\n        \"name\": \"consequatur\"\n    },\n    \"even_more_param\": [\n        11613.31890586\n    ],\n    \"book\": {\n        \"name\": \"consequatur\",\n        \"author_id\": 17,\n        \"pages_count\": 17\n    },\n    \"ids\": [\n        17\n    ],\n    \"users\": [\n        {\n            \"first_name\": \"John\",\n            \"last_name\": \"Doe\"\n        }\n    ]\n}"
-                        },
-                        "description": "",
-                        "auth": {
-                            "type": "noauth"
-                        }
-                    },
-                    "response": []
-                },
-                {
-                    "name": "api\/withQueryParameters",
-                    "request": {
-                        "url": {
-                            "protocol": "http",
-                            "host": "localhost",
-                            "path": "api\/withQueryParameters",
-                            "query": [
-                                {
-                                    "key": "location_id",
-                                    "value": "consequatur",
-                                    "description": "The id of the location.",
-                                    "disabled": false
-                                },
-                                {
-                                    "key": "user_id",
-                                    "value": "me",
-                                    "description": "The id of the user.",
-                                    "disabled": false
-                                },
-                                {
-                                    "key": "page",
-                                    "value": "4",
-                                    "description": "The page number.",
-                                    "disabled": false
-                                },
-                                {
-                                    "key": "filters",
-                                    "value": "consequatur",
-                                    "description": "The filters.",
-                                    "disabled": false
-                                },
-                                {
-                                    "key": "url_encoded",
-                                    "value": "%2B+%5B%5D%26%3D",
-                                    "description": "Used for testing that URL parameters will be URL-encoded where needed.",
-                                    "disabled": false
-                                }
-                            ],
-                            "raw": "http:\/\/localhost\/api\/withQueryParameters?location_id=consequatur&user_id=me&page=4&filters=consequatur&url_encoded=%2B+%5B%5D%26%3D"
-                        },
-                        "method": "GET",
-                        "header": [
-                            {
-                                "key": "Content-Type",
-                                "value": "application\/json"
-                            },
-                            {
-                                "key": "Accept",
-                                "value": "application\/json"
-                            }
-                        ],
-                        "body": null,
-                        "description": "",
-                        "auth": {
-                            "type": "noauth"
-                        }
-                    },
-                    "response": []
-                }
-            ]
-        }
-    ],
-    "auth": {
-        "type": "noauth"
-    }
-}

+ 2 - 117
tests/Fixtures/collection.json

@@ -4,7 +4,8 @@
         "name": "GREAT API!",
         "_postman_id": "",
         "description": "",
-        "schema": "https:\/\/schema.getpostman.com\/json\/collection\/v2.1.0\/collection.json"
+        "schema": "https:\/\/schema.getpostman.com\/json\/collection\/v2.1.0\/collection.json",
+        "version": "3.9.9"
     },
     "item": [
         {
@@ -87,35 +88,6 @@
                     },
                     "response": []
                 },
-                {
-                    "name": "api\/withResponseTag",
-                    "request": {
-                        "url": {
-                            "protocol": "http",
-                            "host": "localhost",
-                            "path": "api\/withResponseTag",
-                            "query": [],
-                            "raw": "http:\/\/localhost\/api\/withResponseTag"
-                        },
-                        "method": "GET",
-                        "header": [
-                            {
-                                "key": "Custom-Header",
-                                "value": "NotSoCustom"
-                            },
-                            {
-                                "key": "Accept",
-                                "value": "application\/json"
-                            }
-                        ],
-                        "body": null,
-                        "description": "",
-                        "auth": {
-                            "type": "noauth"
-                        }
-                    },
-                    "response": []
-                },
                 {
                     "name": "Endpoint with body parameters.",
                     "request": {
@@ -238,64 +210,6 @@
                         "auth": null
                     },
                     "response": []
-                },
-                {
-                    "name": "api\/withEloquentApiResource",
-                    "request": {
-                        "url": {
-                            "protocol": "http",
-                            "host": "localhost",
-                            "path": "api\/withEloquentApiResource",
-                            "query": [],
-                            "raw": "http:\/\/localhost\/api\/withEloquentApiResource"
-                        },
-                        "method": "GET",
-                        "header": [
-                            {
-                                "key": "Custom-Header",
-                                "value": "NotSoCustom"
-                            },
-                            {
-                                "key": "Accept",
-                                "value": "application\/json"
-                            }
-                        ],
-                        "body": null,
-                        "description": "",
-                        "auth": {
-                            "type": "noauth"
-                        }
-                    },
-                    "response": []
-                },
-                {
-                    "name": "api\/withMultipleResponseTagsAndStatusCode",
-                    "request": {
-                        "url": {
-                            "protocol": "http",
-                            "host": "localhost",
-                            "path": "api\/withMultipleResponseTagsAndStatusCode",
-                            "query": [],
-                            "raw": "http:\/\/localhost\/api\/withMultipleResponseTagsAndStatusCode"
-                        },
-                        "method": "POST",
-                        "header": [
-                            {
-                                "key": "Custom-Header",
-                                "value": "NotSoCustom"
-                            },
-                            {
-                                "key": "Accept",
-                                "value": "application\/json"
-                            }
-                        ],
-                        "body": null,
-                        "description": "",
-                        "auth": {
-                            "type": "noauth"
-                        }
-                    },
-                    "response": []
                 }
             ]
         },
@@ -303,35 +217,6 @@
             "name": "Other\ud83d\ude0e",
             "description": "",
             "item": [
-                {
-                    "name": "api\/withEloquentApiResourceCollectionClass",
-                    "request": {
-                        "url": {
-                            "protocol": "http",
-                            "host": "localhost",
-                            "path": "api\/withEloquentApiResourceCollectionClass",
-                            "query": [],
-                            "raw": "http:\/\/localhost\/api\/withEloquentApiResourceCollectionClass"
-                        },
-                        "method": "GET",
-                        "header": [
-                            {
-                                "key": "Custom-Header",
-                                "value": "NotSoCustom"
-                            },
-                            {
-                                "key": "Accept",
-                                "value": "application\/json"
-                            }
-                        ],
-                        "body": null,
-                        "description": "",
-                        "auth": {
-                            "type": "noauth"
-                        }
-                    },
-                    "response": []
-                },
                 {
                     "name": "api\/echoesUrlParameters\/{param}-{param2}\/{param3?}",
                     "request": {

+ 0 - 229
tests/Fixtures/openapi-overridden.yaml

@@ -1,229 +0,0 @@
-openapi: 3.0.3
-info:
-    title: null
-    description: ''
-    version: 3.9.9
-servers:
-    -
-        url: 'http://okay.dev'
-paths:
-    /api/withDescription:
-        get:
-            summary: 'Example title.'
-            description: "This will be the long description.\nIt can also be multiple lines long."
-            parameters:
-                -
-                    in: header
-                    name: Content-Type
-                    description: ''
-                    example: application/json
-                    schema:
-                        type: string
-                -
-                    in: header
-                    name: Accept
-                    description: ''
-                    example: application/json
-                    schema:
-                        type: string
-            responses: {  }
-            tags:
-                - 'Group A'
-            security: []
-    /api/withResponseTag:
-        get:
-            summary: ''
-            description: ''
-            parameters:
-                -
-                    in: header
-                    name: Content-Type
-                    description: ''
-                    example: application/json
-                    schema:
-                        type: string
-                -
-                    in: header
-                    name: Accept
-                    description: ''
-                    example: application/json
-                    schema:
-                        type: string
-            responses:
-                200:
-                    description: '200'
-                    content:
-                        application/json:
-                            schema:
-                                type: object
-                                example:
-                                    id: 4
-                                    name: banana
-                                    color: red
-                                    weight: '1 kg'
-                                    delicious: true
-                                    responseTag: true
-                                properties:
-                                    id: { type: integer, example: 4 }
-                                    name: { type: string, example: banana }
-                                    color: { type: string, example: red }
-                                    weight: { type: string, example: '1 kg' }
-                                    delicious: { type: boolean, example: true }
-                                    responseTag: { type: boolean, example: true }
-            tags:
-                - 'Group A'
-            security: []
-    /api/withBodyParameters:
-        post:
-            summary: 'Endpoint with body parameters.'
-            description: ''
-            parameters:
-                -
-                    in: header
-                    name: Content-Type
-                    description: ''
-                    example: application/json
-                    schema:
-                        type: string
-                -
-                    in: header
-                    name: Accept
-                    description: ''
-                    example: application/json
-                    schema:
-                        type: string
-            responses: {  }
-            tags:
-                - 'Group A'
-            requestBody:
-                required: true
-                content:
-                    application/json:
-                        schema:
-                            type: object
-                            properties:
-                                user_id:
-                                    type: integer
-                                    description: 'The id of the user.'
-                                    example: 9
-                                room_id:
-                                    type: string
-                                    description: 'The id of the room.'
-                                    example: consequatur
-                                forever:
-                                    type: boolean
-                                    description: 'Whether to ban the user forever.'
-                                    example: false
-                                another_one:
-                                    type: number
-                                    description: 'Just need something here.'
-                                    example: 11613.31890586
-                                yet_another_param:
-                                    type: object
-                                    description: 'Some object params.'
-                                    example: {  }
-                                yet_another_param.name:
-                                    type: string
-                                    description: 'Subkey in the object param.'
-                                    example: consequatur
-                                even_more_param:
-                                    type: array
-                                    description: 'Some array params.'
-                                    example: []
-                                    items: { type: object }
-                                'even_more_param.*':
-                                    type: number
-                                    description: 'Subkey in the array param.'
-                                    example: 11613.31890586
-                                book.name:
-                                    type: string
-                                    description: ''
-                                    example: consequatur
-                                book.author_id:
-                                    type: integer
-                                    description: ''
-                                    example: 17
-                                'book[pages_count]':
-                                    type: integer
-                                    description: ''
-                                    example: 17
-                                'ids.*':
-                                    type: integer
-                                    description: ''
-                                    example: 17
-                                'users.*.first_name':
-                                    type: string
-                                    description: 'The first name of the user.'
-                                    example: John
-                                'users.*.last_name':
-                                    type: string
-                                    description: 'The last name of the user.'
-                                    example: Doe
-                            required:
-                                - user_id
-                                - yet_another_param
-                                - yet_another_param.name
-            security: []
-    /api/withQueryParameters:
-        get:
-            summary: ''
-            description: ''
-            parameters:
-                -
-                    in: query
-                    name: location_id
-                    description: 'The id of the location.'
-                    example: consequatur
-                    required: true
-                    schema:
-                        type: string
-                -
-                    in: query
-                    name: user_id
-                    description: 'The id of the user.'
-                    example: me
-                    required: true
-                    schema:
-                        type: string
-                -
-                    in: query
-                    name: page
-                    description: 'The page number.'
-                    example: '4'
-                    required: true
-                    schema:
-                        type: string
-                -
-                    in: query
-                    name: 'filters.*'
-                    description: 'The filters.'
-                    example: consequatur
-                    required: false
-                    schema:
-                        type: string
-                -
-                    in: query
-                    name: url_encoded
-                    description: 'Used for testing that URL parameters will be URL-encoded where needed.'
-                    example: '+ []&='
-                    required: false
-                    schema:
-                        type: string
-                -
-                    in: header
-                    name: Content-Type
-                    description: ''
-                    example: application/json
-                    schema:
-                        type: string
-                -
-                    in: header
-                    name: Accept
-                    description: ''
-                    example: application/json
-                    schema:
-                        type: string
-            responses: {  }
-            tags:
-                - 'Group A'
-            security: []

+ 1 - 92
tests/Fixtures/openapi.yaml

@@ -2,7 +2,7 @@ openapi: 3.0.3
 info:
     title: null
     description: ''
-    version: 1.0.0
+    version: 3.9.9
 servers:
     -
         url: 'http://localhost'
@@ -73,97 +73,6 @@ paths:
             tags:
                 - 'Group A'
             security: []
-    /api/withBodyParameters:
-        post:
-            summary: 'Endpoint with body parameters.'
-            description: ''
-            parameters:
-                -
-                    in: header
-                    name: Content-Type
-                    description: ''
-                    example: application/json
-                    schema:
-                        type: string
-                -
-                    in: header
-                    name: Accept
-                    description: ''
-                    example: application/json
-                    schema:
-                        type: string
-            responses: {  }
-            tags:
-                - 'Group A'
-            requestBody:
-                required: true
-                content:
-                    application/json:
-                        schema:
-                            type: object
-                            properties:
-                                user_id:
-                                    type: integer
-                                    description: 'The id of the user.'
-                                    example: 9
-                                room_id:
-                                    type: string
-                                    description: 'The id of the room.'
-                                    example: consequatur
-                                forever:
-                                    type: boolean
-                                    description: 'Whether to ban the user forever.'
-                                    example: false
-                                another_one:
-                                    type: number
-                                    description: 'Just need something here.'
-                                    example: 11613.31890586
-                                yet_another_param:
-                                    type: object
-                                    description: 'Some object params.'
-                                    example: {  }
-                                yet_another_param.name:
-                                    type: string
-                                    description: 'Subkey in the object param.'
-                                    example: consequatur
-                                even_more_param:
-                                    type: array
-                                    description: 'Some array params.'
-                                    example: []
-                                    items: { type: object }
-                                'even_more_param.*':
-                                    type: number
-                                    description: 'Subkey in the array param.'
-                                    example: 11613.31890586
-                                book.name:
-                                    type: string
-                                    description: ''
-                                    example: consequatur
-                                book.author_id:
-                                    type: integer
-                                    description: ''
-                                    example: 17
-                                'book[pages_count]':
-                                    type: integer
-                                    description: ''
-                                    example: 17
-                                'ids.*':
-                                    type: integer
-                                    description: ''
-                                    example: 17
-                                'users.*.first_name':
-                                    type: string
-                                    description: 'The first name of the user.'
-                                    example: John
-                                'users.*.last_name':
-                                    type: string
-                                    description: 'The last name of the user.'
-                                    example: Doe
-                            required:
-                                - user_id
-                                - yet_another_param
-                                - yet_another_param.name
-            security: []
     /api/withQueryParameters:
         get:
             summary: ''

+ 6 - 55
tests/GenerateDocumentationTest.php

@@ -231,18 +231,17 @@ class GenerateDocumentationTest extends TestCase
     {
         RouteFacade::get('/api/withDescription', [TestController::class, 'withEndpointDescription']);
         RouteFacade::post('/api/withFormDataParams', TestController::class . '@withFormDataParams');
-        RouteFacade::get('/api/withResponseTag', TestController::class . '@withResponseTag');
         RouteFacade::post('/api/withBodyParameters', TestController::class . '@withBodyParameters');
         RouteFacade::get('/api/withQueryParameters', TestController::class . '@withQueryParameters');
         RouteFacade::get('/api/withAuthTag', TestController::class . '@withAuthenticatedTag');
-        RouteFacade::get('/api/withEloquentApiResource', [TestController::class, 'withEloquentApiResource']);
-        RouteFacade::get('/api/withEloquentApiResourceCollectionClass', [TestController::class, 'withEloquentApiResourceCollectionClass']);
-        RouteFacade::post('/api/withMultipleResponseTagsAndStatusCode', [TestController::class, 'withMultipleResponseTagsAndStatusCode']);
         RouteFacade::get('/api/echoesUrlParameters/{param}-{param2}/{param3?}', [TestController::class, 'echoesUrlParameters']);
         // We want to have the same values for params each time
         config(['scribe.faker_seed' => 1234]);
         config(['scribe.title' => 'GREAT API!']);
         config(['scribe.routes.0.match.prefixes' => ['api/*']]);
+        config(['scribe.postman.overrides' => [
+            'info.version' => '3.9.9',
+        ]]);
         config([
             'scribe.routes.0.apply.headers' => [
                 'Custom-Header' => 'NotSoCustom',
@@ -258,47 +257,22 @@ class GenerateDocumentationTest extends TestCase
         $this->assertEquals($fixtureCollection, $generatedCollection);
     }
 
-    /** @test */
-    public function can_override_fields_in_generated_postman_collection_file()
-    {
-        RouteFacade::get('/api/withDescription', [TestController::class, 'withEndpointDescription']);
-        RouteFacade::get('/api/withResponseTag', TestController::class . '@withResponseTag');
-        RouteFacade::post('/api/withBodyParameters', TestController::class . '@withBodyParameters');
-        RouteFacade::get('/api/withQueryParameters', TestController::class . '@withQueryParameters');
-
-        config(['scribe.faker_seed' => 1234]);
-        config(['scribe.postman.enabled' => true]);
-        config(['scribe.postman.overrides' => [
-            'info.version' => '3.9.9',
-            'info.name' => 'Custom API',
-        ]]);
-        config(['scribe.routes.0.match.prefixes' => ['api/*']]);
-
-        $this->artisan('scribe:generate');
-
-        $generatedCollection = json_decode(file_get_contents(__DIR__ . '/../public/docs/collection.json'), true);
-        $generatedCollection['info']['_postman_id'] = '';
-        $fixtureCollection = json_decode(file_get_contents(__DIR__ . '/Fixtures/collection-overridden.json'), true);
-        $this->assertEquals($fixtureCollection, $generatedCollection);
-    }
-
     /** @test */
     public function generated_openapi_spec_file_is_correct()
     {
         RouteFacade::get('/api/withDescription', [TestController::class, 'withEndpointDescription']);
         RouteFacade::post('/api/withFormDataParams', TestController::class . '@withFormDataParams');
         RouteFacade::get('/api/withResponseTag', TestController::class . '@withResponseTag');
-        RouteFacade::post('/api/withBodyParameters', TestController::class . '@withBodyParameters');
         RouteFacade::get('/api/withQueryParameters', TestController::class . '@withQueryParameters');
         RouteFacade::get('/api/withAuthTag', TestController::class . '@withAuthenticatedTag');
-        RouteFacade::get('/api/withEloquentApiResource', [TestController::class, 'withEloquentApiResource']);
-        RouteFacade::get('/api/withEloquentApiResourceCollectionClass', [TestController::class, 'withEloquentApiResourceCollectionClass']);
-        RouteFacade::post('/api/withMultipleResponseTagsAndStatusCode', [TestController::class, 'withMultipleResponseTagsAndStatusCode']);
         RouteFacade::get('/api/echoesUrlParameters/{param}-{param2}/{param3?}', [TestController::class, 'echoesUrlParameters']);
 
         // We want to have the same values for params each time
         config(['scribe.faker_seed' => 1234]);
         config(['scribe.openapi.enabled' => true]);
+        config(['scribe.openapi.overrides' => [
+            'info.version' => '3.9.9',
+        ]]);
         config(['scribe.routes.0.match.prefixes' => ['api/*']]);
         config([
             'scribe.routes.0.apply.headers' => [
@@ -313,29 +287,6 @@ class GenerateDocumentationTest extends TestCase
         $this->assertEquals($fixtureCollection, $generatedCollection);
     }
 
-    /** @test */
-    public function can_override_fields_in_generated_openapi_spec_file()
-    {
-        RouteFacade::get('/api/withDescription', [TestController::class, 'withEndpointDescription']);
-        RouteFacade::get('/api/withResponseTag', TestController::class . '@withResponseTag');
-        RouteFacade::post('/api/withBodyParameters', TestController::class . '@withBodyParameters');
-        RouteFacade::get('/api/withQueryParameters', TestController::class . '@withQueryParameters');
-
-        config(['scribe.faker_seed' => 1234]);
-        config(['scribe.openapi.enabled' => true]);
-        config(['scribe.openapi.overrides' => [
-            'info.version' => '3.9.9',
-            'servers.0.url' => 'http://okay.dev',
-        ]]);
-        config(['scribe.routes.0.match.prefixes' => ['api/*']]);
-
-        $this->artisan('scribe:generate');
-
-        $generatedCollection = json_decode(file_get_contents(__DIR__ . '/../public/docs/openapi.yaml'), true);
-        $fixtureCollection = json_decode(file_get_contents(__DIR__ . '/Fixtures/openapi-overridden.yaml'), true);
-        $this->assertEquals($fixtureCollection, $generatedCollection);
-    }
-
     /** @test */
     public function can_append_custom_http_headers()
     {