Module: RSpec::JsonApi::Constraints

Defined in:
lib/rspec/json_api/constraints.rb

Overview

Constraints evaluates the option hash produced by a schema Proc (e.g. ‘-> { { type: Integer, min: 1, max: 10, allow_blank: true } }`) against an actual value.

allow_blank is a modifier, not a constraint of its own: when it is true a blank value is accepted and the remaining options are skipped; otherwise the value is checked against every other option.

Constant Summary collapse

SUPPORTED_OPTIONS =
%i[allow_blank type value min max inclusion regex lambda].freeze

Class Method Summary collapse

Class Method Details

.match(value, options) ⇒ Boolean

Returns true when the value satisfies the options.

Parameters:

  • value (Object)

    the actual value being matched.

  • options (Hash)

    the option hash returned by the schema Proc.

Returns:

  • (Boolean)

    true when the value satisfies the options.

Raises:

  • (ArgumentError)

    when an option key is not supported.



21
22
23
24
25
26
27
28
29
# File 'lib/rspec/json_api/constraints.rb', line 21

def match(value, options)
  validate!(options)

  return true if value.blank? && options[:allow_blank]

  options.except(:allow_blank).all? do |option, condition|
    satisfies?(value, option, condition)
  end
end

.satisfies?(value, option, condition) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
41
42
43
44
45
46
47
# File 'lib/rspec/json_api/constraints.rb', line 38

def satisfies?(value, option, condition)
  case option
  when :type      then value.instance_of?(condition)
  when :value     then value == condition
  when :inclusion then condition.include?(value)
  when :regex     then condition.match?(value.to_s)
  when :lambda    then condition.call(value)
  when :min, :max then within_bound?(value, option, condition)
  end
end

.validate!(options) ⇒ Object

Raises:

  • (ArgumentError)


31
32
33
34
35
36
# File 'lib/rspec/json_api/constraints.rb', line 31

def validate!(options)
  unknown = options.keys - SUPPORTED_OPTIONS
  return if unknown.empty?

  raise ArgumentError, "Unsupported match option(s): #{unknown.join(", ")}"
end

.within_bound?(value, option, condition) ⇒ Boolean

Returns:

  • (Boolean)


49
50
51
52
53
# File 'lib/rspec/json_api/constraints.rb', line 49

def within_bound?(value, option, condition)
  return false unless value.is_a?(Numeric) && condition.is_a?(Numeric)

  option == :min ? value >= condition : value <= condition
end