Class: Ward::Validator

Inherits:
Object
  • Object
show all
Defined in:
lib/ward/validator.rb

Overview

Pairs a context (or chain) with a matcher.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(context, matcher, options = {}) ⇒ Validator

Creates a new Validator.

Options Hash (options):

  • :scenarios (Symbol, Array<Symbol>)

    An array of scenarios in which this validator should be run

  • :message (Hash{Symbol => String}, String)

    The error message to be used if the validator fails (see DSL::ValidationBuilder#message).

  • :context_name (String)

    The name to be used for the context when generating error messages.



55
56
57
58
59
60
61
# File 'lib/ward/validator.rb', line 55

def initialize(context, matcher, options = {})
  @context, @matcher = context, matcher
  @scenarios = Array(options[:scenarios] || :default).freeze
  @negative = options[:negative] || false
  @message  = options[:message].freeze
  @context_name = options[:context_name].freeze
end

Instance Attribute Details

#contextWard::ContextChain, Ward::Context (readonly)

Returns the context.



10
11
12
# File 'lib/ward/validator.rb', line 10

def context
  @context
end

#matcherWard::Matchers::Matcher (readonly)

Returns the matcher.



16
17
18
# File 'lib/ward/validator.rb', line 16

def matcher
  @matcher
end

#messageHash, ... (readonly)

An override to the default message.

If set, this message will always be used if the validation fails, regardless of whether it is used as a positive or negative assertion.



36
37
38
# File 'lib/ward/validator.rb', line 36

def message
  @message
end

#scenariosEnumerable<Symbol> (readonly)

The scenarios under which the validator will be run.



22
23
24
# File 'lib/ward/validator.rb', line 22

def scenarios
  @scenarios
end

Instance Method Details

#negative?Boolean

Returns if the validator expects that the matcher not match.

Use with the is_not and does_not DSL keyword.



115
116
117
# File 'lib/ward/validator.rb', line 115

def negative?
  @negative
end

#scenario?(scenario) ⇒ Boolean

Returns if the validator should be run as part of the given scenario.



105
106
107
# File 'lib/ward/validator.rb', line 105

def scenario?(scenario)
  @scenarios.include?(scenario)
end

#validate(record) ⇒ Array<Boolean, {nil, String, Symbol}>

Determines if the validator is valid for the given record.

The return value deviates from the ValidatorSet API -- where #valid? returns only a boolean value -- but that's fine since you shouldn't be calling Validator#valid? in your applications anyway. :)



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/ward/validator.rb', line 77

def validate(record)
  # If the matches? method on the matcher takes two arguments, send in the
  # record as well as the value.
  result = if @matcher.method(:matches?).arity != 1
    @matcher.matches?(@context.value(record), record)
  else
    @matcher.matches?(@context.value(record))
  end

  result, error = if defined?(Rubinius)
    # Rubinius treats any value which responds to #to_a as being
    # array-like, thus multiple assignment breaks if the matcher returns
    # such an object.
    result.is_a?(Array) ? result : [result].flatten
  else
    result
  end

  (!! result) ^ negative? ? [ true, nil ] : [ false, error_for(error) ]
end