grape-swagger 1.3.0 → 1.4.2

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.
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