Lightweight Parameter Validation & Type Coercion
This is a variation of the sinatra-param gem https://github.com/mattt/sinatra-param with the sinatra specific things taken out and slight modifications to make it more useful for generic applications.
hash-params allows you to declare, validate, and transform endpoint parameters as you would in frameworks like ActiveModel or DataMapper. but in a lighterweight fashion
See the spec down the page for usage scenarios
This gem also provides a YamlParams object which scours the disk for likely config files, intelligently parses and merges them and passes them into the HashParams for validation
The common way to use it is
YamlParams.autoconfigYou can specify the following in the options hash they will all have sensible defaults except the app_name
- app_name
- env
- roots
- files
roots and files specified will be added to the default list but with higher priority.
require_relative'spec_helper'describeHashParamsdolet(:v){HashParams}it'raises error if required and missing'doproc{v.validate(nil,nil,required: true)}.must_raiseHashParams::Validator::ValidationErrorendit'runs multiple coersions'dov.validate('1aaa2',Float,coerce: [lambda{ |o| o.gsub('a','')},:to_i]).must_equal(12.0)endit'defaults missing values'dov.validate(nil,Integer,default: 1).must_equal(1)v.validate(nil,Integer,default: lambda{2 * 5}).must_equal(10)endit'validates with lambdas'dov.validate(nil,Integer,:validate=>lambda{ |v| v=60 * 60}).must_equal(60 * 60)endit'validates with procs'dov.validate('is_this_valid?',String)do |v|
v='Validated with Proc'end.must_equal('Validated with Proc')endit'verifies numbers with common params'dov.validate(122,Integer,min: 120,max: 500,in: (100..200),is: 122).must_equal(122)endit'verifies strings with common params'dov.validate('this is a test string',String,min_length: 21,max_length: 30,format: /^t.*g$/).must_equal'this is a test string'endit'coerces true'dov.validate('t',:boolean).must_equaltruev.validate('true',:boolean).must_equaltruev.validate('yes',:boolean).must_equaltruev.validate('1',:boolean).must_equaltruev.validate(1,:boolean).must_equaltrueendit'coerces false'dov.validate('f',:boolean).must_equalfalsev.validate('false',:boolean).must_equalfalsev.validate('no',:boolean).must_equalfalsev.validate('0',:boolean).must_equalfalsev.validate(0,:boolean).must_equalfalseendit'coerces array'dov.validate('1|2|3',Array,delimiter: '|').must_equal["1","2","3"]endit'coerces hash'dov.validate('{a => 1,b => 2,c => d}',Hash,delimiter: ',',separator: '=>').must_equal({"a"=>"1","b"=>"2","c"=>"d"})endit'validates a hash using a block'doh={ignored: "this will be ignored because it's not mentioned",to_be_renamed: :renamed_value,'integer_coercion': "1",proc_validation: "is_this_valid?",recursive: {}}r=v.validate(h,Hash,symbolize_keys: true)dokey:doesnt_exist,nil,required: truekey:to_be_renamed,Symbol,as: :renamed#Default Lambdas take no parameterskey:proc_default,Integer,default: lambda{1 * 5}key:proc_validation,String,validate: lambda{ |v| v='Validated in proc'}#recursivekey:recursive,Hashdokey:wasnt_here_before,:boolean,default: trueendend(r.valid?).must_equalfalser[:ignored].must_be_nil# r[:proc_default].must_equal 5r[:renamed].must_equal:renamed_value#recursive checkingr[:recursive][:wasnt_here_before].must_equaltrue#failed items don't show upr[:doesnt_exist].must_be_nilr[:proc_validation].must_equal'Validated in proc'r.validation_errors.size.must_equal1r.validation_errors[0].must_equal"Error processing key 'doesnt_exist': Required Parameter missing and has no default specified"endit'validates variables in the local binding'dox='10'y='this is a test string'z={}will_be_int='100'HashParams.with_bindingdovar:x,Integer,min: 10,max: 100var:y,String,min_length: 21,max_length: 30,format: /^t.*g$/var:z,Hash,raise_errors: true,symbolize_keys: true,make_methods: truedokey:blah,String,default: 1endvar:will_be_int,:to_iendx.must_equal10y.must_equal'this is a test string'z[:blah].must_equal'1'z.blah.must_equal'1'will_be_int.must_equal100endendTim Uckun
hash-parameters is available under the MIT license. See the LICENSE file for more info.