From 7b5573dacb58ed77c95e7296185a3d15b5be64a6 Mon Sep 17 00:00:00 2001 From: azhi Date: Tue, 17 Mar 2015 18:18:59 +0300 Subject: [PATCH] Fixed range :values with float now range values is exposed as array in enum field only if it is Integer or String range float range or procs returning non-array values is exposed as string fixes #233 --- .rubocop_todo.yml | 16 ++--- .travis.yml | 1 + CHANGELOG.md | 1 + lib/grape-swagger.rb | 15 +++- spec/param_values_spec.rb | 130 ++++++++++++++++++++++++++++++++++ spec/range_values_spec.rb | 49 ------------- spec/support/grape_version.rb | 11 +++ 7 files changed, 163 insertions(+), 60 deletions(-) create mode 100644 spec/param_values_spec.rb delete mode 100644 spec/range_values_spec.rb create mode 100644 spec/support/grape_version.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index efde80d8..22b94d82 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,24 +1,24 @@ # This configuration was generated by `rubocop --auto-gen-config` -# on 2015-03-13 06:55:39 -0400 using RuboCop version 0.27.0. +# on 2015-03-18 19:06:42 +0300 using RuboCop version 0.27.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: 10 +# Offense count: 11 Metrics/AbcSize: - Max: 360 + Max: 356 # Offense count: 1 # Configuration parameters: CountComments. Metrics/ClassLength: - Max: 496 + Max: 504 # Offense count: 6 Metrics/CyclomaticComplexity: - Max: 106 + Max: 102 -# Offense count: 300 +# Offense count: 303 # Configuration parameters: AllowURI, URISchemes. Metrics/LineLength: Max: 254 @@ -26,11 +26,11 @@ Metrics/LineLength: # Offense count: 20 # Configuration parameters: CountComments. Metrics/MethodLength: - Max: 377 + Max: 376 # Offense count: 5 Metrics/PerceivedComplexity: - Max: 108 + Max: 104 # Offense count: 8 Style/ClassVars: diff --git a/.travis.yml b/.travis.yml index 1ea3ff07..d24969ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,4 +14,5 @@ env: - GRAPE_VERSION=0.9.0 - GRAPE_VERSION=0.10.0 - GRAPE_VERSION=0.10.1 + - GRAPE_VERSION=0.11.0 - GRAPE_VERSION=HEAD diff --git a/CHANGELOG.md b/CHANGELOG.md index 2832f362..e682e0af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ #### Fixes * [#232](https://github.com/tim-vandecasteele/grape-swagger/pull/232): Fixed missing raw array params - [@u2](https://github.com/u2). +* [#234](https://github.com/tim-vandecasteele/grape-swagger/pull/234): Fixed range :values with float - [@azhi](https://github.com/azhi). ### 0.10.1 (March 11, 2015) diff --git a/lib/grape-swagger.rb b/lib/grape-swagger.rb index 1a9a31f8..76178f07 100644 --- a/lib/grape-swagger.rb +++ b/lib/grape-swagger.rb @@ -160,6 +160,16 @@ def parse_array_params(params) modified_params end + def parse_enum_values(values) + if values.is_a?(Range) && [Integer, String].any? { |klass| values.first.is_a?(klass) } + values.to_a + elsif values.is_a?(Proc) + values.call + else + values + end + end + def create_documentation_class Class.new(Grape::API) do class << self @@ -214,9 +224,8 @@ def parse_params(params, path, method) 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 - enum_values = value.is_a?(Hash) ? value[:values] : nil - enum_values = enum_values.to_a if enum_values && enum_values.is_a?(Range) - enum_values = enum_values.call if enum_values && enum_values.is_a?(Proc) + values = value.is_a?(Hash) ? value[:values] : nil + enum_values = parse_enum_values(values) if value.is_a?(Hash) && value.key?(:documentation) && value[:documentation].key?(:param_type) param_type = value[:documentation][:param_type] diff --git a/spec/param_values_spec.rb b/spec/param_values_spec.rb new file mode 100644 index 00000000..426ea088 --- /dev/null +++ b/spec/param_values_spec.rb @@ -0,0 +1,130 @@ +require 'spec_helper' +require 'grape_version' + +describe 'Convert values to enum' do + def app + Class.new(Grape::API) do + format :json + + params do + requires :letter, type: String, values: %w(a b c) + end + post :plain_array do + end + + params do + requires :letter, type: String, values: proc { %w(d e f) } + end + post :array_in_proc do + end + + params do + requires :letter, type: String, values: 'a'..'z' + end + post :range_letter do + end + + params do + requires :integer, type: Integer, values: -5..5 + end + post :range_integer do + end + + add_swagger_documentation + end + end + + def first_parameter_info(request) + get "/swagger_doc/#{request}" + expect(last_response.status).to eq 200 + body = JSON.parse last_response.body + body['apis'].first['operations'].first['parameters'] + end + + context 'Plain array values' do + subject(:plain_array) { first_parameter_info('plain_array') } + + it 'has values as array in enum' do + expect(plain_array).to eq [ + { 'paramType' => 'form', 'name' => 'letter', 'description' => nil, 'type' => 'string', 'required' => true, 'allowMultiple' => false, 'enum' => %w(a b c) } + ] + end + end + + context 'Array in proc values' do + subject(:array_in_proc) { first_parameter_info('array_in_proc') } + + it 'has proc returned values as array in enum' do + expect(array_in_proc).to eq [ + { 'paramType' => 'form', 'name' => 'letter', 'description' => nil, 'type' => 'string', 'required' => true, 'allowMultiple' => false, 'enum' => %w(d e f) } + ] + end + end + + context 'Range values' do + subject(:range_letter) { first_parameter_info('range_letter') } + + it 'has letter range values as array in enum' do + expect(range_letter).to eq [ + { 'paramType' => 'form', 'name' => 'letter', 'description' => nil, 'type' => 'string', 'required' => true, 'allowMultiple' => false, 'enum' => ('a'..'z').to_a } + ] + end + + subject(:range_integer) { first_parameter_info('range_integer') } + + it 'has integer range values as array in enum' do + expect(range_integer).to eq [ + { 'paramType' => 'form', 'name' => 'integer', 'description' => nil, 'type' => 'integer', 'required' => true, 'allowMultiple' => false, 'format' => 'int32', 'enum' => (-5..5).to_a } + ] + end + end +end + +describe 'Convert values to enum for float range and not arrays inside a proc', if: GrapeVersion.satisfy?('>= 0.11.0') do + def app + Class.new(Grape::API) do + format :json + + params do + requires :letter, type: String, values: proc { 'string' } + end + post :non_array_in_proc do + end + + params do + requires :float, type: Float, values: -5.0..5.0 + end + post :range_float do + end + + add_swagger_documentation + end + end + + def first_parameter_info(request) + get "/swagger_doc/#{request}" + expect(last_response.status).to eq 200 + body = JSON.parse last_response.body + body['apis'].first['operations'].first['parameters'] + end + + context 'Non array in proc values' do + subject(:non_array_in_proc) { first_parameter_info('non_array_in_proc') } + + it 'has proc returned value as string in enum' do + expect(non_array_in_proc).to eq [ + { 'paramType' => 'form', 'name' => 'letter', 'description' => nil, 'type' => 'string', 'required' => true, 'allowMultiple' => false, 'enum' => 'string' } + ] + end + end + + context 'Range values' do + subject(:range_float) { first_parameter_info('range_float') } + + it 'has float range values as string in enum' do + expect(range_float).to eq [ + { 'paramType' => 'form', 'name' => 'float', 'description' => nil, 'type' => 'float', 'required' => true, 'allowMultiple' => false, 'enum' => '-5.0..5.0' } + ] + end + end +end diff --git a/spec/range_values_spec.rb b/spec/range_values_spec.rb deleted file mode 100644 index 1e9264b3..00000000 --- a/spec/range_values_spec.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'spec_helper' - -describe 'Range Params' do - def app - Class.new(Grape::API) do - format :json - - params do - requires :letter, type: String, values: 'a'..'z' - end - post :letter do - end - - params do - requires :number, type: Integer, values: -5..5 - end - post :integer do - end - - add_swagger_documentation - end - end - - subject(:letter) do - get '/swagger_doc/letter' - expect(last_response.status).to eq 200 - body = JSON.parse last_response.body - body['apis'].first['operations'].first['parameters'] - end - - it 'has letter range values' do - expect(letter).to eq [ - { 'paramType' => 'form', 'name' => 'letter', 'description' => nil, 'type' => 'string', 'required' => true, 'allowMultiple' => false, 'enum' => ('a'..'z').to_a } - ] - end - - subject(:number) do - get '/swagger_doc/integer' - expect(last_response.status).to eq 200 - body = JSON.parse last_response.body - body['apis'].first['operations'].first['parameters'] - end - - it 'has number range values' do - expect(number).to eq [ - { 'paramType' => 'form', 'name' => 'number', 'description' => nil, 'type' => 'integer', 'required' => true, 'allowMultiple' => false, 'format' => 'int32', 'enum' => (-5..5).to_a } - ] - end -end diff --git a/spec/support/grape_version.rb b/spec/support/grape_version.rb new file mode 100644 index 00000000..035fa0bd --- /dev/null +++ b/spec/support/grape_version.rb @@ -0,0 +1,11 @@ +class GrapeVersion + class << self + def current_version + Grape::VERSION + end + + def satisfy?(requirement) + Gem::Dependency.new('grape-test', requirement).match?('grape-test', current_version) + end + end +end