Skip to content

Commit 6ef800c

Browse files
scauglogpeter scholz
authored and
peter scholz
committed
multi type and documentation hash (#444)
* multi type parameter default to first type when :type and :default are provided in a documenation hash they override grape :type and :default * rubocop style * changelog style * test multi type only if grape >= 0.14 * rubocop style * test for muli type with grape<0.14
1 parent d3a010d commit 6ef800c

File tree

7 files changed

+208
-34
lines changed

7 files changed

+208
-34
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
#### Features
44

55
* [#448](https://github.com/ruby-grape/grape-swagger/pull/448): Header parameters are now prepended to the parameter list - [@anakinj](https://github.com/anakinj).
6+
* [#444](https://github.com/ruby-grape/grape-swagger/pull/444): With multi types parameter the first type is use as the documentation type [@scauglog](https://github.com/scauglog)
67

78
#### Fixes
89

910
* [#450](https://github.com/ruby-grape/grape-swagger/pull/438): Do not add :description to definitions if :description is missing on path - [@texpert](https://github.com/texpert).
1011
* [#447](https://github.com/ruby-grape/grape-swagger/pull/447): Version part of the url is now ignored when generating tags for endpoint - [@anakinj](https://github.com/anakinj).
12+
* [#444](https://github.com/ruby-grape/grape-swagger//pull/444): Default value provided in the documentation hash, override the grape default [@scauglog](https://github.com/scauglog)
13+
* [#443](https://github.com/ruby-grape/grape-swagger/issues/443): Type provided in the documentation hash, override the grape type [@scauglog](https://github.com/scauglog)
1114

1215
### 0.21.0 (June 1, 2016)
1316

README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,13 @@ add_swagger_documentation \
344344

345345
* [Swagger Header Parameters](#headers)
346346
* [Hiding an Endpoint](#hiding)
347+
* [Overriding Auto-Generated Nicknames](#overriding-auto-generated-nicknames)
347348
* [Defining an endpoint as array](#array)
348349
* [Using an options hash](#options)
349350
* [Specify endpoint details](#details)
351+
* [Overriding param type](#overriding-param-type)
352+
* [Overriding type](#overriding-type)
353+
* [Multi types](#multi-types)
350354
* [Response documentation](#response)
351355

352356

@@ -454,6 +458,51 @@ post :act do
454458
end
455459
```
456460
461+
#### Overriding type
462+
463+
You can override type, using the documentation hash.
464+
465+
```ruby
466+
params do
467+
requires :input, type: String, documentation: { type: 'integer' }
468+
end
469+
post :act do
470+
...
471+
end
472+
```
473+
474+
```json
475+
{
476+
"in": "formData",
477+
"name": "input",
478+
"type": "integer",
479+
"format": "int32",
480+
"required": true
481+
}
482+
```
483+
484+
485+
#### Multi types
486+
487+
By default when you set multi types, the first type is selected as swagger type
488+
489+
```ruby
490+
params do
491+
requires :action, types: [String, Integer]
492+
end
493+
post :act do
494+
...
495+
end
496+
```
497+
498+
```json
499+
{
500+
"in": "formData",
501+
"name": "action",
502+
"type": "string",
503+
"required": true
504+
}
505+
```
457506
458507
#### Overriding the route summary
459508

lib/grape-swagger/doc_methods/data_type.rb

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ module DocMethods
33
class DataType
44
class << self
55
def call(value)
6-
raw_data_type = value[:type] if value.is_a?(Hash)
7-
raw_data_type = value unless value.is_a?(Hash)
8-
raw_data_type ||= 'string'
6+
raw_data_type = value.is_a?(Hash) ? value[:type] : value
7+
raw_data_type ||= 'String'
8+
raw_data_type = parse_multi_type(raw_data_type)
9+
910
case raw_data_type.to_s
1011
when 'Boolean', 'Date', 'Integer', 'String', 'Float', 'JSON', 'Array'
1112
raw_data_type.to_s.downcase
@@ -28,6 +29,17 @@ def call(value)
2829
end
2930
end
3031

32+
def parse_multi_type(raw_data_type)
33+
case raw_data_type
34+
when /\A\[.*\]\z/
35+
raw_data_type.gsub(/[(\A\[)(\s+)(\]\z)]/, '').split(',').first
36+
when Array
37+
raw_data_type.first
38+
else
39+
raw_data_type
40+
end
41+
end
42+
3143
def parse_entity_name(model)
3244
if model.respond_to?(:entity_name)
3345
model.entity_name

lib/grape-swagger/doc_methods/parse_params.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@ def call(param, settings, route)
66
path = route.path
77
method = route.request_method
88

9+
additional_documentation = settings.fetch(:documentation, {})
10+
settings.merge!(additional_documentation)
911
data_type = GrapeSwagger::DocMethods::DataType.call(settings)
10-
additional_documentation = settings[:documentation]
11-
if additional_documentation
12-
settings = additional_documentation.merge(settings)
13-
end
1412

1513
value_type = settings.merge(data_type: data_type, path: path, param_name: param, method: method)
1614

spec/lib/data_type_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@
1818
it { expect(subject).to eql 'object' }
1919
end
2020

21+
describe 'Multi types in a string' do
22+
let(:value) { { type: '[String, Integer]' } }
23+
24+
it { expect(subject).to eql 'string' }
25+
end
26+
27+
describe 'Multi types in array' do
28+
let(:value) { { type: [String, Integer] } }
29+
30+
it { expect(subject).to eql 'string' }
31+
end
32+
2133
describe 'Rack::Multipart::UploadedFile' do
2234
let(:value) { { type: Rack::Multipart::UploadedFile } }
2335

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
require 'spec_helper'
2+
3+
describe 'Params Multi Types' do
4+
def app
5+
Class.new(Grape::API) do
6+
format :json
7+
8+
params do
9+
if Grape::VERSION < '0.14'
10+
requires :input, type: [String, Integer]
11+
else
12+
requires :input, types: [String, Integer]
13+
end
14+
requires :another_input, type: [String, Integer]
15+
end
16+
post :action do
17+
end
18+
19+
add_swagger_documentation
20+
end
21+
end
22+
23+
subject do
24+
get '/swagger_doc/action'
25+
expect(last_response.status).to eq 200
26+
body = JSON.parse last_response.body
27+
body['paths']['/action']['post']['parameters']
28+
end
29+
30+
it 'reads param type correctly' do
31+
expect(subject).to eq [
32+
{
33+
'in' => 'formData',
34+
'name' => 'input',
35+
'type' => 'string',
36+
'required' => true
37+
},
38+
{
39+
'in' => 'formData',
40+
'name' => 'another_input',
41+
'type' => 'string',
42+
'required' => true
43+
}
44+
]
45+
end
46+
47+
describe 'header params' do
48+
def app
49+
Class.new(Grape::API) do
50+
format :json
51+
52+
desc 'Some API', headers: { 'My-Header' => { required: true, description: 'Set this!' } }
53+
params do
54+
if Grape::VERSION < '0.14'
55+
requires :input, type: [String, Integer]
56+
else
57+
requires :input, types: [String, Integer]
58+
end
59+
requires :another_input, type: [String, Integer]
60+
end
61+
post :action do
62+
end
63+
64+
add_swagger_documentation
65+
end
66+
end
67+
68+
it 'has consistent types' do
69+
types = subject.map { |param| param['type'] }
70+
expect(types).to eq(%w(string string string))
71+
end
72+
end
73+
end

spec/swagger_v2/param_type_spec.rb

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,45 +11,72 @@ def app
1111
post :action do
1212
end
1313

14+
params do
15+
requires :input, type: String, default: '14', documentation: { type: 'email', default: '42' }
16+
end
17+
post :action_with_doc do
18+
end
19+
1420
add_swagger_documentation
1521
end
1622
end
23+
context 'with no documentation hash' do
24+
subject do
25+
get '/swagger_doc/action'
26+
expect(last_response.status).to eq 200
27+
body = JSON.parse last_response.body
28+
body['paths']['/action']['post']['parameters']
29+
end
1730

18-
subject do
19-
get '/swagger_doc/action'
20-
expect(last_response.status).to eq 200
21-
body = JSON.parse last_response.body
22-
body['paths']['/action']['post']['parameters']
23-
end
31+
it 'reads param type correctly' do
32+
expect(subject).to eq [{
33+
'in' => 'formData',
34+
'name' => 'input',
35+
'type' => 'string',
36+
'required' => true
37+
}]
38+
end
2439

25-
it 'reads param type correctly' do
26-
expect(subject).to eq [{
27-
'in' => 'formData',
28-
'name' => 'input',
29-
'type' => 'string',
30-
'required' => true
31-
}]
32-
end
40+
describe 'header params' do
41+
def app
42+
Class.new(Grape::API) do
43+
format :json
3344

34-
describe 'header params' do
35-
def app
36-
Class.new(Grape::API) do
37-
format :json
45+
desc 'Some API', headers: { 'My-Header' => { required: true, description: 'Set this!' } }
46+
params do
47+
requires :input, type: String
48+
end
49+
post :action do
50+
end
3851

39-
desc 'Some API', headers: { 'My-Header' => { required: true, description: 'Set this!' } }
40-
params do
41-
requires :input, type: String
42-
end
43-
post :action do
52+
add_swagger_documentation
4453
end
54+
end
4555

46-
add_swagger_documentation
56+
it 'has consistent types' do
57+
types = subject.map { |param| param['type'] }
58+
expect(types).to eq(%w(string string))
4759
end
4860
end
61+
end
62+
63+
context 'with documentation hash' do
64+
subject do
65+
get '/swagger_doc/action_with_doc'
66+
expect(last_response.status).to eq 200
67+
body = JSON.parse last_response.body
68+
body['paths']['/action_with_doc']['post']['parameters']
69+
end
4970

50-
it 'has consistent types' do
51-
types = subject.map { |param| param['type'] }
52-
expect(types).to eq(%w(string string))
71+
it 'reads param type correctly' do
72+
expect(subject).to eq [{
73+
'in' => 'formData',
74+
'name' => 'input',
75+
'type' => 'string',
76+
'format' => 'email',
77+
'default' => '42',
78+
'required' => true
79+
}]
5380
end
5481
end
5582
end

0 commit comments

Comments
 (0)