class Stannum::Contracts::HashContract
A HashContract
defines constraints on an hash’s values.
@example Creating A Hash Contract
hash_contract = Stannum::Contracts::HashContract.new hash_contract.add_constraint( negated_type: 'example.is_boolean', property: :ok, property_type: :key, type: 'example.is_not_boolean' ) { |actual| actual == true || actual == false } hash_contract.add_constraint( Stannum::Constraints::Type.new(Hash), property: :data, property_type: :key, ) hash_contract.add_constraint( Stannum::Constraints::Presence.new, property: :signature, property_type: :key, )
@example With A Non-Hash Object
hash_contract.matches?(nil) #=> false errors = hash_contract.errors_for(nil) #=> [{ type: 'is_not_type', data: { type: Hash }, path: [], message: nil }] hash_contract.does_not_match?(nil) #=> true hash_contract.negated_errors_for?(nil).to_a #=> []
@example With A Hash That Matches None Of The Key Constraints
hash_contract.matches?({}) #=> false errors = hash_contract.errors_for({}) errors.to_a #=> [ { type: 'is_not_boolean', data: {}, path: [:ok], message: nil }, { type: 'is_not_type', data: { type: Hash }, path: [:data], message: nil }, { type: 'absent', data: {}, path: [:signature], message: nil } ] hash_contract.does_not_match?({}) #=> false errors.to_a #=> [ { type: 'is_type', data: { type: Hash }, path: [], message: nil } ]
@example With A Hash That Matches Some Of The Key Constraints
hash = { ok: true, signature: '' } hash_contract.matches?(hash) #=> false errors = hash_contract.errors_for(hash) errors.to_a #=> [ { type: 'is_not_type', data: { type: Hash }, path: [:data], message: nil }, { type: 'absent', data: {}, path: [:signature], message: nil } ] hash_contract.does_not_match?(hash) #=> false errors = hash_contract.negated_errors_for?(hash) errors.to_a #=> [ { type: 'is_type', data: { type: Hash }, path: [], message: nil }, { type: 'is_boolean', data: {}, path: [:ok], message: nil } ]
@example With A Hash That Matches All Of The Key Constraints
hash = { ok: true, data: {}, signature: 'abc' } hash_contract.matches?(hash) #=> true hash_contract.errors_for(hash).to_a #=> [] hash_contract.does_not_match?(hash) #=> false errors = hash_contract.negated_errors_for?(hash) errors.to_a #=> [ { type: 'is_type', data: { type: Hash }, path: [], message: nil }, { type: 'is_boolean', data: {}, path: [:ok], message: nil }, { type: 'present', data: {}, path: [:signature], message: nil }, ]
Public Class Methods
new( allow_extra_keys: false, key_type: nil, value_type: nil, **options, &block )
click to toggle source
@param allow_extra_keys [true, false] If true, the contract will match
hashes with keys that are not constrained by the contract.
@param key_type
[Stannum::Constraints::Base, Class, nil] If set, then the
constraint will check the types of each key in the Hash against the expected type and will fail if any keys do not match.
@param value_type
[Stannum::Constraints::Base, Class, nil] If set, then
the constraint will check the types of each value in the Hash against the expected type and will fail if any values do not match.
@param options [Hash<Symbol, Object>] Configuration options for the
contract. Defaults to an empty Hash.
Calls superclass method
Stannum::Contracts::MapContract::new
# File lib/stannum/contracts/hash_contract.rb, line 96 def initialize( allow_extra_keys: false, key_type: nil, value_type: nil, **options, &block ) super( allow_extra_keys: allow_extra_keys, key_type: key_type, value_type: value_type, **options, &block ) end
Public Instance Methods
key_type()
click to toggle source
@return [Stannum::Constraints::Base, Class, nil] the expected type for the
keys in the Hash, if any.
# File lib/stannum/contracts/hash_contract.rb, line 114 def key_type options[:key_type] end
value_type()
click to toggle source
@return [Stannum::Constraints::Base, Class, nil] the expected type for the
values in the Hash, if any.
# File lib/stannum/contracts/hash_contract.rb, line 120 def value_type options[:value_type] end
Protected Instance Methods
map_errors(errors, **options)
click to toggle source
Calls superclass method
Stannum::Contract#map_errors
# File lib/stannum/contracts/hash_contract.rb, line 126 def map_errors(errors, **options) return super unless options[:property_type] == :key property_name = options.fetch(:property_name, options[:property]) property_name = property_name.nil? ? [nil] : Array(property_name) property_name = property_name.map do |key| Stannum::Support::Coercion.error_key(key) end errors.dig(*property_name) end
Private Instance Methods
add_type_constraint()
click to toggle source
# File lib/stannum/contracts/hash_contract.rb, line 140 def add_type_constraint add_constraint( Stannum::Constraints::Types::HashType.new( key_type: key_type, value_type: value_type ), sanity: true ) end