Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adds support for own format, refactoring #21

Merged
merged 1 commit into from
Feb 3, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,18 @@ AllCops:
- vendor/**/*

inherit_from: .rubocop_todo.yml

Metrics/BlockLength:
Exclude:
- spec/**/*

Metrics/LineLength:
Exclude:
- spec/**/*

Metrics/MethodLength:
Exclude:
- spec/**/*

Style/IndentHash:
EnforcedStyle: consistent
25 changes: 15 additions & 10 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
@@ -1,44 +1,49 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2016-06-08 01:18:12 +0300 using RuboCop version 0.40.0.
# on 2017-02-02 15:42:44 +0100 using RuboCop version 0.47.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.

# Offense count: 1
Metrics/AbcSize:
Max: 48
Max: 45

# Offense count: 8
# Configuration parameters: CountComments, ExcludedMethods.
Metrics/BlockLength:
Max: 27

# Offense count: 1
Metrics/CyclomaticComplexity:
Max: 16
Max: 14

# Offense count: 50
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes.
# Offense count: 11
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
# URISchemes: http, https
Metrics/LineLength:
Max: 136
Max: 120

# Offense count: 2
# Configuration parameters: CountComments.
Metrics/MethodLength:
Max: 42
Max: 30

# Offense count: 1
Metrics/PerceivedComplexity:
Max: 18
Max: 16

# Offense count: 2
Style/Documentation:
Exclude:
- 'spec/**/*'
- 'test/**/*'
- 'lib/grape-swagger/entity.rb'
- 'lib/grape-swagger/entity/parser.rb'

# Offense count: 1
# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts.
# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
Style/FileName:
Exclude:
- 'lib/grape-swagger-entity.rb'
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#### Features

* [#21](https://github.com/ruby-grape/grape-swagger-entity/pull/21): Adds support for own format - [@LeFnord](https://github.com/LeFnord).
* [#19](https://github.com/ruby-grape/grape-swagger-entity/pull/19): Adds support for default value - [@LeFnord](https://github.com/LeFnord).

* Your contribution here.
Expand Down
16 changes: 14 additions & 2 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
require 'bundler/gem_tasks'
require 'rubygems'
require 'bundler'

Bundler.setup(:default, :development)

require 'rake'

Bundler::GemHelper.install_tasks

require 'rspec/core'
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec)

task default: :spec
require 'rubocop/rake_task'
RuboCop::RakeTask.new(:rubocop)

task default: [:spec, :rubocop]
74 changes: 40 additions & 34 deletions lib/grape-swagger/entity/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,61 +32,46 @@ def parse_grape_entity_params(params)
next if entity_options.fetch(:documentation, {}).fetch(:in, nil).to_s == 'header'

entity_name = entity_options[:as] if entity_options[:as]
model = entity_options[:using] if entity_options[:using].present?

if entity_options[:documentation] && could_it_be_a_model?(entity_options[:documentation])
model ||= entity_options[:documentation][:type]
end
documentation = entity_options[:documentation]
model = model_from(entity_options)

if model
name = endpoint.nil? ? model.to_s.demodulize : endpoint.send(:expose_params_from_model, model)
memo[entity_name] = entity_model_type(name, entity_options)
else
documented_type = entity_options[:type]

if entity_options[:documentation]
documented_type ||= entity_options[:documentation][:type]
end
memo[entity_name] = data_type_from(entity_options)
next unless documentation

data_type = GrapeSwagger::DocMethods::DataType.call(documented_type)
memo[entity_name][:default] = documentation[:default] if documentation[:default]

if GrapeSwagger::DocMethods::DataType.primitive?(data_type)
data = GrapeSwagger::DocMethods::DataType.mapping(data_type)

memo[entity_name] = {
type: data.first,
format: data.last
}
else
memo[entity_name] = {
type: data_type
}
end

if entity_options[:documentation] && entity_options[:documentation][:values]
values = entity_options[:documentation][:values]
if (values = documentation[:values])
memo[entity_name][:enum] = values if values.is_a?(Array)
end

if entity_options[:documentation] && entity_options[:documentation][:default]
memo[entity_name][:default] = entity_options[:documentation][:default]
end

if entity_options[:documentation] && entity_options[:documentation][:is_array]
if documentation[:is_array]
memo[entity_name] = {
type: :array,
items: memo.delete(entity_name)
}
end
end

if entity_options[:documentation] && entity_options[:documentation][:desc]
memo[entity_name][:description] = entity_options[:documentation][:desc]
end
memo[entity_name][:description] = documentation[:desc] if documentation && documentation[:desc]
end
end

def model_from(entity_options)
model = entity_options[:using] if entity_options[:using].present?

if could_it_be_a_model?(entity_options[:documentation])
model ||= entity_options[:documentation][:type]
end

model
end

def could_it_be_a_model?(value)
return false if value.nil?
direct_model_type?(value[:type]) || ambiguous_model_type?(value[:type])
end

Expand All @@ -101,6 +86,27 @@ def ambiguous_model_type?(type)
!type == Array
end

def data_type_from(documentation)
documented_type = documentation[:type]
documented_type ||= (documentation[:documentation] && documentation[:documentation][:type])

data_type = GrapeSwagger::DocMethods::DataType.call(documented_type)

document_data_type(documentation[:documentation], data_type)
end

def document_data_type(documentation, data_type)
type = if GrapeSwagger::DocMethods::DataType.primitive?(data_type)
data = GrapeSwagger::DocMethods::DataType.mapping(data_type)
{ type: data.first, format: data.last }
else
{ type: data_type }
end
type[:format] = documentation[:format] if documentation && documentation.key?(:format)

type
end

def entity_model_type(name, entity_options)
if entity_options[:documentation] && entity_options[:documentation][:is_array]
{
Expand Down
4 changes: 3 additions & 1 deletion spec/grape-swagger/entities/response_model_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ module TheseApi
module Entities
class Values < Grape::Entity
expose :guid, documentation: { desc: 'Some values', values: %w(a b c), default: 'c' }
expose :uuid, documentation: { desc: 'customer uuid', type: String, format: 'own' }
end

class Kind < Grape::Entity
Expand Down Expand Up @@ -134,7 +135,8 @@ def app
expect(subject['Values']).to eql(
'type' => 'object',
'properties' => {
'guid' => { 'type' => 'string', 'description' => 'Some values', 'enum' => ['a', 'b', 'c'], 'default' => 'c' }
'guid' => { 'type' => 'string', 'enum' => %w(a b c), 'default' => 'c', 'description' => 'Some values' },
'uuid' => { 'type' => 'string', 'format' => 'own', 'description' => 'customer uuid' }
}
)
expect(subject['Kind']).to eql(
Expand Down