grape-swagger 1.3.0 → 1.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +14 -0
  3. data/.github/workflows/rubocop.yml +26 -0
  4. data/.github/workflows/ruby.yml +30 -0
  5. data/.gitignore +1 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +10 -2
  8. data/.rubocop_todo.yml +1 -1
  9. data/CHANGELOG.md +39 -0
  10. data/Gemfile +3 -3
  11. data/README.md +113 -2
  12. data/UPGRADING.md +8 -0
  13. data/grape-swagger.gemspec +3 -3
  14. data/lib/grape-swagger/doc_methods/format_data.rb +3 -1
  15. data/lib/grape-swagger/doc_methods/move_params.rb +6 -7
  16. data/lib/grape-swagger/doc_methods/parse_params.rb +37 -5
  17. data/lib/grape-swagger/endpoint.rb +45 -6
  18. data/lib/grape-swagger/errors.rb +2 -0
  19. data/lib/grape-swagger/model_parsers.rb +2 -2
  20. data/lib/grape-swagger/rake/oapi_tasks.rb +1 -1
  21. data/lib/grape-swagger/version.rb +1 -1
  22. data/lib/grape-swagger.rb +5 -2
  23. data/spec/issues/537_enum_values_spec.rb +1 -0
  24. data/spec/issues/776_multiple_presents_spec.rb +59 -0
  25. data/spec/issues/809_utf8_routes_spec.rb +55 -0
  26. data/spec/issues/832_array_hash_float_decimal_spec.rb +111 -0
  27. data/spec/lib/format_data_spec.rb +24 -0
  28. data/spec/spec_helper.rb +1 -1
  29. data/spec/support/empty_model_parser.rb +2 -0
  30. data/spec/support/model_parsers/mock_parser.rb +16 -0
  31. data/spec/support/namespace_tags.rb +3 -0
  32. data/spec/support/the_paths_definitions.rb +4 -4
  33. data/spec/swagger_v2/api_swagger_v2_additional_properties_spec.rb +83 -0
  34. data/spec/swagger_v2/api_swagger_v2_mounted_spec.rb +1 -0
  35. data/spec/swagger_v2/api_swagger_v2_param_type_body_nested_spec.rb +73 -1
  36. data/spec/swagger_v2/api_swagger_v2_response_with_headers_spec.rb +4 -2
  37. data/spec/swagger_v2/api_swagger_v2_spec.rb +1 -0
  38. data/spec/swagger_v2/boolean_params_spec.rb +4 -1
  39. data/spec/swagger_v2/float_api_spec.rb +1 -0
  40. data/spec/swagger_v2/inheritance_and_discriminator_spec.rb +1 -0
  41. data/spec/swagger_v2/namespace_tags_prefix_spec.rb +1 -0
  42. data/spec/swagger_v2/param_multi_type_spec.rb +2 -0
  43. data/spec/swagger_v2/param_type_spec.rb +3 -0
  44. data/spec/swagger_v2/param_values_spec.rb +6 -0
  45. data/spec/swagger_v2/{params_array_collection_fromat_spec.rb → params_array_collection_format_spec.rb} +0 -0
  46. data/spec/swagger_v2/params_example_spec.rb +40 -0
  47. data/spec/swagger_v2/simple_mounted_api_spec.rb +3 -0
  48. metadata +21 -7
  49. data/.travis.yml +0 -40
data/lib/grape-swagger.rb CHANGED
@@ -29,7 +29,10 @@ module SwaggerRouting
29
29
  route_match = route_path.split(/^.*?#{route.prefix}/).last
30
30
  next unless route_match
31
31
 
32
- route_match = route_match.match('\/([\w|-]*?)[\.\/\(]') || route_match.match('\/([\w|-]*)$')
32
+ # want to match emojis … ;)
33
+ # route_match = route_match
34
+ # .match('\/([\p{Alnum}|\p{Emoji}|\-|\_]*?)[\.\/\(]') || route_match.match('\/([\p{Alpha}|\p{Emoji}|\-|\_]*)$')
35
+ route_match = route_match.match('\/([\p{Alnum}|\-|\_]*?)[\.\/\(]') || route_match.match('\/([\p{Alpha}|\-|\_]*)$')
33
36
  next unless route_match
34
37
 
35
38
  resource = route_match.captures.first
@@ -85,7 +88,7 @@ module SwaggerRouting
85
88
  route_name = name.match(%r{^/?([^/]*).*$})[1]
86
89
  return route_name unless route_name.include? ':'
87
90
 
88
- matches = name.match(/\/[a-z]+/)
91
+ matches = name.match(/\/\p{Alpha}+/)
89
92
  matches.nil? ? route_name : matches[0].delete('/')
90
93
  end
91
94
 
@@ -15,6 +15,7 @@ describe '#537 enum values spec' do
15
15
  desc 'create account',
16
16
  success: Spec
17
17
  get do
18
+ { message: 'hi' }
18
19
  end
19
20
  end
20
21
 
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#776 multiple presents spec' do
6
+ include_context "#{MODEL_PARSER} swagger example"
7
+
8
+ let(:app) do
9
+ Class.new(Grape::API) do
10
+ namespace :issue_776 do
11
+ desc 'Get multiple presents',
12
+ success: [
13
+ { model: Entities::EnumValues, as: :gender },
14
+ { model: Entities::Something, as: :somethings, is_array: true, required: true }
15
+ ]
16
+
17
+ get do
18
+ present :gender, { number: 1, gender: 'Male' }, with: Entities::EnumValues
19
+ present :somethings, [
20
+ { id: 1, text: 'element_1', links: %w[link1 link2] },
21
+ { id: 2, text: 'element_2', links: %w[link1 link2] }
22
+ ], with: Entities::Something, is_array: true
23
+ end
24
+ end
25
+
26
+ add_swagger_documentation format: :json
27
+ end
28
+ end
29
+
30
+ subject do
31
+ get '/swagger_doc'
32
+ JSON.parse(last_response.body)
33
+ end
34
+
35
+ let(:definitions) { subject['definitions'] }
36
+ let(:schema) { subject['paths']['/issue_776']['get']['responses']['200']['schema'] }
37
+
38
+ specify { expect(definitions.keys).to include 'EnumValues', 'Something' }
39
+
40
+ specify do
41
+ expect(schema).to eql({
42
+ 'properties' => {
43
+ 'somethings' => {
44
+ 'items' => {
45
+ '$ref' => '#/definitions/Something'
46
+ },
47
+ 'type' => 'array'
48
+ },
49
+ 'gender' => {
50
+ '$ref' => '#/definitions/EnumValues'
51
+ }
52
+ },
53
+ 'type' => 'object',
54
+ 'required' => [
55
+ 'somethings'
56
+ ]
57
+ })
58
+ end
59
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#605 root route documentation' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ resource :grunnbeløp do
9
+ desc 'returnerer grunnbeløp'
10
+ get do
11
+ { message: 'hello world' }
12
+ end
13
+ end
14
+
15
+ resource :εσόδων do
16
+ desc 'εσόδων'
17
+ get do
18
+ { message: 'hello world' }
19
+ end
20
+ end
21
+
22
+ resource :数 do
23
+ desc '数'
24
+ get do
25
+ { message: 'hello world' }
26
+ end
27
+ end
28
+
29
+ resource :amount do
30
+ desc 'returns amount'
31
+ get do
32
+ { message: 'hello world' }
33
+ end
34
+ end
35
+
36
+ resource :👍 do
37
+ desc 'returns 👍'
38
+ get do
39
+ { message: 'hello world' }
40
+ end
41
+ end
42
+
43
+ add_swagger_documentation
44
+ end
45
+ end
46
+
47
+ subject do
48
+ get '/swagger_doc'
49
+ JSON.parse(last_response.body)['paths']
50
+ end
51
+
52
+ specify do
53
+ expect(subject.keys).to match_array ['/grunnbeløp', '/amount', '/εσόδων', '/数']
54
+ end
55
+ end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#832 array of objects with nested Float/BigDecimal fields' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ resource :issue_832 do
9
+ params do
10
+ requires :array_param, type: Array do
11
+ requires :float_param, type: Float
12
+ requires :big_decimal_param, type: BigDecimal
13
+ requires :object_param, type: Hash do
14
+ requires :float_param, type: Float
15
+ requires :big_decimal_param, type: BigDecimal
16
+ requires :object_param, type: Hash do
17
+ requires :float_param, type: Float
18
+ requires :big_decimal_param, type: BigDecimal
19
+ requires :array_param, type: Array do
20
+ requires :integer_param, type: Integer
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ post do
27
+ { message: 'hello world' }
28
+ end
29
+ end
30
+
31
+ add_swagger_documentation
32
+ end
33
+ end
34
+ let(:parameters) { subject['paths']['/issue_832']['post']['parameters'] }
35
+
36
+ subject do
37
+ get '/swagger_doc'
38
+ JSON.parse(last_response.body)
39
+ end
40
+
41
+ specify do
42
+ expect(parameters).to eql(
43
+ [
44
+ {
45
+ 'in' => 'formData',
46
+ 'name' => 'array_param[float_param]',
47
+ 'type' => 'array',
48
+ 'required' => true,
49
+ 'items' => {
50
+ 'type' => 'number',
51
+ 'format' => 'float'
52
+ }
53
+ }, {
54
+ 'in' => 'formData',
55
+ 'name' => 'array_param[big_decimal_param]',
56
+ 'type' => 'array',
57
+ 'required' => true,
58
+ 'items' => {
59
+ 'type' => 'number',
60
+ 'format' => 'double'
61
+ }
62
+ }, {
63
+ 'in' => 'formData',
64
+ 'name' => 'array_param[object_param][float_param]',
65
+ 'type' => 'array',
66
+ 'required' => true,
67
+ 'items' => {
68
+ 'type' => 'number',
69
+ 'format' => 'float'
70
+ }
71
+ }, {
72
+ 'in' => 'formData',
73
+ 'name' => 'array_param[object_param][big_decimal_param]',
74
+ 'type' => 'array',
75
+ 'required' => true,
76
+ 'items' => {
77
+ 'type' => 'number',
78
+ 'format' => 'double'
79
+ }
80
+ }, {
81
+ 'in' => 'formData',
82
+ 'name' => 'array_param[object_param][object_param][float_param]',
83
+ 'type' => 'array',
84
+ 'required' => true,
85
+ 'items' => {
86
+ 'type' => 'number',
87
+ 'format' => 'float'
88
+ }
89
+ }, {
90
+ 'in' => 'formData',
91
+ 'name' => 'array_param[object_param][object_param][big_decimal_param]',
92
+ 'type' => 'array',
93
+ 'required' => true,
94
+ 'items' => {
95
+ 'type' => 'number',
96
+ 'format' => 'double'
97
+ }
98
+ }, {
99
+ 'in' => 'formData',
100
+ 'name' => 'array_param[object_param][object_param][array_param][integer_param]',
101
+ 'type' => 'array',
102
+ 'required' => true,
103
+ 'items' => {
104
+ 'type' => 'integer',
105
+ 'format' => 'int32'
106
+ }
107
+ }
108
+ ]
109
+ )
110
+ end
111
+ end
@@ -87,5 +87,29 @@ describe GrapeSwagger::DocMethods::FormatData do
87
87
  expect(subject.to_format(params)).to eq expected_params
88
88
  end
89
89
  end
90
+
91
+ context 'when array params are not related' do
92
+ let(:params) do
93
+ [
94
+ { name: 'id', required: true, type: 'string' },
95
+ { name: 'description', required: false, type: 'string' },
96
+ { name: 'ids[]', required: true, type: 'array', items: { type: 'string' } },
97
+ { name: 'user_ids[]', required: true, type: 'array', items: { type: 'string' } }
98
+ ]
99
+ end
100
+
101
+ let(:expected_params) do
102
+ [
103
+ { name: 'id', required: true, type: 'string' },
104
+ { name: 'description', required: false, type: 'string' },
105
+ { name: 'ids[]', required: true, type: 'array', items: { type: 'string' } },
106
+ { name: 'user_ids[]', required: true, type: 'array', items: { type: 'string' } }
107
+ ]
108
+ end
109
+
110
+ it 'parses params correctly and adds array type all concerned elements' do
111
+ expect(subject.to_format(params)).to eq expected_params
112
+ end
113
+ end
90
114
  end
91
115
  end
data/spec/spec_helper.rb CHANGED
@@ -19,7 +19,7 @@ MODEL_PARSER = ENV.key?('MODEL_PARSER') ? ENV['MODEL_PARSER'].to_s.downcase.sub(
19
19
  require 'grape'
20
20
  require 'grape-swagger'
21
21
 
22
- Dir[File.join(Dir.getwd, 'spec/support/*.rb')].sort.each { |f| require f }
22
+ Dir[File.join(Dir.getwd, 'spec/support/*.rb')].each { |f| require f }
23
23
  require "grape-swagger/#{MODEL_PARSER}" if MODEL_PARSER != 'mock'
24
24
  require File.join(Dir.getwd, "spec/support/model_parsers/#{MODEL_PARSER}_parser.rb")
25
25
 
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rubocop:disable Lint/EmptyClass
3
4
  class EmptyClass
4
5
  end
6
+ # rubocop:enable Lint/EmptyClass
5
7
 
6
8
  module GrapeSwagger
7
9
  class EmptyModelParser
@@ -40,21 +40,37 @@ RSpec.shared_context 'mock swagger example' do
40
40
  end
41
41
 
42
42
  class UseNestedWithAddress < OpenStruct; end
43
+
43
44
  class TypedDefinition < OpenStruct; end
45
+
44
46
  class UseItemResponseAsType < OpenStruct; end
47
+
45
48
  class OtherItem < OpenStruct; end
49
+
46
50
  class EnumValues < OpenStruct; end
51
+
47
52
  class AliasedThing < OpenStruct; end
53
+
48
54
  class FourthLevel < OpenStruct; end
55
+
49
56
  class ThirdLevel < OpenStruct; end
57
+
50
58
  class SecondLevel < OpenStruct; end
59
+
51
60
  class FirstLevel < OpenStruct; end
61
+
52
62
  class QueryInputElement < OpenStruct; end
63
+
53
64
  class QueryInput < OpenStruct; end
65
+
54
66
  class ApiError < OpenStruct; end
67
+
55
68
  class SecondApiError < OpenStruct; end
69
+
56
70
  class RecursiveModel < OpenStruct; end
71
+
57
72
  class DocumentedHashAndArrayModel < OpenStruct; end
73
+
58
74
  module NestedModule
59
75
  class ApiResponse < OpenStruct; end
60
76
  end
@@ -3,12 +3,15 @@
3
3
  RSpec.shared_context 'namespace example' do
4
4
  before :all do
5
5
  module TheApi
6
+ # rubocop:disable Lint/EmptyClass
6
7
  class CustomType; end
8
+ # rubocop:enable Lint/EmptyClass
7
9
 
8
10
  class NamespaceApi < Grape::API
9
11
  namespace :hudson do
10
12
  desc 'Document root'
11
13
  get '/' do
14
+ { message: 'hi' }
12
15
  end
13
16
  end
14
17
 
@@ -8,7 +8,7 @@ RSpec.shared_context 'the api paths/defs' do
8
8
  produces: ['application/json'],
9
9
  consumes: ['application/json'],
10
10
  parameters: [
11
- { in: 'body', name: 'in_body_1', description: 'in_body_1', type: 'integer', format: 'int32', required: true },
11
+ { in: 'body', name: 'in_body_1', description: 'in_body_1', type: 'integer', format: 'int32', required: true, example: 23 },
12
12
  { in: 'body', name: 'in_body_2', description: 'in_body_2', type: 'string', required: false },
13
13
  { in: 'body', name: 'in_body_3', description: 'in_body_3', type: 'string', required: false }
14
14
  ],
@@ -31,7 +31,7 @@ RSpec.shared_context 'the api paths/defs' do
31
31
  { in: 'path', name: 'key', description: nil, type: 'integer', format: 'int32', required: true },
32
32
  { in: 'body', name: 'in_body_1', description: 'in_body_1', type: 'integer', format: 'int32', required: true },
33
33
  { in: 'body', name: 'in_body_2', description: 'in_body_2', type: 'string', required: false },
34
- { in: 'body', name: 'in_body_3', description: 'in_body_3', type: 'string', required: false }
34
+ { in: 'body', name: 'in_body_3', description: 'in_body_3', type: 'string', required: false, example: 'my example string' }
35
35
  ],
36
36
  responses: { 200 => { description: 'put in body /wo entity', schema: { '$ref' => '#/definitions/InBody' } } },
37
37
  tags: ['in_body'],
@@ -85,7 +85,7 @@ RSpec.shared_context 'the api paths/defs' do
85
85
  {
86
86
  type: 'object',
87
87
  properties: {
88
- in_body_1: { type: 'integer', format: 'int32', description: 'in_body_1' },
88
+ in_body_1: { type: 'integer', format: 'int32', description: 'in_body_1', example: 23 },
89
89
  in_body_2: { type: 'string', description: 'in_body_2' },
90
90
  in_body_3: { type: 'string', description: 'in_body_3' }
91
91
  },
@@ -99,7 +99,7 @@ RSpec.shared_context 'the api paths/defs' do
99
99
  properties: {
100
100
  in_body_1: { type: 'integer', format: 'int32', description: 'in_body_1' },
101
101
  in_body_2: { type: 'string', description: 'in_body_2' },
102
- in_body_3: { type: 'string', description: 'in_body_3' }
102
+ in_body_3: { type: 'string', description: 'in_body_3', example: 'my example string' }
103
103
  },
104
104
  required: [:in_body_1]
105
105
  }
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'parsing additional_parameters' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ namespace :things do
9
+ class Element < Grape::Entity
10
+ expose :id
11
+ end
12
+
13
+ params do
14
+ optional :closed, type: Hash, documentation: { additional_properties: false, in: 'body' } do
15
+ requires :only
16
+ end
17
+ optional :open, type: Hash, documentation: { additional_properties: true }
18
+ optional :type_limited, type: Hash, documentation: { additional_properties: String }
19
+ optional :ref_limited, type: Hash, documentation: { additional_properties: Element }
20
+ optional :fallback, type: Hash, documentation: { additional_properties: { type: 'integer' } }
21
+ end
22
+ post do
23
+ present params
24
+ end
25
+ end
26
+
27
+ add_swagger_documentation format: :json, models: [Element]
28
+ end
29
+ end
30
+
31
+ subject do
32
+ get '/swagger_doc/things'
33
+ JSON.parse(last_response.body)
34
+ end
35
+
36
+ describe 'POST' do
37
+ specify do
38
+ expect(subject.dig('paths', '/things', 'post', 'parameters')).to eql(
39
+ [
40
+ { 'name' => 'Things', 'in' => 'body', 'required' => true, 'schema' => { '$ref' => '#/definitions/postThings' } }
41
+ ]
42
+ )
43
+ end
44
+
45
+ specify do
46
+ expect(subject.dig('definitions', 'postThings')).to eql(
47
+ 'type' => 'object',
48
+ 'properties' => {
49
+ 'closed' => {
50
+ 'type' => 'object',
51
+ 'additionalProperties' => false,
52
+ 'properties' => {
53
+ 'only' => { 'type' => 'string' }
54
+ },
55
+ 'required' => ['only']
56
+ },
57
+ 'open' => {
58
+ 'type' => 'object',
59
+ 'additionalProperties' => true
60
+ },
61
+ 'type_limited' => {
62
+ 'type' => 'object',
63
+ 'additionalProperties' => {
64
+ 'type' => 'string'
65
+ }
66
+ },
67
+ 'ref_limited' => {
68
+ 'type' => 'object',
69
+ 'additionalProperties' => {
70
+ '$ref' => '#/definitions/Element'
71
+ }
72
+ },
73
+ 'fallback' => {
74
+ 'type' => 'object',
75
+ 'additionalProperties' => {
76
+ 'type' => 'integer'
77
+ }
78
+ }
79
+ }
80
+ )
81
+ end
82
+ end
83
+ end
@@ -81,6 +81,7 @@ describe 'swagger spec v2.0' do
81
81
  requires :id, type: Integer
82
82
  end
83
83
  delete '/dummy/:id' do
84
+ {}
84
85
  end
85
86
 
86
87
  namespace :other_thing do
@@ -13,7 +13,7 @@ describe 'moving body/formData Params to definitions' do
13
13
  detail: 'more details description',
14
14
  success: Entities::UseNestedWithAddress
15
15
  params do
16
- optional :contact, type: Hash do
16
+ optional :contact, type: Hash, documentation: { additional_properties: true } do
17
17
  requires :name, type: String, documentation: { desc: 'name', in: 'body' }
18
18
  optional :addresses, type: Array do
19
19
  requires :street, type: String, documentation: { desc: 'street', in: 'body' }
@@ -96,6 +96,27 @@ describe 'moving body/formData Params to definitions' do
96
96
  end
97
97
  end
98
98
 
99
+ namespace :nested_params_array do
100
+ desc 'post in body with array of nested parameters',
101
+ detail: 'more details description',
102
+ success: Entities::UseNestedWithAddress
103
+ params do
104
+ optional :contacts, type: Array, documentation: { additional_properties: false } do
105
+ requires :name, type: String, documentation: { desc: 'name', in: 'body' }
106
+ optional :addresses, type: Array do
107
+ requires :street, type: String, documentation: { desc: 'street', in: 'body' }
108
+ requires :postcode, type: String, documentation: { desc: 'postcode', in: 'body' }
109
+ requires :city, type: String, documentation: { desc: 'city', in: 'body' }
110
+ optional :country, type: String, documentation: { desc: 'country', in: 'body' }
111
+ end
112
+ end
113
+ end
114
+
115
+ post '/in_body' do
116
+ { 'declared_params' => declared(params) }
117
+ end
118
+ end
119
+
99
120
  add_swagger_documentation
100
121
  end
101
122
  end
@@ -126,6 +147,7 @@ describe 'moving body/formData Params to definitions' do
126
147
  'properties' => {
127
148
  'contact' => {
128
149
  'type' => 'object',
150
+ 'additionalProperties' => true,
129
151
  'properties' => {
130
152
  'name' => { 'type' => 'string', 'description' => 'name' },
131
153
  'addresses' => {
@@ -280,4 +302,54 @@ describe 'moving body/formData Params to definitions' do
280
302
  end
281
303
  end
282
304
  end
305
+
306
+ describe 'array of nested body parameters given' do
307
+ subject do
308
+ get '/swagger_doc/nested_params_array'
309
+ JSON.parse(last_response.body)
310
+ end
311
+
312
+ describe 'POST' do
313
+ specify do
314
+ expect(subject['paths']['/nested_params_array/in_body']['post']['parameters']).to eql(
315
+ [
316
+ { 'name' => 'NestedParamsArrayInBody', 'in' => 'body', 'required' => true, 'schema' => { '$ref' => '#/definitions/postNestedParamsArrayInBody' } }
317
+ ]
318
+ )
319
+ end
320
+
321
+ specify do
322
+ expect(subject['definitions']['postNestedParamsArrayInBody']).to eql(
323
+ 'type' => 'object',
324
+ 'properties' => {
325
+ 'contacts' => {
326
+ 'type' => 'array',
327
+ 'items' => {
328
+ 'type' => 'object',
329
+ 'additionalProperties' => false,
330
+ 'properties' => {
331
+ 'name' => { 'type' => 'string', 'description' => 'name' },
332
+ 'addresses' => {
333
+ 'type' => 'array',
334
+ 'items' => {
335
+ 'type' => 'object',
336
+ 'properties' => {
337
+ 'street' => { 'type' => 'string', 'description' => 'street' },
338
+ 'postcode' => { 'type' => 'string', 'description' => 'postcode' },
339
+ 'city' => { 'type' => 'string', 'description' => 'city' },
340
+ 'country' => { 'type' => 'string', 'description' => 'country' }
341
+ },
342
+ 'required' => %w[street postcode city]
343
+ }
344
+ }
345
+ },
346
+ 'required' => %w[name]
347
+ }
348
+ }
349
+ },
350
+ 'description' => 'post in body with array of nested parameters'
351
+ )
352
+ end
353
+ end
354
+ end
283
355
  end
@@ -19,7 +19,8 @@ describe 'response with headers' do
19
19
  end
20
20
 
21
21
  desc 'A 204 can have headers too' do
22
- success Hash[status: 204, message: 'No content', headers: { 'Location' => { description: 'Location of resource', type: 'string' } }]
22
+ foo = { status: 204, message: 'No content', headers: { 'Location' => { description: 'Location of resource', type: 'string' } } }
23
+ success foo
23
24
  failure [[400, 'Bad Request', Entities::ApiError, { 'application/json' => { code: 400, message: 'Bad request' } }, { 'Date' => { description: 'Date of failure', type: 'string' } }]]
24
25
  end
25
26
  delete '/no_content_response_headers' do
@@ -27,7 +28,8 @@ describe 'response with headers' do
27
28
  end
28
29
 
29
30
  desc 'A file can have headers too' do
30
- success Hash[status: 200, model: 'File', headers: { 'Cache-Control' => { description: 'Directive for caching', type: 'string' } }]
31
+ foo = { status: 200, model: 'File', headers: { 'Cache-Control': { description: 'Directive for caching', type: 'string' } } }
32
+ success foo
31
33
  failure [[404, 'NotFound', Entities::ApiError, { 'application/json' => { code: 404, message: 'Not found' } }, { 'Date' => { description: 'Date of failure', type: 'string' } }]]
32
34
  end
33
35
  get '/file_response_headers' do
@@ -80,6 +80,7 @@ describe 'swagger spec v2.0' do
80
80
  requires :id, type: Integer
81
81
  end
82
82
  delete '/dummy/:id' do
83
+ {}
83
84
  end
84
85
 
85
86
  namespace :other_thing do
@@ -9,8 +9,10 @@ describe 'Boolean Params' do
9
9
 
10
10
  params do
11
11
  requires :a_boolean, type: Grape::API::Boolean
12
+ optional :another_boolean, type: Grape::API::Boolean, default: false
12
13
  end
13
14
  post :splines do
15
+ { message: 'hi' }
14
16
  end
15
17
 
16
18
  add_swagger_documentation
@@ -26,7 +28,8 @@ describe 'Boolean Params' do
26
28
 
27
29
  it 'converts boolean types' do
28
30
  expect(subject).to eq [
29
- { 'in' => 'formData', 'name' => 'a_boolean', 'type' => 'boolean', 'required' => true }
31
+ { 'in' => 'formData', 'name' => 'a_boolean', 'type' => 'boolean', 'required' => true },
32
+ { 'in' => 'formData', 'name' => 'another_boolean', 'type' => 'boolean', 'required' => false, 'default' => false }
30
33
  ]
31
34
  end
32
35
  end
@@ -11,6 +11,7 @@ describe 'Float Params' do
11
11
  requires :a_float, type: Float
12
12
  end
13
13
  post :splines do
14
+ { message: 'hi' }
14
15
  end
15
16
 
16
17
  add_swagger_documentation
@@ -33,6 +33,7 @@ describe 'Inheritance and Discriminator' do
33
33
  }
34
34
  end
35
35
  end
36
+
36
37
  class NameApi < Grape::API
37
38
  add_swagger_documentation models: [Entities::Pet, Entities::Cat]
38
39
  end
@@ -17,6 +17,7 @@ describe 'namespace tags check while using prefix and version' do
17
17
  namespace :hudson do
18
18
  desc 'Document root'
19
19
  get '/' do
20
+ { message: 'hi' }
20
21
  end
21
22
  end
22
23