Class: Aspect::Verifier

Inherits:
Object
  • Object
show all
Includes:
HasAttributes
Defined in:
lib/aspect/verifier.rb,
lib/aspect/verifier/check.rb

Overview

Verify a set of checks on an object.

The result is a ‘Hash` where the keys are the check name and the value is the expectation or `nil` when the object is verified to be valid.

This allows for it to easily be transformed into messages using MessageTransform, if needed.

Examples:

Simple boolean checks.

require "aspect/verifier"

verifier = Aspect::Verifier.new(:presence, :integer)

verifier.verify(nil)     # => { presence: true, integer: true } # Invalid
verifier.verify("")      # => { presence: true, integer: true } # Invalid
verifier.verify("hello") # => { integer: true }                 # Invalid
verifier.verify("24")    # => nil                               # Valid

Simple checks with arguments.

require "aspect/verifier"

verifier = Aspect::Verifier.new(integer: true, greater_than: 10)

verifier.verify(10) # => { greater_than: 10 }                     # Invalid
verifier.verify("hello") # => { integer: true, greater_than: 10 } # Invalid
verifier.verify("24") # => nil                                    # Valid

Break on fail.

require "aspect/verifier"

verifier = Aspect::Verifier.new(integer: true, greater_than: 10)

verifier.verify("hello") # => { integer: true, greater_than: 10 }
verifier.verify("hello", break_on_fail: true) # => { integer: true }

Fake application usage example

require "aspect/verifier"

age_verifier = Aspect::Verifier.new(:integer, greater_than_or_equal_to: 18)

loop do
  print "age? "

  input = gets
  error = age_verifier.verify(input, break_on_fail: true)

  if error
    puts "  Must give a number." if error[:integer]
    puts "  Must be #{error[:greater_than_or_equal_to]} or older." if error[:greater_than_or_equal_to]
  else
    puts "  Welcome, appropriately-aged user!"

    break
  end
end

# Command line:
#   age? foobar
#     Must give a number.
#   age? 17
#     Must be 18 or older.
#   age? 25
#     Welcome, appropriately-aged user!

Fake application usage example with MessageTransform

require "aspect/verifier"
require "aspect/message_transform"

age_verifier = Aspect::Verifier.new(:integer, greater_than_or_equal_to: 18)
message = Aspect::MessageTransform.new(
  welcome: "Welcome, appropriately-aged user!",
  error: {
    integer: "Must give a number.",
    greater_than_or_equal_to: "Must be %{greater_than_or_equal_to} or older."
  }
)

loop do
  print "age? "

  input = gets
  error = age_verifier.verify(input, break_on_fail: true)

  print "  "
  if error
    puts message.to_s(error: error)
  else
    puts message.to_s(:welcome)

    break
  end
end

# Command line:
#   age? foobar
#     Must give a number.
#   age? 17
#     Must be 18 or older.
#   age? 25
#     Welcome, appropriately-aged user!

Defined Under Namespace

Classes: Check

Instance Method Summary collapse

Methods included from HasAttributes

included, #update_attributes

Constructor Details

#initialize(*arguments) ⇒ Verifier

Returns a new instance of Verifier.

Examples:

Multiple flags, for boolean checks.

Aspect::Verifier.new(:presence, :integer)

‘Array` of flags, for boolean checks.

Aspect::Verifier.new([:presence, :integer])

Passing a ‘Hash`, for non-boolean checks.

Aspect::Verifier.new(presence: true, integer: true, greater_than: 10)

Mixing both boolean and non-boolean checks.

Aspect::Verifier.new(:presence, :integer, greater_than: 10)


113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/aspect/verifier.rb', line 113

def initialize(*arguments)
  attributes = {}

  if arguments.length == 1 && arguments[0].respond_to?(:to_h)
    attributes = arguments[0]
  else
    arguments = arguments[0] if arguments.length == 1 && arguments[0].is_a?(Array)

    arguments.collect(&:to_sym).each { |check| attributes[check] = true }
  end

  update_attributes(attributes)
end

Instance Method Details

#equal_toBoolean

Get whether to for equality against a given object.

Returns:

  • (Boolean)


200
# File 'lib/aspect/verifier.rb', line 200

attribute(:equal_to)

#equal_to=nil, Object

Set the object to check equality against.

Parameters:

  • value (nil, Object)

Returns:

  • (nil, Object)


# File 'lib/aspect/verifier.rb', line 190

#float=Boolean

Set whether to check for ‘Float`.

The values ‘123.4` and `“123.4”` will both pass.

Parameters:

  • value (Boolean)

Returns:

  • (Boolean)


# File 'lib/aspect/verifier.rb', line 176

#float?Boolean

Get whether to check for ‘Float`.

Returns:

  • (Boolean)


188
# File 'lib/aspect/verifier.rb', line 188

attribute(:float, query: true)

#integer=Boolean

Set whether to check for ‘Integer`.

The values ‘123` and `“123”` will both pass, but `123.4` and `“123.4”` will both fail.

Parameters:

  • value (Boolean)

Returns:

  • (Boolean)


# File 'lib/aspect/verifier.rb', line 162

#integer?Boolean

Get whether to check for ‘Integer`.

Returns:

  • (Boolean)


174
# File 'lib/aspect/verifier.rb', line 174

attribute(:integer, query: true)

#presence=Boolean

Set whether to check for presence.

Objects that are ‘nil`, or respond to `empty?` and return `true`, are considered blank.

Parameters:

  • value (Boolean)

Returns:

  • (Boolean)


# File 'lib/aspect/verifier.rb', line 148

#presence?Boolean

Get whether to check for presence.

Returns:

  • (Boolean)


160
# File 'lib/aspect/verifier.rb', line 160

attribute(:presence, query: true)

#validate(value, options = {}) ⇒ <Symbol, Object>

Validate a value.

Parameters:

  • value
  • options (#to_h) (defaults to: {})

Options Hash (options):

  • :break_on_fail (Boolean)

    Set to ‘true` to stop running checks as soon as one fails.

Returns:

  • (<Symbol, Object>)

    The result is a ‘Hash` where the keys are the check name and the value is the expectation or `nil` when the object is verified to be valid.



133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/aspect/verifier.rb', line 133

def validate(value, options={})
  options = { break_on_fail: false }.merge(options.to_h)
  errors = {}

  Check.registry.each do |check_name, check|
    check_iv = instance_variable_get("@#{check_name}")

    errors[check_name] = check_iv if check_iv && !check.call(value, check_iv)

    break if options[:break_on_fail]
  end

  errors
end