valid-1.0.0/0000755000076400007640000000000012571343122011643 5ustar pravipravivalid-1.0.0/README.md0000644000076400007640000000541512571343122013127 0ustar pravipravi# Validator [![Build Status](https://secure.travis-ci.org/zombor/Validator.png)](http://travis-ci.org/zombor/Validator) Validator is a simple ruby validation class. You don't use it directly inside your classes like just about every other ruby validation class out there. I chose to implement it in this way so I didn't automatically pollute the namespace of the objects I wanted to validate. This also solves the problem of validating forms very nicely. Frequently you will have a form that represents many different data objects in your system, and you can pre-validate everything before doing any saving. ## Usage Validator is useful for validating the state of any existing ruby object. ```ruby object = OpenStruct.new(:email => 'foo@bar.com', :password => 'foobar') validator = Validation::Validator.new(object) validator.rule(:email, [:email, :not_empty]) # multiple rules in one line validator.rule(:password, :not_empty) # a single rule on a line validator.rule(:password, :length => {:minimum => 3}) # a rule that takes parameters if validator.valid? # save the data somewhere else @errors = validator.errors end ``` The first paramater can be any message that the object responds to. ### Writing your own rules If you have a custom rule you need to write, just put it inside the `Validation::Rule` namespace: ```ruby module Validation module Rule class MyCustomRule def error_key :my_custom_rule end def valid_value?(value) # Logic for determining the validity of the value end def params {} end end end end ``` A rule class should have the following methods on it: - `error_key` a symbol to represent the error. This shows up in the errors hash. Must be an underscored_version of the class name - `valid_value?(value)` the beef of the rule. This is where you determine if the value is valid or not - `params` the params hash that was passed into the constructor ### Writing self-contained validators You can also create self-contained validation classes if you don't like the dynamic creation approach: ```ruby require 'validation' require 'validation/rule/not_empty' class MyFormValidator < Validation::Validator include Validation rule :email, :not_empty end ``` Now you can use this anywhere in your code: ```ruby form_validator = MyFormValidator.new(OpenStruct.new(params)) form_validator.valid? ``` # Contributing Have an improvement? Have an awesome rule you want included? Simple! 1. Fork the repository 2. Create a branch off of the `develop` branch 3. Write specs for the change 4. Add your change 5. Submit a pull request to merge against the `develop` branch Don't change any version files or gemspec files in your change. valid-1.0.0/metadata.yml0000644000076400007640000000242712571343122014153 0ustar pravipravi--- !ruby/object:Gem::Specification name: valid version: !ruby/object:Gem::Version version: 1.0.0 platform: ruby authors: - Jeremy Bush autorequire: bindir: bin cert_chain: [] date: 2015-08-10 00:00:00.000000000 Z dependencies: [] description: email: - contractfrombelow@gmail.com executables: [] extensions: [] extra_rdoc_files: [] files: - README.md - lib/validation.rb - lib/validation/rule/email.rb - lib/validation/rule/length.rb - lib/validation/rule/matches.rb - lib/validation/rule/not_empty.rb - lib/validation/rule/numeric.rb - lib/validation/rule/phone.rb - lib/validation/rule/regular_expression.rb - lib/validation/rule/uri.rb - lib/validation/rule/uuid.rb - lib/validation/validator.rb - lib/validation/version.rb homepage: https://github.com/zombor/Validator licenses: [] metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 2.2.2 signing_key: specification_version: 4 summary: A standalone, generic object validator for ruby test_files: [] valid-1.0.0/lib/0000755000076400007640000000000012571343122012411 5ustar pravipravivalid-1.0.0/lib/validation/0000755000076400007640000000000012571343122014543 5ustar pravipravivalid-1.0.0/lib/validation/version.rb0000644000076400007640000000005212571343122016552 0ustar pravipravimodule Validation VERSION = '1.0.0' end valid-1.0.0/lib/validation/validator.rb0000644000076400007640000000704412571343122017062 0ustar pravipravimodule Validation module Rules # A hash of rules for this object def rules @rules ||= {} end # A hash of errors for this object def errors @errors ||= {} end # Define a rule for this object # # The rule parameter can be one of the following: # # * a symbol that matches to a class in the Validation::Rule namespace # * e.g. rule(:field, :not_empty) # * a hash containing the rule as the key and it's parameters as the values # * e.g. rule(:field, :length => {:minimum => 3, :maximum => 5}) # * an array combining the two previous types def rule(field, rule) field = field.to_sym if rules[field].nil? rules[field] = [] end begin if rule.respond_to?(:each_pair) add_parameterized_rule(field, rule) elsif rule.respond_to?(:each) rule.each do |r| if r.respond_to?(:each_pair) add_parameterized_rule(field, r) else r = Validation::Rule.const_get(camelize(r)).new add_object_to_rule(r) rules[field] << r end end else rule = Validation::Rule.const_get(camelize(rule)).new add_object_to_rule(rule) rules[field] << rule end rescue NameError => e raise InvalidRule.new(e) end self end # Determines if this object is valid. When a rule fails for a field, # this will stop processing further rules. In this way, you'll only get # one error per field def valid? valid = true rules.each_pair do |field, rules| if ! @obj.respond_to?(field) raise InvalidKey end rules.each do |r| if ! r.valid_value?(@obj.send(field)) valid = false errors[field] = {:rule => r.error_key, :params => r.params} break end end end @valid = valid end protected # Adds a parameterized rule to this object def add_parameterized_rule(field, rule) rule.each_pair do |key, value| r = Validation::Rule.const_get(camelize(key)).new(value) add_object_to_rule(r) rules[field] << r end end # Adds this validation object to a rule if it can accept it def add_object_to_rule(rule) if rule.respond_to?(:obj=) rule.obj = @obj end end # Converts a symbol to a class name, taken from rails def camelize(term) string = term.to_s string = string.sub(/^[a-z\d]*/) { $&.capitalize } string.gsub(/(?:_|(\/))([a-z\d]*)/i) { $2.capitalize }.gsub('/', '::') end end # Validator is a simple ruby validation class. You don't use it directly # inside your classes like just about every other ruby validation class out # there. I chose to implement it in this way so I didn't automatically # pollute the namespace of the objects I wanted to validate. # # This also solves the problem of validating forms very nicely. Frequently # you will have a form that represents many different data objects in your # system, and you can pre-validate everything before doing any saving. class Validator include Validation::Rules def initialize(obj) @rules = self.class.rules if self.class.is_a?(Validation::Rules) @obj = obj end end # InvalidKey is raised if a rule is added to a field that doesn't exist class InvalidKey < RuntimeError end # InvalidRule is raised if a rule is added that doesn't exist class InvalidRule < RuntimeError end end valid-1.0.0/lib/validation/rule/0000755000076400007640000000000012571343122015512 5ustar pravipravivalid-1.0.0/lib/validation/rule/numeric.rb0000644000076400007640000000062512571343122017504 0ustar pravipravimodule Validation module Rule # rule for numeric values class Numeric # Determines if value is numeric. It can only contain whole numbers def valid_value?(value) !!/^[0-9]+$/.match(value.to_s) end # The error key for this rule def error_key :numeric end # this rule has no params def params {} end end end end valid-1.0.0/lib/validation/rule/length.rb0000644000076400007640000000175612571343122017331 0ustar pravipravimodule Validation module Rule # Length rule class Length # params can be any of the following: # # - :minimum - at least this many chars # - :maximum - at most this many chars # - :exact - exactly this many chars # # Example: # # {:minimum => 3, :maximum => 10} # {:exact => 10} def initialize(params) @params = params end # returns the params given in the constructor def params @params end # determines if value is valid according to the constructor params def valid_value?(value) @params.each_pair do |key, param| return false if key == :minimum && (value.nil? || value.length < param) return false if key == :maximum && !value.nil? && value.length > param return false if key == :exact && (value.nil? || value.length != param) end true end def error_key :length end end end end valid-1.0.0/lib/validation/rule/uuid.rb0000644000076400007640000000153412571343122017010 0ustar pravipravimodule Validation # UUID rule module Rule class Uuid class UnknownVersion < StandardError; end # params can be any of the folowing: # # - :version - v4 (only supports v4 at this time) # # Example: # # {:version => v4} def initialize(params) @params = params end def params @params end def valid_value?(value) value.nil? || !!uuid_regex.match(value.to_s) rescue UnknownVersion false end def error_key :uuid end private def uuid_regex if params[:version] == 'v4' uuid_v4_regex else raise UnknownVersion end end def uuid_v4_regex /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i end end end end valid-1.0.0/lib/validation/rule/not_empty.rb0000644000076400007640000000062312571343122020056 0ustar pravipravimodule Validation module Rule # Rule for not empty class NotEmpty # This rule has no params def params {} end # Determines if value is empty or not. In this rule, nil is empty def valid_value?(value) ! (value.nil? || value.empty?) end # The error key for this field def error_key :not_empty end end end end valid-1.0.0/lib/validation/rule/regular_expression.rb0000644000076400007640000000052412571343122021760 0ustar pravipravimodule Validation module Rule class RegularExpression def initialize(params) @params = params end def error_key :regular_expression end def valid_value?(value) value.nil? || !!@params[:regex].match(value) end def params @params end end end end valid-1.0.0/lib/validation/rule/phone.rb0000644000076400007640000000141412571343122017150 0ustar pravipravimodule Validation module Rule # Phone rule class Phone # params can be any of the following: # # - :format - the phone number format # # Example: # # {:format => :america} def initialize(params = {:format => :america}) @params = params end # returns the params given in the constructor def params @params end # determines if value is valid according to the constructor params def valid_value?(value) send(@params[:format], value) end def error_key :phone end protected def america(value) digits = value.gsub(/\D/, '').split(//) digits.length == 10 || digits.length == 11 end end end end valid-1.0.0/lib/validation/rule/uri.rb0000644000076400007640000000112412571343122016634 0ustar pravipravimodule Validation module Rule class URI def initialize(parts=[:host]) @required_parts = parts end def error_key :uri end def params {:required_elements => @required_parts} end def valid_value?(uri_string) return true if uri_string.nil? uri = URI(uri_string) @required_parts.each do |part| if uri.send(part).nil? || uri.send(part).empty? return false end end true rescue ::URI::InvalidURIError return false end end end end valid-1.0.0/lib/validation/rule/matches.rb0000644000076400007640000000144712571343122017471 0ustar pravipravimodule Validation module Rule # Matches rule class Matches attr_writer :obj # This class should take the field to match with in the constructor: # # rule = Validation::Rule::Matches(:password) # rule.obj = OpenStruct.new(:password => 'foo') # rule.valid_value?('foo') def initialize(matcher_field) @matcher_field = matcher_field end # The error key for this rule def error_key :matches end # Params is the matcher_field given in the constructor def params @matcher_field end # Determines if value matches the field given in the constructor def valid_value?(value) matcher_value = @obj.send(@matcher_field) matcher_value == value end end end end valid-1.0.0/lib/validation/rule/email.rb0000644000076400007640000000332012571343122017124 0ustar pravipravimodule Validation module Rule # Email rule class. This rule was adapted from https://github.com/emmanuel/aequitas/blob/master/lib/aequitas/rule/format/email_address.rb class Email EMAIL_ADDRESS = begin letter = 'a-zA-Z' digit = '0-9' atext = "[#{letter}#{digit}\!\#\$\%\&\'\*+\/\=\?\^\_\`\{\|\}\~\-]" dot_atom_text = "#{atext}+([.]#{atext}*)+" dot_atom = dot_atom_text no_ws_ctl = '\x01-\x08\x11\x12\x14-\x1f\x7f' qtext = "[^#{no_ws_ctl}\\x0d\\x22\\x5c]" # Non-whitespace, non-control character except for \ and " text = '[\x01-\x09\x11\x12\x14-\x7f]' quoted_pair = "(\\x5c#{text})" qcontent = "(?:#{qtext}|#{quoted_pair})" quoted_string = "[\"]#{qcontent}+[\"]" atom = "#{atext}+" word = "(?:#{atom}|#{quoted_string})" obs_local_part = "#{word}([.]#{word})*" local_part = "(?:#{dot_atom}|#{quoted_string}|#{obs_local_part})" dtext = "[#{no_ws_ctl}\\x21-\\x5a\\x5e-\\x7e]" dcontent = "(?:#{dtext}|#{quoted_pair})" domain_literal = "\\[#{dcontent}+\\]" obs_domain = "#{atom}([.]#{atom})+" domain = "(?:#{dot_atom}|#{domain_literal}|#{obs_domain})" addr_spec = "#{local_part}\@#{domain}" pattern = /\A#{addr_spec}\z/u end # Determines if value is a valid email def valid_value?(value) !!EMAIL_ADDRESS.match(value) end # The error key for this rule def error_key :email end # This rule has no params def params {} end end end end valid-1.0.0/lib/validation.rb0000644000076400007640000000027412571343122015073 0ustar pravipravirequire 'validation/validator' module Validation class << self private def included(mod) mod.module_eval do extend Validation::Rules end end end end