Commit d169d11f by stantoncbradley

array validation for primative datatypes

array validation for hashes
parent c6d98432
module RailsParam
module Param
DEFAULT_PRECISION = 14
class InvalidParameterError < StandardError
attr_accessor :param, :options
end
def param!(name, type, options = {})
name = name.to_s
class MockController
include RailsParam::Param
attr_accessor :params
end
def param!(name, type, options = {}, &block)
name = name.to_s unless name.is_a? Integer # keep index for validating elements
return unless params.member?(name) || options[:default].present? || options[:required]
......@@ -15,8 +22,23 @@ 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[:transform].to_proc.call(params[name]) if params[name] and options[:transform]
validate!(params[name], options)
if block_given?
if type == Array
params[name].each_with_index do |element, i|
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
params[name]
rescue InvalidParameterError => exception
exception.param, exception.options = name, options
exception.param ||= name
exception.options ||= options
raise exception
end
end
......@@ -41,6 +63,13 @@ module RailsParam
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 = {})
begin
return nil if param.nil?
......@@ -52,8 +81,12 @@ module RailsParam
return Time.parse(param) if type == Time
return DateTime.parse(param) if type == DateTime
return Array(param.split(options[:delimiter] || ",")) if type == Array
return Hash[param.split(options[:delimiter] || ",").map{|c| c.split(options[:separator] || ":")}] if type == Hash
return Hash[param.split(options[:delimiter] || ",").map { |c| c.split(options[:separator] || ":") }] if type == Hash
return (/(false|f|no|n|0)$/i === param.to_s ? false : (/(true|t|yes|y|1)$/i === param.to_s ? true : nil)) if type == TrueClass || type == FalseClass || type == :boolean
if type == BigDecimal
param = param.delete('$,').strip.to_f if param.is_a?(String)
return BigDecimal.new(param, (options[:precision] || DEFAULT_PRECISION))
end
return nil
rescue ArgumentError
raise InvalidParameterError, "'#{param}' is not a valid #{type}"
......@@ -63,37 +96,37 @@ module RailsParam
def validate!(param, options)
options.each do |key, value|
case key
when :required
raise InvalidParameterError, "Parameter is required" if value && param.nil?
when :blank
raise InvalidParameterError, "Parameter cannot be blank" if !value && case param
when String
!(/\S/ === param)
when Array, Hash
param.empty?
else
param.nil?
end
when :format
raise InvalidParameterError, "Parameter must be a string if using the format validation" unless param.kind_of?(String)
raise InvalidParameterError, "Parameter must match format #{value}" unless param =~ value
when :is
raise InvalidParameterError, "Parameter must be #{value}" unless param === value
when :in, :within, :range
raise InvalidParameterError, "Parameter must be within #{value}" unless param.nil? || case value
when Range
value.include?(param)
else
Array(value).include?(param)
end
when :min
raise InvalidParameterError, "Parameter cannot be less than #{value}" unless param.nil? || value <= param
when :max
raise InvalidParameterError, "Parameter cannot be greater than #{value}" unless param.nil? || value >= param
when :min_length
raise InvalidParameterError, "Parameter cannot have length less than #{value}" unless param.nil? || value <= param.length
when :max_length
raise InvalidParameterError, "Parameter cannot have length greater than #{value}" unless param.nil? || value >= param.length
when :required
raise InvalidParameterError, "Parameter is required" if value && param.nil?
when :blank
raise InvalidParameterError, "Parameter cannot be blank" if !value && case param
when String
!(/\S/ === param)
when Array, Hash
param.empty?
else
param.nil?
end
when :format
raise InvalidParameterError, "Parameter must be a string if using the format validation" unless param.kind_of?(String)
raise InvalidParameterError, "Parameter must match format #{value}" unless param =~ value
when :is
raise InvalidParameterError, "Parameter must be #{value}" unless param === value
when :in, :within, :range
raise InvalidParameterError, "Parameter must be within #{value}" unless param.nil? || case value
when Range
value.include?(param)
else
Array(value).include?(param)
end
when :min
raise InvalidParameterError, "Parameter cannot be less than #{value}" unless param.nil? || value <= param
when :max
raise InvalidParameterError, "Parameter cannot be greater than #{value}" unless param.nil? || value >= param
when :min_length
raise InvalidParameterError, "Parameter cannot have length less than #{value}" unless param.nil? || value <= param.length
when :max_length
raise InvalidParameterError, "Parameter cannot have length greater than #{value}" unless param.nil? || value >= param.length
end
end
end
......
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