class Stannum::Constraints::Hashes::ExtraKeys
Constraint
for validating the keys of a hash-like object.
@example
keys = %[fuel mass size] constraint = Stannum::Constraints::Hashes::ExpectedKeys.new(keys) constraint.matches?({}) #=> true constraint.matches?({ fuel: 'Monopropellant' }) #=> true constraint.matches?({ electric: true, fuel: 'Xenon' }) #=> false constraint.matches?({ fuel: 'LF/O', mass: '1 ton', size: 'Medium' }) #=> true constraint.matches?( { fuel: 'LF', mass: '2 tons', nuclear: true, size: 'Medium' } ) #=> false
Constants
- NEGATED_TYPE
The :type of the error generated for a matching object.
- TYPE
The :type of the error generated for a non-matching object.
Public Class Methods
new(expected_keys, **options)
click to toggle source
@param expected_keys
[Array, Proc] The expected keys. If a Proc, will be
evaluated each time the constraint is matched.
@param options [Hash<Symbol, Object>] Configuration options for the
constraint. Defaults to an empty Hash.
Calls superclass method
Stannum::Constraints::Base::new
# File lib/stannum/constraints/hashes/extra_keys.rb, line 33 def initialize(expected_keys, **options) validate_expected_keys(expected_keys) expected_keys = if expected_keys.is_a?(Array) Set.new(expected_keys) else expected_keys end super(expected_keys: expected_keys, **options) end
Public Instance Methods
does_not_match?(actual)
click to toggle source
@return [true, false] true if the object responds to [] and keys and the
object has at least one key that is not in expected_keys.
# File lib/stannum/constraints/hashes/extra_keys.rb, line 48 def does_not_match?(actual) return false unless hash?(actual) !(Set.new(actual.keys) <= expected_keys) # rubocop:disable Style/InverseMethods end
errors_for(actual, errors: nil)
click to toggle source
(see Stannum::Constraints::Base#errors_for
)
# File lib/stannum/constraints/hashes/extra_keys.rb, line 55 def errors_for(actual, errors: nil) errors ||= Stannum::Errors.new unless actual.respond_to?(:keys) return add_invalid_hash_error(actual: actual, errors: errors) end each_extra_key(actual) do |key, value| key = Stannum::Support::Coercion.error_key(key) errors[key].add(type, value: value) end errors end
expected_keys()
click to toggle source
@return [Array] the expected keys.
# File lib/stannum/constraints/hashes/extra_keys.rb, line 72 def expected_keys keys = options[:expected_keys] return keys unless keys.is_a?(Proc) Set.new(keys.call) end
matches?(actual)
click to toggle source
@return [true, false] true if the object responds to [] and keys and the
object does not have any key that is not in expected_keys.
# File lib/stannum/constraints/hashes/extra_keys.rb, line 82 def matches?(actual) return false unless actual.respond_to?(:keys) Set.new(actual.keys) <= expected_keys end
Also aliased as: match?
Private Instance Methods
add_invalid_hash_error(actual:, errors:)
click to toggle source
# File lib/stannum/constraints/hashes/extra_keys.rb, line 91 def add_invalid_hash_error(actual:, errors:) Stannum::Constraints::Signature .new(:keys) .errors_for(actual, errors: errors) end
each_extra_key(actual) { |key, actual| ... }
click to toggle source
# File lib/stannum/constraints/hashes/extra_keys.rb, line 97 def each_extra_key(actual) expected = expected_keys actual.each_key do |key| next if expected.include?(key) yield key, actual[key] end end
hash?(actual)
click to toggle source
# File lib/stannum/constraints/hashes/extra_keys.rb, line 107 def hash?(actual) actual.respond_to?(:[]) && actual.respond_to?(:keys) end
valid_key?(key)
click to toggle source
# File lib/stannum/constraints/hashes/extra_keys.rb, line 111 def valid_key?(key) key.is_a?(String) || key.is_a?(Symbol) end
validate_expected_keys(expected_keys)
click to toggle source
# File lib/stannum/constraints/hashes/extra_keys.rb, line 115 def validate_expected_keys(expected_keys) expected_keys = expected_keys.call if expected_keys.is_a?(Proc) unless expected_keys.is_a?(Array) raise ArgumentError, 'expected_keys must be an Array or a Proc', caller(1..-1) end return if expected_keys.all? { |key| valid_key?(key) } raise ArgumentError, 'key must be a String or Symbol', caller(1..-1) end