From 57947d308eee709c312cd8efa7fbd9af49bf0228 Mon Sep 17 00:00:00 2001 From: peter scholz Date: Mon, 31 Oct 2016 12:14:08 +0100 Subject: [PATCH] accepts string as entity (#527) - adds changelog entry - requires min version of rubocop --- .rubocop.yml | 4 ++ .rubocop_todo.yml | 61 +++++++++---------- .travis.yml | 2 + CHANGELOG.md | 1 + Gemfile | 2 +- grape-swagger.gemspec | 4 +- lib/grape-swagger.rb | 14 +++-- lib/grape-swagger/doc_methods.rb | 8 ++- .../doc_methods/optional_object.rb | 2 +- lib/grape-swagger/doc_methods/parse_params.rb | 38 ++++++------ lib/grape-swagger/endpoint.rb | 3 +- spec/issues/427_entity_as_string_spec.rb | 39 ++++++++++++ spec/support/model_parsers/entity_parser.rb | 2 +- spec/support/model_parsers/mock_parser.rb | 2 +- .../model_parsers/representable_parser.rb | 2 +- spec/swagger_v2/api_swagger_v2_detail_spec.rb | 2 - 16 files changed, 116 insertions(+), 70 deletions(-) create mode 100644 spec/issues/427_entity_as_string_spec.rb diff --git a/.rubocop.yml b/.rubocop.yml index b8cb0937..872e72b9 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -4,3 +4,7 @@ AllCops: - example/**/* inherit_from: .rubocop_todo.yml + +Metrics/LineLength: + Exclude: + - spec/**/* diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 854a8793..5a3ac0b8 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,30 +1,20 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2016-05-11 23:53:37 +0300 using RuboCop version 0.40.0. +# on 2016-10-31 11:51:42 +0100 using RuboCop version 0.45.0. # 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 -Lint/AmbiguousOperator: - Exclude: - - 'spec/lib/move_params_spec.rb' - -# Offense count: 1 -Lint/UnreachableCode: - Exclude: - - 'example/config.ru' - -# Offense count: 1 -Lint/UselessAssignment: - Exclude: - - 'spec/lib/move_params_spec.rb' - # Offense count: 27 Metrics/AbcSize: Max: 56 +# Offense count: 1 +# Configuration parameters: CountComments. +Metrics/BlockLength: + Max: 30 + # Offense count: 3 # Configuration parameters: CountComments. Metrics/ClassLength: @@ -32,38 +22,32 @@ Metrics/ClassLength: # Offense count: 10 Metrics/CyclomaticComplexity: - Max: 16 + Max: 15 -# Offense count: 719 -# Configuration parameters: AllowHeredoc, AllowURI, URISchemes. +# Offense count: 803 +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives. # URISchemes: http, https Metrics/LineLength: - Max: 454 + Max: 160 -# Offense count: 31 +# Offense count: 34 # Configuration parameters: CountComments. Metrics/MethodLength: Max: 101 -# Offense count: 6 +# Offense count: 5 Metrics/PerceivedComplexity: - Max: 17 + Max: 16 -# Offense count: 4 +# Offense count: 3 Style/ClassVars: Exclude: - - 'example/api/endpoints.rb' - 'lib/grape-swagger/doc_methods.rb' -# Offense count: 27 +# Offense count: 23 Style/Documentation: Enabled: false -# Offense count: 1 -Style/DoubleNegation: - Exclude: - - 'example/api/endpoints.rb' - # Offense count: 5 # Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts. Style/FileName: @@ -74,7 +58,20 @@ Style/FileName: - 'spec/swagger_v2/api_swagger_v2_type-format_spec.rb' - 'spec/swagger_v2/grape-swagger_spec.rb' -# Offense count: 3 +# Offense count: 94 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: when_needed, always +Style/FrozenStringLiteralComment: + Enabled: false + +# Offense count: 1 +# Cop supports --auto-correct. +Style/MultilineIfModifier: + Exclude: + - 'lib/grape-swagger/grape/route.rb' + +# Offense count: 4 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes. # SupportedStyles: slashes, percent_r, mixed diff --git a/.travis.yml b/.travis.yml index 11354e91..a3b8c3bd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,8 @@ matrix: env: GRAPE_VERSION=0.16.2 - rvm: 2.3.1 env: GRAPE_VERSION=0.17.0 + - rvm: 2.3.1 + env: GRAPE_VERSION=0.18.0 - rvm: 2.3.1 env: GRAPE_VERSION=HEAD - rvm: 2.3.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 414df6eb..dd488b3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ #### Fixes +* [#527](https://github.com/ruby-grape/grape-swagger/pull/527): Accepts string as entity - [@LeFnord](https://github.com/LeFnord). * [#515](https://github.com/ruby-grape/grape-swagger/pull/515): Removes limit on model names - [@LeFnord](https://github.com/LeFnord). * [#511](https://github.com/ruby-grape/grape-swagger/pull/511): Fix incorrect data type linking for request params of entity types - [@serggl](https://github.com/serggl). * Your contribution here. diff --git a/Gemfile b/Gemfile index 3dd3f647..15d087a7 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source 'http://rubygems.org' gemspec -case version = ENV['GRAPE_VERSION'] || '~> 0.17.0' +case version = ENV['GRAPE_VERSION'] || '~> 0.18' when 'HEAD' gem 'grape', github: 'ruby-grape/grape' else diff --git a/grape-swagger.gemspec b/grape-swagger.gemspec index b8234969..c4b30632 100644 --- a/grape-swagger.gemspec +++ b/grape-swagger.gemspec @@ -8,7 +8,7 @@ Gem::Specification.new do |s| s.authors = ['Tim Vandecasteele'] s.email = ['tim.vandecasteele@gmail.com'] s.homepage = 'https://github.com/ruby-grape/grape-swagger' - s.summary = 'A simple way to add auto generated documentation to your Grape API that can be displayed with Swagger.' + s.summary = 'Add auto generated documentation to your Grape API that can be displayed with Swagger.' s.license = 'MIT' s.add_runtime_dependency 'grape', '>= 0.12.0' @@ -20,7 +20,7 @@ Gem::Specification.new do |s| s.add_development_dependency 'bundler' s.add_development_dependency 'rack-test' s.add_development_dependency 'rack-cors' - s.add_development_dependency 'rubocop', '0.40.0' + s.add_development_dependency 'rubocop', '~> 0.40' s.add_development_dependency 'kramdown' s.add_development_dependency 'redcarpet' unless RUBY_PLATFORM.eql?('java') || RUBY_ENGINE.eql?('rbx') s.add_development_dependency 'rouge' unless RUBY_PLATFORM.eql?('java') || RUBY_ENGINE.eql?('rbx') diff --git a/lib/grape-swagger.rb b/lib/grape-swagger.rb index e3f7813d..bff54586 100644 --- a/lib/grape-swagger.rb +++ b/lib/grape-swagger.rb @@ -52,7 +52,9 @@ def add_swagger_documentation(options = {}) combine_namespace_routes(@target_class.combined_namespaces) exclusive_route_keys = @target_class.combined_routes.keys - @target_class.combined_namespaces.keys - exclusive_route_keys.each { |key| @target_class.combined_namespace_routes[key] = @target_class.combined_routes[key] } + exclusive_route_keys.each do |key| + @target_class.combined_namespace_routes[key] = @target_class.combined_routes[key] + end documentation_class end @@ -128,10 +130,12 @@ def combine_namespace_routes(namespaces) end parent_standalone_namespaces = standalone_namespaces.reject { |ns_name, _| !name.start_with?(ns_name) } - # add only to the main route if the namespace is not within any other namespace appearing as standalone resource + # add only to the main route + # if the namespace is not within any other namespace appearing as standalone resource if parent_standalone_namespaces.empty? # default option, append namespace methods to parent route - @target_class.combined_namespace_routes[parent_route_name] = [] unless @target_class.combined_namespace_routes.key?(parent_route_name) + parent_route = @target_class.combined_namespace_routes.key?(parent_route_name) + @target_class.combined_namespace_routes[parent_route_name] = [] unless parent_route @target_class.combined_namespace_routes[parent_route_name].push(*namespace_routes) end end @@ -175,7 +179,9 @@ def standalone_sub_namespaces(name, namespaces) # skip if sub_ns is standalone, too next unless sub_ns.options.key?(:swagger) && sub_ns.options[:swagger][:nested] == false # remove all namespaces that are nested below this standalone sub_ns - sub_namespaces.each { |sub_sub_name, _| sub_namespaces.delete(sub_sub_name) if sub_sub_name.start_with?(sub_name) } + sub_namespaces.each do |sub_sub_name, _| + sub_namespaces.delete(sub_sub_name) if sub_sub_name.start_with?(sub_name) + end end sub_namespaces end diff --git a/lib/grape-swagger/doc_methods.rb b/lib/grape-swagger/doc_methods.rb index 4e18e0e5..e00cba86 100644 --- a/lib/grape-swagger/doc_methods.rb +++ b/lib/grape-swagger/doc_methods.rb @@ -37,9 +37,11 @@ def setup(options) class_variables_from(options) - [:format, :default_format, :default_error_formatter].each do |method| - send(method, formatter) - end if formatter + if formatter + [:format, :default_format, :default_error_formatter].each do |method| + send(method, formatter) + end + end send(guard.split.first.to_sym, *guard.split(/[\s,]+/).drop(1)) unless guard.nil? diff --git a/lib/grape-swagger/doc_methods/optional_object.rb b/lib/grape-swagger/doc_methods/optional_object.rb index 6c0c92b3..b5f8d2b9 100644 --- a/lib/grape-swagger/doc_methods/optional_object.rb +++ b/lib/grape-swagger/doc_methods/optional_object.rb @@ -12,7 +12,7 @@ def build(key, options, request = nil) end def evaluate(key, options, request) - options[key].arity == 0 ? options[key].call : options[key].call(request) + options[key].arity.zero? ? options[key].call : options[key].call(request) end def default_values diff --git a/lib/grape-swagger/doc_methods/parse_params.rb b/lib/grape-swagger/doc_methods/parse_params.rb index e34edb41..f5326d99 100644 --- a/lib/grape-swagger/doc_methods/parse_params.rb +++ b/lib/grape-swagger/doc_methods/parse_params.rb @@ -21,7 +21,7 @@ def call(param, settings, route, definitions) # optional properties document_description(settings) document_type_and_format(data_type) - document_array_param(value_type, definitions) + document_array_param(value_type, definitions) if value_type[:is_array] document_default_value(settings) document_range_values(settings) document_required(settings) @@ -61,27 +61,25 @@ def document_type_and_format(data_type) end def document_array_param(value_type, definitions) - if value_type[:is_array] - if value_type[:documentation].present? - param_type = value_type[:documentation][:param_type] - doc_type = value_type[:documentation][:type] - type = GrapeSwagger::DocMethods::DataType.mapping(doc_type) if doc_type && !DataType.request_primitive?(doc_type) - collection_format = value_type[:documentation][:collectionFormat] - end - - array_items = {} - if definitions[value_type[:data_type]] - array_items['$ref'] = "#/definitions/#{@parsed_param[:type]}" - else - array_items[:type] = type || @parsed_param[:type] - end - array_items[:format] = @parsed_param.delete(:format) if @parsed_param[:format] + if value_type[:documentation].present? + param_type = value_type[:documentation][:param_type] + doc_type = value_type[:documentation][:type] + type = GrapeSwagger::DocMethods::DataType.mapping(doc_type) if doc_type && !DataType.request_primitive?(doc_type) + collection_format = value_type[:documentation][:collectionFormat] + end - @parsed_param[:in] = param_type || 'formData' - @parsed_param[:items] = array_items - @parsed_param[:type] = 'array' - @parsed_param[:collectionFormat] = collection_format if %w(csv ssv tsv pipes multi).include?(collection_format) + array_items = {} + if definitions[value_type[:data_type]] + array_items['$ref'] = "#/definitions/#{@parsed_param[:type]}" + else + array_items[:type] = type || @parsed_param[:type] end + array_items[:format] = @parsed_param.delete(:format) if @parsed_param[:format] + + @parsed_param[:in] = param_type || 'formData' + @parsed_param[:items] = array_items + @parsed_param[:type] = 'array' + @parsed_param[:collectionFormat] = collection_format if %w(csv ssv tsv pipes multi).include?(collection_format) end def param_type(value_type) diff --git a/lib/grape-swagger/endpoint.rb b/lib/grape-swagger/endpoint.rb index 6f674d07..c7529737 100644 --- a/lib/grape-swagger/endpoint.rb +++ b/lib/grape-swagger/endpoint.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - require 'active_support' require 'active_support/core_ext/string/inflections.rb' @@ -279,6 +277,7 @@ def expose_params(value) end def expose_params_from_model(model) + model = model.is_a?(String) ? model.constantize : model model_name = model_name(model) return model_name if @definitions.key?(model_name) diff --git a/spec/issues/427_entity_as_string_spec.rb b/spec/issues/427_entity_as_string_spec.rb new file mode 100644 index 00000000..c8344c22 --- /dev/null +++ b/spec/issues/427_entity_as_string_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper' +require 'grape-entity' +require 'grape-swagger-entity' + +describe '#427 nested entity given as string' do + let(:app) do + Class.new(Grape::API) do + namespace :issue_427 do + module Permission + class WithoutRole < Grape::Entity + expose :id + expose :description + end + end + + class RoleEntity < Grape::Entity + expose :id + expose :description + expose :role + expose :permissions, using: 'Permission::WithoutRole' + end + desc 'Get a list of roles', + success: RoleEntity + get '/' do + present [], with: RoleEntity + end + end + + add_swagger_documentation format: :json + end + end + + subject do + get '/swagger_doc' + JSON.parse(last_response.body)['definitions'] + end + + specify { expect(subject.keys).to include 'RoleEntity', 'WithoutRole' } +end diff --git a/spec/support/model_parsers/entity_parser.rb b/spec/support/model_parsers/entity_parser.rb index 1e59573a..babfd221 100644 --- a/spec/support/model_parsers/entity_parser.rb +++ b/spec/support/model_parsers/entity_parser.rb @@ -336,5 +336,5 @@ class DocumentedHashAndArrayModel < Grape::Entity end def mounted_paths - %w( /thing /other_thing /dummy ) + %w(/thing /other_thing /dummy) end diff --git a/spec/support/model_parsers/mock_parser.rb b/spec/support/model_parsers/mock_parser.rb index fe9708ef..eef0d6e7 100644 --- a/spec/support/model_parsers/mock_parser.rb +++ b/spec/support/model_parsers/mock_parser.rb @@ -332,5 +332,5 @@ class ApiResponse < OpenStruct; end end def mounted_paths - %w( /thing /other_thing /dummy ) + %w(/thing /other_thing /dummy) end diff --git a/spec/support/model_parsers/representable_parser.rb b/spec/support/model_parsers/representable_parser.rb index 43d9d869..a2e08498 100644 --- a/spec/support/model_parsers/representable_parser.rb +++ b/spec/support/model_parsers/representable_parser.rb @@ -408,5 +408,5 @@ class DocumentedHashAndArrayModel < Representable::Decorator end def mounted_paths - %w( /thing /other_thing /dummy ) + %w(/thing /other_thing /dummy) end diff --git a/spec/swagger_v2/api_swagger_v2_detail_spec.rb b/spec/swagger_v2/api_swagger_v2_detail_spec.rb index 5cb0005e..de076426 100644 --- a/spec/swagger_v2/api_swagger_v2_detail_spec.rb +++ b/spec/swagger_v2/api_swagger_v2_detail_spec.rb @@ -1,5 +1,3 @@ -# encoding: UTF-8 - require 'spec_helper' def details