grape-swagger 0.27.3 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4f8965c701e729810dda5456398ca1be10ede83f
4
- data.tar.gz: ea1d30739c20e4317301e8f4117c62ae9b48a3aa
2
+ SHA256:
3
+ metadata.gz: 5d425dcb8ef7eb5f98bba7c012f624b7cfd0052e91a5b3f7f5d7374c7d7529b2
4
+ data.tar.gz: 83c9d09cc29e30b73a263fdc66eaffe587a9503efcbf2b427cb1dd46280ed7e2
5
5
  SHA512:
6
- metadata.gz: e3ddeb7ee947dbc7bcfbc5aa6c102e71c68bf9f366f2a9fdb0db56c7ea8beba030d5eea0353821c32ba4c0596e82e48f37f9e99f5d215e1ddcb0ea1cd954f782
7
- data.tar.gz: 96e40804304834a0c1615cc0a1915b370a1b84c9df308311972fedbc92ccf7e771f87120b9963d216532c825aed47538b6e9c335ddb5b8f8378edb2ea99899b1
6
+ metadata.gz: 5d4f19f682ba1a5f999429ec3568107b8873ada3c9e033363d90be6d669e653f16ea7ac1da116bd1702326c4dc5ed65746819d34fb67ca41cbfd2cc0611dbe4d
7
+ data.tar.gz: 022cdcba56eb3e8c9bf38c406851b40546053bb170204e429a92d218e96ad7a1fc507802eb5f90bb8d8b77e1a5509e63a54a4a27424db1b95b1b62a9e4e5c667
data/.rubocop.yml CHANGED
@@ -6,6 +6,9 @@ AllCops:
6
6
  - example/**/*
7
7
  TargetRubyVersion: 2.4
8
8
 
9
+ Layout/EmptyLinesAroundArguments:
10
+ Enabled: false
11
+
9
12
  Layout/IndentHash:
10
13
  EnforcedStyle: consistent
11
14
 
@@ -14,6 +17,7 @@ Metrics/BlockLength:
14
17
  - spec/**/*
15
18
 
16
19
  Metrics/LineLength:
20
+ Max: 120
17
21
  Exclude:
18
22
  - spec/**/*
19
23
 
@@ -21,6 +25,8 @@ Metrics/MethodLength:
21
25
  Exclude:
22
26
  - spec/**/*
23
27
 
28
+ Naming:
29
+ Enabled: false
24
30
 
25
- Style/FileName:
31
+ Style/RegexpLiteral:
26
32
  Enabled: false
data/.rubocop_todo.yml CHANGED
@@ -1,67 +1,46 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2016-11-24 18:42:08 +0800 using RuboCop version 0.45.0.
3
+ # on 2017-12-13 08:44:09 +0100 using RuboCop version 0.52.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 29
9
+ # Offense count: 1
10
+ # Configuration parameters: Include.
11
+ # Include: **/*.gemspec
12
+ Gemspec/RequiredRubyVersion:
13
+ Exclude:
14
+ - 'grape-swagger.gemspec'
15
+
16
+
17
+ # Offense count: 30
10
18
  Metrics/AbcSize:
11
19
  Max: 56
12
20
 
13
- # Offense count: 1
14
- # Configuration parameters: CountComments.
15
- Metrics/BlockLength:
16
- Max: 29
17
-
18
21
  # Offense count: 3
19
22
  # Configuration parameters: CountComments.
20
23
  Metrics/ClassLength:
21
- Max: 275
24
+ Max: 280
22
25
 
23
- # Offense count: 12
26
+ # Offense count: 10
24
27
  Metrics/CyclomaticComplexity:
25
- Max: 15
26
-
27
- # Offense count: 129
28
- # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives.
29
- # URISchemes: http, https
30
- Metrics/LineLength:
31
- Max: 120
28
+ Max: 13
32
29
 
33
- # Offense count: 35
30
+ # Offense count: 20
34
31
  # Configuration parameters: CountComments.
35
32
  Metrics/MethodLength:
36
33
  Max: 40
37
34
 
38
- # Offense count: 7
35
+ # Offense count: 6
39
36
  Metrics/PerceivedComplexity:
40
- Max: 16
37
+ Max: 14
41
38
 
42
39
  # Offense count: 3
43
40
  Style/ClassVars:
44
41
  Exclude:
45
42
  - 'lib/grape-swagger/doc_methods.rb'
46
43
 
47
- # Offense count: 23
44
+ # Offense count: 20
48
45
  Style/Documentation:
49
46
  Enabled: false
50
-
51
- Style/MixinGrouping:
52
- Exclude:
53
- - spec/**/*
54
-
55
- # Offense count: 1
56
- # Cop supports --auto-correct.
57
- Style/MultilineIfModifier:
58
- Exclude:
59
- - 'lib/grape-swagger/grape/route.rb'
60
-
61
- # Offense count: 5
62
- # Cop supports --auto-correct.
63
- # Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes.
64
- # SupportedStyles: slashes, percent_r, mixed
65
- Style/RegexpLiteral:
66
- Exclude:
67
- - 'lib/grape-swagger.rb'
data/.travis.yml CHANGED
@@ -7,36 +7,37 @@ before_install:
7
7
  - gem install bundler
8
8
 
9
9
  after_success:
10
+ - coveralls
10
11
  - bundle exec danger
11
12
 
12
13
  rvm:
13
- - 2.4.1
14
- - 2.3.4
14
+ - 2.5.0
15
+ - 2.4.3
15
16
 
16
17
  env:
17
18
  - MODEL_PARSER=grape-swagger-entity
18
19
  - MODEL_PARSER=grape-swagger-representable
19
- - GRAPE_VERSION=0.16.2
20
20
  - GRAPE_VERSION=0.17.0
21
21
  - GRAPE_VERSION=0.18.0
22
22
  - GRAPE_VERSION=0.19.2
23
- - GRAPE_VERSION=1.0.0
23
+ - GRAPE_VERSION=1.0.1
24
24
  - GRAPE_VERSION=HEAD
25
25
 
26
26
  matrix:
27
27
  fast_finish: true
28
28
 
29
29
  include:
30
- - rvm: 2.2.7
30
+ - rvm: 2.3.6
31
31
  env:
32
32
  - rvm: ruby-head
33
33
  env:
34
34
  - rvm: jruby-head
35
35
  env:
36
- - rvm: rbx-2
36
+ - rvm: rbx-3
37
37
  env:
38
38
 
39
39
  allow_failures:
40
+ - rvm: 2.3.6
40
41
  - rvm: ruby-head
41
42
  - rvm: jruby-head
42
- - rvm: rbx-2
43
+ - rvm: rbx-3
data/CHANGELOG.md CHANGED
@@ -8,6 +8,22 @@
8
8
 
9
9
  * Your contribution here.
10
10
 
11
+ ### 0.28.0 (February 3, 2018)
12
+
13
+ #### Features
14
+
15
+ * [#622](https://github.com/ruby-grape/grape-swagger/pull/622): Add support for 'brackets' collection format - [@korstiaan](https://github.com/korstiaan).
16
+
17
+ #### Fixes
18
+
19
+ * [#631](https://github.com/ruby-grape/grape-swagger/pull/631): Fix order of mounts with overrides - [@adie](https://github.com/adie).
20
+ * [#267](https://github.com/ruby-grape/grape-swagger/pull/634): Fix mounting APIs in route_param namespaces - [@milgner](https://github.com/milgner), [@wojciechka](https://github.com/wojciechka).
21
+ * [#642](https://github.com/ruby-grape/grape-swagger/pull/642): Fix examples link in readme - [@iBublik](https://github.com/iBublik).
22
+ * [#641](https://github.com/ruby-grape/grape-swagger/pull/641): Exclude default success code if http_codes define one already - [@anakinj](https://github.com/anakinj).
23
+ * [#651](https://github.com/ruby-grape/grape-swagger/pull/651): Apply `values` and `default` of array params to its items - [@yewton](https://github.com/yewton).
24
+ * [#654](https://github.com/ruby-grape/grape-swagger/pull/654): Allow setting the consumes for PATCH methods - [@anakinj](https://github.com/anakinj).
25
+ * [#656](https://github.com/ruby-grape/grape-swagger/pull/656): Fix `description` field may be null - [@soranoba](https://github.com/soranoba).
26
+
11
27
  ### 0.27.3 (July 11, 2017)
12
28
 
13
29
  #### Features
data/Gemfile CHANGED
@@ -17,6 +17,7 @@ gem ENV['MODEL_PARSER'] if ENV.key?('MODEL_PARSER')
17
17
 
18
18
  group :development, :test do
19
19
  gem 'bundler'
20
+ gem 'grape-entity'
20
21
  gem 'pry', platforms: [:mri]
21
22
  gem 'pry-byebug', platforms: [:mri]
22
23
  gem 'rack'
@@ -25,12 +26,11 @@ group :development, :test do
25
26
  gem 'rake'
26
27
  gem 'rdoc'
27
28
  gem 'rspec', '~> 3.0'
28
- gem 'rubocop', '~> 0.49'
29
+ gem 'rubocop', '~>0.51', require: false
29
30
  end
30
31
 
31
32
  group :test do
32
33
  gem 'coveralls', require: false
33
- gem 'grape-entity', '~>0.5'
34
34
  gem 'grape-swagger-entity'
35
35
  gem 'ruby-grape-danger', '~> 0.1.1', require: false
36
36
  gem 'simplecov', require: false
data/README.md CHANGED
@@ -17,8 +17,7 @@
17
17
  * [Routes Configuration](#routes)
18
18
  * [Using Grape Entities](#grape-entity)
19
19
  * [Securing the Swagger UI](#oauth)
20
- * [Markdown (deprecated)](#md_usage)
21
- * [Example](#example)
20
+ * [Examples](#examples)
22
21
  * [Rake Tasks](#rake)
23
22
 
24
23
 
@@ -110,7 +109,7 @@ gem 'grape-swagger-entity'
110
109
  gem 'grape-swagger-representable'
111
110
  ```
112
111
 
113
- If you are not using Rails, make sure to load the parser inside your application initialization logic, e.g., via `require 'grape-swagger/entity'` or `require 'grape-swagger/representable`.
112
+ If you are not using Rails, make sure to load the parser inside your application initialization logic, e.g., via `require 'grape-swagger/entity'` or `require 'grape-swagger/representable'`.
114
113
 
115
114
  ### Custom Model Parsers
116
115
 
@@ -265,10 +264,6 @@ add_swagger_documentation \
265
264
  ```
266
265
 
267
266
 
268
- #### markdown: (deprecated) <a name="markdown" />
269
- OAPI accepts GFM for descriptions
270
-
271
-
272
267
  #### endpoint_auth_wrapper: <a name="endpoint_auth_wrapper" />
273
268
  Specify the middleware to use for securing endpoints.
274
269
 
@@ -462,7 +457,7 @@ Or by using a route setting:
462
457
 
463
458
  ```ruby
464
459
  route_setting :swagger, { hidden: true }
465
- gem '/kittens' do
460
+ get '/kittens' do
466
461
  ```
467
462
 
468
463
  Endpoints can be conditionally hidden by providing a callable object such as a lambda which evaluates to the desired
@@ -565,7 +560,7 @@ desc 'Get all kittens!', {
565
560
  nickname: 'getKittens',
566
561
  success: Entities::Kitten, # or success
567
562
  failure: [[401, 'KittenBitesError', Entities::BadKitten]] # or failure
568
- # also explicit as hash: [{ code: 401, mssage: 'KittenBitesError', model: Entities::BadKitten }]
563
+ # also explicit as hash: [{ code: 401, message: 'KittenBitesError', model: Entities::BadKitten }]
569
564
  produces: [ "array", "of", "mime_types" ],
570
565
  consumes: [ "array", "of", "mime_types" ]
571
566
  }
@@ -1198,15 +1193,7 @@ The lambda is checking whether the user is authenticated (if not, the token_owne
1198
1193
  role - only admins can see this endpoint.
1199
1194
 
1200
1195
 
1201
- ## Markdown in Detail (deprecated) <a name="md_usage" />
1202
-
1203
- Usage of option `markdown` will no longer be supported,
1204
- cause OAPI accepts [GFM](https://help.github.com/articles/github-flavored-markdown) and plain text.
1205
- (see: [description of `Info`](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/2.0.md#info-object))
1206
-
1207
-
1208
- <a="example" />
1209
- ## Examples
1196
+ ## Examples <a="example" />
1210
1197
 
1211
1198
  Go into example directory and run it: `$ bundle exec rackup`
1212
1199
  go to: `http://localhost:9292/swagger_doc` to get it
data/Rakefile CHANGED
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require 'rubygems'
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
13
13
  s.summary = 'Add auto generated documentation to your Grape API that can be displayed with Swagger.'
14
14
  s.license = 'MIT'
15
15
 
16
- s.required_ruby_version = '>= 2.2'
16
+ s.required_ruby_version = '>= 2.3'
17
17
  s.add_runtime_dependency 'grape', '>= 0.16.2'
18
18
 
19
19
  s.files = `git ls-files`.split("\n")
data/lib/grape-swagger.rb CHANGED
@@ -29,11 +29,9 @@ module Grape
29
29
  version_for(options)
30
30
  options = { target_class: self }.merge(options)
31
31
  @target_class = options[:target_class]
32
- auth_wrapper = options[:endpoint_auth_wrapper]
32
+ auth_wrapper = options[:endpoint_auth_wrapper] || Class.new
33
33
 
34
- if auth_wrapper && auth_wrapper.method_defined?(:before) && !middleware.flatten.include?(auth_wrapper)
35
- use auth_wrapper
36
- end
34
+ use auth_wrapper if auth_wrapper.method_defined?(:before) && !middleware.flatten.include?(auth_wrapper)
37
35
 
38
36
  documentation_class.setup(options)
39
37
  mount(documentation_class)
@@ -72,7 +70,7 @@ module Grape
72
70
  resource = '/' if resource.empty?
73
71
  @target_class.combined_routes[resource] ||= []
74
72
  next if doc_klass.hide_documentation_path && route.path.match(/#{doc_klass.mount_path}($|\/|\(\.)/)
75
- @target_class.combined_routes[resource] << route
73
+ @target_class.combined_routes[resource].unshift route
76
74
  end
77
75
  end
78
76
 
@@ -90,16 +88,24 @@ module Grape
90
88
  end
91
89
  end
92
90
 
91
+ def determine_namespaced_routes(name, parent_route)
92
+ if parent_route.nil?
93
+ @target_class.combined_routes.values.flatten
94
+ else
95
+ parent_route.reject do |route|
96
+ !route_path_start_with?(route, name) || !route_instance_variable_equals?(route, name)
97
+ end
98
+ end
99
+ end
100
+
93
101
  def combine_namespace_routes(namespaces)
94
102
  # iterate over each single namespace
95
- namespaces.each do |name, _|
103
+ namespaces.each_key do |name, _|
96
104
  # get the parent route for the namespace
97
105
  parent_route_name = extract_parent_route(name)
98
106
  parent_route = @target_class.combined_routes[parent_route_name]
99
107
  # fetch all routes that are within the current namespace
100
- namespace_routes = parent_route.reject do |route|
101
- !route_path_start_with?(route, name) || !route_instance_variable_equals?(route, name)
102
- end
108
+ namespace_routes = determine_namespaced_routes(name, parent_route)
103
109
 
104
110
  # default case when not explicitly specified or nested == true
105
111
  standalone_namespaces = namespaces.reject do |_, ns|
@@ -118,11 +124,15 @@ module Grape
118
124
  @target_class.combined_namespace_routes[parent_route_name] = [] unless parent_route
119
125
  @target_class.combined_namespace_routes[parent_route_name].push(*namespace_routes)
120
126
  end
127
+ # rubocop:enable Style/Next
121
128
  end
122
129
  end
123
130
 
124
131
  def extract_parent_route(name)
125
- name.match(%r{^/?([^/]*).*$})[1]
132
+ route_name = name.match(%r{^/?([^/]*).*$})[1]
133
+ return route_name unless route_name.include? ':'
134
+ matches = name.match(/\/[a-z]+/)
135
+ matches.nil? ? route_name : matches[0].delete('/')
126
136
  end
127
137
 
128
138
  def route_instance_variable(route)
@@ -25,9 +25,6 @@ module GrapeSwagger
25
25
  end
26
26
 
27
27
  def setup(options)
28
- # FIXME: move out after next minor is released
29
- GrapeSwagger::Errors::SwaggerSpecDeprecated.tell!(options[:markdown]) if options.key?(:markdown)
30
-
31
28
  options = defaults.merge(options)
32
29
 
33
30
  # options could be set on #add_swagger_documentation call,
@@ -80,7 +80,7 @@ module GrapeSwagger
80
80
  end
81
81
 
82
82
  def collections
83
- %w[csv ssv tsv pipes multi]
83
+ %w[csv ssv tsv pipes multi brackets]
84
84
  end
85
85
  end
86
86
 
@@ -68,7 +68,7 @@ module GrapeSwagger
68
68
  def concatenate(extensions)
69
69
  result = {}
70
70
 
71
- extensions.values.each do |extension|
71
+ extensions.each_value do |extension|
72
72
  extension.each do |key, value|
73
73
  result["x-#{key}"] = value
74
74
  end
@@ -198,7 +198,7 @@ module GrapeSwagger
198
198
  end
199
199
 
200
200
  def property_keys
201
- %i[type format description minimum maximum items]
201
+ %i[type format description minimum maximum items enum]
202
202
  end
203
203
 
204
204
  def deletable?(param)
@@ -22,8 +22,8 @@ module GrapeSwagger
22
22
  document_description(settings)
23
23
  document_type_and_format(settings, data_type)
24
24
  document_array_param(value_type, definitions) if value_type[:is_array]
25
- document_default_value(settings)
26
- document_range_values(settings)
25
+ document_default_value(settings) unless value_type[:is_array]
26
+ document_range_values(settings) unless value_type[:is_array]
27
27
  document_required(settings)
28
28
 
29
29
  @parsed_param
@@ -79,6 +79,12 @@ module GrapeSwagger
79
79
  end
80
80
  array_items[:format] = @parsed_param.delete(:format) if @parsed_param[:format]
81
81
 
82
+ values = value_type[:values] || nil
83
+ enum_or_range_values = parse_enum_or_range_values(values)
84
+ array_items.merge!(enum_or_range_values) if enum_or_range_values
85
+
86
+ array_items[:default] = value_type[:default] if value_type[:default].present?
87
+
82
88
  @parsed_param[:in] = param_type || 'formData'
83
89
  @parsed_param[:items] = array_items
84
90
  @parsed_param[:type] = 'array'
@@ -7,6 +7,7 @@ module GrapeSwagger
7
7
  def build(paths)
8
8
  paths.values.each_with_object([]) do |path, memo|
9
9
  tags = path.values.first[:tags]
10
+ next if tags.nil?
10
11
 
11
12
  case tags
12
13
  when String
@@ -77,7 +77,7 @@ module Grape
77
77
  def path_and_definition_objects(namespace_routes, options)
78
78
  @paths = {}
79
79
  @definitions = {}
80
- namespace_routes.keys.each do |key|
80
+ namespace_routes.each_key do |key|
81
81
  routes = namespace_routes[key]
82
82
  path_item(routes, options)
83
83
  end
@@ -143,6 +143,7 @@ module Grape
143
143
  def description_object(route)
144
144
  description = route.description if route.description.present?
145
145
  description = route.options[:detail] if route.options.key?(:detail)
146
+ description ||= ''
146
147
 
147
148
  description
148
149
  end
@@ -161,14 +162,11 @@ module Grape
161
162
  route_mime_types.present? ? route_mime_types : mime_types
162
163
  end
163
164
 
164
- def consumes_object(route, format)
165
- method = route.request_method.downcase.to_sym
166
- if route.settings[:description] && route.settings[:description][:consumes]
167
- format = route.settings[:description][:consumes]
168
- end
169
- mime_types = GrapeSwagger::DocMethods::ProducesConsumes.call(format) if %i[post put].include?(method)
165
+ SUPPORTS_CONSUMES = %i[post put patch].freeze
170
166
 
171
- mime_types
167
+ def consumes_object(route, format)
168
+ return unless SUPPORTS_CONSUMES.include?(route.request_method.downcase.to_sym)
169
+ GrapeSwagger::DocMethods::ProducesConsumes.call(route.settings.dig(:description, :consumes) || format)
172
170
  end
173
171
 
174
172
  def params_object(route, path)
@@ -191,12 +189,11 @@ module Grape
191
189
  end
192
190
 
193
191
  def response_object(route)
194
- codes = (route.http_codes || route.options[:failure] || [])
195
-
196
- codes = apply_success_codes(route) + codes
192
+ codes = http_codes_from_route(route)
197
193
  codes.map! { |x| x.is_a?(Array) ? { code: x[0], message: x[1], model: x[2] } : x }
198
194
 
199
195
  codes.each_with_object({}) do |value, memo|
196
+ value[:message] ||= ''
200
197
  memo[value[:code]] = { description: value[:message] }
201
198
  next build_file_response(memo[value[:code]]) if file_response?(value[:model])
202
199
 
@@ -222,7 +219,15 @@ module Grape
222
219
  end
223
220
  end
224
221
 
225
- def apply_success_codes(route)
222
+ def http_codes_from_route(route)
223
+ if route.http_codes.is_a?(Array) && route.http_codes.any? { |code| code[:code].between?(200, 299) }
224
+ route.http_codes.clone
225
+ else
226
+ success_codes_from_route(route) + (route.http_codes || route.options[:failure] || [])
227
+ end
228
+ end
229
+
230
+ def success_codes_from_route(route)
226
231
  default_code = GrapeSwagger::DocMethods::StatusCodes.get[route.request_method.downcase.to_sym]
227
232
  if @entity.is_a?(Hash)
228
233
  default_code[:code] = @entity[:code] if @entity[:code].present?
@@ -257,6 +262,7 @@ module Grape
257
262
  memo['schema'] = { type: 'file' }
258
263
  end
259
264
 
265
+ # rubocop:disable Style/IfUnlessModifier
260
266
  def partition_params(route)
261
267
  declared_params = route.settings[:declared_params] if route.settings[:declared_params].present?
262
268
  required = merge_params(route)
@@ -270,6 +276,7 @@ module Grape
270
276
 
271
277
  request_params.empty? ? required : request_params
272
278
  end
279
+ # rubocop:enable Style/IfUnlessModifier
273
280
 
274
281
  def merge_params(route)
275
282
  param_keys = route.params.keys
@@ -326,7 +333,7 @@ module Grape
326
333
  raise GrapeSwagger::Errors::UnregisteredParser, "No parser registered for #{model_name}." unless parser
327
334
 
328
335
  properties = parser.new(model, self).call
329
- unless properties && properties.any?
336
+ unless properties&.any?
330
337
  raise GrapeSwagger::Errors::SwaggerSpec,
331
338
  "Empty model #{model_name}, swagger 2.0 doesn't support empty definitions."
332
339
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GrapeSwagger
4
- VERSION = '0.27.3'
4
+ VERSION = '0.28.0'
5
5
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'nested namespaces' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ route_param :root do
9
+ resources :apps do
10
+ route_param :app_id do
11
+ resource :build do
12
+ desc 'Builds an application'
13
+ post do
14
+ { name: 'Test' }
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ add_swagger_documentation version: 'v1'
22
+ end
23
+ end
24
+
25
+ describe 'combined_namespace_routes' do
26
+ it 'parses root namespace properly' do
27
+ expect(app.combined_namespace_routes.keys).to include('apps')
28
+ end
29
+ end
30
+
31
+ describe '#extract_parent_route' do
32
+ it 'extracts parent for non-namespaced path properly' do
33
+ expect(app.send(:extract_parent_route, '/apps/:app_id/build')).to eq('apps')
34
+ end
35
+
36
+ it 'extracts parent for namespaced path properly' do
37
+ expect(app.send(:extract_parent_route, '/:root/apps/:app_id/build')).to eq('apps')
38
+ end
39
+ end
40
+
41
+ describe 'retrieves swagger-documentation on /swagger_doc' do
42
+ let(:route_name) { '{root}/apps/{app_id}/build' }
43
+
44
+ subject do
45
+ get '/swagger_doc.json'
46
+ JSON.parse(last_response.body)
47
+ end
48
+
49
+ context 'paths' do
50
+ specify do
51
+ expect(subject['paths'].keys).to include "/#{route_name}"
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require 'spec_helper'
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#605 Group Params as Array' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ params do
9
+ requires :array_of_range_string, type: [String], values: %w[a b c]
10
+ requires :array_of_range_integer, type: [Integer], values: [1, 2, 3]
11
+ end
12
+ post '/array_of_range' do
13
+ { 'declared_params' => declared(params) }
14
+ end
15
+
16
+ params do
17
+ requires :array_with_default_string, type: [String], default: 'abc'
18
+ requires :array_with_default_integer, type: Array[Integer], default: 123
19
+ end
20
+ post '/array_with_default' do
21
+ { 'declared_params' => declared(params) }
22
+ end
23
+
24
+ add_swagger_documentation
25
+ end
26
+ end
27
+
28
+ describe 'retrieves the documentation for typed group range parameters' do
29
+ subject do
30
+ get '/swagger_doc/array_of_range'
31
+ JSON.parse(last_response.body)
32
+ end
33
+
34
+ specify do
35
+ expect(subject['paths']['/array_of_range']['post']['parameters']).to eql(
36
+ [
37
+ { 'in' => 'formData', 'name' => 'array_of_range_string', 'type' => 'array', 'items' => { 'type' => 'string', 'enum' => %w[a b c] }, 'required' => true },
38
+ { 'in' => 'formData', 'name' => 'array_of_range_integer', 'type' => 'array', 'items' => { 'type' => 'integer', 'format' => 'int32', 'enum' => [1, 2, 3] }, 'required' => true }
39
+ ]
40
+ )
41
+ end
42
+ end
43
+
44
+ describe 'retrieves the documentation for typed group parameters with default' do
45
+ subject do
46
+ get '/swagger_doc/array_with_default'
47
+ JSON.parse(last_response.body)
48
+ end
49
+
50
+ specify do
51
+ expect(subject['paths']['/array_with_default']['post']['parameters']).to eql(
52
+ [
53
+ { 'in' => 'formData', 'name' => 'array_with_default_string', 'type' => 'array', 'items' => { 'type' => 'string', 'default' => 'abc' }, 'required' => true },
54
+ { 'in' => 'formData', 'name' => 'array_with_default_integer', 'type' => 'array', 'items' => { 'type' => 'integer', 'format' => 'int32', 'default' => 123 }, 'required' => true }
55
+ ]
56
+ )
57
+ end
58
+ end
59
+ end
@@ -40,6 +40,7 @@ describe GrapeSwagger::DocMethods::OptionalObject do
40
40
  let(:options) do
41
41
  { host: proc { |request| request.host =~ /^example/ ? '/api-example' : '/api' } }
42
42
  end
43
+ # rubocop:enable RegexpMatch
43
44
  specify do
44
45
  expect(subject.build(key, options, request)).to eql '/api-example'
45
46
  end
@@ -48,7 +48,7 @@ describe 'details' do
48
48
  { 'declared_params' => declared(params) }
49
49
  end
50
50
 
51
- add_swagger_documentation markdown: 'foo'
51
+ add_swagger_documentation
52
52
  end
53
53
  end
54
54
  end
@@ -49,6 +49,14 @@ describe 'format, content_type' do
49
49
  { 'declared_params' => declared(params) }
50
50
  end
51
51
 
52
+ desc 'This uses consumes for consumes',
53
+ failure: [{ code: 400, model: Entities::ApiError }],
54
+ consumes: ['application/www_url_encoded'],
55
+ entity: Entities::UseResponse
56
+ patch '/use_consumes' do
57
+ { 'declared_params' => declared(params) }
58
+ end
59
+
52
60
  add_swagger_documentation
53
61
  end
54
62
  end
@@ -123,6 +131,7 @@ describe 'format, content_type' do
123
131
  specify do
124
132
  expect(subject['paths']['/use_consumes']['post']).to include('consumes')
125
133
  expect(subject['paths']['/use_consumes']['post']['consumes']).to eql ['application/www_url_encoded']
134
+ expect(subject['paths']['/use_consumes']['patch']['consumes']).to eql ['application/www_url_encoded']
126
135
  end
127
136
  end
128
137
  end
@@ -131,7 +131,7 @@ describe 'swagger spec v2.0' do
131
131
 
132
132
  specify do
133
133
  unexpected_paths = mounted_paths - [expected_path]
134
- subject.keys.each do |path|
134
+ subject.each_key do |path|
135
135
  unexpected_paths.each do |unexpected_path|
136
136
  expect(path).not_to start_with unexpected_path
137
137
  end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'http status code behaivours' do
6
+ include_context "#{MODEL_PARSER} swagger example"
7
+
8
+ subject do
9
+ get '/swagger_doc'
10
+ JSON.parse(last_response.body)
11
+ end
12
+
13
+ context 'when non-default success codes are deifined' do
14
+ let(:app) do
15
+ Class.new(Grape::API) do
16
+ desc 'Has explicit success http_codes defined' do
17
+ http_codes [{ code: 202, message: 'We got it!' },
18
+ { code: 204, message: 'Or returned no content' },
19
+ { code: 400, message: 'Bad request' }]
20
+ end
21
+
22
+ post '/accepting_endpoint' do
23
+ 'We got the message!'
24
+ end
25
+ add_swagger_documentation
26
+ end
27
+ end
28
+
29
+ it 'only includes the defined http_codes' do
30
+ expect(subject['paths']['/accepting_endpoint']['post']['responses'].keys.sort).to eq(%w[202 204 400].sort)
31
+ end
32
+ end
33
+
34
+ context 'when no success codes defined' do
35
+ let(:app) do
36
+ Class.new(Grape::API) do
37
+ desc 'Has explicit error http_codes defined' do
38
+ http_codes [{ code: 400, message: 'Error!' },
39
+ { code: 404, message: 'Not found' }]
40
+ end
41
+
42
+ post '/error_endpoint' do
43
+ 'We got the message!'
44
+ end
45
+ add_swagger_documentation
46
+ end
47
+ end
48
+
49
+ it 'adds the success codes to the response' do
50
+ expect(subject['paths']['/error_endpoint']['post']['responses'].keys.sort).to eq(%w[201 400 404].sort)
51
+ end
52
+ end
53
+
54
+ context 'when success and error codes are defined' do
55
+ let(:app) do
56
+ Class.new(Grape::API) do
57
+ desc 'Has success and error codes defined' do
58
+ http_codes [{ code: 200, message: 'Found' },
59
+ { code: 404, message: 'Not found' }]
60
+ end
61
+
62
+ get '/endpoint' do
63
+ 'We got the message!'
64
+ end
65
+ add_swagger_documentation
66
+ end
67
+ end
68
+
69
+ it 'adds the success codes and error codes to the response' do
70
+ expect(subject['paths']['/endpoint']['get']['responses'].keys.sort).to eq(%w[200 404].sort)
71
+ end
72
+ end
73
+ end
@@ -14,14 +14,6 @@ class SampleAuth < Grape::Middleware::Base
14
14
  @protected_endpoint || false
15
15
  end
16
16
 
17
- def access_token
18
- @_access_token
19
- end
20
-
21
- def access_token=(token)
22
- @_access_token = token
23
- end
24
-
25
17
  def resource_owner
26
18
  @resource_owner = true if access_token == '12345'
27
19
  end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'mount override api' do
6
+ def app
7
+ old_api = Class.new(Grape::API) do
8
+ desc 'old endpoint', success: { code: 200, message: 'old message' }
9
+ params do
10
+ optional :param, type: Integer, desc: 'old param'
11
+ end
12
+ get do
13
+ 'old'
14
+ end
15
+ end
16
+
17
+ new_api = Class.new(Grape::API) do
18
+ desc 'new endpoint', success: { code: 200, message: 'new message' }
19
+ params do
20
+ optional :param, type: String, desc: 'new param'
21
+ end
22
+ get do
23
+ 'new'
24
+ end
25
+ end
26
+
27
+ Class.new(Grape::API) do
28
+ mount new_api
29
+ mount old_api
30
+
31
+ add_swagger_documentation format: :json
32
+ end
33
+ end
34
+
35
+ context 'actual api request' do
36
+ subject do
37
+ get '/'
38
+ last_response.body
39
+ end
40
+
41
+ it 'returns data from new endpoint' do
42
+ is_expected.to eq 'new'
43
+ end
44
+ end
45
+
46
+ context 'api documentation' do
47
+ subject do
48
+ get '/swagger_doc'
49
+ JSON.parse(last_response.body)['paths']['/']['get']
50
+ end
51
+
52
+ it 'shows documentation from new endpoint' do
53
+ expect(subject['summary']).to eql('new endpoint')
54
+ expect(subject['parameters'][0]['description']).to eql('new param')
55
+ expect(subject['parameters'][0]['type']).to eql('string')
56
+ expect(subject['responses']['200']['description']).to eql('new message')
57
+ end
58
+ end
59
+ end
@@ -31,6 +31,14 @@ describe 'Group Array Params, using collection format' do
31
31
  { 'declared_params' => declared(params) }
32
32
  end
33
33
 
34
+ params do
35
+ optional :array_of_strings, type: Array[String], desc: 'array in brackets collection format', documentation: { collectionFormat: 'brackets' }
36
+ end
37
+
38
+ get '/array_of_strings_brackets_collection_format' do
39
+ { 'declared_params' => declared(params) }
40
+ end
41
+
34
42
  add_swagger_documentation
35
43
  end
36
44
  end
@@ -65,6 +73,21 @@ describe 'Group Array Params, using collection format' do
65
73
  end
66
74
  end
67
75
 
76
+ describe 'documentation for array parameters in brackets collectionFormat set from documentation' do
77
+ subject do
78
+ get '/swagger_doc/array_of_strings_brackets_collection_format'
79
+ JSON.parse(last_response.body)
80
+ end
81
+
82
+ specify do
83
+ expect(subject['paths']['/array_of_strings_brackets_collection_format']['get']['parameters']).to eql(
84
+ [
85
+ { 'in' => 'formData', 'name' => 'array_of_strings', 'type' => 'array', 'items' => { 'type' => 'string' }, 'required' => false, 'collectionFormat' => 'brackets', 'description' => 'array in brackets collection format' }
86
+ ]
87
+ )
88
+ end
89
+ end
90
+
68
91
  describe 'documentation for array parameters with collectionFormat set to invalid option' do
69
92
  subject do
70
93
  get '/swagger_doc/array_of_strings_invalid_collection_format'
@@ -101,7 +101,7 @@ describe 'Group Params as Array' do
101
101
  { 'in' => 'formData', 'name' => 'typed_group[id]', 'description' => 'integer given', 'type' => 'array', 'items' => { 'type' => 'integer', 'format' => 'int32' }, 'required' => true },
102
102
  { 'in' => 'formData', 'name' => 'typed_group[name]', 'description' => 'string given', 'type' => 'array', 'items' => { 'type' => 'string' }, 'required' => true },
103
103
  { 'in' => 'formData', 'name' => 'typed_group[email]', 'description' => 'email given', 'type' => 'array', 'items' => { 'type' => 'string' }, 'required' => false },
104
- { 'in' => 'formData', 'name' => 'typed_group[others]', 'type' => 'array', 'items' => { 'type' => 'integer', 'format' => 'int32' }, 'enum' => [1, 2, 3], 'required' => false }
104
+ { 'in' => 'formData', 'name' => 'typed_group[others]', 'type' => 'array', 'items' => { 'type' => 'integer', 'format' => 'int32', 'enum' => [1, 2, 3] }, 'required' => false }
105
105
  ]
106
106
  )
107
107
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape-swagger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.27.3
4
+ version: 0.28.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Vandecasteele
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-11 00:00:00.000000000 Z
11
+ date: 2018-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grape
@@ -75,6 +75,7 @@ files:
75
75
  - lib/grape-swagger/model_parsers.rb
76
76
  - lib/grape-swagger/rake/oapi_tasks.rb
77
77
  - lib/grape-swagger/version.rb
78
+ - spec/issues/267_nested_namespaces.rb
78
79
  - spec/issues/403_versions_spec.rb
79
80
  - spec/issues/427_entity_as_string_spec.rb
80
81
  - spec/issues/430_entity_definitions_spec.rb
@@ -89,6 +90,7 @@ files:
89
90
  - spec/issues/582_file_response_spec.rb
90
91
  - spec/issues/587_range_parameter_delimited_by_dash_spec.rb
91
92
  - spec/issues/605_root_route_documentation_spec.rb
93
+ - spec/issues/650_params_array_spec.rb
92
94
  - spec/lib/data_type_spec.rb
93
95
  - spec/lib/endpoint_spec.rb
94
96
  - spec/lib/extensions_spec.rb
@@ -129,6 +131,7 @@ files:
129
131
  - spec/swagger_v2/api_swagger_v2_request_params_fix_spec.rb
130
132
  - spec/swagger_v2/api_swagger_v2_response_spec.rb
131
133
  - spec/swagger_v2/api_swagger_v2_spec.rb
134
+ - spec/swagger_v2/api_swagger_v2_status_codes_spec.rb
132
135
  - spec/swagger_v2/api_swagger_v2_type-format_spec.rb
133
136
  - spec/swagger_v2/boolean_params_spec.rb
134
137
  - spec/swagger_v2/default_api_spec.rb
@@ -141,6 +144,7 @@ files:
141
144
  - spec/swagger_v2/guarded_endpoint_spec.rb
142
145
  - spec/swagger_v2/hide_api_spec.rb
143
146
  - spec/swagger_v2/host.rb
147
+ - spec/swagger_v2/mount_override_api_spec.rb
144
148
  - spec/swagger_v2/mounted_target_class_spec.rb
145
149
  - spec/swagger_v2/namespace_tags_prefix_spec.rb
146
150
  - spec/swagger_v2/namespace_tags_spec.rb
@@ -171,7 +175,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
171
175
  requirements:
172
176
  - - ">="
173
177
  - !ruby/object:Gem::Version
174
- version: '2.2'
178
+ version: '2.3'
175
179
  required_rubygems_version: !ruby/object:Gem::Requirement
176
180
  requirements:
177
181
  - - ">="
@@ -179,12 +183,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
179
183
  version: '0'
180
184
  requirements: []
181
185
  rubyforge_project:
182
- rubygems_version: 2.6.12
186
+ rubygems_version: 2.7.3
183
187
  signing_key:
184
188
  specification_version: 4
185
189
  summary: Add auto generated documentation to your Grape API that can be displayed
186
190
  with Swagger.
187
191
  test_files:
192
+ - spec/issues/267_nested_namespaces.rb
188
193
  - spec/issues/403_versions_spec.rb
189
194
  - spec/issues/427_entity_as_string_spec.rb
190
195
  - spec/issues/430_entity_definitions_spec.rb
@@ -199,6 +204,7 @@ test_files:
199
204
  - spec/issues/582_file_response_spec.rb
200
205
  - spec/issues/587_range_parameter_delimited_by_dash_spec.rb
201
206
  - spec/issues/605_root_route_documentation_spec.rb
207
+ - spec/issues/650_params_array_spec.rb
202
208
  - spec/lib/data_type_spec.rb
203
209
  - spec/lib/endpoint_spec.rb
204
210
  - spec/lib/extensions_spec.rb
@@ -239,6 +245,7 @@ test_files:
239
245
  - spec/swagger_v2/api_swagger_v2_request_params_fix_spec.rb
240
246
  - spec/swagger_v2/api_swagger_v2_response_spec.rb
241
247
  - spec/swagger_v2/api_swagger_v2_spec.rb
248
+ - spec/swagger_v2/api_swagger_v2_status_codes_spec.rb
242
249
  - spec/swagger_v2/api_swagger_v2_type-format_spec.rb
243
250
  - spec/swagger_v2/boolean_params_spec.rb
244
251
  - spec/swagger_v2/default_api_spec.rb
@@ -251,6 +258,7 @@ test_files:
251
258
  - spec/swagger_v2/guarded_endpoint_spec.rb
252
259
  - spec/swagger_v2/hide_api_spec.rb
253
260
  - spec/swagger_v2/host.rb
261
+ - spec/swagger_v2/mount_override_api_spec.rb
254
262
  - spec/swagger_v2/mounted_target_class_spec.rb
255
263
  - spec/swagger_v2/namespace_tags_prefix_spec.rb
256
264
  - spec/swagger_v2/namespace_tags_spec.rb