Skip to content

Commit

Permalink
multi type and documentation hash (#444)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
scauglog authored and peter scholz committed Jun 9, 2016
1 parent d3a010d commit 6ef800c
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 34 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
#### Features

* [#448](https://github.com/ruby-grape/grape-swagger/pull/448): Header parameters are now prepended to the parameter list - [@anakinj](https://github.com/anakinj).
* [#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)

#### Fixes

* [#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).
* [#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).
* [#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)
* [#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)

### 0.21.0 (June 1, 2016)

Expand Down
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,13 @@ add_swagger_documentation \

* [Swagger Header Parameters](#headers)
* [Hiding an Endpoint](#hiding)
* [Overriding Auto-Generated Nicknames](#overriding-auto-generated-nicknames)
* [Defining an endpoint as array](#array)
* [Using an options hash](#options)
* [Specify endpoint details](#details)
* [Overriding param type](#overriding-param-type)
* [Overriding type](#overriding-type)
* [Multi types](#multi-types)
* [Response documentation](#response)


Expand Down Expand Up @@ -454,6 +458,51 @@ post :act do
end
```
#### Overriding type
You can override type, using the documentation hash.
```ruby
params do
requires :input, type: String, documentation: { type: 'integer' }
end
post :act do
...
end
```
```json
{
"in": "formData",
"name": "input",
"type": "integer",
"format": "int32",
"required": true
}
```
#### Multi types
By default when you set multi types, the first type is selected as swagger type
```ruby
params do
requires :action, types: [String, Integer]
end
post :act do
...
end
```
```json
{
"in": "formData",
"name": "action",
"type": "string",
"required": true
}
```
#### Overriding the route summary
Expand Down
18 changes: 15 additions & 3 deletions lib/grape-swagger/doc_methods/data_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ module DocMethods
class DataType
class << self
def call(value)
raw_data_type = value[:type] if value.is_a?(Hash)
raw_data_type = value unless value.is_a?(Hash)
raw_data_type ||= 'string'
raw_data_type = value.is_a?(Hash) ? value[:type] : value
raw_data_type ||= 'String'
raw_data_type = parse_multi_type(raw_data_type)

case raw_data_type.to_s
when 'Boolean', 'Date', 'Integer', 'String', 'Float', 'JSON', 'Array'
raw_data_type.to_s.downcase
Expand All @@ -28,6 +29,17 @@ def call(value)
end
end

def parse_multi_type(raw_data_type)
case raw_data_type
when /\A\[.*\]\z/
raw_data_type.gsub(/[(\A\[)(\s+)(\]\z)]/, '').split(',').first
when Array
raw_data_type.first
else
raw_data_type
end
end

def parse_entity_name(model)
if model.respond_to?(:entity_name)
model.entity_name
Expand Down
6 changes: 2 additions & 4 deletions lib/grape-swagger/doc_methods/parse_params.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ def call(param, settings, route)
path = route.path
method = route.request_method

additional_documentation = settings.fetch(:documentation, {})
settings.merge!(additional_documentation)
data_type = GrapeSwagger::DocMethods::DataType.call(settings)
additional_documentation = settings[:documentation]
if additional_documentation
settings = additional_documentation.merge(settings)
end

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

Expand Down
12 changes: 12 additions & 0 deletions spec/lib/data_type_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@
it { expect(subject).to eql 'object' }
end

describe 'Multi types in a string' do
let(:value) { { type: '[String, Integer]' } }

it { expect(subject).to eql 'string' }
end

describe 'Multi types in array' do
let(:value) { { type: [String, Integer] } }

it { expect(subject).to eql 'string' }
end

describe 'Rack::Multipart::UploadedFile' do
let(:value) { { type: Rack::Multipart::UploadedFile } }

Expand Down
73 changes: 73 additions & 0 deletions spec/swagger_v2/param_multi_type_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
require 'spec_helper'

describe 'Params Multi Types' do
def app
Class.new(Grape::API) do
format :json

params do
if Grape::VERSION < '0.14'
requires :input, type: [String, Integer]
else
requires :input, types: [String, Integer]
end
requires :another_input, type: [String, Integer]
end
post :action do
end

add_swagger_documentation
end
end

subject do
get '/swagger_doc/action'
expect(last_response.status).to eq 200
body = JSON.parse last_response.body
body['paths']['/action']['post']['parameters']
end

it 'reads param type correctly' do
expect(subject).to eq [
{
'in' => 'formData',
'name' => 'input',
'type' => 'string',
'required' => true
},
{
'in' => 'formData',
'name' => 'another_input',
'type' => 'string',
'required' => true
}
]
end

describe 'header params' do
def app
Class.new(Grape::API) do
format :json

desc 'Some API', headers: { 'My-Header' => { required: true, description: 'Set this!' } }
params do
if Grape::VERSION < '0.14'
requires :input, type: [String, Integer]
else
requires :input, types: [String, Integer]
end
requires :another_input, type: [String, Integer]
end
post :action do
end

add_swagger_documentation
end
end

it 'has consistent types' do
types = subject.map { |param| param['type'] }
expect(types).to eq(%w(string string string))
end
end
end
81 changes: 54 additions & 27 deletions spec/swagger_v2/param_type_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,45 +11,72 @@ def app
post :action do
end

params do
requires :input, type: String, default: '14', documentation: { type: 'email', default: '42' }
end
post :action_with_doc do
end

add_swagger_documentation
end
end
context 'with no documentation hash' do
subject do
get '/swagger_doc/action'
expect(last_response.status).to eq 200
body = JSON.parse last_response.body
body['paths']['/action']['post']['parameters']
end

subject do
get '/swagger_doc/action'
expect(last_response.status).to eq 200
body = JSON.parse last_response.body
body['paths']['/action']['post']['parameters']
end
it 'reads param type correctly' do
expect(subject).to eq [{
'in' => 'formData',
'name' => 'input',
'type' => 'string',
'required' => true
}]
end

it 'reads param type correctly' do
expect(subject).to eq [{
'in' => 'formData',
'name' => 'input',
'type' => 'string',
'required' => true
}]
end
describe 'header params' do
def app
Class.new(Grape::API) do
format :json

describe 'header params' do
def app
Class.new(Grape::API) do
format :json
desc 'Some API', headers: { 'My-Header' => { required: true, description: 'Set this!' } }
params do
requires :input, type: String
end
post :action do
end

desc 'Some API', headers: { 'My-Header' => { required: true, description: 'Set this!' } }
params do
requires :input, type: String
end
post :action do
add_swagger_documentation
end
end

add_swagger_documentation
it 'has consistent types' do
types = subject.map { |param| param['type'] }
expect(types).to eq(%w(string string))
end
end
end

context 'with documentation hash' do
subject do
get '/swagger_doc/action_with_doc'
expect(last_response.status).to eq 200
body = JSON.parse last_response.body
body['paths']['/action_with_doc']['post']['parameters']
end

it 'has consistent types' do
types = subject.map { |param| param['type'] }
expect(types).to eq(%w(string string))
it 'reads param type correctly' do
expect(subject).to eq [{
'in' => 'formData',
'name' => 'input',
'type' => 'string',
'format' => 'email',
'default' => '42',
'required' => true
}]
end
end
end

0 comments on commit 6ef800c

Please sign in to comment.