Module: ICFS::Validate

Defined in:
lib/icfs/validate.rb

Overview

Object validation

Constant Summary collapse

IsBoolean =

Boolean

{
  method: :type,
  type: [ TrueClass, FalseClass ].freeze,
}.freeze
IsTempfile =

Tempfile

{
  method: :type,
  type: Tempfile,
}.freeze
IsFloat =

Float

{
  method: :type,
  type: [ Float ].freeze
}.freeze
IsIntPos =

Positive Integer

{
  method: :integer,
  min: 1
}.freeze
IsIntUns =

Unsigned Integer

{
  method: :integer,
  min: 0
}.freeze

Class Method Summary collapse

Class Method Details

.all(obj, val) ⇒ Array, NilClass

check that all the validations are good

Parameters:

  • obj (Object)

    object to validate

  • val (Hash)

    options

Options Hash (val):

  • :check (Array<Hash>)

    validations to check

  • :all (Boolean)

    Always check all the validations

Returns:

  • (Array, NilClass)

    error descriptions



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

def self.all(obj, val)
  return nil unless val[:check].is_a?(Array)

  errors = []
  bad = false

  val[:check].each do |check|
    err = Validate.check(obj, check)
    if err
      errors << err
      bad = true
      break unless val[:all]
    else
      errors << nil
    end
  end

  return bad ? errors : nil
end

.any(obj, val) ⇒ Array, NilClass

check that any one validation is good

Parameters:

  • obj (Object)

    object to validate

  • val (Hash)

    options

Options Hash (val):

  • :check (Array<Hash>)

    validations to check

Returns:

  • (Array, NilClass)

    error descriptions



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/icfs/validate.rb', line 53

def self.any(obj, val)
  return nil unless val[:check].is_a?(Array)

  errors = []

  val[:check].each do |chk|
    err = Validate.check(obj, chk)
    return nil if err.nil?
    errors << err
  end

  return errors
end

.array(obj, val) ⇒ Hash, NilClass

check an array

Parameters:

  • obj (Object)

    object to validate

  • val (Hash)

    options

Options Hash (val):

  • :min (Integer)

    Minimum length

  • :max (Integer)

    Maximum length

  • :uniq (TrueClass)

    Require all members to be unique

  • :check (Hash, Array)

    Validations for members of the array. If a Hash is provided, all members will be checked against it. If an Array is provided, they will be checked in order.

Returns:

  • (Hash, NilClass)

    error descriptions



250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/icfs/validate.rb', line 250

def self.array(obj, val)

  # type
  return 'not an Array'.freeze unless obj.is_a?(Array)

  errors = {}

  # min size
  if val[:min] && obj.size < val[:min]
    errors[:min] = true
  end

  # max size
  if val[:max] && obj.size > val[:max]
    errors[:max] = true
  end

  # all members uniq
  if val[:uniq] && obj.size != obj.uniq.size
    errors[:uniq] = true
  end

  # single check, all items of the array
  if val[:check].is_a?(Hash)
    check = val[:check]

    # each value
    obj.each_index do |ix|
      if val[ix]
        err = Validate.check(obj[ix], val[ix])
      else
        err = Validate.check(obj[ix], check)
      end
      errors[ix] = err if err
    end

  # an array of checks
  elsif val[:check].is_a?(Array)
    cka = val[:check]
    cs = cka.size

    # each value
    obj.each_index do |ix|
      if val[ix]
        err = Validate.check(obj[ix], val[ix])
      else
        err = Validate.check(obj[ix], cka[ix % cs])
      end
      errors[ix] = err if err
    end
  end

  return errors.empty? ? nil : errors
end

.check(obj, val) ⇒ Object

check an object

Parameters:

  • obj (Object)

    object to validate

  • val (Hash)

    the check to use

Returns:

  • (Object)

    error description



30
31
32
33
34
35
36
37
# File 'lib/icfs/validate.rb', line 30

def self.check(obj, val)
  if val.key?(:object)
    err = val[:object].send(val[:method], obj, val)
  else
    err = Validate.send(val[:method], obj, val)
  end
  return err
end

.equals(obj, val) ⇒ String, NilClass

Check for an exact value

Parameters:

  • obj (Object)

    object to validate

  • val (Hash)

    options

Options Hash (val):

  • :check (Integer)

    Value to compare

Returns:

  • (String, NilClass)

    error descriptions



106
107
108
109
110
111
112
# File 'lib/icfs/validate.rb', line 106

def self.equals(obj, val)
  if val[:check] == obj
    return nil
  else
    return 'not equal'.freeze
  end
end

.float(obj, val) ⇒ String, NilClass

check a float

Parameters:

  • obj (Object)

    object to validate

  • val (Hash)

    options

Options Hash (val):

  • :min (Float)

    Minimum value

  • :max (Float)

    Maximum value

Returns:

  • (String, NilClass)

    error descriptions



149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/icfs/validate.rb', line 149

def self.float(obj, val)
  return 'not a Float'.freeze unless obj.is_a?(Float)

  if val[:min] && obj < val[:min]
    return 'too small: %f < %f'.freeze % [obj, val[:min]]
  end

  if val[:max] && obj > val[:max]
    return 'too large: %f > %f'.freeze % [obj, val[:max]]
  end

  return nil
end

.hash(obj, val) ⇒ Hash, NilClass

check a hash

Parameters:

  • obj (Object)

    object to validate

  • val (Hash)

    options

Options Hash (val):

  • :required (Hash)

    Keys which must be present and their checks

  • :optional (Hash)

    Keys which may be present and their checks

  • :others (TrueClass)

    Allow other keys

Returns:

  • (Hash, NilClass)

    error descriptions



316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
# File 'lib/icfs/validate.rb', line 316

def self.hash(obj, val)

  # type
  return 'not a Hash'.freeze unless obj.is_a?(Hash)

  ary = obj.to_a
  chk = Array.new(ary.size)
  errors = {}

  # check all required keys
  if val[:required]
    val[:required].each do |key, check|

      # find the index
      ix = ary.index{|ok, ov| ok == key }

      # missing required key
      if ix.nil?
        errors[key] = 'missing'.freeze
        next
      end

      # check it
      err = Validate.check(ary[ix][1], check)
      errors[key] = err if err
      chk[ix] = true
    end
  end

  # check all optional keys
  if val[:optional]
    val[:optional].each do |key, check|

      # find the index
      ix = ary.index{|ok, ov| ok == key }
      next if ix.nil?

      # do the check
      err = Validate.check(ary[ix][1], check)
      errors[key] = err if err
      chk[ix] = true
    end
  end

  # make sure we have validated all keys
  if !val[:others]
    chk.each_index do |ix|
      next if chk[ix]
      errors[ary[ix][0]] = 'not allowed'.freeze
    end
  end

  # do we have any errors?
  return errors.empty? ? nil : errors

end

.integer(obj, val) ⇒ String, NilClass

check an integer

Parameters:

  • obj (Object)

    object to validate

  • val (Hash)

    options

Options Hash (val):

  • :min (Integer)

    Minimum value

  • :max (Integer)

    Maximum value

Returns:

  • (String, NilClass)

    error descriptions



125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/icfs/validate.rb', line 125

def self.integer(obj, val)
  return 'not an Integer'.freeze unless obj.is_a?(Integer)

  if val[:min] && obj < val[:min]
    return 'too small: %d < %d'.freeze % [obj, val[:min]]
  end

  if val[:max] && obj > val[:max]
    return 'too large: %d > %d '.freeze % [obj, val[:max]]
  end

  return nil
end

.string(obj, val) ⇒ Hash, NilClass

check a string

Parameters:

  • obj (Object)

    object to validate

  • val (Hash)

    options

Options Hash (val):

  • :allowed (#include?)

    Value which is always okay

  • :valid (#match)

    check for okay value

  • :whitelist (Boolean)

    Must be valid or allowed

  • :invalid (#match)

    check for bad values

  • :min (Integer)

    Minimum length

  • :max (Integer)

    Maximum length

Returns:

  • (Hash, NilClass)

    error descriptions



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/icfs/validate.rb', line 200

def self.string(obj, val)

  # type
  return 'not a String'.freeze unless obj.is_a?(String)

  errors = {}

  # good values
  if (val[:allowed] && val[:allowed].include?(obj)) ||
     (val[:valid] && val[:valid].match(obj))
    return nil
  end

  # if whitelisting
  if val[:whitelist]
    errors[:whitelist] = 'Value was not whitelisted'.freeze
  end

  # min length
  if val[:min] && obj.size < val[:min]
    errors[:min] = 'too short: %d < %d' % [obj.size, val[:min]]
  end

  # max length
  if val[:max] && obj.size > val[:max]
    errors[:max] = 'too long: %d > %d' % [obj.size, val[:max]]
  end

  # invalid
  if val[:invalid] && val[:invalid].match(obj)
    errors[:invalid] = true
  end

  return errors.empty? ? nil : errors
end

.type(obj, val) ⇒ String, NilClass

check for a type

Parameters:

  • obj (Object)

    object to validate

  • val (Hash)

    options

Options Hash (val):

  • :type (Class, Array)

    The class or module to check

Returns:

  • (String, NilClass)

    error descriptions



172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/icfs/validate.rb', line 172

def self.type(obj, val)
  if val[:type]
    if val[:type].is_a?(Array)
      val[:type].each{|cl| return nil if obj.is_a?(cl) }
      return 'not a listed type'.freeze
    else
      if !obj.is_a?(val[:type])
        return 'not a %s'.freeze % val[:type].name
      end
    end
  end
  return nil
end