Commit 5e75a26a by Brad Urani

Merge pull request #4 from stantoncbradley/master

Array validation
parents ca96eb98 44e4b51f
...@@ -12,8 +12,8 @@ module RailsParam ...@@ -12,8 +12,8 @@ module RailsParam
attr_accessor :params attr_accessor :params
end end
def param!(name, type, options = {}) def param!(name, type, options = {}, &block)
name = name.to_s name = name.to_s unless name.is_a? Integer # keep index for validating elements
return unless params.member?(name) || options[:default].present? || options[:required] return unless params.member?(name) || options[:default].present? || options[:required]
...@@ -22,11 +22,22 @@ module RailsParam ...@@ -22,11 +22,22 @@ module RailsParam
params[name] = (options[:default].call if options[:default].respond_to?(:call)) || options[:default] if params[name].nil? and options[:default] params[name] = (options[:default].call if options[:default].respond_to?(:call)) || options[:default] if params[name].nil? and options[:default]
params[name] = options[:transform].to_proc.call(params[name]) if params[name] and options[:transform] params[name] = options[:transform].to_proc.call(params[name]) if params[name] and options[:transform]
validate!(params[name], options) validate!(params[name], options)
if block_given? if block_given?
controller = RailsParam::Param::MockController.new if type == Array
controller.params = params[name] params[name].each_with_index do |element, i|
yield(controller) if element.is_a?(Hash)
recurse element, &block
else
params[name][i] = recurse({ i => element }, i, &block) # supply index as key unless value is hash
end
end
else
recurse params[name], &block
end
end end
params[name]
rescue InvalidParameterError => exception rescue InvalidParameterError => exception
exception.param ||= name exception.param ||= name
exception.options ||= options exception.options ||= options
...@@ -54,6 +65,13 @@ module RailsParam ...@@ -54,6 +65,13 @@ module RailsParam
private private
def recurse(params, index = nil)
raise InvalidParameterError, 'no block given' unless block_given?
controller = RailsParam::Param::MockController.new
controller.params = params
yield(controller, index)
end
def coerce(param, type, options = {}) def coerce(param, type, options = {})
begin begin
return nil if param.nil? return nil if param.nil?
......
...@@ -192,6 +192,80 @@ describe RailsParam::Param do ...@@ -192,6 +192,80 @@ describe RailsParam::Param do
end end
end end
describe 'validating arrays' do
it 'typecasts array of primitive elements' do
allow(controller).to receive(:params).and_return({'array' => ['1', '2']})
controller.param! :array, Array do |a, i|
a.param! i, Integer, required: true
end
expect(controller.params['array'][0]).to be_a Integer
expect(controller.params['array'][1]).to be_a Integer
end
it 'validates array of hashes' do
params = {'array' => [{'object'=>{ 'num' => '1', 'float' => '1.5' }},{'object'=>{ 'num' => '2', 'float' => '2.3' }}] }
allow(controller).to receive(:params).and_return(params)
controller.param! :array, Array do |a|
a.param! :object, Hash do |h|
h.param! :num, Integer, required: true
h.param! :float, Float, required: true
end
end
expect(controller.params['array'][0]['object']['num']).to be_a Integer
expect(controller.params['array'][0]['object']['float']).to be_instance_of Float
expect(controller.params['array'][1]['object']['num']).to be_a Integer
expect(controller.params['array'][1]['object']['float']).to be_instance_of Float
end
it 'validates an array of arrays' do
params = {'array' => [[ '1', '2' ],[ '3', '4' ]] }
allow(controller).to receive(:params).and_return(params)
controller.param! :array, Array do |a, i|
a.param! i, Array do |b, e|
b.param! e, Integer, required: true
end
end
expect(controller.params['array'][0][0]).to be_a Integer
expect(controller.params['array'][0][1]).to be_a Integer
expect(controller.params['array'][1][0]).to be_a Integer
expect(controller.params['array'][1][1]).to be_a Integer
end
it 'raises exception when primitive element missing' do
allow(controller).to receive(:params).and_return({'array' => ['1', nil]})
expect {
controller.param! :array, Array do |a, i|
a.param! i, Integer, required: true
end
}.to raise_exception
end
it 'raises exception when nested hash element missing' do
params = {'array' => [{'object'=>{ 'num' => '1', 'float' => nil }},{'object'=>{ 'num' => '2', 'float' => '2.3' }}] }
allow(controller).to receive(:params).and_return(params)
expect {
controller.param! :array, Array do |a|
a.param! :object, Hash do |h|
h.param! :num, Integer, required: true
h.param! :float, Float, required: true
end
end
}.to raise_exception
end
it 'raises exception when nested array element missing' do
params = {'array' => [[ '1', '2' ],[ '3', nil ]] }
allow(controller).to receive(:params).and_return(params)
expect {
controller.param! :array, Array do |a, i|
a.param! i, Array do |b, e|
b.param! e, Integer, required: true
end
end
}.to raise_exception
end
end
describe "validation" do describe "validation" do
describe "required parameter" do describe "required parameter" do
it "succeeds" do it "succeeds" do
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment