Add ruby-param-validation to repo
This commit is contained in:
		
							parent
							
								
									387a22a6aa
								
							
						
					
					
						commit
						68f00c8028
					
				
					 11 changed files with 561 additions and 10 deletions
				
			
		|  | @ -6,4 +6,4 @@ | |||
| !script/build/debian/*.sh | ||||
| !Rakefile | ||||
| !config/* | ||||
| !db/* | ||||
| !gems/* | ||||
							
								
								
									
										3
									
								
								Gemfile
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								Gemfile
									
										
									
									
									
								
							|  | @ -47,8 +47,7 @@ gem 'dalli' | |||
| gem 'memcachier' | ||||
| 
 | ||||
| 
 | ||||
| gem 'param_validation', git: 'https://github.com/commitchange/ruby-param-validation.git' | ||||
| #gem 'param_validation', path: '../ruby-param-validation' | ||||
| gem 'param_validation', path: 'gems/ruby-param-validation' | ||||
| 
 | ||||
| # Print colorized text lol | ||||
| gem 'colorize' | ||||
|  |  | |||
							
								
								
									
										13
									
								
								Gemfile.lock
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								Gemfile.lock
									
										
									
									
									
								
							|  | @ -1,10 +1,3 @@ | |||
| GIT | ||||
|   remote: https://github.com/commitchange/ruby-param-validation.git | ||||
|   revision: 4269cdef83eb95eea749f05c22a9b747b8f1f256 | ||||
|   specs: | ||||
|     param_validation (0.0.2) | ||||
|       chronic | ||||
| 
 | ||||
| GIT | ||||
|   remote: https://github.com/commitchange/ruby-qx.git | ||||
|   revision: 3c7fbb9c844e3ea86c9faea204058aa76e5ea35d | ||||
|  | @ -41,6 +34,12 @@ GIT | |||
|       activesupport (>= 3.0.0) | ||||
|       multi_json (>= 1.3.2) | ||||
| 
 | ||||
| PATH | ||||
|   remote: gems/ruby-param-validation | ||||
|   specs: | ||||
|     param_validation (0.0.2) | ||||
|       chronic | ||||
| 
 | ||||
| GEM | ||||
|   remote: https://rubygems.org/ | ||||
|   specs: | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ COPY script/build/debian/postgres.sh myapp/script/build/debian/postgres.sh | |||
| RUN myapp/script/build/debian/postgres.sh | ||||
| COPY script/build/debian/java.sh myapp/script/build/debian/java.sh | ||||
| RUN myapp/script/build/debian/java.sh | ||||
| COPY gems /myapp/gems/ | ||||
| WORKDIR /myapp | ||||
| COPY Gemfile /myapp/Gemfile | ||||
| COPY Gemfile.lock /myapp/Gemfile.lock | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ COPY script/build/debian/postgres.sh myapp/script/build/debian/postgres.sh | |||
| RUN myapp/script/build/debian/postgres.sh | ||||
| COPY script/build/debian/java.sh myapp/script/build/debian/java.sh | ||||
| RUN myapp/script/build/debian/java.sh | ||||
| COPY gems /myapp/gems/ | ||||
| WORKDIR /myapp | ||||
| RUN groupadd -r -g 1000 $USER | ||||
| RUN useradd -r -m -g $USER -u 1000 $USER | ||||
|  |  | |||
							
								
								
									
										21
									
								
								gems/ruby-param-validation/LICENSE
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								gems/ruby-param-validation/LICENSE
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| MIT License | ||||
| 
 | ||||
| Copyright (c) 2016 Jay R Bolton, CommitChange | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
							
								
								
									
										162
									
								
								gems/ruby-param-validation/README.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								gems/ruby-param-validation/README.md
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,162 @@ | |||
| # ParamValidation | ||||
| 
 | ||||
| A standalone and simple ruby hash validation lib, useful for validating the data passed to your functions.  | ||||
| 
 | ||||
| ```rb | ||||
| new_charge_validation = { | ||||
|   amount: { | ||||
|     required: true | ||||
|   }, | ||||
|   stripe_card_token: { | ||||
|     required: true, | ||||
|     format: /^tok_.*$/ | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| def update_database(data) | ||||
|   ParamValidation.new(data, new_charge_validation) | ||||
|   # do stuff | ||||
|   return result | ||||
| end | ||||
| ``` | ||||
| 
 | ||||
| The above checks the `:amount` and `:stripe_card_token` keys inside the `data` | ||||
| hash and runs validations on them. If a value is invalid, an exception is | ||||
| thrown. The exception can be handled outside your function call, typically in a | ||||
| controller/router or in a test suite. | ||||
| 
 | ||||
| An exception is thrown for each failure. | ||||
| 
 | ||||
| ## ParamValidation::Error | ||||
| 
 | ||||
| The ParamValidation::Error object has the following information on it: | ||||
| 
 | ||||
| ```rb | ||||
| begin  | ||||
|   update_database(data) | ||||
| rescue ParamValidation::Error => e | ||||
|   e.message # string validation failure message | ||||
|   e.val     # value that failed validation | ||||
|   e.key     # key name of the above value inside the data hash | ||||
|   e.name    # name of the validator that failed | ||||
| rescue Exception => e | ||||
|   # a non-validation exception | ||||
| end | ||||
| ``` | ||||
| 
 | ||||
| ## Using in Rails | ||||
| 
 | ||||
| To handle validation exceptions from the controller, you can add a custom helper function in your ApplicationController like this: | ||||
| 
 | ||||
| ```rb | ||||
| def render_json(&block) | ||||
|   begin | ||||
|     result = yield block | ||||
|   rescue ParamValidation::Error => e | ||||
|     return {status: 422, json: {error: e.message, key: e.key}} | ||||
|   rescue Error => e # a non-validation related exception | ||||
|     return {status: 500, json: e} | ||||
|   end | ||||
|   return {status: 200, json: result} | ||||
| end | ||||
| ``` | ||||
| 
 | ||||
| With the above, you can simply call render_json on your validated function call: | ||||
| 
 | ||||
| ```rb | ||||
| UsersController < ApplicationController | ||||
|   def update | ||||
|     render_json{ update_user(params[:user]) } | ||||
|   end | ||||
| end | ||||
| ``` | ||||
| 
 | ||||
| ```rb | ||||
| update_validation = { | ||||
|   email: { | ||||
|     presence: :optional, | ||||
|     format: email_regex | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| def update_user(params) | ||||
|   ParamValidation.new(params, update_validation) | ||||
| end | ||||
| ``` | ||||
| 
 | ||||
| ### built-in validators | ||||
| 
 | ||||
| - required: value must be non-nil | ||||
| - absent: value must be nil | ||||
| - not_included_in: value must not be in array | ||||
| - included_in: value must be in array | ||||
| - format: value must match regex | ||||
| - is_integer: value must look like an integer (can be a string) | ||||
| - is_float: value must look like a float (can be a string) | ||||
| - min_length: array value must have length >= min | ||||
| - max_length: array value must have length <= max | ||||
| - length_range: array value must have length within given range | ||||
| - length_equals: array value length must equal given arg | ||||
| - equals: value must equal given arg | ||||
| - min: value must be >= arg | ||||
| - max: value must be <= arg | ||||
| - in_range: value must be within the given range | ||||
| 
 | ||||
| ### custom validators | ||||
| 
 | ||||
| ParamValidation.add_validator takes a name and a block. That block performs the | ||||
| validations and simply returns true/false. The block takes three params: the | ||||
| actual value to validate, and the argument provided in the validation hash, and | ||||
| the entire data hash being validated. | ||||
| 
 | ||||
| ```rb | ||||
| # You can use other validators inside a new validator | ||||
| ParamValidation.add_validator(:dollars) do |val, arg, data| | ||||
|   ParamValidation.validators[:format](val, /^\$\d+\.(\d\d)$?, data) | ||||
| end | ||||
| 
 | ||||
| # # Validators that don't need an argument typically just get 'true' passed in | ||||
| # ParamValidation.new(params, {  | ||||
| #   amount: { dollars: true } | ||||
| # }) | ||||
| 
 | ||||
| # Other examples | ||||
| 
 | ||||
| # Uniqueness validation (of course it may be better to use the UNIQUE constraint in sql) | ||||
| ParamValidation.add_validator(:unique) do |val, arg, data| | ||||
|   Qx.select("COUNT(*)").from(:table).where(name: val).first['count'] == 0 | ||||
| end | ||||
| ``` | ||||
| 
 | ||||
| ### custom validation messages | ||||
| 
 | ||||
| Within a validation instance, you can set a custom message with the :message key. | ||||
| 
 | ||||
| ```rb | ||||
| ParamValidation.new(params, { | ||||
|   amount: { | ||||
|     dollars: true, | ||||
|     message: 'Please enter a dollar amount' | ||||
|   } | ||||
| }) | ||||
| ``` | ||||
| 
 | ||||
| To change the global default message, simply use ParamValidation.set_message(:validation_name, &block). | ||||
| 
 | ||||
| ```rb | ||||
| ParamValidation.set_message(:dollars) do |h| | ||||
|   "#{h[:key]} must be in dollars" | ||||
| end | ||||
| ``` | ||||
| 
 | ||||
| The `set_message` block receives a hash with some data: | ||||
| 
 | ||||
| * :key  - name of the key in the hash that failed this validation | ||||
| * :arg  - argument to validator (eg format regex) | ||||
| * :val  - actual value that failed validation | ||||
| * :data - entire data hash that is being validated | ||||
| 
 | ||||
| 
 | ||||
| #### internationalization -- TODO! | ||||
| 
 | ||||
| Internationalization support is not yet in place; please make a PR for it! | ||||
							
								
								
									
										9
									
								
								gems/ruby-param-validation/Rakefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								gems/ruby-param-validation/Rakefile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | |||
| require 'rake/testtask' | ||||
| 
 | ||||
| Rake::TestTask.new do |t| | ||||
|   t.libs << 'test' | ||||
|   t.test_files = FileList['test/test*.rb', 'test/*test.rb'] | ||||
| end | ||||
| 
 | ||||
| desc "Run tests" | ||||
| task :default => :test | ||||
							
								
								
									
										130
									
								
								gems/ruby-param-validation/lib/param_validation.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								gems/ruby-param-validation/lib/param_validation.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,130 @@ | |||
| require 'json' | ||||
| require 'chronic' | ||||
| 
 | ||||
| class ParamValidation | ||||
| 
 | ||||
|   # Given a hash of data and a validation hash, check all the validations, raising an Error on the first invalid key | ||||
|   # @raise [ValidationError] if one or more of the validations fail. | ||||
|   def initialize(data, validations) | ||||
|     errors = [] | ||||
|     validations.each do |key, validators| | ||||
|       val = key === :root ? data : (data[key] || data[key.to_s] || data[key.to_sym]) | ||||
|       next if validators[:required].nil? && val.nil? | ||||
|       validators.each do |name, arg| | ||||
|         validator = @@validators[name] | ||||
|         msg = validations[key][:message] | ||||
|         next unless validator | ||||
|         is_valid = @@validators[name].call(val, arg, data) | ||||
|         msg_proc = @@messages[name] | ||||
|         msg ||= @@messages[name].call({key: key, data: data, val: val, arg: arg}) if msg_proc | ||||
|         errors.push({msg: msg, data: {key: key, val: val, name: name, msg: msg}}) unless is_valid | ||||
|       end | ||||
|     end | ||||
|     if errors.length == 1 | ||||
|       raise ValidationError.new(errors[0][:msg], errors[0][:data]) | ||||
|     elsif errors.length > 1 | ||||
|       msg = errors.collect {|e| e[:msg]}.join('\n') | ||||
|       raise ValidationError.new(msg, errors.collect{|e| e[:data]}) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def self.messages; @@messages; end | ||||
|   def self.set_message(name, &block) | ||||
|     @@messages[name] = block | ||||
|   end | ||||
| 
 | ||||
|   def self.validators; @@validators; end | ||||
|   def self.add_validator(name, &block) | ||||
|     @@validators[name] = block | ||||
|   end | ||||
|   def self.structure_validators; @@structure_validators; end | ||||
|   def self.add_structure_validator(name, &block) | ||||
|     @@structure_validators[name] = block | ||||
|   end | ||||
| 
 | ||||
|   # In each Proc | ||||
|   #  - val is the value we are actually validating from the data passed in | ||||
|   #  - arg is the argument passed into the validator (eg for {required: true}, it is `true`) | ||||
|   #  - data is the entire set of data | ||||
|   @@validators = { | ||||
|     required:  lambda {|val, arg, data| !val.nil?}, | ||||
|     absent: lambda {|val, arg, data| val.nil?}, | ||||
|     not_blank: lambda {|val, arg, data| val.is_a?(String) && val.length > 0}, | ||||
|     not_included_in: lambda {|val, arg, data| !arg.include?(val) rescue false}, | ||||
|     included_in: lambda {|val, arg, data| arg.include?(val) rescue false}, | ||||
|     format: lambda {|val, arg, data| val =~ arg rescue false}, | ||||
|     is_integer: lambda {|val, arg, data| val.is_a?(Integer) || val =~ /\A[+-]?\d+\Z/}, | ||||
|     is_float: lambda {|val, arg, data| val.is_a?(Float) || (!!Float(val) rescue false) }, | ||||
|     min_length: lambda {|val, arg, data| val.length >= arg rescue false}, | ||||
|     max_length: lambda {|val, arg, data| val.length <= arg rescue false}, | ||||
|     length_range: lambda {|val, arg, data| arg.cover?(val.length) rescue false}, | ||||
|     length_equals: lambda {|val, arg, data| val.length == arg}, | ||||
|     is_reference: lambda{|val, arg, data| (val.is_a?(Integer)&& val >=0) || val =~ /\A\d+\Z/ || val == ''}, | ||||
|     equals: lambda {|val, arg, data| val == arg}, | ||||
|     min: lambda {|val, arg, data| val >= arg rescue false}, | ||||
|     max: lambda {|val, arg, data| val <= arg rescue false}, | ||||
|     is_array: lambda {|val, arg, data| val.is_a?(Array)}, | ||||
|     is_hash: lambda {|val, arg, data| val.is_a?(Hash)}, | ||||
|     is_json: lambda {|val, arg, data| ParamValidation.is_valid_json?(val)}, | ||||
|     in_range: lambda {|val, arg, data| arg.cover?(val) rescue false}, | ||||
|     is_a: lambda {|val, arg, data| arg.kind_of?(Enumerable) ? arg.any? {|i| val.is_a?(i)} : val.is_a?(arg)}, | ||||
|     can_be_date: lambda {|val, arg, data| val.is_a?(Date) || val.is_a?(DateTime) || Chronic.parse(val)}, | ||||
|     array_of_hashes: lambda {|val, arg, data| data.is_a?(Array) && data.map{|pair| ParamValidation.new(pair.to_h, arg)}.all?} | ||||
|   } | ||||
| 
 | ||||
|   @@messages = { | ||||
|     required: lambda {|h| "#{h[:key]} is required"}, | ||||
|     absent: lambda {|h| "#{h[:key]} must not be present"}, | ||||
|     not_blank: lambda {|h| "#{h[:key]} must not be blank"}, | ||||
|     not_included_in: lambda {|h| "#{h[:key]} must not be included in #{h[:arg].join(", ")}"}, | ||||
|     included_in: lambda {|h|"#{h[:key]} must be one of #{h[:arg].join(", ")}"}, | ||||
|     format: lambda {|h|"#{h[:key]} doesn't have the right format"}, | ||||
|     is_integer: lambda {|h|"#{h[:key]} should be an integer"}, | ||||
|     is_float: lambda {|h|"#{h[:key]} should be a float"}, | ||||
|     min_length: lambda {|h|"#{h[:key]} has a minimum length of #{h[:arg]}"}, | ||||
|     max_length: lambda {|h|"#{h[:key]} has a maximum length of #{h[:arg]}"}, | ||||
|     length_range: lambda {|h|"#{h[:key]} should have a length within #{h[:arg]}"}, | ||||
|     length_equals: lambda {|h|"#{h[:key]} should have a length of #{h[:arg]}"}, | ||||
|     is_reference: lambda{|h| "#{h[:key]} should be an integer or blank"}, | ||||
|     equals: lambda {|h|"#{h[:key]} should equal #{h[:arg]}"}, | ||||
|     min: lambda {|h|"#{h[:key]} must be at least #{h[:arg]}"}, | ||||
|     max: lambda {|h|"#{h[:key]} cannot be more than #{h[:arg]}"}, | ||||
|     in_range: lambda {|h|"#{h[:key]} should be within #{h[:arg]}"}, | ||||
|     is_json: lambda {|h| "#{h[:key]} should be valid JSON"}, | ||||
|     is_hash: lambda {|h| "#{h[:key]} should be a hash"}, | ||||
|     is_a: lambda  {|h| "#{h[:key]} should be of the type(s): #{h[:arg].kind_of?(Enumerable) ? h[:arg].join(', '): h[:arg]}"}, | ||||
|     can_be_date: lambda  {|h| "#{h[:key]} should be a datetime or be parsable as one"}, | ||||
|     array_of_hashes: lambda {|h| "Please pass in an array of hashes"} | ||||
|   } | ||||
| 
 | ||||
|   # small utility for testing json validity | ||||
|   def self.is_valid_json?(str) | ||||
|     begin | ||||
|       JSON.parse(str) | ||||
|       return true | ||||
|     rescue => e | ||||
|       return false | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   # Special error class that holds all the error data for reference | ||||
|   class ValidationError < TypeError | ||||
|     attr_reader :data | ||||
| 
 | ||||
|     # @param [String] msg message for the validation error(s). Multiple error | ||||
|     #   messages are split by new lines (\n) | ||||
|     # @param [Hash, Array<Hash>] data information about the validation failure | ||||
|     #   or failures. If one failure, a single failure hash is returned, if multiple, an array is returned. | ||||
|     #   Each failure hash has the following: | ||||
|     #     * :key - the [Symbol] of the key in the hash where verification failed | ||||
|     #     * :val - the value of pair in the hash selected by :key | ||||
|     #     * :name - the [Symbol] for the verification which failed | ||||
|     #     * :msg - the [String] for the msg for the verifications which failed | ||||
|     def initialize(msg, data) | ||||
|       @data = data | ||||
|       super(msg) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
| end | ||||
| 
 | ||||
							
								
								
									
										14
									
								
								gems/ruby-param-validation/param_validation.gemspec
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								gems/ruby-param-validation/param_validation.gemspec
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| Gem::Specification.new do |s| | ||||
|   s.name = 'param_validation' | ||||
|   s.version = '0.0.2' | ||||
|   s.date = '2017-07-21' | ||||
|   s.summary = 'Simple hash validator' | ||||
|   s.description = 'A hash validator that throws exceptions, with a lot of customization options' | ||||
|   s.authors = ['Jay R Bolton'] | ||||
|   s.email = 'jayrbolton@gmail.com' | ||||
|   s.files = 'lib/param_validation.rb' | ||||
|   s.homepage = 'https://github.com/jayrbolton/ruby-param-validation' | ||||
|   s.license = 'MIT' | ||||
| 
 | ||||
|   s.add_runtime_dependency 'chronic' | ||||
| end | ||||
							
								
								
									
										215
									
								
								gems/ruby-param-validation/test/param_validation_test.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								gems/ruby-param-validation/test/param_validation_test.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,215 @@ | |||
| require './lib/param_validation.rb' | ||||
| require 'minitest/autorun' | ||||
| 
 | ||||
| class ParamValidationTest < Minitest::Test | ||||
| 
 | ||||
|   def setup | ||||
|   end | ||||
| 
 | ||||
|   def test_required | ||||
|     begin; ParamValidation.new({}, {x: {required: true}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal :x, e.data[:key] | ||||
|   end | ||||
|   # If a key is not required, then don't run the tests on it | ||||
|   def test_not_required_and_absent_then_tests_do_not_run | ||||
|     ParamValidation.new({}, {x: {max: 100}}) | ||||
|     assert true | ||||
|   end | ||||
|   def test_not_blank_fail | ||||
|     begin; ParamValidation.new({x: ''}, {x: {not_blank: true}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal :x, e.data[:key] | ||||
|   end | ||||
|   def test_not_blank_fail_nil | ||||
|     begin; ParamValidation.new({x: nil}, {x: {not_blank: true, required: true}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert(e.data.one?{|i| i[:name] == :not_blank && i[:key] == :x}) | ||||
|     assert(e.data.one?{|i| i[:name] == :required && i[:key] == :x}) | ||||
|   end | ||||
|   def test_not_blank_succeed | ||||
|     ParamValidation.new({x: 'x'}, {x: {not_blank: true}}) | ||||
|     assert true | ||||
|   end | ||||
|   def test_require_no_err | ||||
|     begin; ParamValidation.new({x: 1}, {x: {required: true}}) | ||||
|     rescue ParamValidation::ValidationError => e; end | ||||
|     assert e.nil? | ||||
|   end | ||||
|   def test_absent | ||||
|     begin; ParamValidation.new({x: 1}, {x: {absent: true}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal :x, e.data[:key] | ||||
|   end | ||||
|   def test_not_included_in | ||||
|     begin; ParamValidation.new({x: 1}, {x: {not_included_in: [1]}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal :x, e.data[:key] | ||||
|   end | ||||
|   def test_included_in | ||||
|     begin; ParamValidation.new({x: 1}, {x: {included_in: [2]}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal :x, e.data[:key] | ||||
|   end | ||||
|   def test_format | ||||
|     begin; ParamValidation.new({x: 'x'}, {x: {format: /y/}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal :x, e.data[:key] | ||||
|   end | ||||
| 
 | ||||
|   def test_is_reference_string | ||||
|     begin; ParamValidation.new({x: '-0'}, {x: {is_reference: true}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal :x, e.data[:key] | ||||
|   end | ||||
| 
 | ||||
|   def test_is_reference_negative_integer | ||||
|     begin; ParamValidation.new({x: -1}, {x: {is_reference: true}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal :x, e.data[:key] | ||||
|   end | ||||
| 
 | ||||
|   def test_is_reference_passes | ||||
|     ParamValidation.new({x: '0'}, {x: {is_reference: true}}) | ||||
|     ParamValidation.new({x: 1}, {x: {is_reference: true}}) | ||||
|     ParamValidation.new({x: ''}, {x: {is_reference: true}}) | ||||
|     pass() | ||||
|   end | ||||
| 
 | ||||
|   def test_is_integer | ||||
|     begin; ParamValidation.new({x: 'x'}, {x: {is_integer: true}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal :x, e.data[:key] | ||||
|   end | ||||
|   def test_is_float | ||||
|     begin; ParamValidation.new({x: 'x'}, {x: {is_float: true}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal :x, e.data[:key] | ||||
|   end | ||||
|   def test_min_length | ||||
|     begin; ParamValidation.new({x: []}, {x: {min_length: 2}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal :x, e.data[:key] | ||||
|   end | ||||
|   def test_max_length | ||||
|     begin; ParamValidation.new({x: [1,2,3]}, {x: {max_length: 2}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal e.data[:key], :x | ||||
|   end | ||||
|   def test_length_range | ||||
|     begin; ParamValidation.new({x: [1,2,3,4]}, {x: {length_range: 1..3}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal e.data[:key], :x | ||||
|   end | ||||
|   def test_length_equals | ||||
|     begin; ParamValidation.new({x: [1,2]}, {x: {length_equals: 1}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal e.data[:key], :x | ||||
|   end | ||||
|   def test_min | ||||
|     begin; ParamValidation.new({x: 1}, {x: {min: 2}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal e.data[:key], :x | ||||
|   end | ||||
|   def test_max | ||||
|     begin; ParamValidation.new({x: 4}, {x: {max: 2}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal e.data[:name], :max | ||||
|   end | ||||
|   def test_in_range | ||||
|     begin; ParamValidation.new({x: 1}, {x: {in_range: 2..4}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal e.data[:val], 1 | ||||
|   end | ||||
|   def test_equals | ||||
|     begin; ParamValidation.new({x: 1}, {x: {equals: 2}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal "x should equal #{2}", e.to_s | ||||
|   end | ||||
|   def test_root_array_of_hashes | ||||
|     begin; ParamValidation.new({x: 1}, {root: {array_of_hashes: {x: {required: true}}}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal "Please pass in an array of hashes", e.to_s | ||||
|   end | ||||
|   def test_root_array_of_hashes_with_nesting_ok | ||||
|     v = ParamValidation.new([{'x' => 1}, {x: 1}], {root: {array_of_hashes: {x: {is_integer: true}}}}) | ||||
|     assert_equal v, v # test that it does not raise | ||||
|   end | ||||
|   def test_root_array_of_hashes_with_nesting | ||||
|     begin; ParamValidation.new([{x: 1}, {x: 'hi'}], {root: {array_of_hashes: {x: {is_integer: true}}}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal "x should be an integer", e.to_s | ||||
|   end | ||||
| 
 | ||||
|   def test_is_json_with_string | ||||
|     begin; ParamValidation.new({x: '[[[[[[['}, {x: {is_json: true}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal "x should be valid JSON", e.to_s | ||||
|   end | ||||
| 
 | ||||
|   def test_is_json_without_string | ||||
|     begin; ParamValidation.new({x: {}}, {x: {is_json: true}}) | ||||
|     rescue ParamValidation::ValidationError => e; e; end | ||||
|     assert_equal "x should be valid JSON", e.to_s | ||||
|   end | ||||
| 
 | ||||
|   def test_is_a_single | ||||
|     ParamValidation.new({x: 5.6}, {x: {is_a: Float}}) | ||||
|     begin | ||||
|       ParamValidation.new({x: 5.6}, {x: {is_a: Integer}}) | ||||
|     rescue ParamValidation::ValidationError => e | ||||
|       e | ||||
|     end | ||||
|     assert_equal 'x should be of the type(s): Integer', e.to_s | ||||
|   end | ||||
| 
 | ||||
| 
 | ||||
|   def test_is_a_multiple | ||||
|     ParamValidation.new({x: 5.6}, {x: {is_a: [Integer,Float]}}) | ||||
|     begin | ||||
|       ParamValidation.new({x: 5.6}, {x: {is_a: [Integer, Array]}}) | ||||
|     rescue ParamValidation::ValidationError => e | ||||
|       e | ||||
|     end | ||||
| 
 | ||||
|     assert_equal 'x should be of the type(s): Integer, Array', e.to_s | ||||
|   end | ||||
| 
 | ||||
|   def test_can_be_date | ||||
|     ParamValidation.new({x: Date.new()}, {x: {can_be_date: true}}) | ||||
|     ParamValidation.new({x: DateTime.new()}, {x: {can_be_date: true}}) | ||||
|     ParamValidation.new({x: '2017-05-15T12:00:00.000Z'}, {x: {can_be_date: true}}) | ||||
|     ParamValidation.new({x: '2017-05-15'}, {x: {can_be_date: true}}) | ||||
| 
 | ||||
|     begin | ||||
|       ParamValidation.new({x: 'not_a _date'}, {x: {can_be_date: true}}) | ||||
|     rescue ParamValidation::ValidationError => e | ||||
|       e | ||||
|     end | ||||
| 
 | ||||
|     assert_equal 'x should be a datetime or be parsable as one', e.to_s | ||||
|   end | ||||
| 
 | ||||
|   def test_add_validator | ||||
|     ParamValidation.add_validator(:dollars){|val, arg, data| val =~ /^\d+(\.\d\d)?$/} | ||||
|     begin | ||||
|       ParamValidation.new({x: 'hi'}, {x: {dollars: true}}) | ||||
|     rescue ParamValidation::ValidationError => e | ||||
|       e | ||||
|     end | ||||
|     assert_equal :dollars, e.data[:name] | ||||
|   end | ||||
|   def test_set_message | ||||
|     ParamValidation.add_validator(:dollars){|val, arg, data| val =~ /^\d+(\.\d\d)?$/} | ||||
|     ParamValidation.set_message(:dollars){|h| "#{h[:key]} must be a dollar amount"} | ||||
|     begin | ||||
|       ParamValidation.new({x: 'hi'}, {x: {dollars: true}}) | ||||
|     rescue ParamValidation::ValidationError => e | ||||
|       e | ||||
|     end | ||||
|     assert_equal "x must be a dollar amount", e.to_s | ||||
|   end | ||||
| 
 | ||||
|   def test_custom_validator | ||||
|   end | ||||
| end | ||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Eric Schultz
						Eric Schultz