Class: RubyMotionQuery::Validation

Inherits:
Object
  • Object
show all
Defined in:
lib/project/ruby_motion_query/rmq_validation.rb

Overview

End RMQ

Constant Summary collapse

EMAIL =
'^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$'
URL =
'^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&\'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&\'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&\'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&\'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&\'\(\)\*\+,;=]|:|@)|\/|\?)*)?$'
DATEISO =
'^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$'
NUMBER =
'^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$'
DIGITS =
'^\d+$'
IPV4 =
'^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
TIME =
'^(20|21|22|23|[01]\d|\d)((:[0-5]\d){1,2})$'
USZIP =

Future Password strength validations -> stackoverflow.com/questions/5142103/regex-for-password-strength

'^\d{5}(-\d{4})?$'
UKZIP =

UK Postal Code regex from: stackoverflow.com/a/7259020/814123

'^(GIR ?0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]([0-9ABEHMNPRV-Y])?)|[0-9][A-HJKPS-UW]) ?[0-9][ABD-HJLNP-UW-Z]{2})$'
USPHONE =

7 or 10 digit number, delimiters are spaces, dashes, or periods

'^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]‌​)\s*)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-‌​9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})$'
INTLPHONE =

International Phone numbers

'^(\(?\+?[0-9]*\)?)?[0-9_\- \(\)]*$'
STRONGPW =

Strong password (at least [8 chars, 1 upper, 1 lower, 1 number])

'^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$'
HASUPPER =

Has at least 1 uppercase letter

'^(?=.*[A-Z]).+$'
HASLOWER =

Has at least 1 lowercase letter

'^(?=.*[a-z]).+$'
NOT_PRESENCE =

is just whitespace

'^\s*$'
@@validation_methods =

Needed for android presence madness

{
  :email => lambda { |value, opts| value.toString.matches(EMAIL)},
  :url => lambda { |value, opts| value.toString.matches(URL)},
  :dateiso => lambda { |value, opts| value.toString.matches(DATEISO)},
  :number => lambda { |value, opts| value.toString.matches(NUMBER)},
  :digits => lambda { |value, opts| value.toString.matches(DIGITS)},
  :ipv4 => lambda { |value, opts| value.toString.matches(IPV4)},
  :time => lambda { |value, opts| value.toString.matches(TIME)},
  :uszip => lambda { |value, opts| value.toString.matches(USZIP)},
  :ukzip => lambda { |value, opts| value.toString.matches(UKZIP)},
  :usphone => lambda { |value, opts| value.toString.matches(USPHONE)},
  :intlphone => lambda { |value, opts| value.toString.matches(INTLPHONE)},
  :strong_password => lambda { |value, opts| value.toString.matches(STRONGPW)},
  :has_upper => lambda { |value, opts| value.toString.matches(HASUPPER)},
  :has_lower => lambda { |value, opts| value.toString.matches(HASLOWER)},
  :presence => lambda { |value, opts| !value.toString.matches(NOT_PRESENCE)},
  :length => lambda { |value, opts|
    opts = {
      exact_length: nil,
      max_length: Float::INFINITY,
      min_length: 0,
      strip: false
    }.merge(opts)
     # Range magic 8..16
    if opts[:exact_length].is_a? Range
      opts[:min_length] = opts[:exact_length].begin
      opts[:max_length] = opts[:exact_length].end
      opts[:exact_length] = nil
    end
     # allowing option to strip input before assessing length
    value.strip! if opts[:strip]
     # check length validation
    v = if opts[:exact_length] then (value.length == opts[:exact_length]) else true end
    v = v && value.length <= opts[:max_length]
    v = v && value.length >= opts[:min_length]
  },
  :custom => lambda { |value, opts| value.toString.matches(opts[:regex])},
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(rule, options = {}) ⇒ Validation

Returns a new instance of Validation.



165
166
167
168
169
170
171
# File 'lib/project/ruby_motion_query/rmq_validation.rb', line 165

def initialize(rule, options={})
  @rule = @@validation_methods[rule]
  raise "RMQ validation error: :#{rule} is not one of the supported validation methods." unless @rule
  @rule_name = rule
  @options = options
  @valid_status = true
end

Instance Attribute Details

#rule_nameObject (readonly)

Returns the value of attribute rule_name.



89
90
91
# File 'lib/project/ruby_motion_query/rmq_validation.rb', line 89

def rule_name
  @rule_name
end

#valid_statusObject (readonly)

Returns the value of attribute valid_status.



89
90
91
# File 'lib/project/ruby_motion_query/rmq_validation.rb', line 89

def valid_status
  @valid_status
end

Class Method Details

.add_validator(rule, &block) ⇒ Object

Raises:

  • (ArgumentError)


211
212
213
214
215
# File 'lib/project/ruby_motion_query/rmq_validation.rb', line 211

def add_validator(rule, &block)
  raise(ArgumentError, "add_validator requires a block") if block.nil?

  @@validation_methods[rule] = block
end

.valid?(value, rule, options = {}) ⇒ Boolean

Add tags

Examples:

rmq.validation.valid?('[email protected]', :email)
rmq.validation.valid?(53.8, :number)
rmq.validation.valid?(54, :digits)
rmq.validation.valid?('https://www.tacoland.com', :url)
rmq.validation.valid?('2014-03-02', :dateiso)
rmq.validation.valid?('', :email, allow_blank: true)

Returns:

  • (Boolean)


207
208
209
# File 'lib/project/ruby_motion_query/rmq_validation.rb', line 207

def valid?(value, rule, options={})
  Validation.new(rule).valid?(value, options)
end

Instance Method Details

#universal_validation_checks(data, options = {}) ⇒ Object

this method shortcuts specific validation rules. As such it should only be added to for universal validation needs. It must be kept as efficient as possible.



184
185
186
187
188
189
190
191
192
193
# File 'lib/project/ruby_motion_query/rmq_validation.rb', line 184

def universal_validation_checks (data, options={})
  # shortcircuit if debugging
  return true if RubyMotionQuery::RMQ.debugging?
  # allow blank data if specified
  return true if (options[:allow_blank] && (data.nil? || data.empty?))
  # allow whitelist data if specified
  return true if (options[:white_list] && options[:white_list].include?(data))

  false
end

#valid?(data, options = {}) ⇒ Boolean

Returns:

  • (Boolean)


173
174
175
176
177
178
179
180
# File 'lib/project/ruby_motion_query/rmq_validation.rb', line 173

def valid?(data, options={})
  @options = options.merge(@options)

  # shortcircuit for universal validation parameters
  return true if universal_validation_checks(data, @options)

  @valid_status = @rule.call(data, @options)
end