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