Skip to content

Commit

Permalink
Update CHANGELOG.md
Browse files Browse the repository at this point in the history
  • Loading branch information
peter scholz committed Mar 17, 2016
1 parent 3a97ec1 commit 8b9825d
Show file tree
Hide file tree
Showing 11 changed files with 193 additions and 120 deletions.
2 changes: 1 addition & 1 deletion .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Metrics/AbcSize:
# Offense count: 1
# Configuration parameters: CountComments.
Metrics/ClassLength:
Max: 300
Max: 230

# Offense count: 6
Metrics/CyclomaticComplexity:
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@

n.n.n / 2016-03-16
==================
[#356](https://github.com/ruby-grape/grape-swagger/pull/356)

- adds `consumes` setting
- refactoring

[#354](https://github.com/ruby-grape/grape-swagger/pull/354) some improvements

Expand Down
2 changes: 2 additions & 0 deletions lib/grape-swagger.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
require 'grape-swagger/doc_methods/optional_object'
require 'grape-swagger/doc_methods/path_string'
require 'grape-swagger/doc_methods/tag_name_description'
require 'grape-swagger/doc_methods/parse_params'

require 'grape-swagger/doc_methods'

require 'grape-swagger/markdown/kramdown_adapter'
Expand Down
102 changes: 102 additions & 0 deletions lib/grape-swagger/doc_methods/parse_params.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
module GrapeSwagger
module DocMethods
class ParseParams
class << self
def call(param, value, route)
@array_items = {}
path = route.route_path
method = route.route_method

additional_documentation = value.is_a?(Hash) ? value[:documentation] : nil
data_type = GrapeSwagger::DocMethods::DataType.call(value)

if additional_documentation && value.is_a?(Hash)
value = additional_documentation.merge(value)
end

description = value.is_a?(Hash) ? value[:desc] || value[:description] : nil
required = value.is_a?(Hash) ? value[:required] : false
default_value = value.is_a?(Hash) ? value[:default] : nil
example = value.is_a?(Hash) ? value[:example] : nil
is_array = value.is_a?(Hash) ? (value[:is_array] || false) : false
values = value.is_a?(Hash) ? value[:values] : nil
name = (value.is_a?(Hash) && value[:full_name]) || param
enum_or_range_values = parse_enum_or_range_values(values)

value_type = { value: value, data_type: data_type, path: path }

parsed_params = {
in: param_type(value_type, param, method, is_array),
name: name,
description: description,
type: data_type,
required: required,
allowMultiple: is_array
}

if GrapeSwagger::DocMethods::DataType::PRIMITIVE_MAPPINGS.key?(data_type)
parsed_params[:type], parsed_params[:format] = GrapeSwagger::DocMethods::DataType::PRIMITIVE_MAPPINGS[data_type]
end

parsed_params[:items] = @array_items if @array_items.present?

parsed_params[:defaultValue] = example if example
parsed_params[:defaultValue] = default_value if default_value && example.blank?

parsed_params.merge!(enum_or_range_values) if enum_or_range_values
parsed_params
end

def primitive?(type)
%w(object integer long float double string byte boolean date datetime).include? type.to_s.downcase
end

private

def param_type(value_type, param, method, is_array)
# TODO: use `value_type.dig():value, :documentation, :param_type)` instead req ruby2.3
#
if value_type[:value].is_a?(Hash) &&
value_type[:value].key?(:documentation) &&
value_type[:value][:documentation].key?(:param_type)

if is_array
@array_items = { 'type' => value_type[:data_type] }

'array'
end
else
case
when value_type[:path].include?("{#{param}}")
'path'
when %w(POST PUT PATCH).include?(method)
primitive?(value_type[:data_type]) ? 'formData' : 'body'
else
'query'
end
end
end

def parse_enum_or_range_values(values)
case values
when Range
parse_range_values(values) if values.first.is_a?(Integer)
when Proc
values_result = values.call
if values_result.is_a?(Range) && values_result.first.is_a?(Integer)
parse_range_values(values_result)
else
{ enum: values_result }
end
else
{ enum: values } if values
end
end

def parse_range_values(values)
{ minimum: values.first, maximum: values.last }
end
end
end
end
end
117 changes: 17 additions & 100 deletions lib/grape-swagger/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ def license_object(infos)
# contact
def contact_object(infos)
{
contact_name: infos.delete(:contact_name),
contact_email: infos.delete(:contact_email),
contact_url: infos.delete(:contact_url)
name: infos.delete(:contact_name),
email: infos.delete(:contact_email),
url: infos.delete(:contact_url)
}.delete_if { |_, value| value.blank? }
end

Expand Down Expand Up @@ -194,7 +194,7 @@ def default_staus_codes
def params_object(route)
partition_params(route).map do |param, value|
value = { required: false }.merge(value) if value.is_a?(Hash)
parse_params(param, value, route.route_path, route.route_method)
GrapeSwagger::DocMethods::ParseParams.call(param, value, route)
end
end

Expand Down Expand Up @@ -236,8 +236,12 @@ def parse_response_params(params)

params.each_with_object({}) do |x, memo|
x[0] = x.last[:as] if x.last[:as]
if x.last[:using].present? || could_it_be_a_model?(x.last)
name = expose_params_from_model(x.last[:using] || x.last[:type])

model = x.last[:using] if x.last[:using].present?
model ||= x.last[:documentation][:type] if x.last[:documentation] && could_it_be_a_model?(x.last[:documentation])

if model
name = expose_params_from_model(model)
memo[x.first] = if x.last[:documentation] && x.last[:documentation][:is_array]
{ 'type' => 'array', 'items' => { '$ref' => "#/definitions/#{name}" } }
else
Expand All @@ -251,7 +255,7 @@ def parse_response_params(params)
end

def expose_params_from_model(model)
model_name = model.name.demodulize.camelize
model_name = model.respond_to?(:name) ? model.name.demodulize.camelize : model.split('::').last

# DONE: has to be adept, to be ready for grape-entity >0.5.0
# TODO: this should only be a temporary hack ;)
Expand All @@ -270,10 +274,14 @@ def expose_params_from_model(model)
end

def could_it_be_a_model?(value)
value[:type] &&
(
value[:type].to_s.include?('Entity') || value[:type].to_s.include?('Entities')
) || (
value[:type] &&
value[:type].is_a?(Class) &&
!primitive?(value[:type].name.downcase) &&
!GrapeSwagger::DocMethods::ParseParams.primitive?(value[:type].name.downcase) &&
!value[:type] == Array
)
end

def hidden?(route)
Expand All @@ -284,97 +292,6 @@ def hidden?(route)
false
end

# original methods
#
def parse_params(param, value, path, method)
@array_items = {}

additional_documentation = value.is_a?(Hash) ? value[:documentation] : nil
data_type = GrapeSwagger::DocMethods::DataType.call(value)

if additional_documentation && value.is_a?(Hash)
value = additional_documentation.merge(value)
end

description = value.is_a?(Hash) ? value[:desc] || value[:description] : nil
required = value.is_a?(Hash) ? value[:required] : false
default_value = value.is_a?(Hash) ? value[:default] : nil
example = value.is_a?(Hash) ? value[:example] : nil
is_array = value.is_a?(Hash) ? (value[:is_array] || false) : false
values = value.is_a?(Hash) ? value[:values] : nil
name = (value.is_a?(Hash) && value[:full_name]) || param
enum_or_range_values = parse_enum_or_range_values(values)

value_type = { value: value, data_type: data_type, path: path }

parsed_params = {
in: param_type(value_type, param, method, is_array),
name: name,
description: description,
type: data_type,
required: required,
allowMultiple: is_array
}

if GrapeSwagger::DocMethods::DataType::PRIMITIVE_MAPPINGS.key?(data_type)
parsed_params[:type], parsed_params[:format] = GrapeSwagger::DocMethods::DataType::PRIMITIVE_MAPPINGS[data_type]
end

parsed_params[:items] = @array_items if @array_items.present?

parsed_params[:defaultValue] = example if example
parsed_params[:defaultValue] = default_value if default_value && example.blank?

parsed_params.merge!(enum_or_range_values) if enum_or_range_values
parsed_params
end

def param_type(value_type, param, method, is_array)
if value_type[:value].is_a?(Hash) &&
value_type[:value].key?(:documentation) &&
value_type[:value][:documentation].key?(:param_type)

if is_array
@array_items = { 'type' => value_type[:data_type] }

'array'
end
else
case
when value_type[:path].include?("{#{param}}")
'path'
when %w(POST PUT PATCH).include?(method)
primitive?(value_type[:data_type]) ? 'formData' : 'body'
else
'query'
end
end
end

def parse_enum_or_range_values(values)
case values
when Range
parse_range_values(values) if values.first.is_a?(Integer)
when Proc
values_result = values.call
if values_result.is_a?(Range) && values_result.first.is_a?(Integer)
parse_range_values(values_result)
else
{ enum: values_result }
end
else
{ enum: values } if values
end
end

def parse_range_values(values)
{ minimum: values.first, maximum: values.last }
end

def primitive?(type)
%w(object integer long float double string byte boolean date dateTime).include? type
end

def tag_object(route, version)
Array(route.route_path.split('{')[0].split('/').reject(&:empty?).delete_if { |i| ((i == route.route_prefix.to_s) || (i == version)) }.first)
end
Expand Down
1 change: 0 additions & 1 deletion spec/lib/path_string_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
expect(subject.build('/{version}/thing/:id', options)).to eql ['Thing', '/v1/thing/{id}']
expect(subject.build('/{version}/thing/foo/:id', options)).to eql ['Foo', '/v1/thing/foo/{id}']
end

end
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/support/api_swagger_v2_result.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class ApiError < Grape::Entity
"title"=>"The API title to be displayed on the API homepage.",
"description"=>"A description of the API.",
"termsOfServiceUrl"=>"www.The-URL-of-the-terms-and-service.com",
"contact"=>{"contact_name"=>"Contact name", "contact_email"=>"Contact@email.com", "contact_url"=>"Contact URL"},
"contact"=>{"name"=>"Contact name", "email"=>"Contact@email.com", "url"=>"Contact URL"},
"license"=>{"name"=>"The name of the license.", "url"=>"www.The-URL-of-the-license.org"},
"version"=>"v1"
},
Expand Down
5 changes: 5 additions & 0 deletions spec/support/the_api_entities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ class UseResponse < Grape::Entity
expose :description, documentation: { type: String }
expose :items, as: '$responses', using: Entities::ResponseItem, documentation: { is_array: true }
end

class UseTemResponseAsType < Grape::Entity
expose :description, documentation: { type: String }
expose :responses, documentation: { type: Entities::ResponseItem, is_array: false }
end
end
end
end
Expand Down
Loading

0 comments on commit 8b9825d

Please sign in to comment.