Class: Aequitas::Rule::Format

Inherits:
Aequitas::Rule show all
Defined in:
lib/aequitas/rule/format.rb,
lib/aequitas/rule/format/url.rb,
lib/aequitas/rule/format/proc.rb,
lib/aequitas/rule/format/regexp.rb,
lib/aequitas/rule/format/email_address.rb

Direct Known Subclasses

Proc, Regexp

Defined Under Namespace

Classes: Proc, Regexp

Constant Summary

FORMATS =
{}
FORMAT_MESSAGES =

TODO: evaluate re-implementing custom error messages per format type previously these strings were wrapped in lambdas, which were, at one point, invoked with #try_call with the humanized attribute name and value

{
  :email_address => '%s is not a valid email address',
  :url           => '%s is not a valid URL',
}
URL =
begin
  /(^$)|(^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}((\:[0-9]{1,5})?\/?.*)?$)/ix
end
EMAIL_ADDRESS =

Almost RFC2822 (No attribution reference available).

This differs in that it does not allow local domains (test@localhost). 99% of the time you do not want to allow these email addresses in a public web application.

begin
  if (RUBY_VERSION == '1.9.2' && RUBY_ENGINE == 'jruby' && JRUBY_VERSION <= '1.6.3') || RUBY_VERSION == '1.9.3'
    # There is an obscure bug in jruby 1.6 that prevents matching
    # on unicode properties here. Remove this logic branch once
    # a stable jruby release fixes this.
    #
    # http://jira.codehaus.org/browse/JRUBY-5622
    #
    # There is a similar bug in preview releases of 1.9.3
    #
    # http://redmine.ruby-lang.org/issues/5126
    letter = 'a-zA-Z'
  else
    letter = 'a-zA-Z\p{L}'  # Changed from RFC2822 to include unicode chars
  end
  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

Instance Attribute Summary (collapse)

Attributes inherited from Aequitas::Rule

#attribute_name, #custom_message, #guard, #skip_condition

Attributes included from ValueObject

#equalizer

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods inherited from Aequitas::Rule

#attribute_value, #execute?, #skip?, #validate, #violation_data, #violation_info, #violation_values

Methods included from ValueObject

#equalize_on

Constructor Details

- (Format) initialize(attribute_name, options)



47
48
49
50
51
52
53
54
# File 'lib/aequitas/rule/format.rb', line 47

def initialize(attribute_name, options)
  super

  @format = options.fetch(:format)

  skip_condition.default_to_allowing_nil!
  skip_condition.default_to_allowing_blank!
end

Instance Attribute Details

- (Object) format (readonly)

Returns the value of attribute format



45
46
47
# File 'lib/aequitas/rule/format.rb', line 45

def format
  @format
end

Class Method Details

+ (Object) rules_for(attribute_name, options)

Raises:

  • (UnknownValidationFormat)

    if the :as (or :with) option is a Symbol that is not a key in FORMATS, or if the provided format is not a Regexp, Symbol or Proc



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/aequitas/rule/format.rb', line 24

def self.rules_for(attribute_name, options)
  format = options.values_at(:as, :with).compact.first

  rule =
    case format
    when Symbol
      regexp = FORMATS.fetch(format) do
        raise UnknownValidationFormat, "No such predefined format '#{format}'"
      end
      self::Regexp.new(attribute_name, options.merge(:format => regexp, :format_name => format))
    when ::Regexp
      self::Regexp.new(attribute_name, options.merge(:format => format))
    when ::Proc
      self::Proc.new(attribute_name, options.merge(:format => format))
    else
      raise UnknownValidationFormat, "Expected a Regexp, Symbol, or Proc format. Got: #{format.inspect}"
    end

  Array(rule)
end

Instance Method Details

- (Boolean) valid_value?(value)



56
57
58
59
60
61
# File 'lib/aequitas/rule/format.rb', line 56

def valid_value?(value)
  expected_format?(value)
rescue ::Encoding::CompatibilityError
  # This is to work around a bug in jruby - see formats/email.rb
  false
end

- (Object) violation_type



63
64
65
# File 'lib/aequitas/rule/format.rb', line 63

def violation_type
  :invalid
end