grape-swagger 0.27.3 → 0.28.0

Sign up to get free protection for your applications and to get access to all the features.
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