Class: Stannum::Contracts::TupleContract

Inherits:
Stannum::Contract show all
Defined in:
lib/stannum/contracts/tuple_contract.rb

Overview

A TupleContract defines constraints for an ordered, indexed object.

In order to match a TupleContract, the object must respond to the :[], :each, and :size methods, and the items in the object at each index must match the item constraint defined for that index. Finally, unless the :allow_extra_items option is set to true, the object must not have any extra items.

Examples:

Creating A Contract With Item Constraints

third_base_constraint = Stannum::Constraint.new do |actual|
  actual == "I Don't Know"
end
tuple_contract = Stannum::Contracts::TupleContract.new do
  item { |actual| actual == 'Who' }
  item { |actual| actual == 'What' }
  item third_base_constraint
end

With A Non-Tuple Object

tuple_contract.matches?(nil) #=> false
errors = tuple_contract.errors_for(nil)
errors.to_a
#=> [
  {
    type:    'stannum.constraints.does_not_have_methods',
    data:    { methods: [:[], :each, :size], missing: [:[], :each, :size] },
    message: nil,
    path:    []
  }
]

With An Object With Missing Items

tuple_contract.matches?(['Who']) #=> false
errors = tuple_contract.errors_for(['Who'])
errors.to_a
#=> [
  { type: 'stannum.constraints.invalid', data: {}, path: [1], message: nil },
  { type: 'stannum.constraints.invalid', data: {}, path: [2], message: nil }
]

With An Object With Incorrect Items

tuple_contract.matches?(['What', 'What', "I Don't Know"]) #=> false
errors = tuple_contract.errors_for(['What', 'What', "I Don't Know"])
errors.to_a
#=> [
  { type: 'stannum.constraints.invalid', data: {}, path: [0], message: nil }
]

With An Object With Valid Items

tuple_contract.matches?(['Who', 'What', "I Don't Know"]) #=> true
errors = tuple_contract.errors_for(['What', 'What', "I Don't Know"])
errors.to_a #=> []

With An Object With Extra Items

tuple_contract.matches?(['Who', 'What', "I Don't Know", 'Tomorrow', 'Today']) #=> false
errors = tuple_contract.errors_for(['Who', 'What', "I Don't Know", 'Tomorrow', 'Today'])
errors.to_a
#=> [
  { type: 'stannum.constraints.tuples.extra_items', data: {}, path: [3], message: nil },
  { type: 'stannum.constraints.tuples.extra_items', data: {}, path: [4], message: nil }
]

Direct Known Subclasses

ArrayContract, Parameters::ArgumentsContract

Defined Under Namespace

Classes: Builder

Constant Summary

Constants inherited from Stannum::Constraints::Base

Stannum::Constraints::Base::NEGATED_TYPE, Stannum::Constraints::Base::TYPE

Instance Attribute Summary

Attributes inherited from Stannum::Constraints::Base

#options

Instance Method Summary collapse

Methods inherited from Stannum::Contract

#add_constraint, #add_property_constraint

Methods inherited from Base

#==, #add_constraint, #concat, #does_not_match?, #each_constraint, #each_pair, #errors_for, #match, #matches?, #negated_errors_for, #negated_match

Methods inherited from Stannum::Constraints::Base

#==, #clone, #does_not_match?, #dup, #errors_for, #match, #matches?, #message, #negated_errors_for, #negated_match, #negated_message, #negated_type, #type

Constructor Details

#initialize(allow_extra_items: false, **options, &block) ⇒ TupleContract

Returns a new instance of TupleContract.

Parameters:

  • allow_extra_items (true, false) (defaults to: false)

    If false, then a tuple with extra items after the last expected item will not match the contract.

  • options (Hash<Symbol, Object>)

    Configuration options for the contract. Defaults to an empty Hash.



119
120
121
# File 'lib/stannum/contracts/tuple_contract.rb', line 119

def initialize(allow_extra_items: false, **options, &block)
  super(allow_extra_items: allow_extra_items, **options, &block)
end

Instance Method Details

#add_index_constraint(index, constraint, sanity: false, **options) ⇒ self

Adds an index constraint to the contract.

When the contract is called, the contract will find the value of the object at the given index.

Parameters:

  • index (Integer)

    The index of the value to match.

  • constraint (Stannum::Constraints::Base)

    The constraint to add.

  • sanity (true, false) (defaults to: false)

    Marks the constraint as a sanity constraint, which is always matched first and will always short-circuit on a failed match.

  • options (Hash<Symbol, Object>)

    Options for the constraint. These can be used by subclasses to define the value and error mappings for the constraint.

Returns:

  • (self)

    the contract.

See Also:

  • Stannum::Contract#add_constraint.


140
141
142
143
144
145
146
147
148
# File 'lib/stannum/contracts/tuple_contract.rb', line 140

def add_index_constraint(index, constraint, sanity: false, **options)
  add_constraint(
    constraint,
    property:      index,
    property_type: :index,
    sanity:        sanity,
    **options
  )
end

#allow_extra_items?true, false

Returns If false, then a tuple with extra items after the last expected item will not match the contract.

Returns:

  • (true, false)

    If false, then a tuple with extra items after the last expected item will not match the contract.



152
153
154
# File 'lib/stannum/contracts/tuple_contract.rb', line 152

def allow_extra_items?
  !!options[:allow_extra_items]
end

#with_options(**options) ⇒ Object

Raises:

  • (ArgumentError)


157
158
159
160
161
# File 'lib/stannum/contracts/tuple_contract.rb', line 157

def with_options(**options)
  return super unless options.key?(:allow_extra_items)

  raise ArgumentError, "can't change option :allow_extra_items"
end