From d29c822ca7921c823c886e1c0471c8a6eefee0f6 Mon Sep 17 00:00:00 2001 From: dm1try Date: Fri, 11 Jul 2014 05:25:48 +0300 Subject: [PATCH] try to implement behaviour for default vaues in Hash/Array groupedparams --- lib/grape/validations.rb | 7 +-- lib/grape/validations/default.rb | 3 +- spec/grape/validations/default_spec.rb | 69 +++++++++++++++++++++++--- spec/grape/validations_spec.rb | 20 -------- 4 files changed, 68 insertions(+), 31 deletions(-) diff --git a/lib/grape/validations.rb b/lib/grape/validations.rb index 3f50f24420..044f0f18d7 100644 --- a/lib/grape/validations.rb +++ b/lib/grape/validations.rb @@ -83,6 +83,7 @@ def self.register_validator(short_name, klass) class ParamsScope attr_accessor :element, :parent + attr_reader :type def initialize(opts, &block) @element = opts[:element] @@ -210,9 +211,9 @@ def validate_attributes(attrs, opts, &block) end def new_scope(attrs, optional = false, &block) - opts = attrs[1] || { type: Array } - raise ArgumentError unless opts.keys.to_set.subset? [:type].to_set - ParamsScope.new(api: @api, element: attrs.first, parent: self, optional: optional, type: opts[:type], &block) + opts = attrs[1] || {} + type = opts.delete(:type) || Array + ParamsScope.new(api: @api, element: attrs.first, parent: self, optional: optional, type: type, &block) end # Pushes declared params to parent or settings diff --git a/lib/grape/validations/default.rb b/lib/grape/validations/default.rb index 41fb2e9b94..621bd55b61 100644 --- a/lib/grape/validations/default.rb +++ b/lib/grape/validations/default.rb @@ -3,6 +3,7 @@ module Validations class DefaultValidator < Validator def initialize(attrs, options, required, scope) @default = options + @type = scope.type super end @@ -12,11 +13,9 @@ def validate_param!(attr_name, params) def validate!(params) attrs = AttributesIterator.new(self, @scope, params) - parent_element = @scope.element attrs.each do |resource_params, attr_name| if resource_params[attr_name].nil? validate_param!(attr_name, resource_params) - params[parent_element] = resource_params if parent_element && params[parent_element].nil? end end end diff --git a/spec/grape/validations/default_spec.rb b/spec/grape/validations/default_spec.rb index 25a9bf7574..c9d3776b4f 100644 --- a/spec/grape/validations/default_spec.rb +++ b/spec/grape/validations/default_spec.rb @@ -64,6 +64,42 @@ class API < Grape::API get '/array' do { array: params[:array] } end + + params do + optional :foo, type: Array do + optional :bar, default: "bar" + end + end + get '/optional_with_default_inside_optional_array_without_default' do + { foo: params[:foo] } + end + + params do + optional :foo, type: Array, default: [] do + optional :bar, default: "bar" + end + end + get '/optional_with_default_inside_optional_array_with_default' do + { foo: params[:foo] } + end + + params do + optional :foo, type: Hash do + optional :bar, default: "bar" + end + end + get '/optional_with_default_inside_optional_hash_without_default' do + { foo: params[:foo] } + end + + params do + optional :foo, type: Hash, default: {} do + optional :bar, default: "bar" + end + end + get '/optional_with_default_inside_optional_hash_with_default' do + { foo: params[:foo] } + end end end end @@ -108,16 +144,37 @@ def app expect(before['random_number']).not_to eq(after['random_number']) end - it 'set default values for optional grouped params' do - get('/group') - expect(last_response.status).to eq(200) - expect(last_response.body).to eq({ foo_bar: 'foo-bar' }.to_json) - end - it 'sets default values for grouped arrays' do get('/array?array[][name]=name&array[][name]=name2&array[][with_default]=bar2') expect(last_response.status).to eq(200) expect(last_response.body).to eq({ array: [{ name: "name", with_default: "default" }, { name: "name2", with_default: "bar2" }] }.to_json) end + context 'defaults for grouped params' do + context 'with array type' do + it 'sets nil if root param has no default value' do + get('/optional_with_default_inside_optional_array_without_default') + expect(last_response.body).to eq({ foo: nil }.to_json) + end + + it 'sets nil if root param has no default value' do + get('/optional_with_default_inside_optional_array_with_default') + expect(last_response.body).to eq({ foo: [] }.to_json) + end + end + + context 'with hash type' do + context 'optional with default value inside optional hash with default' do + it 'sets nil if root param has no default value' do + get('/optional_with_default_inside_optional_hash_without_default') + expect(last_response.body).to eq({ foo: nil }.to_json) + end + + it 'sets default optional hash value if param unspecified' do + get('/optional_with_default_inside_optional_hash_with_default') + expect(last_response.body).to eq({ foo: {} }.to_json) + end + end + end + end end diff --git a/spec/grape/validations_spec.rb b/spec/grape/validations_spec.rb index c7ea8252b9..89a0f7727a 100644 --- a/spec/grape/validations_spec.rb +++ b/spec/grape/validations_spec.rb @@ -182,16 +182,6 @@ def define_requires_none expect(last_response.body).to eq('required works') end - it "doesn't allow any key in the options hash other than type" do - expect { - subject.params do - requires(:items, desc: 'Foo') do - requires :key - end - end - }.to raise_error ArgumentError - end - it 'adds to declared parameters' do subject.params do requires :items do @@ -236,16 +226,6 @@ def define_requires_none expect(last_response.body).to eq('required works') end - it "doesn't allow any key in the options hash other than type" do - expect { - subject.params do - requires(:items, desc: 'Foo') do - requires :key - end - end - }.to raise_error ArgumentError - end - it 'adds to declared parameters' do subject.params do requires :items do